Merge branch 'master' of /usr/src/ntfs-2.6/
This commit is contained in:
commit
1f04c0a24b
|
@ -0,0 +1,122 @@
|
||||||
|
RCU Torture Test Operation
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_RCU_TORTURE_TEST
|
||||||
|
|
||||||
|
The CONFIG_RCU_TORTURE_TEST config option is available for all RCU
|
||||||
|
implementations. It creates an rcutorture kernel module that can
|
||||||
|
be loaded to run a torture test. The test periodically outputs
|
||||||
|
status messages via printk(), which can be examined via the dmesg
|
||||||
|
command (perhaps grepping for "rcutorture"). The test is started
|
||||||
|
when the module is loaded, and stops when the module is unloaded.
|
||||||
|
|
||||||
|
However, actually setting this config option to "y" results in the system
|
||||||
|
running the test immediately upon boot, and ending only when the system
|
||||||
|
is taken down. Normally, one will instead want to build the system
|
||||||
|
with CONFIG_RCU_TORTURE_TEST=m and to use modprobe and rmmod to control
|
||||||
|
the test, perhaps using a script similar to the one shown at the end of
|
||||||
|
this document. Note that you will need CONFIG_MODULE_UNLOAD in order
|
||||||
|
to be able to end the test.
|
||||||
|
|
||||||
|
|
||||||
|
MODULE PARAMETERS
|
||||||
|
|
||||||
|
This module has the following parameters:
|
||||||
|
|
||||||
|
nreaders This is the number of RCU reading threads supported.
|
||||||
|
The default is twice the number of CPUs. Why twice?
|
||||||
|
To properly exercise RCU implementations with preemptible
|
||||||
|
read-side critical sections.
|
||||||
|
|
||||||
|
stat_interval The number of seconds between output of torture
|
||||||
|
statistics (via printk()). Regardless of the interval,
|
||||||
|
statistics are printed when the module is unloaded.
|
||||||
|
Setting the interval to zero causes the statistics to
|
||||||
|
be printed -only- when the module is unloaded, and this
|
||||||
|
is the default.
|
||||||
|
|
||||||
|
verbose Enable debug printk()s. Default is disabled.
|
||||||
|
|
||||||
|
|
||||||
|
OUTPUT
|
||||||
|
|
||||||
|
The statistics output is as follows:
|
||||||
|
|
||||||
|
rcutorture: --- Start of test: nreaders=16 stat_interval=0 verbose=0
|
||||||
|
rcutorture: rtc: 0000000000000000 ver: 1916 tfle: 0 rta: 1916 rtaf: 0 rtf: 1915
|
||||||
|
rcutorture: Reader Pipe: 1466408 9747 0 0 0 0 0 0 0 0 0
|
||||||
|
rcutorture: Reader Batch: 1464477 11678 0 0 0 0 0 0 0 0
|
||||||
|
rcutorture: Free-Block Circulation: 1915 1915 1915 1915 1915 1915 1915 1915 1915 1915 0
|
||||||
|
rcutorture: --- End of test
|
||||||
|
|
||||||
|
The command "dmesg | grep rcutorture:" will extract this information on
|
||||||
|
most systems. On more esoteric configurations, it may be necessary to
|
||||||
|
use other commands to access the output of the printk()s used by
|
||||||
|
the RCU torture test. The printk()s use KERN_ALERT, so they should
|
||||||
|
be evident. ;-)
|
||||||
|
|
||||||
|
The entries are as follows:
|
||||||
|
|
||||||
|
o "ggp": The number of counter flips (or batches) since boot.
|
||||||
|
|
||||||
|
o "rtc": The hexadecimal address of the structure currently visible
|
||||||
|
to readers.
|
||||||
|
|
||||||
|
o "ver": The number of times since boot that the rcutw writer task
|
||||||
|
has changed the structure visible to readers.
|
||||||
|
|
||||||
|
o "tfle": If non-zero, indicates that the "torture freelist"
|
||||||
|
containing structure to be placed into the "rtc" area is empty.
|
||||||
|
This condition is important, since it can fool you into thinking
|
||||||
|
that RCU is working when it is not. :-/
|
||||||
|
|
||||||
|
o "rta": Number of structures allocated from the torture freelist.
|
||||||
|
|
||||||
|
o "rtaf": Number of allocations from the torture freelist that have
|
||||||
|
failed due to the list being empty.
|
||||||
|
|
||||||
|
o "rtf": Number of frees into the torture freelist.
|
||||||
|
|
||||||
|
o "Reader Pipe": Histogram of "ages" of structures seen by readers.
|
||||||
|
If any entries past the first two are non-zero, RCU is broken.
|
||||||
|
And rcutorture prints the error flag string "!!!" to make sure
|
||||||
|
you notice. The age of a newly allocated structure is zero,
|
||||||
|
it becomes one when removed from reader visibility, and is
|
||||||
|
incremented once per grace period subsequently -- and is freed
|
||||||
|
after passing through (RCU_TORTURE_PIPE_LEN-2) grace periods.
|
||||||
|
|
||||||
|
The output displayed above was taken from a correctly working
|
||||||
|
RCU. If you want to see what it looks like when broken, break
|
||||||
|
it yourself. ;-)
|
||||||
|
|
||||||
|
o "Reader Batch": Another histogram of "ages" of structures seen
|
||||||
|
by readers, but in terms of counter flips (or batches) rather
|
||||||
|
than in terms of grace periods. The legal number of non-zero
|
||||||
|
entries is again two. The reason for this separate view is
|
||||||
|
that it is easier to get the third entry to show up in the
|
||||||
|
"Reader Batch" list than in the "Reader Pipe" list.
|
||||||
|
|
||||||
|
o "Free-Block Circulation": Shows the number of torture structures
|
||||||
|
that have reached a given point in the pipeline. The first element
|
||||||
|
should closely correspond to the number of structures allocated,
|
||||||
|
the second to the number that have been removed from reader view,
|
||||||
|
and all but the last remaining to the corresponding number of
|
||||||
|
passes through a grace period. The last entry should be zero,
|
||||||
|
as it is only incremented if a torture structure's counter
|
||||||
|
somehow gets incremented farther than it should.
|
||||||
|
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
|
||||||
|
The following script may be used to torture RCU:
|
||||||
|
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
modprobe rcutorture
|
||||||
|
sleep 100
|
||||||
|
rmmod rcutorture
|
||||||
|
dmesg | grep rcutorture:
|
||||||
|
|
||||||
|
The output can be manually inspected for the error flag of "!!!".
|
||||||
|
One could of course create a more elaborate script that automatically
|
||||||
|
checked for such errors.
|
|
@ -94,7 +94,7 @@ the available CPU and Memory resources amongst the requesting tasks.
|
||||||
But larger systems, which benefit more from careful processor and
|
But larger systems, which benefit more from careful processor and
|
||||||
memory placement to reduce memory access times and contention,
|
memory placement to reduce memory access times and contention,
|
||||||
and which typically represent a larger investment for the customer,
|
and which typically represent a larger investment for the customer,
|
||||||
can benefit from explictly placing jobs on properly sized subsets of
|
can benefit from explicitly placing jobs on properly sized subsets of
|
||||||
the system.
|
the system.
|
||||||
|
|
||||||
This can be especially valuable on:
|
This can be especially valuable on:
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
#include "linux/firmware.h"
|
#include "linux/firmware.h"
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/string.h>
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -273,6 +273,7 @@ For now, you can ignore the `flags' parameter. It is there for future use.
|
||||||
if (is_isa) {
|
if (is_isa) {
|
||||||
|
|
||||||
/* Discard immediately if this ISA range is already used */
|
/* Discard immediately if this ISA range is already used */
|
||||||
|
/* FIXME: never use check_region(), only request_region() */
|
||||||
if (check_region(address,FOO_EXTENT))
|
if (check_region(address,FOO_EXTENT))
|
||||||
goto ERROR0;
|
goto ERROR0;
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ KEY ACCESS PERMISSIONS
|
||||||
|
|
||||||
Keys have an owner user ID, a group access ID, and a permissions mask. The mask
|
Keys have an owner user ID, a group access ID, and a permissions mask. The mask
|
||||||
has up to eight bits each for possessor, user, group and other access. Only
|
has up to eight bits each for possessor, user, group and other access. Only
|
||||||
five of each set of eight bits are defined. These permissions granted are:
|
six of each set of eight bits are defined. These permissions granted are:
|
||||||
|
|
||||||
(*) View
|
(*) View
|
||||||
|
|
||||||
|
@ -224,6 +224,10 @@ five of each set of eight bits are defined. These permissions granted are:
|
||||||
keyring to a key, a process must have Write permission on the keyring and
|
keyring to a key, a process must have Write permission on the keyring and
|
||||||
Link permission on the key.
|
Link permission on the key.
|
||||||
|
|
||||||
|
(*) Set Attribute
|
||||||
|
|
||||||
|
This permits a key's UID, GID and permissions mask to be changed.
|
||||||
|
|
||||||
For changing the ownership, group ID or permissions mask, being the owner of
|
For changing the ownership, group ID or permissions mask, being the owner of
|
||||||
the key or having the sysadmin capability is sufficient.
|
the key or having the sysadmin capability is sufficient.
|
||||||
|
|
||||||
|
@ -242,15 +246,15 @@ about the status of the key service:
|
||||||
this way:
|
this way:
|
||||||
|
|
||||||
SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
|
SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
|
||||||
00000001 I----- 39 perm 1f1f0000 0 0 keyring _uid_ses.0: 1/4
|
00000001 I----- 39 perm 1f3f0000 0 0 keyring _uid_ses.0: 1/4
|
||||||
00000002 I----- 2 perm 1f1f0000 0 0 keyring _uid.0: empty
|
00000002 I----- 2 perm 1f3f0000 0 0 keyring _uid.0: empty
|
||||||
00000007 I----- 1 perm 1f1f0000 0 0 keyring _pid.1: empty
|
00000007 I----- 1 perm 1f3f0000 0 0 keyring _pid.1: empty
|
||||||
0000018d I----- 1 perm 1f1f0000 0 0 keyring _pid.412: empty
|
0000018d I----- 1 perm 1f3f0000 0 0 keyring _pid.412: empty
|
||||||
000004d2 I--Q-- 1 perm 1f1f0000 32 -1 keyring _uid.32: 1/4
|
000004d2 I--Q-- 1 perm 1f3f0000 32 -1 keyring _uid.32: 1/4
|
||||||
000004d3 I--Q-- 3 perm 1f1f0000 32 -1 keyring _uid_ses.32: empty
|
000004d3 I--Q-- 3 perm 1f3f0000 32 -1 keyring _uid_ses.32: empty
|
||||||
00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0
|
00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0
|
||||||
00000893 I--Q-N 1 35s 1f1f0000 0 0 user metal:silver: 0
|
00000893 I--Q-N 1 35s 1f3f0000 0 0 user metal:silver: 0
|
||||||
00000894 I--Q-- 1 10h 001f0000 0 0 user metal:gold: 0
|
00000894 I--Q-- 1 10h 003f0000 0 0 user metal:gold: 0
|
||||||
|
|
||||||
The flags are:
|
The flags are:
|
||||||
|
|
||||||
|
|
|
@ -2286,6 +2286,11 @@ W: http://tpmdd.sourceforge.net
|
||||||
L: tpmdd-devel@lists.sourceforge.net
|
L: tpmdd-devel@lists.sourceforge.net
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
Telecom Clock Driver for MCPL0010
|
||||||
|
P: Mark Gross
|
||||||
|
M: mark.gross@intel.com
|
||||||
|
S: Supported
|
||||||
|
|
||||||
TENSILICA XTENSA PORT (xtensa):
|
TENSILICA XTENSA PORT (xtensa):
|
||||||
P: Chris Zankel
|
P: Chris Zankel
|
||||||
M: chris@zankel.net
|
M: chris@zankel.net
|
||||||
|
|
4
README
4
README
|
@ -54,6 +54,10 @@ INSTALLING the kernel:
|
||||||
|
|
||||||
gzip -cd linux-2.6.XX.tar.gz | tar xvf -
|
gzip -cd linux-2.6.XX.tar.gz | tar xvf -
|
||||||
|
|
||||||
|
or
|
||||||
|
bzip2 -dc linux-2.6.XX.tar.bz2 | tar xvf -
|
||||||
|
|
||||||
|
|
||||||
Replace "XX" with the version number of the latest kernel.
|
Replace "XX" with the version number of the latest kernel.
|
||||||
|
|
||||||
Do NOT use the /usr/src/linux area! This area has a (usually
|
Do NOT use the /usr/src/linux area! This area has a (usually
|
||||||
|
|
|
@ -55,10 +55,6 @@
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "irq_impl.h"
|
#include "irq_impl.h"
|
||||||
|
|
||||||
u64 jiffies_64 = INITIAL_JIFFIES;
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(jiffies_64);
|
|
||||||
|
|
||||||
extern unsigned long wall_jiffies; /* kernel/timer.c */
|
extern unsigned long wall_jiffies; /* kernel/timer.c */
|
||||||
|
|
||||||
static int set_rtc_mmss(unsigned long);
|
static int set_rtc_mmss(unsigned long);
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
|
@ -33,8 +33,8 @@
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
|
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
|
||||||
#undef STATS
|
#undef STATS
|
||||||
|
|
||||||
#ifdef STATS
|
#ifdef STATS
|
||||||
#define DO_STATS(X) do { X ; } while (0)
|
#define DO_STATS(X) do { X ; } while (0)
|
||||||
#else
|
#else
|
||||||
|
@ -52,26 +52,31 @@ struct safe_buffer {
|
||||||
int direction;
|
int direction;
|
||||||
|
|
||||||
/* safe buffer info */
|
/* safe buffer info */
|
||||||
struct dma_pool *pool;
|
struct dmabounce_pool *pool;
|
||||||
void *safe;
|
void *safe;
|
||||||
dma_addr_t safe_dma_addr;
|
dma_addr_t safe_dma_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dmabounce_pool {
|
||||||
|
unsigned long size;
|
||||||
|
struct dma_pool *pool;
|
||||||
|
#ifdef STATS
|
||||||
|
unsigned long allocs;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
struct dmabounce_device_info {
|
struct dmabounce_device_info {
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
|
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct dma_pool *small_buffer_pool;
|
|
||||||
struct dma_pool *large_buffer_pool;
|
|
||||||
struct list_head safe_buffers;
|
struct list_head safe_buffers;
|
||||||
unsigned long small_buffer_size, large_buffer_size;
|
|
||||||
#ifdef STATS
|
#ifdef STATS
|
||||||
unsigned long sbp_allocs;
|
|
||||||
unsigned long lbp_allocs;
|
|
||||||
unsigned long total_allocs;
|
unsigned long total_allocs;
|
||||||
unsigned long map_op_count;
|
unsigned long map_op_count;
|
||||||
unsigned long bounce_count;
|
unsigned long bounce_count;
|
||||||
#endif
|
#endif
|
||||||
|
struct dmabounce_pool small;
|
||||||
|
struct dmabounce_pool large;
|
||||||
};
|
};
|
||||||
|
|
||||||
static LIST_HEAD(dmabounce_devs);
|
static LIST_HEAD(dmabounce_devs);
|
||||||
|
@ -82,9 +87,9 @@ static void print_alloc_stats(struct dmabounce_device_info *device_info)
|
||||||
printk(KERN_INFO
|
printk(KERN_INFO
|
||||||
"%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n",
|
"%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n",
|
||||||
device_info->dev->bus_id,
|
device_info->dev->bus_id,
|
||||||
device_info->sbp_allocs, device_info->lbp_allocs,
|
device_info->small.allocs, device_info->large.allocs,
|
||||||
device_info->total_allocs - device_info->sbp_allocs -
|
device_info->total_allocs - device_info->small.allocs -
|
||||||
device_info->lbp_allocs,
|
device_info->large.allocs,
|
||||||
device_info->total_allocs);
|
device_info->total_allocs);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -106,18 +111,22 @@ find_dmabounce_dev(struct device *dev)
|
||||||
/* allocate a 'safe' buffer and keep track of it */
|
/* allocate a 'safe' buffer and keep track of it */
|
||||||
static inline struct safe_buffer *
|
static inline struct safe_buffer *
|
||||||
alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
|
alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
|
||||||
size_t size, enum dma_data_direction dir)
|
size_t size, enum dma_data_direction dir)
|
||||||
{
|
{
|
||||||
struct safe_buffer *buf;
|
struct safe_buffer *buf;
|
||||||
struct dma_pool *pool;
|
struct dmabounce_pool *pool;
|
||||||
struct device *dev = device_info->dev;
|
struct device *dev = device_info->dev;
|
||||||
void *safe;
|
|
||||||
dma_addr_t safe_dma_addr;
|
|
||||||
|
|
||||||
dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n",
|
dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n",
|
||||||
__func__, ptr, size, dir);
|
__func__, ptr, size, dir);
|
||||||
|
|
||||||
DO_STATS ( device_info->total_allocs++ );
|
if (size <= device_info->small.size) {
|
||||||
|
pool = &device_info->small;
|
||||||
|
} else if (size <= device_info->large.size) {
|
||||||
|
pool = &device_info->large;
|
||||||
|
} else {
|
||||||
|
pool = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
|
buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
|
@ -125,41 +134,35 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size <= device_info->small_buffer_size) {
|
buf->ptr = ptr;
|
||||||
pool = device_info->small_buffer_pool;
|
buf->size = size;
|
||||||
safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
|
buf->direction = dir;
|
||||||
|
buf->pool = pool;
|
||||||
|
|
||||||
DO_STATS ( device_info->sbp_allocs++ );
|
if (pool) {
|
||||||
} else if (size <= device_info->large_buffer_size) {
|
buf->safe = dma_pool_alloc(pool->pool, GFP_ATOMIC,
|
||||||
pool = device_info->large_buffer_pool;
|
&buf->safe_dma_addr);
|
||||||
safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
|
|
||||||
|
|
||||||
DO_STATS ( device_info->lbp_allocs++ );
|
|
||||||
} else {
|
} else {
|
||||||
pool = NULL;
|
buf->safe = dma_alloc_coherent(dev, size, &buf->safe_dma_addr,
|
||||||
safe = dma_alloc_coherent(dev, size, &safe_dma_addr, GFP_ATOMIC);
|
GFP_ATOMIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (safe == NULL) {
|
if (buf->safe == NULL) {
|
||||||
dev_warn(device_info->dev,
|
dev_warn(dev,
|
||||||
"%s: could not alloc dma memory (size=%d)\n",
|
"%s: could not alloc dma memory (size=%d)\n",
|
||||||
__func__, size);
|
__func__, size);
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STATS
|
#ifdef STATS
|
||||||
|
if (pool)
|
||||||
|
pool->allocs++;
|
||||||
|
device_info->total_allocs++;
|
||||||
if (device_info->total_allocs % 1000 == 0)
|
if (device_info->total_allocs % 1000 == 0)
|
||||||
print_alloc_stats(device_info);
|
print_alloc_stats(device_info);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
buf->ptr = ptr;
|
|
||||||
buf->size = size;
|
|
||||||
buf->direction = dir;
|
|
||||||
buf->pool = pool;
|
|
||||||
buf->safe = safe;
|
|
||||||
buf->safe_dma_addr = safe_dma_addr;
|
|
||||||
|
|
||||||
list_add(&buf->node, &device_info->safe_buffers);
|
list_add(&buf->node, &device_info->safe_buffers);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
|
@ -186,7 +189,7 @@ free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *
|
||||||
list_del(&buf->node);
|
list_del(&buf->node);
|
||||||
|
|
||||||
if (buf->pool)
|
if (buf->pool)
|
||||||
dma_pool_free(buf->pool, buf->safe, buf->safe_dma_addr);
|
dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr);
|
||||||
else
|
else
|
||||||
dma_free_coherent(device_info->dev, buf->size, buf->safe,
|
dma_free_coherent(device_info->dev, buf->size, buf->safe,
|
||||||
buf->safe_dma_addr);
|
buf->safe_dma_addr);
|
||||||
|
@ -197,12 +200,10 @@ free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *
|
||||||
/* ************************************************** */
|
/* ************************************************** */
|
||||||
|
|
||||||
#ifdef STATS
|
#ifdef STATS
|
||||||
|
|
||||||
static void print_map_stats(struct dmabounce_device_info *device_info)
|
static void print_map_stats(struct dmabounce_device_info *device_info)
|
||||||
{
|
{
|
||||||
printk(KERN_INFO
|
dev_info(device_info->dev,
|
||||||
"%s: dmabounce: map_op_count=%lu, bounce_count=%lu\n",
|
"dmabounce: map_op_count=%lu, bounce_count=%lu\n",
|
||||||
device_info->dev->bus_id,
|
|
||||||
device_info->map_op_count, device_info->bounce_count);
|
device_info->map_op_count, device_info->bounce_count);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -258,13 +259,13 @@ map_single(struct device *dev, void *ptr, size_t size,
|
||||||
__func__, ptr, buf->safe, size);
|
__func__, ptr, buf->safe, size);
|
||||||
memcpy(buf->safe, ptr, size);
|
memcpy(buf->safe, ptr, size);
|
||||||
}
|
}
|
||||||
consistent_sync(buf->safe, size, dir);
|
ptr = buf->safe;
|
||||||
|
|
||||||
dma_addr = buf->safe_dma_addr;
|
dma_addr = buf->safe_dma_addr;
|
||||||
} else {
|
|
||||||
consistent_sync(ptr, size, dir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consistent_sync(ptr, size, dir);
|
||||||
|
|
||||||
return dma_addr;
|
return dma_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +279,7 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
|
||||||
/*
|
/*
|
||||||
* Trying to unmap an invalid mapping
|
* Trying to unmap an invalid mapping
|
||||||
*/
|
*/
|
||||||
if (dma_addr == ~0) {
|
if (dma_mapping_error(dma_addr)) {
|
||||||
dev_err(dev, "Trying to unmap invalid mapping\n");
|
dev_err(dev, "Trying to unmap invalid mapping\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -570,11 +571,25 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, const char *name,
|
||||||
|
unsigned long size)
|
||||||
|
{
|
||||||
|
pool->size = size;
|
||||||
|
DO_STATS(pool->allocs = 0);
|
||||||
|
pool->pool = dma_pool_create(name, dev, size,
|
||||||
|
0 /* byte alignment */,
|
||||||
|
0 /* no page-crossing issues */);
|
||||||
|
|
||||||
|
return pool->pool ? 0 : -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
|
dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
|
||||||
unsigned long large_buffer_size)
|
unsigned long large_buffer_size)
|
||||||
{
|
{
|
||||||
struct dmabounce_device_info *device_info;
|
struct dmabounce_device_info *device_info;
|
||||||
|
int ret;
|
||||||
|
|
||||||
device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
|
device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
|
||||||
if (!device_info) {
|
if (!device_info) {
|
||||||
|
@ -584,45 +599,31 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_info->small_buffer_pool =
|
ret = dmabounce_init_pool(&device_info->small, dev,
|
||||||
dma_pool_create("small_dmabounce_pool",
|
"small_dmabounce_pool", small_buffer_size);
|
||||||
dev,
|
if (ret) {
|
||||||
small_buffer_size,
|
dev_err(dev,
|
||||||
0 /* byte alignment */,
|
"dmabounce: could not allocate DMA pool for %ld byte objects\n",
|
||||||
0 /* no page-crossing issues */);
|
small_buffer_size);
|
||||||
if (!device_info->small_buffer_pool) {
|
goto err_free;
|
||||||
printk(KERN_ERR
|
|
||||||
"dmabounce: could not allocate small DMA pool for %s\n",
|
|
||||||
dev->bus_id);
|
|
||||||
kfree(device_info);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (large_buffer_size) {
|
if (large_buffer_size) {
|
||||||
device_info->large_buffer_pool =
|
ret = dmabounce_init_pool(&device_info->large, dev,
|
||||||
dma_pool_create("large_dmabounce_pool",
|
"large_dmabounce_pool",
|
||||||
dev,
|
large_buffer_size);
|
||||||
large_buffer_size,
|
if (ret) {
|
||||||
0 /* byte alignment */,
|
dev_err(dev,
|
||||||
0 /* no page-crossing issues */);
|
"dmabounce: could not allocate DMA pool for %ld byte objects\n",
|
||||||
if (!device_info->large_buffer_pool) {
|
large_buffer_size);
|
||||||
printk(KERN_ERR
|
goto err_destroy;
|
||||||
"dmabounce: could not allocate large DMA pool for %s\n",
|
|
||||||
dev->bus_id);
|
|
||||||
dma_pool_destroy(device_info->small_buffer_pool);
|
|
||||||
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
device_info->dev = dev;
|
device_info->dev = dev;
|
||||||
device_info->small_buffer_size = small_buffer_size;
|
|
||||||
device_info->large_buffer_size = large_buffer_size;
|
|
||||||
INIT_LIST_HEAD(&device_info->safe_buffers);
|
INIT_LIST_HEAD(&device_info->safe_buffers);
|
||||||
|
|
||||||
#ifdef STATS
|
#ifdef STATS
|
||||||
device_info->sbp_allocs = 0;
|
|
||||||
device_info->lbp_allocs = 0;
|
|
||||||
device_info->total_allocs = 0;
|
device_info->total_allocs = 0;
|
||||||
device_info->map_op_count = 0;
|
device_info->map_op_count = 0;
|
||||||
device_info->bounce_count = 0;
|
device_info->bounce_count = 0;
|
||||||
|
@ -634,6 +635,12 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
|
||||||
dev->bus_id, dev->bus->name);
|
dev->bus_id, dev->bus->name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_destroy:
|
||||||
|
dma_pool_destroy(device_info->small.pool);
|
||||||
|
err_free:
|
||||||
|
kfree(device_info);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -655,10 +662,10 @@ dmabounce_unregister_dev(struct device *dev)
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device_info->small_buffer_pool)
|
if (device_info->small.pool)
|
||||||
dma_pool_destroy(device_info->small_buffer_pool);
|
dma_pool_destroy(device_info->small.pool);
|
||||||
if (device_info->large_buffer_pool)
|
if (device_info->large.pool)
|
||||||
dma_pool_destroy(device_info->large_buffer_pool);
|
dma_pool_destroy(device_info->large.pool);
|
||||||
|
|
||||||
#ifdef STATS
|
#ifdef STATS
|
||||||
print_alloc_stats(device_info);
|
print_alloc_stats(device_info);
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/hardware/scoop.h>
|
#include <asm/hardware/scoop.h>
|
||||||
|
|
||||||
|
|
|
@ -559,7 +559,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
|
||||||
#
|
#
|
||||||
CONFIG_SERIAL_8250=y
|
CONFIG_SERIAL_8250=y
|
||||||
CONFIG_SERIAL_8250_CONSOLE=y
|
CONFIG_SERIAL_8250_CONSOLE=y
|
||||||
CONFIG_SERIAL_8250_NR_UARTS=2
|
CONFIG_SERIAL_8250_NR_UARTS=1
|
||||||
# CONFIG_SERIAL_8250_EXTENDED is not set
|
# CONFIG_SERIAL_8250_EXTENDED is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -559,7 +559,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
|
||||||
#
|
#
|
||||||
CONFIG_SERIAL_8250=y
|
CONFIG_SERIAL_8250=y
|
||||||
CONFIG_SERIAL_8250_CONSOLE=y
|
CONFIG_SERIAL_8250_CONSOLE=y
|
||||||
CONFIG_SERIAL_8250_NR_UARTS=2
|
CONFIG_SERIAL_8250_NR_UARTS=1
|
||||||
# CONFIG_SERIAL_8250_EXTENDED is not set
|
# CONFIG_SERIAL_8250_EXTENDED is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <linux/stddef.h>
|
#include <linux/stddef.h>
|
||||||
#include <linux/signal.h>
|
#include <linux/signal.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
|
|
||||||
|
|
|
@ -782,7 +782,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
|
asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
|
||||||
{
|
{
|
||||||
struct task_struct *child;
|
struct task_struct *child;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -36,10 +36,6 @@
|
||||||
#include <asm/thread_info.h>
|
#include <asm/thread_info.h>
|
||||||
#include <asm/mach/time.h>
|
#include <asm/mach/time.h>
|
||||||
|
|
||||||
u64 jiffies_64 = INITIAL_JIFFIES;
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(jiffies_64);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our system timer.
|
* Our system timer.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -198,25 +198,16 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
|
||||||
barrier();
|
barrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_SPINLOCK(die_lock);
|
static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
|
||||||
|
|
||||||
/*
|
|
||||||
* This function is protected against re-entrancy.
|
|
||||||
*/
|
|
||||||
NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
|
|
||||||
{
|
{
|
||||||
struct task_struct *tsk = current;
|
struct task_struct *tsk = thread->task;
|
||||||
static int die_counter;
|
static int die_counter;
|
||||||
|
|
||||||
console_verbose();
|
|
||||||
spin_lock_irq(&die_lock);
|
|
||||||
bust_spinlocks(1);
|
|
||||||
|
|
||||||
printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
|
printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
|
||||||
print_modules();
|
print_modules();
|
||||||
__show_regs(regs);
|
__show_regs(regs);
|
||||||
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
|
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
|
||||||
tsk->comm, tsk->pid, tsk->thread_info + 1);
|
tsk->comm, tsk->pid, thread + 1);
|
||||||
|
|
||||||
if (!user_mode(regs) || in_interrupt()) {
|
if (!user_mode(regs) || in_interrupt()) {
|
||||||
dump_mem("Stack: ", regs->ARM_sp,
|
dump_mem("Stack: ", regs->ARM_sp,
|
||||||
|
@ -224,7 +215,21 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
|
||||||
dump_backtrace(regs, tsk);
|
dump_backtrace(regs, tsk);
|
||||||
dump_instr(regs);
|
dump_instr(regs);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_SPINLOCK(die_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is protected against re-entrancy.
|
||||||
|
*/
|
||||||
|
NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
|
||||||
|
{
|
||||||
|
struct thread_info *thread = current_thread_info();
|
||||||
|
|
||||||
|
console_verbose();
|
||||||
|
spin_lock_irq(&die_lock);
|
||||||
|
bust_spinlocks(1);
|
||||||
|
__die(str, err, thread, regs);
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
do_exit(SIGSEGV);
|
do_exit(SIGSEGV);
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU General Public License, the
|
||||||
|
Free Software Foundation gives you unlimited permission to link the
|
||||||
|
compiled version of this file into combinations with other programs,
|
||||||
|
and to distribute those combinations without any restriction coming
|
||||||
|
from the use of this file. (The General Public License restrictions
|
||||||
|
do apply in other respects; for example, they cover modification of
|
||||||
|
the file, and distribution when not linked into a combine
|
||||||
|
executable.)
|
||||||
|
|
||||||
|
This file is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING. If not, write to
|
||||||
|
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
|
||||||
|
#ifdef __ARMEB__
|
||||||
|
#define al r1
|
||||||
|
#define ah r0
|
||||||
|
#else
|
||||||
|
#define al r0
|
||||||
|
#define ah r1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ENTRY(__ashldi3)
|
||||||
|
|
||||||
|
subs r3, r2, #32
|
||||||
|
rsb ip, r2, #32
|
||||||
|
movmi ah, ah, lsl r2
|
||||||
|
movpl ah, al, lsl r3
|
||||||
|
orrmi ah, ah, al, lsr ip
|
||||||
|
mov al, al, lsl r2
|
||||||
|
mov pc, lr
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
/* More subroutines needed by GCC output code on some machines. */
|
|
||||||
/* Compile this one with gcc. */
|
|
||||||
/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GNU CC.
|
|
||||||
|
|
||||||
GNU CC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GNU CC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GNU CC; see the file COPYING. If not, write to
|
|
||||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* As a special exception, if you link this library with other files,
|
|
||||||
some of which are compiled with GCC, to produce an executable,
|
|
||||||
this library does not by itself cause the resulting executable
|
|
||||||
to be covered by the GNU General Public License.
|
|
||||||
This exception does not however invalidate any other reasons why
|
|
||||||
the executable file might be covered by the GNU General Public License.
|
|
||||||
*/
|
|
||||||
/* support functions required by the kernel. based on code from gcc-2.95.3 */
|
|
||||||
/* I Molton 29/07/01 */
|
|
||||||
|
|
||||||
#include "gcclib.h"
|
|
||||||
|
|
||||||
s64 __ashldi3(s64 u, int b)
|
|
||||||
{
|
|
||||||
DIunion w;
|
|
||||||
int bm;
|
|
||||||
DIunion uu;
|
|
||||||
|
|
||||||
if (b == 0)
|
|
||||||
return u;
|
|
||||||
|
|
||||||
uu.ll = u;
|
|
||||||
|
|
||||||
bm = (sizeof(s32) * BITS_PER_UNIT) - b;
|
|
||||||
if (bm <= 0) {
|
|
||||||
w.s.low = 0;
|
|
||||||
w.s.high = (u32) uu.s.low << -bm;
|
|
||||||
} else {
|
|
||||||
u32 carries = (u32) uu.s.low >> bm;
|
|
||||||
w.s.low = (u32) uu.s.low << b;
|
|
||||||
w.s.high = ((u32) uu.s.high << b) | carries;
|
|
||||||
}
|
|
||||||
|
|
||||||
return w.ll;
|
|
||||||
}
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU General Public License, the
|
||||||
|
Free Software Foundation gives you unlimited permission to link the
|
||||||
|
compiled version of this file into combinations with other programs,
|
||||||
|
and to distribute those combinations without any restriction coming
|
||||||
|
from the use of this file. (The General Public License restrictions
|
||||||
|
do apply in other respects; for example, they cover modification of
|
||||||
|
the file, and distribution when not linked into a combine
|
||||||
|
executable.)
|
||||||
|
|
||||||
|
This file is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING. If not, write to
|
||||||
|
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
|
||||||
|
#ifdef __ARMEB__
|
||||||
|
#define al r1
|
||||||
|
#define ah r0
|
||||||
|
#else
|
||||||
|
#define al r0
|
||||||
|
#define ah r1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ENTRY(__ashrdi3)
|
||||||
|
|
||||||
|
subs r3, r2, #32
|
||||||
|
rsb ip, r2, #32
|
||||||
|
movmi al, al, lsr r2
|
||||||
|
movpl al, ah, asr r3
|
||||||
|
orrmi al, al, ah, lsl ip
|
||||||
|
mov ah, ah, asr r2
|
||||||
|
mov pc, lr
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
/* More subroutines needed by GCC output code on some machines. */
|
|
||||||
/* Compile this one with gcc. */
|
|
||||||
/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GNU CC.
|
|
||||||
|
|
||||||
GNU CC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GNU CC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GNU CC; see the file COPYING. If not, write to
|
|
||||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* As a special exception, if you link this library with other files,
|
|
||||||
some of which are compiled with GCC, to produce an executable,
|
|
||||||
this library does not by itself cause the resulting executable
|
|
||||||
to be covered by the GNU General Public License.
|
|
||||||
This exception does not however invalidate any other reasons why
|
|
||||||
the executable file might be covered by the GNU General Public License.
|
|
||||||
*/
|
|
||||||
/* support functions required by the kernel. based on code from gcc-2.95.3 */
|
|
||||||
/* I Molton 29/07/01 */
|
|
||||||
|
|
||||||
#include "gcclib.h"
|
|
||||||
|
|
||||||
s64 __ashrdi3(s64 u, int b)
|
|
||||||
{
|
|
||||||
DIunion w;
|
|
||||||
int bm;
|
|
||||||
DIunion uu;
|
|
||||||
|
|
||||||
if (b == 0)
|
|
||||||
return u;
|
|
||||||
|
|
||||||
uu.ll = u;
|
|
||||||
|
|
||||||
bm = (sizeof(s32) * BITS_PER_UNIT) - b;
|
|
||||||
if (bm <= 0) {
|
|
||||||
/* w.s.high = 1..1 or 0..0 */
|
|
||||||
w.s.high = uu.s.high >> (sizeof(s32) * BITS_PER_UNIT - 1);
|
|
||||||
w.s.low = uu.s.high >> -bm;
|
|
||||||
} else {
|
|
||||||
u32 carries = (u32) uu.s.high << bm;
|
|
||||||
w.s.high = uu.s.high >> b;
|
|
||||||
w.s.low = ((u32) uu.s.low >> b) | carries;
|
|
||||||
}
|
|
||||||
|
|
||||||
return w.ll;
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
|
|
||||||
/* I Molton 29/07/01 */
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
#define BITS_PER_UNIT 8
|
|
||||||
#define SI_TYPE_SIZE (sizeof(s32) * BITS_PER_UNIT)
|
|
||||||
|
|
||||||
#ifdef __ARMEB__
|
|
||||||
struct DIstruct {
|
|
||||||
s32 high, low;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
struct DIstruct {
|
|
||||||
s32 low, high;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
struct DIstruct s;
|
|
||||||
s64 ll;
|
|
||||||
} DIunion;
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU General Public License, the
|
||||||
|
Free Software Foundation gives you unlimited permission to link the
|
||||||
|
compiled version of this file into combinations with other programs,
|
||||||
|
and to distribute those combinations without any restriction coming
|
||||||
|
from the use of this file. (The General Public License restrictions
|
||||||
|
do apply in other respects; for example, they cover modification of
|
||||||
|
the file, and distribution when not linked into a combine
|
||||||
|
executable.)
|
||||||
|
|
||||||
|
This file is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING. If not, write to
|
||||||
|
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
|
||||||
|
#ifdef __ARMEB__
|
||||||
|
#define al r1
|
||||||
|
#define ah r0
|
||||||
|
#else
|
||||||
|
#define al r0
|
||||||
|
#define ah r1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ENTRY(__lshrdi3)
|
||||||
|
|
||||||
|
subs r3, r2, #32
|
||||||
|
rsb ip, r2, #32
|
||||||
|
movmi al, al, lsr r2
|
||||||
|
movpl al, ah, lsr r3
|
||||||
|
orrmi al, al, ah, lsl ip
|
||||||
|
mov ah, ah, lsr r2
|
||||||
|
mov pc, lr
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
/* More subroutines needed by GCC output code on some machines. */
|
|
||||||
/* Compile this one with gcc. */
|
|
||||||
/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GNU CC.
|
|
||||||
|
|
||||||
GNU CC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GNU CC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GNU CC; see the file COPYING. If not, write to
|
|
||||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* As a special exception, if you link this library with other files,
|
|
||||||
some of which are compiled with GCC, to produce an executable,
|
|
||||||
this library does not by itself cause the resulting executable
|
|
||||||
to be covered by the GNU General Public License.
|
|
||||||
This exception does not however invalidate any other reasons why
|
|
||||||
the executable file might be covered by the GNU General Public License.
|
|
||||||
*/
|
|
||||||
/* support functions required by the kernel. based on code from gcc-2.95.3 */
|
|
||||||
/* I Molton 29/07/01 */
|
|
||||||
|
|
||||||
#include "gcclib.h"
|
|
||||||
|
|
||||||
s64 __lshrdi3(s64 u, int b)
|
|
||||||
{
|
|
||||||
DIunion w;
|
|
||||||
int bm;
|
|
||||||
DIunion uu;
|
|
||||||
|
|
||||||
if (b == 0)
|
|
||||||
return u;
|
|
||||||
|
|
||||||
uu.ll = u;
|
|
||||||
|
|
||||||
bm = (sizeof(s32) * BITS_PER_UNIT) - b;
|
|
||||||
if (bm <= 0) {
|
|
||||||
w.s.high = 0;
|
|
||||||
w.s.low = (u32) uu.s.high >> -bm;
|
|
||||||
} else {
|
|
||||||
u32 carries = (u32) uu.s.high << bm;
|
|
||||||
w.s.high = (u32) uu.s.high >> b;
|
|
||||||
w.s.low = ((u32) uu.s.low >> b) | carries;
|
|
||||||
}
|
|
||||||
|
|
||||||
return w.ll;
|
|
||||||
}
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/lib/muldi3.S
|
||||||
|
*
|
||||||
|
* Author: Nicolas Pitre
|
||||||
|
* Created: Oct 19, 2005
|
||||||
|
* Copyright: Monta Vista Software, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
|
||||||
|
#ifdef __ARMEB__
|
||||||
|
#define xh r0
|
||||||
|
#define xl r1
|
||||||
|
#define yh r2
|
||||||
|
#define yl r3
|
||||||
|
#else
|
||||||
|
#define xl r0
|
||||||
|
#define xh r1
|
||||||
|
#define yl r2
|
||||||
|
#define yh r3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ENTRY(__muldi3)
|
||||||
|
|
||||||
|
mul xh, yl, xh
|
||||||
|
mla xh, xl, yh, xh
|
||||||
|
mov ip, xl, asr #16
|
||||||
|
mov yh, yl, asr #16
|
||||||
|
bic xl, xl, ip, lsl #16
|
||||||
|
bic yl, yl, yh, lsl #16
|
||||||
|
mla xh, yh, ip, xh
|
||||||
|
mul yh, xl, yh
|
||||||
|
mul xl, yl, xl
|
||||||
|
mul ip, yl, ip
|
||||||
|
adds xl, xl, yh, lsl #16
|
||||||
|
adc xh, xh, yh, lsr #16
|
||||||
|
adds xl, xl, ip, lsl #16
|
||||||
|
adc xh, xh, ip, lsr #16
|
||||||
|
mov pc, lr
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
/* More subroutines needed by GCC output code on some machines. */
|
|
||||||
/* Compile this one with gcc. */
|
|
||||||
/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GNU CC.
|
|
||||||
|
|
||||||
GNU CC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GNU CC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GNU CC; see the file COPYING. If not, write to
|
|
||||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* As a special exception, if you link this library with other files,
|
|
||||||
some of which are compiled with GCC, to produce an executable,
|
|
||||||
this library does not by itself cause the resulting executable
|
|
||||||
to be covered by the GNU General Public License.
|
|
||||||
This exception does not however invalidate any other reasons why
|
|
||||||
the executable file might be covered by the GNU General Public License.
|
|
||||||
*/
|
|
||||||
/* support functions required by the kernel. based on code from gcc-2.95.3 */
|
|
||||||
/* I Molton 29/07/01 */
|
|
||||||
|
|
||||||
#include "gcclib.h"
|
|
||||||
|
|
||||||
#define umul_ppmm(xh, xl, a, b) \
|
|
||||||
{register u32 __t0, __t1, __t2; \
|
|
||||||
__asm__ ("%@ Inlined umul_ppmm \n\
|
|
||||||
mov %2, %5, lsr #16 \n\
|
|
||||||
mov %0, %6, lsr #16 \n\
|
|
||||||
bic %3, %5, %2, lsl #16 \n\
|
|
||||||
bic %4, %6, %0, lsl #16 \n\
|
|
||||||
mul %1, %3, %4 \n\
|
|
||||||
mul %4, %2, %4 \n\
|
|
||||||
mul %3, %0, %3 \n\
|
|
||||||
mul %0, %2, %0 \n\
|
|
||||||
adds %3, %4, %3 \n\
|
|
||||||
addcs %0, %0, #65536 \n\
|
|
||||||
adds %1, %1, %3, lsl #16 \n\
|
|
||||||
adc %0, %0, %3, lsr #16" \
|
|
||||||
: "=&r" ((u32) (xh)), \
|
|
||||||
"=r" ((u32) (xl)), \
|
|
||||||
"=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
|
|
||||||
: "r" ((u32) (a)), \
|
|
||||||
"r" ((u32) (b)));}
|
|
||||||
|
|
||||||
#define __umulsidi3(u, v) \
|
|
||||||
({DIunion __w; \
|
|
||||||
umul_ppmm (__w.s.high, __w.s.low, u, v); \
|
|
||||||
__w.ll; })
|
|
||||||
|
|
||||||
s64 __muldi3(s64 u, s64 v)
|
|
||||||
{
|
|
||||||
DIunion w;
|
|
||||||
DIunion uu, vv;
|
|
||||||
|
|
||||||
uu.ll = u, vv.ll = v;
|
|
||||||
|
|
||||||
w.ll = __umulsidi3(uu.s.low, vv.s.low);
|
|
||||||
w.s.high += ((u32) uu.s.low * (u32) vv.s.high
|
|
||||||
+ (u32) uu.s.high * (u32) vv.s.low);
|
|
||||||
|
|
||||||
return w.ll;
|
|
||||||
}
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/lib/ucmpdi2.S
|
||||||
|
*
|
||||||
|
* Author: Nicolas Pitre
|
||||||
|
* Created: Oct 19, 2005
|
||||||
|
* Copyright: Monta Vista Software, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
|
||||||
|
#ifdef __ARMEB__
|
||||||
|
#define xh r0
|
||||||
|
#define xl r1
|
||||||
|
#define yh r2
|
||||||
|
#define yl r3
|
||||||
|
#else
|
||||||
|
#define xl r0
|
||||||
|
#define xh r1
|
||||||
|
#define yl r2
|
||||||
|
#define yh r3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ENTRY(__ucmpdi2)
|
||||||
|
|
||||||
|
cmp xh, yh
|
||||||
|
cmpeq xl, yl
|
||||||
|
movlo r0, #0
|
||||||
|
moveq r0, #1
|
||||||
|
movhi r0, #2
|
||||||
|
mov pc, lr
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
/* More subroutines needed by GCC output code on some machines. */
|
|
||||||
/* Compile this one with gcc. */
|
|
||||||
/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GNU CC.
|
|
||||||
|
|
||||||
GNU CC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GNU CC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GNU CC; see the file COPYING. If not, write to
|
|
||||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* As a special exception, if you link this library with other files,
|
|
||||||
some of which are compiled with GCC, to produce an executable,
|
|
||||||
this library does not by itself cause the resulting executable
|
|
||||||
to be covered by the GNU General Public License.
|
|
||||||
This exception does not however invalidate any other reasons why
|
|
||||||
the executable file might be covered by the GNU General Public License.
|
|
||||||
*/
|
|
||||||
/* support functions required by the kernel. based on code from gcc-2.95.3 */
|
|
||||||
/* I Molton 29/07/01 */
|
|
||||||
|
|
||||||
#include "gcclib.h"
|
|
||||||
|
|
||||||
int __ucmpdi2(s64 a, s64 b)
|
|
||||||
{
|
|
||||||
DIunion au, bu;
|
|
||||||
|
|
||||||
au.ll = a, bu.ll = b;
|
|
||||||
|
|
||||||
if ((u32) au.s.high < (u32) bu.s.high)
|
|
||||||
return 0;
|
|
||||||
else if ((u32) au.s.high > (u32) bu.s.high)
|
|
||||||
return 2;
|
|
||||||
if ((u32) au.s.low < (u32) bu.s.low)
|
|
||||||
return 0;
|
|
||||||
else if ((u32) au.s.low > (u32) bu.s.low)
|
|
||||||
return 2;
|
|
||||||
return 1;
|
|
||||||
}
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
#include <asm/arch/imxfb.h>
|
#include <asm/arch/imxfb.h>
|
||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
#include <asm/arch/imx-regs.h>
|
#include <asm/arch/imx-regs.h>
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
#include <asm/semaphore.h>
|
#include <asm/semaphore.h>
|
||||||
#include <asm/hardware/clock.h>
|
#include <asm/hardware/clock.h>
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
#include <asm/param.h> /* HZ */
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
#include <asm/hardware/amba.h>
|
#include <asm/hardware/amba.h>
|
||||||
#include <asm/hardware/amba_kmi.h>
|
#include <asm/hardware/amba_kmi.h>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <asm/arch/lm.h>
|
#include <asm/arch/lm.h>
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include <asm/arch/pxa-regs.h>
|
#include <asm/arch/pxa-regs.h>
|
||||||
#include <asm/arch/irq.h>
|
#include <asm/arch/irq.h>
|
||||||
|
#include <asm/arch/irda.h>
|
||||||
#include <asm/arch/mmc.h>
|
#include <asm/arch/mmc.h>
|
||||||
#include <asm/arch/udc.h>
|
#include <asm/arch/udc.h>
|
||||||
#include <asm/arch/corgi.h>
|
#include <asm/arch/corgi.h>
|
||||||
|
@ -224,6 +225,22 @@ static struct pxamci_platform_data corgi_mci_platform_data = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Irda
|
||||||
|
*/
|
||||||
|
static void corgi_irda_transceiver_mode(struct device *dev, int mode)
|
||||||
|
{
|
||||||
|
if (mode & IR_OFF)
|
||||||
|
GPSR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
|
||||||
|
else
|
||||||
|
GPCR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pxaficp_platform_data corgi_ficp_platform_data = {
|
||||||
|
.transceiver_cap = IR_SIRMODE | IR_OFF,
|
||||||
|
.transceiver_mode = corgi_irda_transceiver_mode,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* USB Device Controller
|
* USB Device Controller
|
||||||
|
@ -269,10 +286,13 @@ static void __init corgi_init(void)
|
||||||
|
|
||||||
corgi_ssp_set_machinfo(&corgi_ssp_machinfo);
|
corgi_ssp_set_machinfo(&corgi_ssp_machinfo);
|
||||||
|
|
||||||
|
pxa_gpio_mode(CORGI_GPIO_IR_ON | GPIO_OUT);
|
||||||
pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
|
pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
|
||||||
pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
|
pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
|
||||||
|
|
||||||
pxa_set_udc_info(&udc_info);
|
pxa_set_udc_info(&udc_info);
|
||||||
pxa_set_mci_info(&corgi_mci_platform_data);
|
pxa_set_mci_info(&corgi_mci_platform_data);
|
||||||
|
pxa_set_ficp_info(&corgi_ficp_platform_data);
|
||||||
|
|
||||||
scoop_num = 1;
|
scoop_num = 1;
|
||||||
scoop_devs = &corgi_pcmcia_scoop[0];
|
scoop_devs = &corgi_pcmcia_scoop[0];
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <asm/arch/irq.h>
|
#include <asm/arch/irq.h>
|
||||||
#include <asm/arch/mmc.h>
|
#include <asm/arch/mmc.h>
|
||||||
#include <asm/arch/udc.h>
|
#include <asm/arch/udc.h>
|
||||||
|
#include <asm/arch/irda.h>
|
||||||
#include <asm/arch/poodle.h>
|
#include <asm/arch/poodle.h>
|
||||||
#include <asm/arch/pxafb.h>
|
#include <asm/arch/pxafb.h>
|
||||||
|
|
||||||
|
@ -151,6 +152,24 @@ static struct pxamci_platform_data poodle_mci_platform_data = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Irda
|
||||||
|
*/
|
||||||
|
static void poodle_irda_transceiver_mode(struct device *dev, int mode)
|
||||||
|
{
|
||||||
|
if (mode & IR_OFF) {
|
||||||
|
GPSR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
|
||||||
|
} else {
|
||||||
|
GPCR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pxaficp_platform_data poodle_ficp_platform_data = {
|
||||||
|
.transceiver_cap = IR_SIRMODE | IR_OFF,
|
||||||
|
.transceiver_mode = poodle_irda_transceiver_mode,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* USB Device Controller
|
* USB Device Controller
|
||||||
*/
|
*/
|
||||||
|
@ -244,8 +263,10 @@ static void __init poodle_init(void)
|
||||||
|
|
||||||
set_pxa_fb_info(&poodle_fb_info);
|
set_pxa_fb_info(&poodle_fb_info);
|
||||||
pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
|
pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
|
||||||
|
pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT);
|
||||||
pxa_set_udc_info(&udc_info);
|
pxa_set_udc_info(&udc_info);
|
||||||
pxa_set_mci_info(&poodle_mci_platform_data);
|
pxa_set_mci_info(&poodle_mci_platform_data);
|
||||||
|
pxa_set_ficp_info(&poodle_ficp_platform_data);
|
||||||
|
|
||||||
scoop_num = 1;
|
scoop_num = 1;
|
||||||
scoop_devs = &poodle_pcmcia_scoop[0];
|
scoop_devs = &poodle_pcmcia_scoop[0];
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include <asm/arch/pxa-regs.h>
|
#include <asm/arch/pxa-regs.h>
|
||||||
#include <asm/arch/irq.h>
|
#include <asm/arch/irq.h>
|
||||||
|
#include <asm/arch/irda.h>
|
||||||
#include <asm/arch/mmc.h>
|
#include <asm/arch/mmc.h>
|
||||||
#include <asm/arch/udc.h>
|
#include <asm/arch/udc.h>
|
||||||
#include <asm/arch/pxafb.h>
|
#include <asm/arch/pxafb.h>
|
||||||
|
@ -276,6 +277,23 @@ static struct pxamci_platform_data spitz_mci_platform_data = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Irda
|
||||||
|
*/
|
||||||
|
static void spitz_irda_transceiver_mode(struct device *dev, int mode)
|
||||||
|
{
|
||||||
|
if (mode & IR_OFF)
|
||||||
|
set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
|
||||||
|
else
|
||||||
|
reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pxaficp_platform_data spitz_ficp_platform_data = {
|
||||||
|
.transceiver_cap = IR_SIRMODE | IR_OFF,
|
||||||
|
.transceiver_mode = spitz_irda_transceiver_mode,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Spitz PXA Framebuffer
|
* Spitz PXA Framebuffer
|
||||||
*/
|
*/
|
||||||
|
@ -326,6 +344,7 @@ static void __init common_init(void)
|
||||||
|
|
||||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||||
pxa_set_mci_info(&spitz_mci_platform_data);
|
pxa_set_mci_info(&spitz_mci_platform_data);
|
||||||
|
pxa_set_ficp_info(&spitz_ficp_platform_data);
|
||||||
set_pxa_fb_parent(&spitzssp_device.dev);
|
set_pxa_fb_parent(&spitzssp_device.dev);
|
||||||
set_pxa_fb_info(&spitz_pxafb_info);
|
set_pxa_fb_info(&spitz_pxafb_info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/cpufreq.h>
|
#include <linux/cpufreq.h>
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/sched.h> /* just for sched_clock() - funny that */
|
||||||
|
|
||||||
#include <asm/div64.h>
|
#include <asm/div64.h>
|
||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
#include <asm/semaphore.h>
|
#include <asm/semaphore.h>
|
||||||
#include <asm/hardware/clock.h>
|
#include <asm/hardware/clock.h>
|
||||||
|
|
|
@ -22,9 +22,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define from_address (0xffff8000)
|
#define from_address (0xffff8000)
|
||||||
#define from_pgprot PAGE_KERNEL
|
|
||||||
#define to_address (0xffffc000)
|
#define to_address (0xffffc000)
|
||||||
#define to_pgprot PAGE_KERNEL
|
|
||||||
|
|
||||||
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
|
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
|
||||||
|
|
||||||
|
@ -34,7 +32,7 @@ static DEFINE_SPINLOCK(v6_lock);
|
||||||
* Copy the user page. No aliasing to deal with so we can just
|
* Copy the user page. No aliasing to deal with so we can just
|
||||||
* attack the kernel's existing mapping of these pages.
|
* attack the kernel's existing mapping of these pages.
|
||||||
*/
|
*/
|
||||||
void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long vaddr)
|
static void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long vaddr)
|
||||||
{
|
{
|
||||||
copy_page(kto, kfrom);
|
copy_page(kto, kfrom);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +41,7 @@ void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long v
|
||||||
* Clear the user page. No aliasing to deal with so we can just
|
* Clear the user page. No aliasing to deal with so we can just
|
||||||
* attack the kernel's existing mapping of this page.
|
* attack the kernel's existing mapping of this page.
|
||||||
*/
|
*/
|
||||||
void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
|
static void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
|
||||||
{
|
{
|
||||||
clear_page(kaddr);
|
clear_page(kaddr);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +49,7 @@ void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
|
||||||
/*
|
/*
|
||||||
* Copy the page, taking account of the cache colour.
|
* Copy the page, taking account of the cache colour.
|
||||||
*/
|
*/
|
||||||
void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
|
static void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
|
||||||
{
|
{
|
||||||
unsigned int offset = CACHE_COLOUR(vaddr);
|
unsigned int offset = CACHE_COLOUR(vaddr);
|
||||||
unsigned long from, to;
|
unsigned long from, to;
|
||||||
|
@ -72,8 +70,8 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
|
||||||
*/
|
*/
|
||||||
spin_lock(&v6_lock);
|
spin_lock(&v6_lock);
|
||||||
|
|
||||||
set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
|
set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, PAGE_KERNEL));
|
||||||
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
|
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, PAGE_KERNEL));
|
||||||
|
|
||||||
from = from_address + (offset << PAGE_SHIFT);
|
from = from_address + (offset << PAGE_SHIFT);
|
||||||
to = to_address + (offset << PAGE_SHIFT);
|
to = to_address + (offset << PAGE_SHIFT);
|
||||||
|
@ -91,7 +89,7 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
|
||||||
* so remap the kernel page into the same cache colour as the user
|
* so remap the kernel page into the same cache colour as the user
|
||||||
* page.
|
* page.
|
||||||
*/
|
*/
|
||||||
void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
|
static void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
|
||||||
{
|
{
|
||||||
unsigned int offset = CACHE_COLOUR(vaddr);
|
unsigned int offset = CACHE_COLOUR(vaddr);
|
||||||
unsigned long to = to_address + (offset << PAGE_SHIFT);
|
unsigned long to = to_address + (offset << PAGE_SHIFT);
|
||||||
|
@ -112,7 +110,7 @@ void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
|
||||||
*/
|
*/
|
||||||
spin_lock(&v6_lock);
|
spin_lock(&v6_lock);
|
||||||
|
|
||||||
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
|
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, PAGE_KERNEL));
|
||||||
flush_tlb_kernel_page(to);
|
flush_tlb_kernel_page(to);
|
||||||
clear_page((void *)to);
|
clear_page((void *)to);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/semaphore.h>
|
#include <asm/semaphore.h>
|
||||||
|
|
|
@ -665,7 +665,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
|
asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
|
||||||
{
|
{
|
||||||
struct task_struct *child;
|
struct task_struct *child;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -34,10 +34,6 @@
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/ioc.h>
|
#include <asm/ioc.h>
|
||||||
|
|
||||||
u64 jiffies_64 = INITIAL_JIFFIES;
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(jiffies_64);
|
|
||||||
|
|
||||||
extern unsigned long wall_jiffies;
|
extern unsigned long wall_jiffies;
|
||||||
|
|
||||||
/* this needs a better home */
|
/* this needs a better home */
|
||||||
|
|
|
@ -140,6 +140,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <linux/mtd/concat.h>
|
#include <linux/mtd/concat.h>
|
||||||
#include <linux/mtd/map.h>
|
#include <linux/mtd/map.h>
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <linux/mtd/concat.h>
|
#include <linux/mtd/concat.h>
|
||||||
#include <linux/mtd/map.h>
|
#include <linux/mtd/map.h>
|
||||||
|
|
|
@ -31,10 +31,7 @@
|
||||||
#include <linux/timex.h>
|
#include <linux/timex.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/profile.h>
|
#include <linux/profile.h>
|
||||||
|
#include <linux/sched.h> /* just for sched_clock() - funny that */
|
||||||
u64 jiffies_64 = INITIAL_JIFFIES;
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(jiffies_64);
|
|
||||||
|
|
||||||
int have_rtc; /* used to remember if we have an RTC or not */;
|
int have_rtc; /* used to remember if we have an RTC or not */;
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ void ptrace_enable(struct task_struct *child)
|
||||||
child->thread.frame0->__status |= REG__STATUS_STEP;
|
child->thread.frame0->__status |= REG__STATUS_STEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
|
asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
|
||||||
{
|
{
|
||||||
struct task_struct *child;
|
struct task_struct *child;
|
||||||
unsigned long tmp;
|
unsigned long tmp;
|
||||||
|
|
|
@ -34,9 +34,6 @@
|
||||||
|
|
||||||
extern unsigned long wall_jiffies;
|
extern unsigned long wall_jiffies;
|
||||||
|
|
||||||
u64 jiffies_64 = INITIAL_JIFFIES;
|
|
||||||
EXPORT_SYMBOL(jiffies_64);
|
|
||||||
|
|
||||||
unsigned long __nongprelbss __clkin_clock_speed_HZ;
|
unsigned long __nongprelbss __clkin_clock_speed_HZ;
|
||||||
unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
|
unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
|
||||||
unsigned long __nongprelbss __res_bus_clock_speed_HZ;
|
unsigned long __nongprelbss __res_bus_clock_speed_HZ;
|
||||||
|
|
|
@ -57,7 +57,7 @@ void ptrace_disable(struct task_struct *child)
|
||||||
h8300_disable_trace(child);
|
h8300_disable_trace(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
|
asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
|
||||||
{
|
{
|
||||||
struct task_struct *child;
|
struct task_struct *child;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -32,10 +32,6 @@
|
||||||
|
|
||||||
#define TICK_SIZE (tick_nsec / 1000)
|
#define TICK_SIZE (tick_nsec / 1000)
|
||||||
|
|
||||||
u64 jiffies_64;
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(jiffies_64);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* timer_interrupt() needs to keep up the real-time clock,
|
* timer_interrupt() needs to keep up the real-time clock,
|
||||||
* as well as call the "do_timer()" routine every clocktick
|
* as well as call the "do_timer()" routine every clocktick
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
mainmenu "Linux Kernel Configuration"
|
mainmenu "Linux Kernel Configuration"
|
||||||
|
|
||||||
config X86
|
config X86_32
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
|
@ -18,6 +18,10 @@ config SEMAPHORE_SLEEPERS
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config X86
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config MMU
|
config MMU
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@ -151,304 +155,7 @@ config ES7000_CLUSTERED_APIC
|
||||||
default y
|
default y
|
||||||
depends on SMP && X86_ES7000 && MPENTIUMIII
|
depends on SMP && X86_ES7000 && MPENTIUMIII
|
||||||
|
|
||||||
if !X86_ELAN
|
source "arch/i386/Kconfig.cpu"
|
||||||
|
|
||||||
choice
|
|
||||||
prompt "Processor family"
|
|
||||||
default M686
|
|
||||||
|
|
||||||
config M386
|
|
||||||
bool "386"
|
|
||||||
---help---
|
|
||||||
This is the processor type of your CPU. This information is used for
|
|
||||||
optimizing purposes. In order to compile a kernel that can run on
|
|
||||||
all x86 CPU types (albeit not optimally fast), you can specify
|
|
||||||
"386" here.
|
|
||||||
|
|
||||||
The kernel will not necessarily run on earlier architectures than
|
|
||||||
the one you have chosen, e.g. a Pentium optimized kernel will run on
|
|
||||||
a PPro, but not necessarily on a i486.
|
|
||||||
|
|
||||||
Here are the settings recommended for greatest speed:
|
|
||||||
- "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
|
|
||||||
486DLC/DLC2, UMC 486SX-S and NexGen Nx586. Only "386" kernels
|
|
||||||
will run on a 386 class machine.
|
|
||||||
- "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
|
|
||||||
SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
|
|
||||||
- "586" for generic Pentium CPUs lacking the TSC
|
|
||||||
(time stamp counter) register.
|
|
||||||
- "Pentium-Classic" for the Intel Pentium.
|
|
||||||
- "Pentium-MMX" for the Intel Pentium MMX.
|
|
||||||
- "Pentium-Pro" for the Intel Pentium Pro.
|
|
||||||
- "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
|
|
||||||
- "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
|
|
||||||
- "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
|
|
||||||
- "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
|
|
||||||
- "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
|
|
||||||
- "Crusoe" for the Transmeta Crusoe series.
|
|
||||||
- "Efficeon" for the Transmeta Efficeon series.
|
|
||||||
- "Winchip-C6" for original IDT Winchip.
|
|
||||||
- "Winchip-2" for IDT Winchip 2.
|
|
||||||
- "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
|
|
||||||
- "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
|
|
||||||
- "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
|
|
||||||
- "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
|
|
||||||
|
|
||||||
If you don't know what to do, choose "386".
|
|
||||||
|
|
||||||
config M486
|
|
||||||
bool "486"
|
|
||||||
help
|
|
||||||
Select this for a 486 series processor, either Intel or one of the
|
|
||||||
compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX,
|
|
||||||
DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
|
|
||||||
U5S.
|
|
||||||
|
|
||||||
config M586
|
|
||||||
bool "586/K5/5x86/6x86/6x86MX"
|
|
||||||
help
|
|
||||||
Select this for an 586 or 686 series processor such as the AMD K5,
|
|
||||||
the Cyrix 5x86, 6x86 and 6x86MX. This choice does not
|
|
||||||
assume the RDTSC (Read Time Stamp Counter) instruction.
|
|
||||||
|
|
||||||
config M586TSC
|
|
||||||
bool "Pentium-Classic"
|
|
||||||
help
|
|
||||||
Select this for a Pentium Classic processor with the RDTSC (Read
|
|
||||||
Time Stamp Counter) instruction for benchmarking.
|
|
||||||
|
|
||||||
config M586MMX
|
|
||||||
bool "Pentium-MMX"
|
|
||||||
help
|
|
||||||
Select this for a Pentium with the MMX graphics/multimedia
|
|
||||||
extended instructions.
|
|
||||||
|
|
||||||
config M686
|
|
||||||
bool "Pentium-Pro"
|
|
||||||
help
|
|
||||||
Select this for Intel Pentium Pro chips. This enables the use of
|
|
||||||
Pentium Pro extended instructions, and disables the init-time guard
|
|
||||||
against the f00f bug found in earlier Pentiums.
|
|
||||||
|
|
||||||
config MPENTIUMII
|
|
||||||
bool "Pentium-II/Celeron(pre-Coppermine)"
|
|
||||||
help
|
|
||||||
Select this for Intel chips based on the Pentium-II and
|
|
||||||
pre-Coppermine Celeron core. This option enables an unaligned
|
|
||||||
copy optimization, compiles the kernel with optimization flags
|
|
||||||
tailored for the chip, and applies any applicable Pentium Pro
|
|
||||||
optimizations.
|
|
||||||
|
|
||||||
config MPENTIUMIII
|
|
||||||
bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
|
|
||||||
help
|
|
||||||
Select this for Intel chips based on the Pentium-III and
|
|
||||||
Celeron-Coppermine core. This option enables use of some
|
|
||||||
extended prefetch instructions in addition to the Pentium II
|
|
||||||
extensions.
|
|
||||||
|
|
||||||
config MPENTIUMM
|
|
||||||
bool "Pentium M"
|
|
||||||
help
|
|
||||||
Select this for Intel Pentium M (not Pentium-4 M)
|
|
||||||
notebook chips.
|
|
||||||
|
|
||||||
config MPENTIUM4
|
|
||||||
bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon"
|
|
||||||
help
|
|
||||||
Select this for Intel Pentium 4 chips. This includes the
|
|
||||||
Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
|
|
||||||
(not Pentium M) chips. This option enables compile flags
|
|
||||||
optimized for the chip, uses the correct cache shift, and
|
|
||||||
applies any applicable Pentium III optimizations.
|
|
||||||
|
|
||||||
config MK6
|
|
||||||
bool "K6/K6-II/K6-III"
|
|
||||||
help
|
|
||||||
Select this for an AMD K6-family processor. Enables use of
|
|
||||||
some extended instructions, and passes appropriate optimization
|
|
||||||
flags to GCC.
|
|
||||||
|
|
||||||
config MK7
|
|
||||||
bool "Athlon/Duron/K7"
|
|
||||||
help
|
|
||||||
Select this for an AMD Athlon K7-family processor. Enables use of
|
|
||||||
some extended instructions, and passes appropriate optimization
|
|
||||||
flags to GCC.
|
|
||||||
|
|
||||||
config MK8
|
|
||||||
bool "Opteron/Athlon64/Hammer/K8"
|
|
||||||
help
|
|
||||||
Select this for an AMD Opteron or Athlon64 Hammer-family processor. Enables
|
|
||||||
use of some extended instructions, and passes appropriate optimization
|
|
||||||
flags to GCC.
|
|
||||||
|
|
||||||
config MCRUSOE
|
|
||||||
bool "Crusoe"
|
|
||||||
help
|
|
||||||
Select this for a Transmeta Crusoe processor. Treats the processor
|
|
||||||
like a 586 with TSC, and sets some GCC optimization flags (like a
|
|
||||||
Pentium Pro with no alignment requirements).
|
|
||||||
|
|
||||||
config MEFFICEON
|
|
||||||
bool "Efficeon"
|
|
||||||
help
|
|
||||||
Select this for a Transmeta Efficeon processor.
|
|
||||||
|
|
||||||
config MWINCHIPC6
|
|
||||||
bool "Winchip-C6"
|
|
||||||
help
|
|
||||||
Select this for an IDT Winchip C6 chip. Linux and GCC
|
|
||||||
treat this chip as a 586TSC with some extended instructions
|
|
||||||
and alignment requirements.
|
|
||||||
|
|
||||||
config MWINCHIP2
|
|
||||||
bool "Winchip-2"
|
|
||||||
help
|
|
||||||
Select this for an IDT Winchip-2. Linux and GCC
|
|
||||||
treat this chip as a 586TSC with some extended instructions
|
|
||||||
and alignment requirements.
|
|
||||||
|
|
||||||
config MWINCHIP3D
|
|
||||||
bool "Winchip-2A/Winchip-3"
|
|
||||||
help
|
|
||||||
Select this for an IDT Winchip-2A or 3. Linux and GCC
|
|
||||||
treat this chip as a 586TSC with some extended instructions
|
|
||||||
and alignment reqirements. Also enable out of order memory
|
|
||||||
stores for this CPU, which can increase performance of some
|
|
||||||
operations.
|
|
||||||
|
|
||||||
config MGEODEGX1
|
|
||||||
bool "GeodeGX1"
|
|
||||||
help
|
|
||||||
Select this for a Geode GX1 (Cyrix MediaGX) chip.
|
|
||||||
|
|
||||||
config MCYRIXIII
|
|
||||||
bool "CyrixIII/VIA-C3"
|
|
||||||
help
|
|
||||||
Select this for a Cyrix III or C3 chip. Presently Linux and GCC
|
|
||||||
treat this chip as a generic 586. Whilst the CPU is 686 class,
|
|
||||||
it lacks the cmov extension which gcc assumes is present when
|
|
||||||
generating 686 code.
|
|
||||||
Note that Nehemiah (Model 9) and above will not boot with this
|
|
||||||
kernel due to them lacking the 3DNow! instructions used in earlier
|
|
||||||
incarnations of the CPU.
|
|
||||||
|
|
||||||
config MVIAC3_2
|
|
||||||
bool "VIA C3-2 (Nehemiah)"
|
|
||||||
help
|
|
||||||
Select this for a VIA C3 "Nehemiah". Selecting this enables usage
|
|
||||||
of SSE and tells gcc to treat the CPU as a 686.
|
|
||||||
Note, this kernel will not boot on older (pre model 9) C3s.
|
|
||||||
|
|
||||||
endchoice
|
|
||||||
|
|
||||||
config X86_GENERIC
|
|
||||||
bool "Generic x86 support"
|
|
||||||
help
|
|
||||||
Instead of just including optimizations for the selected
|
|
||||||
x86 variant (e.g. PII, Crusoe or Athlon), include some more
|
|
||||||
generic optimizations as well. This will make the kernel
|
|
||||||
perform better on x86 CPUs other than that selected.
|
|
||||||
|
|
||||||
This is really intended for distributors who need more
|
|
||||||
generic optimizations.
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
#
|
|
||||||
# Define implied options from the CPU selection here
|
|
||||||
#
|
|
||||||
config X86_CMPXCHG
|
|
||||||
bool
|
|
||||||
depends on !M386
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_XADD
|
|
||||||
bool
|
|
||||||
depends on !M386
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_L1_CACHE_SHIFT
|
|
||||||
int
|
|
||||||
default "7" if MPENTIUM4 || X86_GENERIC
|
|
||||||
default "4" if X86_ELAN || M486 || M386
|
|
||||||
default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
|
|
||||||
default "6" if MK7 || MK8 || MPENTIUMM
|
|
||||||
|
|
||||||
config RWSEM_GENERIC_SPINLOCK
|
|
||||||
bool
|
|
||||||
depends on M386
|
|
||||||
default y
|
|
||||||
|
|
||||||
config RWSEM_XCHGADD_ALGORITHM
|
|
||||||
bool
|
|
||||||
depends on !M386
|
|
||||||
default y
|
|
||||||
|
|
||||||
config GENERIC_CALIBRATE_DELAY
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_PPRO_FENCE
|
|
||||||
bool
|
|
||||||
depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_F00F_BUG
|
|
||||||
bool
|
|
||||||
depends on M586MMX || M586TSC || M586 || M486 || M386
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_WP_WORKS_OK
|
|
||||||
bool
|
|
||||||
depends on !M386
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_INVLPG
|
|
||||||
bool
|
|
||||||
depends on !M386
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_BSWAP
|
|
||||||
bool
|
|
||||||
depends on !M386
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_POPAD_OK
|
|
||||||
bool
|
|
||||||
depends on !M386
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_ALIGNMENT_16
|
|
||||||
bool
|
|
||||||
depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_GOOD_APIC
|
|
||||||
bool
|
|
||||||
depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_INTEL_USERCOPY
|
|
||||||
bool
|
|
||||||
depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_USE_PPRO_CHECKSUM
|
|
||||||
bool
|
|
||||||
depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_USE_3DNOW
|
|
||||||
bool
|
|
||||||
depends on MCYRIXIII || MK7
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_OOSTORE
|
|
||||||
bool
|
|
||||||
depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
|
|
||||||
default y
|
|
||||||
|
|
||||||
config HPET_TIMER
|
config HPET_TIMER
|
||||||
bool "HPET Timer Support"
|
bool "HPET Timer Support"
|
||||||
|
@ -561,11 +268,6 @@ config X86_VISWS_APIC
|
||||||
depends on X86_VISWS
|
depends on X86_VISWS
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config X86_TSC
|
|
||||||
bool
|
|
||||||
depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
|
|
||||||
default y
|
|
||||||
|
|
||||||
config X86_MCE
|
config X86_MCE
|
||||||
bool "Machine Check Exception"
|
bool "Machine Check Exception"
|
||||||
depends on !X86_VOYAGER
|
depends on !X86_VOYAGER
|
||||||
|
|
|
@ -0,0 +1,309 @@
|
||||||
|
# Put here option for CPU selection and depending optimization
|
||||||
|
if !X86_ELAN
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "Processor family"
|
||||||
|
default M686
|
||||||
|
|
||||||
|
config M386
|
||||||
|
bool "386"
|
||||||
|
---help---
|
||||||
|
This is the processor type of your CPU. This information is used for
|
||||||
|
optimizing purposes. In order to compile a kernel that can run on
|
||||||
|
all x86 CPU types (albeit not optimally fast), you can specify
|
||||||
|
"386" here.
|
||||||
|
|
||||||
|
The kernel will not necessarily run on earlier architectures than
|
||||||
|
the one you have chosen, e.g. a Pentium optimized kernel will run on
|
||||||
|
a PPro, but not necessarily on a i486.
|
||||||
|
|
||||||
|
Here are the settings recommended for greatest speed:
|
||||||
|
- "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
|
||||||
|
486DLC/DLC2, UMC 486SX-S and NexGen Nx586. Only "386" kernels
|
||||||
|
will run on a 386 class machine.
|
||||||
|
- "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
|
||||||
|
SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
|
||||||
|
- "586" for generic Pentium CPUs lacking the TSC
|
||||||
|
(time stamp counter) register.
|
||||||
|
- "Pentium-Classic" for the Intel Pentium.
|
||||||
|
- "Pentium-MMX" for the Intel Pentium MMX.
|
||||||
|
- "Pentium-Pro" for the Intel Pentium Pro.
|
||||||
|
- "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
|
||||||
|
- "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
|
||||||
|
- "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
|
||||||
|
- "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
|
||||||
|
- "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
|
||||||
|
- "Crusoe" for the Transmeta Crusoe series.
|
||||||
|
- "Efficeon" for the Transmeta Efficeon series.
|
||||||
|
- "Winchip-C6" for original IDT Winchip.
|
||||||
|
- "Winchip-2" for IDT Winchip 2.
|
||||||
|
- "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
|
||||||
|
- "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
|
||||||
|
- "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
|
||||||
|
- "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
|
||||||
|
|
||||||
|
If you don't know what to do, choose "386".
|
||||||
|
|
||||||
|
config M486
|
||||||
|
bool "486"
|
||||||
|
help
|
||||||
|
Select this for a 486 series processor, either Intel or one of the
|
||||||
|
compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX,
|
||||||
|
DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
|
||||||
|
U5S.
|
||||||
|
|
||||||
|
config M586
|
||||||
|
bool "586/K5/5x86/6x86/6x86MX"
|
||||||
|
help
|
||||||
|
Select this for an 586 or 686 series processor such as the AMD K5,
|
||||||
|
the Cyrix 5x86, 6x86 and 6x86MX. This choice does not
|
||||||
|
assume the RDTSC (Read Time Stamp Counter) instruction.
|
||||||
|
|
||||||
|
config M586TSC
|
||||||
|
bool "Pentium-Classic"
|
||||||
|
help
|
||||||
|
Select this for a Pentium Classic processor with the RDTSC (Read
|
||||||
|
Time Stamp Counter) instruction for benchmarking.
|
||||||
|
|
||||||
|
config M586MMX
|
||||||
|
bool "Pentium-MMX"
|
||||||
|
help
|
||||||
|
Select this for a Pentium with the MMX graphics/multimedia
|
||||||
|
extended instructions.
|
||||||
|
|
||||||
|
config M686
|
||||||
|
bool "Pentium-Pro"
|
||||||
|
help
|
||||||
|
Select this for Intel Pentium Pro chips. This enables the use of
|
||||||
|
Pentium Pro extended instructions, and disables the init-time guard
|
||||||
|
against the f00f bug found in earlier Pentiums.
|
||||||
|
|
||||||
|
config MPENTIUMII
|
||||||
|
bool "Pentium-II/Celeron(pre-Coppermine)"
|
||||||
|
help
|
||||||
|
Select this for Intel chips based on the Pentium-II and
|
||||||
|
pre-Coppermine Celeron core. This option enables an unaligned
|
||||||
|
copy optimization, compiles the kernel with optimization flags
|
||||||
|
tailored for the chip, and applies any applicable Pentium Pro
|
||||||
|
optimizations.
|
||||||
|
|
||||||
|
config MPENTIUMIII
|
||||||
|
bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
|
||||||
|
help
|
||||||
|
Select this for Intel chips based on the Pentium-III and
|
||||||
|
Celeron-Coppermine core. This option enables use of some
|
||||||
|
extended prefetch instructions in addition to the Pentium II
|
||||||
|
extensions.
|
||||||
|
|
||||||
|
config MPENTIUMM
|
||||||
|
bool "Pentium M"
|
||||||
|
help
|
||||||
|
Select this for Intel Pentium M (not Pentium-4 M)
|
||||||
|
notebook chips.
|
||||||
|
|
||||||
|
config MPENTIUM4
|
||||||
|
bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon"
|
||||||
|
help
|
||||||
|
Select this for Intel Pentium 4 chips. This includes the
|
||||||
|
Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
|
||||||
|
(not Pentium M) chips. This option enables compile flags
|
||||||
|
optimized for the chip, uses the correct cache shift, and
|
||||||
|
applies any applicable Pentium III optimizations.
|
||||||
|
|
||||||
|
config MK6
|
||||||
|
bool "K6/K6-II/K6-III"
|
||||||
|
help
|
||||||
|
Select this for an AMD K6-family processor. Enables use of
|
||||||
|
some extended instructions, and passes appropriate optimization
|
||||||
|
flags to GCC.
|
||||||
|
|
||||||
|
config MK7
|
||||||
|
bool "Athlon/Duron/K7"
|
||||||
|
help
|
||||||
|
Select this for an AMD Athlon K7-family processor. Enables use of
|
||||||
|
some extended instructions, and passes appropriate optimization
|
||||||
|
flags to GCC.
|
||||||
|
|
||||||
|
config MK8
|
||||||
|
bool "Opteron/Athlon64/Hammer/K8"
|
||||||
|
help
|
||||||
|
Select this for an AMD Opteron or Athlon64 Hammer-family processor. Enables
|
||||||
|
use of some extended instructions, and passes appropriate optimization
|
||||||
|
flags to GCC.
|
||||||
|
|
||||||
|
config MCRUSOE
|
||||||
|
bool "Crusoe"
|
||||||
|
help
|
||||||
|
Select this for a Transmeta Crusoe processor. Treats the processor
|
||||||
|
like a 586 with TSC, and sets some GCC optimization flags (like a
|
||||||
|
Pentium Pro with no alignment requirements).
|
||||||
|
|
||||||
|
config MEFFICEON
|
||||||
|
bool "Efficeon"
|
||||||
|
help
|
||||||
|
Select this for a Transmeta Efficeon processor.
|
||||||
|
|
||||||
|
config MWINCHIPC6
|
||||||
|
bool "Winchip-C6"
|
||||||
|
help
|
||||||
|
Select this for an IDT Winchip C6 chip. Linux and GCC
|
||||||
|
treat this chip as a 586TSC with some extended instructions
|
||||||
|
and alignment requirements.
|
||||||
|
|
||||||
|
config MWINCHIP2
|
||||||
|
bool "Winchip-2"
|
||||||
|
help
|
||||||
|
Select this for an IDT Winchip-2. Linux and GCC
|
||||||
|
treat this chip as a 586TSC with some extended instructions
|
||||||
|
and alignment requirements.
|
||||||
|
|
||||||
|
config MWINCHIP3D
|
||||||
|
bool "Winchip-2A/Winchip-3"
|
||||||
|
help
|
||||||
|
Select this for an IDT Winchip-2A or 3. Linux and GCC
|
||||||
|
treat this chip as a 586TSC with some extended instructions
|
||||||
|
and alignment reqirements. Also enable out of order memory
|
||||||
|
stores for this CPU, which can increase performance of some
|
||||||
|
operations.
|
||||||
|
|
||||||
|
config MGEODEGX1
|
||||||
|
bool "GeodeGX1"
|
||||||
|
help
|
||||||
|
Select this for a Geode GX1 (Cyrix MediaGX) chip.
|
||||||
|
|
||||||
|
config MCYRIXIII
|
||||||
|
bool "CyrixIII/VIA-C3"
|
||||||
|
help
|
||||||
|
Select this for a Cyrix III or C3 chip. Presently Linux and GCC
|
||||||
|
treat this chip as a generic 586. Whilst the CPU is 686 class,
|
||||||
|
it lacks the cmov extension which gcc assumes is present when
|
||||||
|
generating 686 code.
|
||||||
|
Note that Nehemiah (Model 9) and above will not boot with this
|
||||||
|
kernel due to them lacking the 3DNow! instructions used in earlier
|
||||||
|
incarnations of the CPU.
|
||||||
|
|
||||||
|
config MVIAC3_2
|
||||||
|
bool "VIA C3-2 (Nehemiah)"
|
||||||
|
help
|
||||||
|
Select this for a VIA C3 "Nehemiah". Selecting this enables usage
|
||||||
|
of SSE and tells gcc to treat the CPU as a 686.
|
||||||
|
Note, this kernel will not boot on older (pre model 9) C3s.
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config X86_GENERIC
|
||||||
|
bool "Generic x86 support"
|
||||||
|
help
|
||||||
|
Instead of just including optimizations for the selected
|
||||||
|
x86 variant (e.g. PII, Crusoe or Athlon), include some more
|
||||||
|
generic optimizations as well. This will make the kernel
|
||||||
|
perform better on x86 CPUs other than that selected.
|
||||||
|
|
||||||
|
This is really intended for distributors who need more
|
||||||
|
generic optimizations.
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define implied options from the CPU selection here
|
||||||
|
#
|
||||||
|
config X86_CMPXCHG
|
||||||
|
bool
|
||||||
|
depends on !M386
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_XADD
|
||||||
|
bool
|
||||||
|
depends on !M386
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_L1_CACHE_SHIFT
|
||||||
|
int
|
||||||
|
default "7" if MPENTIUM4 || X86_GENERIC
|
||||||
|
default "4" if X86_ELAN || M486 || M386
|
||||||
|
default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
|
||||||
|
default "6" if MK7 || MK8 || MPENTIUMM
|
||||||
|
|
||||||
|
config RWSEM_GENERIC_SPINLOCK
|
||||||
|
bool
|
||||||
|
depends on M386
|
||||||
|
default y
|
||||||
|
|
||||||
|
config RWSEM_XCHGADD_ALGORITHM
|
||||||
|
bool
|
||||||
|
depends on !M386
|
||||||
|
default y
|
||||||
|
|
||||||
|
config GENERIC_CALIBRATE_DELAY
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_PPRO_FENCE
|
||||||
|
bool
|
||||||
|
depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_F00F_BUG
|
||||||
|
bool
|
||||||
|
depends on M586MMX || M586TSC || M586 || M486 || M386
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_WP_WORKS_OK
|
||||||
|
bool
|
||||||
|
depends on !M386
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_INVLPG
|
||||||
|
bool
|
||||||
|
depends on !M386
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_BSWAP
|
||||||
|
bool
|
||||||
|
depends on !M386
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_POPAD_OK
|
||||||
|
bool
|
||||||
|
depends on !M386
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_CMPXCHG64
|
||||||
|
bool
|
||||||
|
depends on !M386 && !M486
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_ALIGNMENT_16
|
||||||
|
bool
|
||||||
|
depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_GOOD_APIC
|
||||||
|
bool
|
||||||
|
depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_INTEL_USERCOPY
|
||||||
|
bool
|
||||||
|
depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_USE_PPRO_CHECKSUM
|
||||||
|
bool
|
||||||
|
depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_USE_3DNOW
|
||||||
|
bool
|
||||||
|
depends on MCYRIXIII || MK7
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_OOSTORE
|
||||||
|
bool
|
||||||
|
depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
|
||||||
|
default y
|
||||||
|
|
||||||
|
config X86_TSC
|
||||||
|
bool
|
||||||
|
depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
|
||||||
|
default y
|
|
@ -34,35 +34,8 @@ CFLAGS += -pipe -msoft-float
|
||||||
# prevent gcc from keeping the stack 16 byte aligned
|
# prevent gcc from keeping the stack 16 byte aligned
|
||||||
CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
|
CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
|
||||||
|
|
||||||
align := $(cc-option-align)
|
# CPU-specific tuning. Anything which can be shared with UML should go here.
|
||||||
cflags-$(CONFIG_M386) += -march=i386
|
include $(srctree)/arch/i386/Makefile.cpu
|
||||||
cflags-$(CONFIG_M486) += -march=i486
|
|
||||||
cflags-$(CONFIG_M586) += -march=i586
|
|
||||||
cflags-$(CONFIG_M586TSC) += -march=i586
|
|
||||||
cflags-$(CONFIG_M586MMX) += $(call cc-option,-march=pentium-mmx,-march=i586)
|
|
||||||
cflags-$(CONFIG_M686) += -march=i686
|
|
||||||
cflags-$(CONFIG_MPENTIUMII) += -march=i686 $(call cc-option,-mtune=pentium2)
|
|
||||||
cflags-$(CONFIG_MPENTIUMIII) += -march=i686 $(call cc-option,-mtune=pentium3)
|
|
||||||
cflags-$(CONFIG_MPENTIUMM) += -march=i686 $(call cc-option,-mtune=pentium3)
|
|
||||||
cflags-$(CONFIG_MPENTIUM4) += -march=i686 $(call cc-option,-mtune=pentium4)
|
|
||||||
cflags-$(CONFIG_MK6) += -march=k6
|
|
||||||
# Please note, that patches that add -march=athlon-xp and friends are pointless.
|
|
||||||
# They make zero difference whatsosever to performance at this time.
|
|
||||||
cflags-$(CONFIG_MK7) += $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)
|
|
||||||
cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4))
|
|
||||||
cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
|
|
||||||
cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call cc-option,-mtune=pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
|
|
||||||
cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586)
|
|
||||||
cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586)
|
|
||||||
cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586)
|
|
||||||
cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
|
|
||||||
cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
|
|
||||||
|
|
||||||
# AMD Elan support
|
|
||||||
cflags-$(CONFIG_X86_ELAN) += -march=i486
|
|
||||||
|
|
||||||
# Geode GX1 support
|
|
||||||
cflags-$(CONFIG_MGEODEGX1) += $(call cc-option,-march=pentium-mmx,-march=i486)
|
|
||||||
|
|
||||||
# -mregparm=3 works ok on gcc-3.0 and later
|
# -mregparm=3 works ok on gcc-3.0 and later
|
||||||
#
|
#
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
# CPU tuning section - shared with UML.
|
||||||
|
# Must change only cflags-y (or [yn]), not CFLAGS! That makes a difference for UML.
|
||||||
|
|
||||||
|
#-mtune exists since gcc 3.4, and some -mcpu flavors didn't exist in gcc 2.95.
|
||||||
|
HAS_MTUNE := $(call cc-option-yn, -mtune=i386)
|
||||||
|
ifeq ($(HAS_MTUNE),y)
|
||||||
|
tune = $(call cc-option,-mtune=$(1),)
|
||||||
|
else
|
||||||
|
tune = $(call cc-option,-mcpu=$(1),)
|
||||||
|
endif
|
||||||
|
|
||||||
|
align := $(cc-option-align)
|
||||||
|
cflags-$(CONFIG_M386) += -march=i386
|
||||||
|
cflags-$(CONFIG_M486) += -march=i486
|
||||||
|
cflags-$(CONFIG_M586) += -march=i586
|
||||||
|
cflags-$(CONFIG_M586TSC) += -march=i586
|
||||||
|
cflags-$(CONFIG_M586MMX) += $(call cc-option,-march=pentium-mmx,-march=i586)
|
||||||
|
cflags-$(CONFIG_M686) += -march=i686
|
||||||
|
cflags-$(CONFIG_MPENTIUMII) += -march=i686 $(call tune,pentium2)
|
||||||
|
cflags-$(CONFIG_MPENTIUMIII) += -march=i686 $(call tune,pentium3)
|
||||||
|
cflags-$(CONFIG_MPENTIUMM) += -march=i686 $(call tune,pentium3)
|
||||||
|
cflags-$(CONFIG_MPENTIUM4) += -march=i686 $(call tune,pentium4)
|
||||||
|
cflags-$(CONFIG_MK6) += -march=k6
|
||||||
|
# Please note, that patches that add -march=athlon-xp and friends are pointless.
|
||||||
|
# They make zero difference whatsosever to performance at this time.
|
||||||
|
cflags-$(CONFIG_MK7) += $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)
|
||||||
|
cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4))
|
||||||
|
cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
|
||||||
|
cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
|
||||||
|
cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586)
|
||||||
|
cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586)
|
||||||
|
cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586)
|
||||||
|
cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
|
||||||
|
cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
|
||||||
|
|
||||||
|
# AMD Elan support
|
||||||
|
cflags-$(CONFIG_X86_ELAN) += -march=i486
|
||||||
|
|
||||||
|
# Geode GX1 support
|
||||||
|
cflags-$(CONFIG_MGEODEGX1) += $(call cc-option,-march=pentium-mmx,-march=i486)
|
||||||
|
|
|
@ -803,6 +803,7 @@ no_apic:
|
||||||
|
|
||||||
void __init init_apic_mappings(void)
|
void __init init_apic_mappings(void)
|
||||||
{
|
{
|
||||||
|
unsigned int orig_apicid;
|
||||||
unsigned long apic_phys;
|
unsigned long apic_phys;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -824,8 +825,11 @@ void __init init_apic_mappings(void)
|
||||||
* Fetch the APIC ID of the BSP in case we have a
|
* Fetch the APIC ID of the BSP in case we have a
|
||||||
* default configuration (or the MP table is broken).
|
* default configuration (or the MP table is broken).
|
||||||
*/
|
*/
|
||||||
if (boot_cpu_physical_apicid == -1U)
|
orig_apicid = boot_cpu_physical_apicid;
|
||||||
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
|
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
|
||||||
|
if ((orig_apicid != -1U) && (orig_apicid != boot_cpu_physical_apicid))
|
||||||
|
printk(KERN_WARNING "Boot APIC ID in local APIC unexpected (%d vs %d)",
|
||||||
|
orig_apicid, boot_cpu_physical_apicid);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_IO_APIC
|
#ifdef CONFIG_X86_IO_APIC
|
||||||
{
|
{
|
||||||
|
@ -1046,10 +1050,11 @@ static unsigned int calibration_result;
|
||||||
|
|
||||||
void __init setup_boot_APIC_clock(void)
|
void __init setup_boot_APIC_clock(void)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n");
|
apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n");
|
||||||
using_apic_timer = 1;
|
using_apic_timer = 1;
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_save(flags);
|
||||||
|
|
||||||
calibration_result = calibrate_APIC_clock();
|
calibration_result = calibrate_APIC_clock();
|
||||||
/*
|
/*
|
||||||
|
@ -1057,7 +1062,7 @@ void __init setup_boot_APIC_clock(void)
|
||||||
*/
|
*/
|
||||||
setup_APIC_timer(calibration_result);
|
setup_APIC_timer(calibration_result);
|
||||||
|
|
||||||
local_irq_enable();
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __devinit setup_secondary_APIC_clock(void)
|
void __devinit setup_secondary_APIC_clock(void)
|
||||||
|
@ -1254,40 +1259,81 @@ fastcall void smp_error_interrupt(struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This initializes the IO-APIC and APIC hardware if this is
|
* This initializes the IO-APIC and APIC hardware.
|
||||||
* a UP kernel.
|
|
||||||
*/
|
*/
|
||||||
int __init APIC_init_uniprocessor (void)
|
int __init APIC_init(void)
|
||||||
{
|
{
|
||||||
if (enable_local_apic < 0)
|
if (enable_local_apic < 0) {
|
||||||
clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
|
printk(KERN_INFO "APIC disabled\n");
|
||||||
|
|
||||||
if (!smp_found_config && !cpu_has_apic)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if we have a SMP configuration or have forced enabled
|
||||||
|
* the local apic.
|
||||||
|
*/
|
||||||
|
if (!smp_found_config && !acpi_lapic && !cpu_has_apic) {
|
||||||
|
enable_local_apic = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Complain if the BIOS pretends there is one.
|
* Complain if the BIOS pretends there is an apic.
|
||||||
|
* Then get out because we don't have an a local apic.
|
||||||
*/
|
*/
|
||||||
if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
|
if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
|
||||||
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
|
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
|
||||||
boot_cpu_physical_apicid);
|
boot_cpu_physical_apicid);
|
||||||
|
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
|
||||||
|
enable_local_apic = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
verify_local_APIC();
|
verify_local_APIC();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should not be necessary because the MP table should list the boot
|
||||||
|
* CPU too, but we do it for the sake of robustness anyway.
|
||||||
|
* Makes no sense to do this check in clustered apic mode, so skip it
|
||||||
|
*/
|
||||||
|
if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
|
||||||
|
printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
|
||||||
|
boot_cpu_physical_apicid);
|
||||||
|
physid_set(boot_cpu_physical_apicid, phys_cpu_present_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Switch from PIC to APIC mode.
|
||||||
|
*/
|
||||||
connect_bsp_APIC();
|
connect_bsp_APIC();
|
||||||
|
|
||||||
phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
|
|
||||||
|
|
||||||
setup_local_APIC();
|
setup_local_APIC();
|
||||||
|
|
||||||
#ifdef CONFIG_X86_IO_APIC
|
#ifdef CONFIG_X86_IO_APIC
|
||||||
if (smp_found_config)
|
/*
|
||||||
if (!skip_ioapic_setup && nr_ioapics)
|
* Now start the IO-APICs
|
||||||
setup_IO_APIC();
|
*/
|
||||||
|
if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
|
||||||
|
setup_IO_APIC();
|
||||||
#endif
|
#endif
|
||||||
setup_boot_APIC_clock();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __init APIC_late_time_init(void)
|
||||||
|
{
|
||||||
|
/* Improve our loops per jiffy estimate */
|
||||||
|
loops_per_jiffy = ((1000 + HZ - 1)/HZ)*cpu_khz;
|
||||||
|
boot_cpu_data.loops_per_jiffy = loops_per_jiffy;
|
||||||
|
cpu_data[0].loops_per_jiffy = loops_per_jiffy;
|
||||||
|
|
||||||
|
/* setup_apic_nmi_watchdog doesn't work properly before cpu_khz is
|
||||||
|
* initialized. So redo it here to ensure the boot cpu is setup
|
||||||
|
* properly.
|
||||||
|
*/
|
||||||
|
if (nmi_watchdog == NMI_LOCAL_APIC)
|
||||||
|
setup_apic_nmi_watchdog();
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_IO_APIC
|
||||||
|
if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
|
||||||
|
IO_APIC_late_time_init();
|
||||||
|
#endif
|
||||||
|
setup_boot_APIC_clock();
|
||||||
|
}
|
||||||
|
|
|
@ -597,12 +597,14 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
|
||||||
cpumask_t cpus;
|
cpumask_t cpus;
|
||||||
int cpu;
|
int cpu;
|
||||||
struct desc_struct save_desc_40;
|
struct desc_struct save_desc_40;
|
||||||
|
struct desc_struct *gdt;
|
||||||
|
|
||||||
cpus = apm_save_cpus();
|
cpus = apm_save_cpus();
|
||||||
|
|
||||||
cpu = get_cpu();
|
cpu = get_cpu();
|
||||||
save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
|
gdt = get_cpu_gdt_table(cpu);
|
||||||
per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
|
save_desc_40 = gdt[0x40 / 8];
|
||||||
|
gdt[0x40 / 8] = bad_bios_desc;
|
||||||
|
|
||||||
local_save_flags(flags);
|
local_save_flags(flags);
|
||||||
APM_DO_CLI;
|
APM_DO_CLI;
|
||||||
|
@ -610,7 +612,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
|
||||||
apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
|
apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
|
||||||
APM_DO_RESTORE_SEGS;
|
APM_DO_RESTORE_SEGS;
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = save_desc_40;
|
gdt[0x40 / 8] = save_desc_40;
|
||||||
put_cpu();
|
put_cpu();
|
||||||
apm_restore_cpus(cpus);
|
apm_restore_cpus(cpus);
|
||||||
|
|
||||||
|
@ -639,13 +641,14 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
|
||||||
cpumask_t cpus;
|
cpumask_t cpus;
|
||||||
int cpu;
|
int cpu;
|
||||||
struct desc_struct save_desc_40;
|
struct desc_struct save_desc_40;
|
||||||
|
struct desc_struct *gdt;
|
||||||
|
|
||||||
cpus = apm_save_cpus();
|
cpus = apm_save_cpus();
|
||||||
|
|
||||||
cpu = get_cpu();
|
cpu = get_cpu();
|
||||||
save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
|
gdt = get_cpu_gdt_table(cpu);
|
||||||
per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
|
save_desc_40 = gdt[0x40 / 8];
|
||||||
|
gdt[0x40 / 8] = bad_bios_desc;
|
||||||
|
|
||||||
local_save_flags(flags);
|
local_save_flags(flags);
|
||||||
APM_DO_CLI;
|
APM_DO_CLI;
|
||||||
|
@ -653,7 +656,7 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
|
||||||
error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
|
error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
|
||||||
APM_DO_RESTORE_SEGS;
|
APM_DO_RESTORE_SEGS;
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
__get_cpu_var(cpu_gdt_table)[0x40 / 8] = save_desc_40;
|
gdt[0x40 / 8] = save_desc_40;
|
||||||
put_cpu();
|
put_cpu();
|
||||||
apm_restore_cpus(cpus);
|
apm_restore_cpus(cpus);
|
||||||
return error;
|
return error;
|
||||||
|
@ -2295,35 +2298,36 @@ static int __init apm_init(void)
|
||||||
apm_bios_entry.segment = APM_CS;
|
apm_bios_entry.segment = APM_CS;
|
||||||
|
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for (i = 0; i < NR_CPUS; i++) {
|
||||||
set_base(per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
|
struct desc_struct *gdt = get_cpu_gdt_table(i);
|
||||||
|
set_base(gdt[APM_CS >> 3],
|
||||||
__va((unsigned long)apm_info.bios.cseg << 4));
|
__va((unsigned long)apm_info.bios.cseg << 4));
|
||||||
set_base(per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
|
set_base(gdt[APM_CS_16 >> 3],
|
||||||
__va((unsigned long)apm_info.bios.cseg_16 << 4));
|
__va((unsigned long)apm_info.bios.cseg_16 << 4));
|
||||||
set_base(per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
|
set_base(gdt[APM_DS >> 3],
|
||||||
__va((unsigned long)apm_info.bios.dseg << 4));
|
__va((unsigned long)apm_info.bios.dseg << 4));
|
||||||
#ifndef APM_RELAX_SEGMENTS
|
#ifndef APM_RELAX_SEGMENTS
|
||||||
if (apm_info.bios.version == 0x100) {
|
if (apm_info.bios.version == 0x100) {
|
||||||
#endif
|
#endif
|
||||||
/* For ASUS motherboard, Award BIOS rev 110 (and others?) */
|
/* For ASUS motherboard, Award BIOS rev 110 (and others?) */
|
||||||
_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 - 1);
|
_set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 - 1);
|
||||||
/* For some unknown machine. */
|
/* For some unknown machine. */
|
||||||
_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3], 64 * 1024 - 1);
|
_set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
|
||||||
/* For the DEC Hinote Ultra CT475 (and others?) */
|
/* For the DEC Hinote Ultra CT475 (and others?) */
|
||||||
_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3], 64 * 1024 - 1);
|
_set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
|
||||||
#ifndef APM_RELAX_SEGMENTS
|
#ifndef APM_RELAX_SEGMENTS
|
||||||
} else {
|
} else {
|
||||||
_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
|
_set_limit((char *)&gdt[APM_CS >> 3],
|
||||||
(apm_info.bios.cseg_len - 1) & 0xffff);
|
(apm_info.bios.cseg_len - 1) & 0xffff);
|
||||||
_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
|
_set_limit((char *)&gdt[APM_CS_16 >> 3],
|
||||||
(apm_info.bios.cseg_16_len - 1) & 0xffff);
|
(apm_info.bios.cseg_16_len - 1) & 0xffff);
|
||||||
_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
|
_set_limit((char *)&gdt[APM_DS >> 3],
|
||||||
(apm_info.bios.dseg_len - 1) & 0xffff);
|
(apm_info.bios.dseg_len - 1) & 0xffff);
|
||||||
/* workaround for broken BIOSes */
|
/* workaround for broken BIOSes */
|
||||||
if (apm_info.bios.cseg_len <= apm_info.bios.offset)
|
if (apm_info.bios.cseg_len <= apm_info.bios.offset)
|
||||||
_set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 -1);
|
_set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 -1);
|
||||||
if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
|
if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
|
||||||
/* for the BIOS that assumes granularity = 1 */
|
/* for the BIOS that assumes granularity = 1 */
|
||||||
per_cpu(cpu_gdt_table, i)[APM_DS >> 3].b |= 0x800000;
|
gdt[APM_DS >> 3].b |= 0x800000;
|
||||||
printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
|
printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -573,6 +573,7 @@ void __devinit cpu_init(void)
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
struct tss_struct * t = &per_cpu(init_tss, cpu);
|
struct tss_struct * t = &per_cpu(init_tss, cpu);
|
||||||
struct thread_struct *thread = ¤t->thread;
|
struct thread_struct *thread = ¤t->thread;
|
||||||
|
struct desc_struct *gdt = get_cpu_gdt_table(cpu);
|
||||||
__u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
|
__u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
|
||||||
|
|
||||||
if (cpu_test_and_set(cpu, cpu_initialized)) {
|
if (cpu_test_and_set(cpu, cpu_initialized)) {
|
||||||
|
@ -594,24 +595,16 @@ void __devinit cpu_init(void)
|
||||||
* Initialize the per-CPU GDT with the boot GDT,
|
* Initialize the per-CPU GDT with the boot GDT,
|
||||||
* and set up the GDT descriptor:
|
* and set up the GDT descriptor:
|
||||||
*/
|
*/
|
||||||
memcpy(&per_cpu(cpu_gdt_table, cpu), cpu_gdt_table,
|
memcpy(gdt, cpu_gdt_table, GDT_SIZE);
|
||||||
GDT_SIZE);
|
|
||||||
|
|
||||||
/* Set up GDT entry for 16bit stack */
|
/* Set up GDT entry for 16bit stack */
|
||||||
*(__u64 *)&(per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_ESPFIX_SS]) |=
|
*(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
|
||||||
((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) |
|
((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) |
|
||||||
((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
|
((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
|
||||||
(CPU_16BIT_STACK_SIZE - 1);
|
(CPU_16BIT_STACK_SIZE - 1);
|
||||||
|
|
||||||
cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
|
cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
|
||||||
cpu_gdt_descr[cpu].address =
|
cpu_gdt_descr[cpu].address = (unsigned long)gdt;
|
||||||
(unsigned long)&per_cpu(cpu_gdt_table, cpu);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up the per-thread TLS descriptor cache:
|
|
||||||
*/
|
|
||||||
memcpy(thread->tls_array, &per_cpu(cpu_gdt_table, cpu),
|
|
||||||
GDT_ENTRY_TLS_ENTRIES * 8);
|
|
||||||
|
|
||||||
load_gdt(&cpu_gdt_descr[cpu]);
|
load_gdt(&cpu_gdt_descr[cpu]);
|
||||||
load_idt(&idt_descr);
|
load_idt(&idt_descr);
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/sched.h> /* current */
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/delay.h>
|
#include <asm/delay.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <linux/cpufreq.h>
|
#include <linux/cpufreq.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
|
#include <linux/sched.h> /* current / set_cpus_allowed() */
|
||||||
|
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/msr.h>
|
#include <asm/msr.h>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
|
#include <linux/sched.h> /* for current / set_cpus_allowed() */
|
||||||
|
|
||||||
#include <asm/msr.h>
|
#include <asm/msr.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/cpufreq.h>
|
#include <linux/cpufreq.h>
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
|
#include <linux/sched.h> /* current */
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
* Changes:
|
* Changes:
|
||||||
* Venkatesh Pallipadi : Adding cache identification through cpuid(4)
|
* Venkatesh Pallipadi : Adding cache identification through cpuid(4)
|
||||||
|
* Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
@ -10,6 +11,7 @@
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
@ -28,7 +30,7 @@ struct _cache_table
|
||||||
};
|
};
|
||||||
|
|
||||||
/* all the cache descriptor types we care about (no TLB or trace cache entries) */
|
/* all the cache descriptor types we care about (no TLB or trace cache entries) */
|
||||||
static struct _cache_table cache_table[] __devinitdata =
|
static struct _cache_table cache_table[] __cpuinitdata =
|
||||||
{
|
{
|
||||||
{ 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
|
{ 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
|
||||||
{ 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
|
{ 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
|
||||||
|
@ -117,10 +119,9 @@ struct _cpuid4_info {
|
||||||
cpumask_t shared_cpu_map;
|
cpumask_t shared_cpu_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_CACHE_LEAVES 4
|
|
||||||
static unsigned short num_cache_leaves;
|
static unsigned short num_cache_leaves;
|
||||||
|
|
||||||
static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
|
static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
|
||||||
{
|
{
|
||||||
unsigned int eax, ebx, ecx, edx;
|
unsigned int eax, ebx, ecx, edx;
|
||||||
union _cpuid4_leaf_eax cache_eax;
|
union _cpuid4_leaf_eax cache_eax;
|
||||||
|
@ -144,23 +145,18 @@ static int __init find_num_cache_leaves(void)
|
||||||
{
|
{
|
||||||
unsigned int eax, ebx, ecx, edx;
|
unsigned int eax, ebx, ecx, edx;
|
||||||
union _cpuid4_leaf_eax cache_eax;
|
union _cpuid4_leaf_eax cache_eax;
|
||||||
int i;
|
int i = -1;
|
||||||
int retval;
|
|
||||||
|
|
||||||
retval = MAX_CACHE_LEAVES;
|
do {
|
||||||
/* Do cpuid(4) loop to find out num_cache_leaves */
|
++i;
|
||||||
for (i = 0; i < MAX_CACHE_LEAVES; i++) {
|
/* Do cpuid(4) loop to find out num_cache_leaves */
|
||||||
cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
|
cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
|
||||||
cache_eax.full = eax;
|
cache_eax.full = eax;
|
||||||
if (cache_eax.split.type == CACHE_TYPE_NULL) {
|
} while (cache_eax.split.type != CACHE_TYPE_NULL);
|
||||||
retval = i;
|
return i;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
|
unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
|
||||||
{
|
{
|
||||||
unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
|
unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
|
||||||
unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
|
unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
|
||||||
|
@ -284,13 +280,7 @@ unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
|
||||||
if ( l3 )
|
if ( l3 )
|
||||||
printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
|
printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
|
||||||
|
|
||||||
/*
|
c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
|
||||||
* This assumes the L3 cache is shared; it typically lives in
|
|
||||||
* the northbridge. The L1 caches are included by the L2
|
|
||||||
* cache, and so should not be included for the purpose of
|
|
||||||
* SMP switching weights.
|
|
||||||
*/
|
|
||||||
c->x86_cache_size = l2 ? l2 : (l1i+l1d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return l2;
|
return l2;
|
||||||
|
@ -301,7 +291,7 @@ static struct _cpuid4_info *cpuid4_info[NR_CPUS];
|
||||||
#define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y]))
|
#define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y]))
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
|
static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
|
||||||
{
|
{
|
||||||
struct _cpuid4_info *this_leaf;
|
struct _cpuid4_info *this_leaf;
|
||||||
unsigned long num_threads_sharing;
|
unsigned long num_threads_sharing;
|
||||||
|
@ -334,7 +324,7 @@ static void free_cache_attributes(unsigned int cpu)
|
||||||
cpuid4_info[cpu] = NULL;
|
cpuid4_info[cpu] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit detect_cache_attributes(unsigned int cpu)
|
static int __cpuinit detect_cache_attributes(unsigned int cpu)
|
||||||
{
|
{
|
||||||
struct _cpuid4_info *this_leaf;
|
struct _cpuid4_info *this_leaf;
|
||||||
unsigned long j;
|
unsigned long j;
|
||||||
|
@ -511,7 +501,7 @@ static void cpuid4_cache_sysfs_exit(unsigned int cpu)
|
||||||
free_cache_attributes(cpu);
|
free_cache_attributes(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit cpuid4_cache_sysfs_init(unsigned int cpu)
|
static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (num_cache_leaves == 0)
|
if (num_cache_leaves == 0)
|
||||||
|
@ -542,7 +532,7 @@ err_out:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add/Remove cache interface for CPU device */
|
/* Add/Remove cache interface for CPU device */
|
||||||
static int __devinit cache_add_dev(struct sys_device * sys_dev)
|
static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
|
||||||
{
|
{
|
||||||
unsigned int cpu = sys_dev->id;
|
unsigned int cpu = sys_dev->id;
|
||||||
unsigned long i, j;
|
unsigned long i, j;
|
||||||
|
@ -579,7 +569,7 @@ static int __devinit cache_add_dev(struct sys_device * sys_dev)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devexit cache_remove_dev(struct sys_device * sys_dev)
|
static void __cpuexit cache_remove_dev(struct sys_device * sys_dev)
|
||||||
{
|
{
|
||||||
unsigned int cpu = sys_dev->id;
|
unsigned int cpu = sys_dev->id;
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
|
@ -588,24 +578,49 @@ static int __devexit cache_remove_dev(struct sys_device * sys_dev)
|
||||||
kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
|
kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
|
||||||
kobject_unregister(cache_kobject[cpu]);
|
kobject_unregister(cache_kobject[cpu]);
|
||||||
cpuid4_cache_sysfs_exit(cpu);
|
cpuid4_cache_sysfs_exit(cpu);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sysdev_driver cache_sysdev_driver = {
|
static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
|
||||||
.add = cache_add_dev,
|
unsigned long action, void *hcpu)
|
||||||
.remove = __devexit_p(cache_remove_dev),
|
{
|
||||||
|
unsigned int cpu = (unsigned long)hcpu;
|
||||||
|
struct sys_device *sys_dev;
|
||||||
|
|
||||||
|
sys_dev = get_cpu_sysdev(cpu);
|
||||||
|
switch (action) {
|
||||||
|
case CPU_ONLINE:
|
||||||
|
cache_add_dev(sys_dev);
|
||||||
|
break;
|
||||||
|
case CPU_DEAD:
|
||||||
|
cache_remove_dev(sys_dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NOTIFY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block cacheinfo_cpu_notifier =
|
||||||
|
{
|
||||||
|
.notifier_call = cacheinfo_cpu_callback,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Register/Unregister the cpu_cache driver */
|
static int __cpuinit cache_sysfs_init(void)
|
||||||
static int __devinit cache_register_driver(void)
|
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (num_cache_leaves == 0)
|
if (num_cache_leaves == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return sysdev_driver_register(&cpu_sysdev_class,&cache_sysdev_driver);
|
register_cpu_notifier(&cacheinfo_cpu_notifier);
|
||||||
|
|
||||||
|
for_each_online_cpu(i) {
|
||||||
|
cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE,
|
||||||
|
(void *)(long)i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_initcall(cache_register_driver);
|
device_initcall(cache_sysfs_init);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -102,11 +102,16 @@ void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c)
|
||||||
wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
|
wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
|
||||||
nr_mce_banks = l & 0xff;
|
nr_mce_banks = l & 0xff;
|
||||||
|
|
||||||
/* Don't enable bank 0 on intel P6 cores, it goes bang quickly. */
|
/*
|
||||||
for (i=1; i<nr_mce_banks; i++) {
|
* Following the example in IA-32 SDM Vol 3:
|
||||||
|
* - MC0_CTL should not be written
|
||||||
|
* - Status registers on all banks should be cleared on reset
|
||||||
|
*/
|
||||||
|
for (i=1; i<nr_mce_banks; i++)
|
||||||
wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
|
wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
|
||||||
|
|
||||||
|
for (i=0; i<nr_mce_banks; i++)
|
||||||
wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
|
wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
|
||||||
}
|
|
||||||
|
|
||||||
set_in_cr4 (X86_CR4_MCE);
|
set_in_cr4 (X86_CR4_MCE);
|
||||||
printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
|
printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
|
||||||
|
|
|
@ -149,60 +149,89 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static long
|
||||||
mtrr_ioctl(struct inode *inode, struct file *file,
|
mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
|
||||||
unsigned int cmd, unsigned long __arg)
|
|
||||||
{
|
{
|
||||||
int err;
|
int err = 0;
|
||||||
mtrr_type type;
|
mtrr_type type;
|
||||||
struct mtrr_sentry sentry;
|
struct mtrr_sentry sentry;
|
||||||
struct mtrr_gentry gentry;
|
struct mtrr_gentry gentry;
|
||||||
void __user *arg = (void __user *) __arg;
|
void __user *arg = (void __user *) __arg;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case MTRRIOC_ADD_ENTRY:
|
||||||
|
case MTRRIOC_SET_ENTRY:
|
||||||
|
case MTRRIOC_DEL_ENTRY:
|
||||||
|
case MTRRIOC_KILL_ENTRY:
|
||||||
|
case MTRRIOC_ADD_PAGE_ENTRY:
|
||||||
|
case MTRRIOC_SET_PAGE_ENTRY:
|
||||||
|
case MTRRIOC_DEL_PAGE_ENTRY:
|
||||||
|
case MTRRIOC_KILL_PAGE_ENTRY:
|
||||||
|
if (copy_from_user(&sentry, arg, sizeof sentry))
|
||||||
|
return -EFAULT;
|
||||||
|
break;
|
||||||
|
case MTRRIOC_GET_ENTRY:
|
||||||
|
case MTRRIOC_GET_PAGE_ENTRY:
|
||||||
|
if (copy_from_user(&gentry, arg, sizeof gentry))
|
||||||
|
return -EFAULT;
|
||||||
|
break;
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
case MTRRIOC32_ADD_ENTRY:
|
||||||
|
case MTRRIOC32_SET_ENTRY:
|
||||||
|
case MTRRIOC32_DEL_ENTRY:
|
||||||
|
case MTRRIOC32_KILL_ENTRY:
|
||||||
|
case MTRRIOC32_ADD_PAGE_ENTRY:
|
||||||
|
case MTRRIOC32_SET_PAGE_ENTRY:
|
||||||
|
case MTRRIOC32_DEL_PAGE_ENTRY:
|
||||||
|
case MTRRIOC32_KILL_PAGE_ENTRY: {
|
||||||
|
struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)__arg;
|
||||||
|
err = get_user(sentry.base, &s32->base);
|
||||||
|
err |= get_user(sentry.size, &s32->size);
|
||||||
|
err |= get_user(sentry.type, &s32->type);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MTRRIOC32_GET_ENTRY:
|
||||||
|
case MTRRIOC32_GET_PAGE_ENTRY: {
|
||||||
|
struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
|
||||||
|
err = get_user(gentry.regnum, &g32->regnum);
|
||||||
|
err |= get_user(gentry.base, &g32->base);
|
||||||
|
err |= get_user(gentry.size, &g32->size);
|
||||||
|
err |= get_user(gentry.type, &g32->type);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
default:
|
default:
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
case MTRRIOC_ADD_ENTRY:
|
case MTRRIOC_ADD_ENTRY:
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&sentry, arg, sizeof sentry))
|
|
||||||
return -EFAULT;
|
|
||||||
err =
|
err =
|
||||||
mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
|
mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
|
||||||
file, 0);
|
file, 0);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
break;
|
break;
|
||||||
case MTRRIOC_SET_ENTRY:
|
case MTRRIOC_SET_ENTRY:
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&sentry, arg, sizeof sentry))
|
|
||||||
return -EFAULT;
|
|
||||||
err = mtrr_add(sentry.base, sentry.size, sentry.type, 0);
|
err = mtrr_add(sentry.base, sentry.size, sentry.type, 0);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
break;
|
break;
|
||||||
case MTRRIOC_DEL_ENTRY:
|
case MTRRIOC_DEL_ENTRY:
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&sentry, arg, sizeof sentry))
|
|
||||||
return -EFAULT;
|
|
||||||
err = mtrr_file_del(sentry.base, sentry.size, file, 0);
|
err = mtrr_file_del(sentry.base, sentry.size, file, 0);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
break;
|
break;
|
||||||
case MTRRIOC_KILL_ENTRY:
|
case MTRRIOC_KILL_ENTRY:
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&sentry, arg, sizeof sentry))
|
|
||||||
return -EFAULT;
|
|
||||||
err = mtrr_del(-1, sentry.base, sentry.size);
|
err = mtrr_del(-1, sentry.base, sentry.size);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
break;
|
break;
|
||||||
case MTRRIOC_GET_ENTRY:
|
case MTRRIOC_GET_ENTRY:
|
||||||
if (copy_from_user(&gentry, arg, sizeof gentry))
|
|
||||||
return -EFAULT;
|
|
||||||
if (gentry.regnum >= num_var_ranges)
|
if (gentry.regnum >= num_var_ranges)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
|
mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
|
||||||
|
@ -217,60 +246,59 @@ mtrr_ioctl(struct inode *inode, struct file *file,
|
||||||
gentry.type = type;
|
gentry.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copy_to_user(arg, &gentry, sizeof gentry))
|
|
||||||
return -EFAULT;
|
|
||||||
break;
|
break;
|
||||||
case MTRRIOC_ADD_PAGE_ENTRY:
|
case MTRRIOC_ADD_PAGE_ENTRY:
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&sentry, arg, sizeof sentry))
|
|
||||||
return -EFAULT;
|
|
||||||
err =
|
err =
|
||||||
mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
|
mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
|
||||||
file, 1);
|
file, 1);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
break;
|
break;
|
||||||
case MTRRIOC_SET_PAGE_ENTRY:
|
case MTRRIOC_SET_PAGE_ENTRY:
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&sentry, arg, sizeof sentry))
|
|
||||||
return -EFAULT;
|
|
||||||
err = mtrr_add_page(sentry.base, sentry.size, sentry.type, 0);
|
err = mtrr_add_page(sentry.base, sentry.size, sentry.type, 0);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
break;
|
break;
|
||||||
case MTRRIOC_DEL_PAGE_ENTRY:
|
case MTRRIOC_DEL_PAGE_ENTRY:
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&sentry, arg, sizeof sentry))
|
|
||||||
return -EFAULT;
|
|
||||||
err = mtrr_file_del(sentry.base, sentry.size, file, 1);
|
err = mtrr_file_del(sentry.base, sentry.size, file, 1);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
break;
|
break;
|
||||||
case MTRRIOC_KILL_PAGE_ENTRY:
|
case MTRRIOC_KILL_PAGE_ENTRY:
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&sentry, arg, sizeof sentry))
|
|
||||||
return -EFAULT;
|
|
||||||
err = mtrr_del_page(-1, sentry.base, sentry.size);
|
err = mtrr_del_page(-1, sentry.base, sentry.size);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
break;
|
break;
|
||||||
case MTRRIOC_GET_PAGE_ENTRY:
|
case MTRRIOC_GET_PAGE_ENTRY:
|
||||||
if (copy_from_user(&gentry, arg, sizeof gentry))
|
|
||||||
return -EFAULT;
|
|
||||||
if (gentry.regnum >= num_var_ranges)
|
if (gentry.regnum >= num_var_ranges)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
|
mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
|
||||||
gentry.type = type;
|
gentry.type = type;
|
||||||
|
|
||||||
if (copy_to_user(arg, &gentry, sizeof gentry))
|
|
||||||
return -EFAULT;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
switch(cmd) {
|
||||||
|
case MTRRIOC_GET_ENTRY:
|
||||||
|
case MTRRIOC_GET_PAGE_ENTRY:
|
||||||
|
if (copy_to_user(arg, &gentry, sizeof gentry))
|
||||||
|
err = -EFAULT;
|
||||||
|
break;
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
case MTRRIOC32_GET_ENTRY:
|
||||||
|
case MTRRIOC32_GET_PAGE_ENTRY: {
|
||||||
|
struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
|
||||||
|
err = put_user(gentry.base, &g32->base);
|
||||||
|
err |= put_user(gentry.size, &g32->size);
|
||||||
|
err |= put_user(gentry.regnum, &g32->regnum);
|
||||||
|
err |= put_user(gentry.type, &g32->type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -310,7 +338,8 @@ static struct file_operations mtrr_fops = {
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
.llseek = seq_lseek,
|
.llseek = seq_lseek,
|
||||||
.write = mtrr_write,
|
.write = mtrr_write,
|
||||||
.ioctl = mtrr_ioctl,
|
.unlocked_ioctl = mtrr_ioctl,
|
||||||
|
.compat_ioctl = mtrr_ioctl,
|
||||||
.release = mtrr_close,
|
.release = mtrr_close,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
|
||||||
/* Intel-defined (#2) */
|
/* Intel-defined (#2) */
|
||||||
"pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "est",
|
"pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est",
|
||||||
"tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
|
"tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <asm/hardirq.h>
|
#include <asm/hardirq.h>
|
||||||
#include <asm/nmi.h>
|
#include <asm/nmi.h>
|
||||||
#include <asm/hw_irq.h>
|
#include <asm/hw_irq.h>
|
||||||
#include <asm/apic.h>
|
|
||||||
#include <mach_ipi.h>
|
#include <mach_ipi.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,7 +147,6 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu)
|
||||||
regs = &fixed_regs;
|
regs = &fixed_regs;
|
||||||
}
|
}
|
||||||
crash_save_this_cpu(regs, cpu);
|
crash_save_this_cpu(regs, cpu);
|
||||||
disable_local_APIC();
|
|
||||||
atomic_dec(&waiting_for_crash_ipi);
|
atomic_dec(&waiting_for_crash_ipi);
|
||||||
/* Assume hlt works */
|
/* Assume hlt works */
|
||||||
halt();
|
halt();
|
||||||
|
@ -188,7 +186,6 @@ static void nmi_shootdown_cpus(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Leave the nmi callback set */
|
/* Leave the nmi callback set */
|
||||||
disable_local_APIC();
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void nmi_shootdown_cpus(void)
|
static void nmi_shootdown_cpus(void)
|
||||||
|
@ -213,9 +210,5 @@ void machine_crash_shutdown(struct pt_regs *regs)
|
||||||
/* Make a note of crashing cpu. Will be used in NMI callback.*/
|
/* Make a note of crashing cpu. Will be used in NMI callback.*/
|
||||||
crashing_cpu = smp_processor_id();
|
crashing_cpu = smp_processor_id();
|
||||||
nmi_shootdown_cpus();
|
nmi_shootdown_cpus();
|
||||||
lapic_shutdown();
|
|
||||||
#if defined(CONFIG_X86_IO_APIC)
|
|
||||||
disable_IO_APIC();
|
|
||||||
#endif
|
|
||||||
crash_save_self(regs);
|
crash_save_self(regs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -435,4 +435,8 @@ void __init init_IRQ(void)
|
||||||
setup_irq(FPU_IRQ, &fpu_irq);
|
setup_irq(FPU_IRQ, &fpu_irq);
|
||||||
|
|
||||||
irq_ctx_init(smp_processor_id());
|
irq_ctx_init(smp_processor_id());
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
|
APIC_init();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,9 @@
|
||||||
int (*ioapic_renumber_irq)(int ioapic, int irq);
|
int (*ioapic_renumber_irq)(int ioapic, int irq);
|
||||||
atomic_t irq_mis_count;
|
atomic_t irq_mis_count;
|
||||||
|
|
||||||
|
/* Where if anywhere is the i8259 connect in external int mode */
|
||||||
|
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(ioapic_lock);
|
static DEFINE_SPINLOCK(ioapic_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -738,7 +741,7 @@ static int find_irq_entry(int apic, int pin, int type)
|
||||||
/*
|
/*
|
||||||
* Find the pin to which IRQ[irq] (ISA) is connected
|
* Find the pin to which IRQ[irq] (ISA) is connected
|
||||||
*/
|
*/
|
||||||
static int find_isa_irq_pin(int irq, int type)
|
static int __init find_isa_irq_pin(int irq, int type)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -758,6 +761,33 @@ static int find_isa_irq_pin(int irq, int type)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __init find_isa_irq_apic(int irq, int type)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < mp_irq_entries; i++) {
|
||||||
|
int lbus = mp_irqs[i].mpc_srcbus;
|
||||||
|
|
||||||
|
if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
|
||||||
|
mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
|
||||||
|
mp_bus_id_to_type[lbus] == MP_BUS_MCA ||
|
||||||
|
mp_bus_id_to_type[lbus] == MP_BUS_NEC98
|
||||||
|
) &&
|
||||||
|
(mp_irqs[i].mpc_irqtype == type) &&
|
||||||
|
(mp_irqs[i].mpc_srcbusirq == irq))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < mp_irq_entries) {
|
||||||
|
int apic;
|
||||||
|
for(apic = 0; apic < nr_ioapics; apic++) {
|
||||||
|
if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
|
||||||
|
return apic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find a specific PCI IRQ entry.
|
* Find a specific PCI IRQ entry.
|
||||||
* Not an __init, possibly needed by modules
|
* Not an __init, possibly needed by modules
|
||||||
|
@ -1253,7 +1283,7 @@ static void __init setup_IO_APIC_irqs(void)
|
||||||
/*
|
/*
|
||||||
* Set up the 8259A-master output pin:
|
* Set up the 8259A-master output pin:
|
||||||
*/
|
*/
|
||||||
static void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
|
static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector)
|
||||||
{
|
{
|
||||||
struct IO_APIC_route_entry entry;
|
struct IO_APIC_route_entry entry;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -1287,8 +1317,8 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
|
||||||
* Add it to the IO-APIC irq-routing table:
|
* Add it to the IO-APIC irq-routing table:
|
||||||
*/
|
*/
|
||||||
spin_lock_irqsave(&ioapic_lock, flags);
|
spin_lock_irqsave(&ioapic_lock, flags);
|
||||||
io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
|
io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
|
||||||
io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
|
io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
|
||||||
spin_unlock_irqrestore(&ioapic_lock, flags);
|
spin_unlock_irqrestore(&ioapic_lock, flags);
|
||||||
|
|
||||||
enable_8259A_irq(0);
|
enable_8259A_irq(0);
|
||||||
|
@ -1595,7 +1625,8 @@ void /*__init*/ print_PIC(void)
|
||||||
static void __init enable_IO_APIC(void)
|
static void __init enable_IO_APIC(void)
|
||||||
{
|
{
|
||||||
union IO_APIC_reg_01 reg_01;
|
union IO_APIC_reg_01 reg_01;
|
||||||
int i;
|
int i8259_apic, i8259_pin;
|
||||||
|
int i, apic;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
for (i = 0; i < PIN_MAP_SIZE; i++) {
|
for (i = 0; i < PIN_MAP_SIZE; i++) {
|
||||||
|
@ -1609,11 +1640,52 @@ static void __init enable_IO_APIC(void)
|
||||||
/*
|
/*
|
||||||
* The number of IO-APIC IRQ registers (== #pins):
|
* The number of IO-APIC IRQ registers (== #pins):
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < nr_ioapics; i++) {
|
for (apic = 0; apic < nr_ioapics; apic++) {
|
||||||
spin_lock_irqsave(&ioapic_lock, flags);
|
spin_lock_irqsave(&ioapic_lock, flags);
|
||||||
reg_01.raw = io_apic_read(i, 1);
|
reg_01.raw = io_apic_read(apic, 1);
|
||||||
spin_unlock_irqrestore(&ioapic_lock, flags);
|
spin_unlock_irqrestore(&ioapic_lock, flags);
|
||||||
nr_ioapic_registers[i] = reg_01.bits.entries+1;
|
nr_ioapic_registers[apic] = reg_01.bits.entries+1;
|
||||||
|
}
|
||||||
|
for(apic = 0; apic < nr_ioapics; apic++) {
|
||||||
|
int pin;
|
||||||
|
/* See if any of the pins is in ExtINT mode */
|
||||||
|
for(pin = 0; pin < nr_ioapic_registers[i]; pin++) {
|
||||||
|
struct IO_APIC_route_entry entry;
|
||||||
|
spin_lock_irqsave(&ioapic_lock, flags);
|
||||||
|
*(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
|
||||||
|
*(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
|
||||||
|
spin_unlock_irqrestore(&ioapic_lock, flags);
|
||||||
|
|
||||||
|
|
||||||
|
/* If the interrupt line is enabled and in ExtInt mode
|
||||||
|
* I have found the pin where the i8259 is connected.
|
||||||
|
*/
|
||||||
|
if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
|
||||||
|
ioapic_i8259.apic = apic;
|
||||||
|
ioapic_i8259.pin = pin;
|
||||||
|
goto found_i8259;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found_i8259:
|
||||||
|
/* Look to see what if the MP table has reported the ExtINT */
|
||||||
|
/* If we could not find the appropriate pin by looking at the ioapic
|
||||||
|
* the i8259 probably is not connected the ioapic but give the
|
||||||
|
* mptable a chance anyway.
|
||||||
|
*/
|
||||||
|
i8259_pin = find_isa_irq_pin(0, mp_ExtINT);
|
||||||
|
i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
|
||||||
|
/* Trust the MP table if nothing is setup in the hardware */
|
||||||
|
if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
|
||||||
|
printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
|
||||||
|
ioapic_i8259.pin = i8259_pin;
|
||||||
|
ioapic_i8259.apic = i8259_apic;
|
||||||
|
}
|
||||||
|
/* Complain if the MP table and the hardware disagree */
|
||||||
|
if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
|
||||||
|
(i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
|
||||||
|
{
|
||||||
|
printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1627,7 +1699,6 @@ static void __init enable_IO_APIC(void)
|
||||||
*/
|
*/
|
||||||
void disable_IO_APIC(void)
|
void disable_IO_APIC(void)
|
||||||
{
|
{
|
||||||
int pin;
|
|
||||||
/*
|
/*
|
||||||
* Clear the IO-APIC before rebooting:
|
* Clear the IO-APIC before rebooting:
|
||||||
*/
|
*/
|
||||||
|
@ -1638,8 +1709,7 @@ void disable_IO_APIC(void)
|
||||||
* Put that IOAPIC in virtual wire mode
|
* Put that IOAPIC in virtual wire mode
|
||||||
* so legacy interrupts can be delivered.
|
* so legacy interrupts can be delivered.
|
||||||
*/
|
*/
|
||||||
pin = find_isa_irq_pin(0, mp_ExtINT);
|
if (ioapic_i8259.pin != -1) {
|
||||||
if (pin != -1) {
|
|
||||||
struct IO_APIC_route_entry entry;
|
struct IO_APIC_route_entry entry;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
@ -1650,7 +1720,7 @@ void disable_IO_APIC(void)
|
||||||
entry.polarity = 0; /* High */
|
entry.polarity = 0; /* High */
|
||||||
entry.delivery_status = 0;
|
entry.delivery_status = 0;
|
||||||
entry.dest_mode = 0; /* Physical */
|
entry.dest_mode = 0; /* Physical */
|
||||||
entry.delivery_mode = 7; /* ExtInt */
|
entry.delivery_mode = dest_ExtINT; /* ExtInt */
|
||||||
entry.vector = 0;
|
entry.vector = 0;
|
||||||
entry.dest.physical.physical_dest = 0;
|
entry.dest.physical.physical_dest = 0;
|
||||||
|
|
||||||
|
@ -1659,11 +1729,13 @@ void disable_IO_APIC(void)
|
||||||
* Add it to the IO-APIC irq-routing table:
|
* Add it to the IO-APIC irq-routing table:
|
||||||
*/
|
*/
|
||||||
spin_lock_irqsave(&ioapic_lock, flags);
|
spin_lock_irqsave(&ioapic_lock, flags);
|
||||||
io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
|
io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin,
|
||||||
io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
|
*(((int *)&entry)+1));
|
||||||
|
io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin,
|
||||||
|
*(((int *)&entry)+0));
|
||||||
spin_unlock_irqrestore(&ioapic_lock, flags);
|
spin_unlock_irqrestore(&ioapic_lock, flags);
|
||||||
}
|
}
|
||||||
disconnect_bsp_APIC(pin != -1);
|
disconnect_bsp_APIC(ioapic_i8259.pin != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2113,20 +2185,21 @@ static void setup_nmi (void)
|
||||||
*/
|
*/
|
||||||
static inline void unlock_ExtINT_logic(void)
|
static inline void unlock_ExtINT_logic(void)
|
||||||
{
|
{
|
||||||
int pin, i;
|
int apic, pin, i;
|
||||||
struct IO_APIC_route_entry entry0, entry1;
|
struct IO_APIC_route_entry entry0, entry1;
|
||||||
unsigned char save_control, save_freq_select;
|
unsigned char save_control, save_freq_select;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
pin = find_isa_irq_pin(8, mp_INT);
|
pin = find_isa_irq_pin(8, mp_INT);
|
||||||
|
apic = find_isa_irq_apic(8, mp_INT);
|
||||||
if (pin == -1)
|
if (pin == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spin_lock_irqsave(&ioapic_lock, flags);
|
spin_lock_irqsave(&ioapic_lock, flags);
|
||||||
*(((int *)&entry0) + 1) = io_apic_read(0, 0x11 + 2 * pin);
|
*(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
|
||||||
*(((int *)&entry0) + 0) = io_apic_read(0, 0x10 + 2 * pin);
|
*(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
|
||||||
spin_unlock_irqrestore(&ioapic_lock, flags);
|
spin_unlock_irqrestore(&ioapic_lock, flags);
|
||||||
clear_IO_APIC_pin(0, pin);
|
clear_IO_APIC_pin(apic, pin);
|
||||||
|
|
||||||
memset(&entry1, 0, sizeof(entry1));
|
memset(&entry1, 0, sizeof(entry1));
|
||||||
|
|
||||||
|
@ -2139,8 +2212,8 @@ static inline void unlock_ExtINT_logic(void)
|
||||||
entry1.vector = 0;
|
entry1.vector = 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&ioapic_lock, flags);
|
spin_lock_irqsave(&ioapic_lock, flags);
|
||||||
io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
|
io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
|
||||||
io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
|
io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
|
||||||
spin_unlock_irqrestore(&ioapic_lock, flags);
|
spin_unlock_irqrestore(&ioapic_lock, flags);
|
||||||
|
|
||||||
save_control = CMOS_READ(RTC_CONTROL);
|
save_control = CMOS_READ(RTC_CONTROL);
|
||||||
|
@ -2158,11 +2231,11 @@ static inline void unlock_ExtINT_logic(void)
|
||||||
|
|
||||||
CMOS_WRITE(save_control, RTC_CONTROL);
|
CMOS_WRITE(save_control, RTC_CONTROL);
|
||||||
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
|
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
|
||||||
clear_IO_APIC_pin(0, pin);
|
clear_IO_APIC_pin(apic, pin);
|
||||||
|
|
||||||
spin_lock_irqsave(&ioapic_lock, flags);
|
spin_lock_irqsave(&ioapic_lock, flags);
|
||||||
io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
|
io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
|
||||||
io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
|
io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
|
||||||
spin_unlock_irqrestore(&ioapic_lock, flags);
|
spin_unlock_irqrestore(&ioapic_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2174,7 +2247,7 @@ static inline void unlock_ExtINT_logic(void)
|
||||||
*/
|
*/
|
||||||
static inline void check_timer(void)
|
static inline void check_timer(void)
|
||||||
{
|
{
|
||||||
int pin1, pin2;
|
int apic1, pin1, apic2, pin2;
|
||||||
int vector;
|
int vector;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2196,10 +2269,13 @@ static inline void check_timer(void)
|
||||||
timer_ack = 1;
|
timer_ack = 1;
|
||||||
enable_8259A_irq(0);
|
enable_8259A_irq(0);
|
||||||
|
|
||||||
pin1 = find_isa_irq_pin(0, mp_INT);
|
pin1 = find_isa_irq_pin(0, mp_INT);
|
||||||
pin2 = find_isa_irq_pin(0, mp_ExtINT);
|
apic1 = find_isa_irq_apic(0, mp_INT);
|
||||||
|
pin2 = ioapic_i8259.pin;
|
||||||
|
apic2 = ioapic_i8259.apic;
|
||||||
|
|
||||||
printk(KERN_INFO "..TIMER: vector=0x%02X pin1=%d pin2=%d\n", vector, pin1, pin2);
|
printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
|
||||||
|
vector, apic1, pin1, apic2, pin2);
|
||||||
|
|
||||||
if (pin1 != -1) {
|
if (pin1 != -1) {
|
||||||
/*
|
/*
|
||||||
|
@ -2216,8 +2292,9 @@ static inline void check_timer(void)
|
||||||
clear_IO_APIC_pin(0, pin1);
|
clear_IO_APIC_pin(0, pin1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clear_IO_APIC_pin(0, pin1);
|
clear_IO_APIC_pin(apic1, pin1);
|
||||||
printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
|
printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to "
|
||||||
|
"IO-APIC\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
|
printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
|
||||||
|
@ -2226,13 +2303,13 @@ static inline void check_timer(void)
|
||||||
/*
|
/*
|
||||||
* legacy devices should be connected to IO APIC #0
|
* legacy devices should be connected to IO APIC #0
|
||||||
*/
|
*/
|
||||||
setup_ExtINT_IRQ0_pin(pin2, vector);
|
setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
|
||||||
if (timer_irq_works()) {
|
if (timer_irq_works()) {
|
||||||
printk("works.\n");
|
printk("works.\n");
|
||||||
if (pin1 != -1)
|
if (pin1 != -1)
|
||||||
replace_pin_at_irq(0, 0, pin1, 0, pin2);
|
replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
|
||||||
else
|
else
|
||||||
add_pin_to_irq(0, 0, pin2);
|
add_pin_to_irq(0, apic2, pin2);
|
||||||
if (nmi_watchdog == NMI_IO_APIC) {
|
if (nmi_watchdog == NMI_IO_APIC) {
|
||||||
setup_nmi();
|
setup_nmi();
|
||||||
}
|
}
|
||||||
|
@ -2241,7 +2318,7 @@ static inline void check_timer(void)
|
||||||
/*
|
/*
|
||||||
* Cleanup, just in case ...
|
* Cleanup, just in case ...
|
||||||
*/
|
*/
|
||||||
clear_IO_APIC_pin(0, pin2);
|
clear_IO_APIC_pin(apic2, pin2);
|
||||||
}
|
}
|
||||||
printk(" failed.\n");
|
printk(" failed.\n");
|
||||||
|
|
||||||
|
@ -2310,11 +2387,15 @@ void __init setup_IO_APIC(void)
|
||||||
sync_Arb_IDs();
|
sync_Arb_IDs();
|
||||||
setup_IO_APIC_irqs();
|
setup_IO_APIC_irqs();
|
||||||
init_IO_APIC_traps();
|
init_IO_APIC_traps();
|
||||||
check_timer();
|
|
||||||
if (!acpi_ioapic)
|
if (!acpi_ioapic)
|
||||||
print_IO_APIC();
|
print_IO_APIC();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __init IO_APIC_late_time_init(void)
|
||||||
|
{
|
||||||
|
check_timer();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called after all the initialization is done. If we didnt find any
|
* Called after all the initialization is done. If we didnt find any
|
||||||
* APIC bugs then we can allow the modify fast path
|
* APIC bugs then we can allow the modify fast path
|
||||||
|
|
|
@ -218,7 +218,7 @@ int show_interrupts(struct seq_file *p, void *v)
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
seq_printf(p, " ");
|
seq_printf(p, " ");
|
||||||
for_each_cpu(j)
|
for_each_online_cpu(j)
|
||||||
seq_printf(p, "CPU%d ",j);
|
seq_printf(p, "CPU%d ",j);
|
||||||
seq_putc(p, '\n');
|
seq_putc(p, '\n');
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ int show_interrupts(struct seq_file *p, void *v)
|
||||||
#ifndef CONFIG_SMP
|
#ifndef CONFIG_SMP
|
||||||
seq_printf(p, "%10u ", kstat_irqs(i));
|
seq_printf(p, "%10u ", kstat_irqs(i));
|
||||||
#else
|
#else
|
||||||
for_each_cpu(j)
|
for_each_online_cpu(j)
|
||||||
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
|
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
|
||||||
#endif
|
#endif
|
||||||
seq_printf(p, " %14s", irq_desc[i].handler->typename);
|
seq_printf(p, " %14s", irq_desc[i].handler->typename);
|
||||||
|
@ -246,12 +246,12 @@ skip:
|
||||||
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
|
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
|
||||||
} else if (i == NR_IRQS) {
|
} else if (i == NR_IRQS) {
|
||||||
seq_printf(p, "NMI: ");
|
seq_printf(p, "NMI: ");
|
||||||
for_each_cpu(j)
|
for_each_online_cpu(j)
|
||||||
seq_printf(p, "%10u ", nmi_count(j));
|
seq_printf(p, "%10u ", nmi_count(j));
|
||||||
seq_putc(p, '\n');
|
seq_putc(p, '\n');
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
seq_printf(p, "LOC: ");
|
seq_printf(p, "LOC: ");
|
||||||
for_each_cpu(j)
|
for_each_online_cpu(j)
|
||||||
seq_printf(p, "%10u ",
|
seq_printf(p, "%10u ",
|
||||||
per_cpu(irq_stat,j).apic_timer_irqs);
|
per_cpu(irq_stat,j).apic_timer_irqs);
|
||||||
seq_putc(p, '\n');
|
seq_putc(p, '\n');
|
||||||
|
|
|
@ -69,7 +69,7 @@ unsigned int def_to_bigsmp = 0;
|
||||||
/* Processor that is doing the boot up */
|
/* Processor that is doing the boot up */
|
||||||
unsigned int boot_cpu_physical_apicid = -1U;
|
unsigned int boot_cpu_physical_apicid = -1U;
|
||||||
/* Internal processor count */
|
/* Internal processor count */
|
||||||
static unsigned int __initdata num_processors;
|
static unsigned int __devinitdata num_processors;
|
||||||
|
|
||||||
/* Bitmask of physically existing CPUs */
|
/* Bitmask of physically existing CPUs */
|
||||||
physid_mask_t phys_cpu_present_map;
|
physid_mask_t phys_cpu_present_map;
|
||||||
|
@ -119,7 +119,7 @@ static int MP_valid_apicid(int apicid, int version)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void __init MP_processor_info (struct mpc_config_processor *m)
|
static void __devinit MP_processor_info (struct mpc_config_processor *m)
|
||||||
{
|
{
|
||||||
int ver, apicid;
|
int ver, apicid;
|
||||||
physid_mask_t phys_cpu;
|
physid_mask_t phys_cpu;
|
||||||
|
@ -182,17 +182,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
|
||||||
boot_cpu_physical_apicid = m->mpc_apicid;
|
boot_cpu_physical_apicid = m->mpc_apicid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_processors >= NR_CPUS) {
|
|
||||||
printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
|
|
||||||
" Processor ignored.\n", NR_CPUS);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_processors >= maxcpus) {
|
|
||||||
printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
|
|
||||||
" Processor ignored.\n", maxcpus);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ver = m->mpc_apicver;
|
ver = m->mpc_apicver;
|
||||||
|
|
||||||
if (!MP_valid_apicid(apicid, ver)) {
|
if (!MP_valid_apicid(apicid, ver)) {
|
||||||
|
@ -201,11 +190,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_set(num_processors, cpu_possible_map);
|
|
||||||
num_processors++;
|
|
||||||
phys_cpu = apicid_to_cpu_present(apicid);
|
|
||||||
physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate version
|
* Validate version
|
||||||
*/
|
*/
|
||||||
|
@ -216,6 +200,25 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
|
||||||
ver = 0x10;
|
ver = 0x10;
|
||||||
}
|
}
|
||||||
apic_version[m->mpc_apicid] = ver;
|
apic_version[m->mpc_apicid] = ver;
|
||||||
|
|
||||||
|
phys_cpu = apicid_to_cpu_present(apicid);
|
||||||
|
physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
|
||||||
|
|
||||||
|
if (num_processors >= NR_CPUS) {
|
||||||
|
printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
|
||||||
|
" Processor ignored.\n", NR_CPUS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_processors >= maxcpus) {
|
||||||
|
printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
|
||||||
|
" Processor ignored.\n", maxcpus);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu_set(num_processors, cpu_possible_map);
|
||||||
|
num_processors++;
|
||||||
|
|
||||||
if ((num_processors > 8) &&
|
if ((num_processors > 8) &&
|
||||||
APIC_XAPIC(ver) &&
|
APIC_XAPIC(ver) &&
|
||||||
(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
|
(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
|
||||||
|
@ -834,7 +837,7 @@ void __init mp_register_lapic_address (
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void __init mp_register_lapic (
|
void __devinit mp_register_lapic (
|
||||||
u8 id,
|
u8 id,
|
||||||
u8 enabled)
|
u8 enabled)
|
||||||
{
|
{
|
||||||
|
|
|
@ -100,16 +100,44 @@ int nmi_active;
|
||||||
(P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \
|
(P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \
|
||||||
P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
|
P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
/* The performance counters used by NMI_LOCAL_APIC don't trigger when
|
||||||
|
* the CPU is idle. To make sure the NMI watchdog really ticks on all
|
||||||
|
* CPUs during the test make them busy.
|
||||||
|
*/
|
||||||
|
static __init void nmi_cpu_busy(void *data)
|
||||||
|
{
|
||||||
|
volatile int *endflag = data;
|
||||||
|
local_irq_enable();
|
||||||
|
/* Intentionally don't use cpu_relax here. This is
|
||||||
|
to make sure that the performance counter really ticks,
|
||||||
|
even if there is a simulator or similar that catches the
|
||||||
|
pause instruction. On a real HT machine this is fine because
|
||||||
|
all other CPUs are busy with "useless" delay loops and don't
|
||||||
|
care if they get somewhat less cycles. */
|
||||||
|
while (*endflag == 0)
|
||||||
|
barrier();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int __init check_nmi_watchdog(void)
|
static int __init check_nmi_watchdog(void)
|
||||||
{
|
{
|
||||||
unsigned int prev_nmi_count[NR_CPUS];
|
volatile int endflag = 0;
|
||||||
|
unsigned int *prev_nmi_count;
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
if (nmi_watchdog == NMI_NONE)
|
if (nmi_watchdog == NMI_NONE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
|
||||||
|
if (!prev_nmi_count)
|
||||||
|
return -1;
|
||||||
|
|
||||||
printk(KERN_INFO "Testing NMI watchdog ... ");
|
printk(KERN_INFO "Testing NMI watchdog ... ");
|
||||||
|
|
||||||
|
if (nmi_watchdog == NMI_LOCAL_APIC)
|
||||||
|
smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
|
||||||
|
|
||||||
for (cpu = 0; cpu < NR_CPUS; cpu++)
|
for (cpu = 0; cpu < NR_CPUS; cpu++)
|
||||||
prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
|
prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
@ -123,12 +151,18 @@ static int __init check_nmi_watchdog(void)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) {
|
if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) {
|
||||||
printk("CPU#%d: NMI appears to be stuck!\n", cpu);
|
endflag = 1;
|
||||||
|
printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
|
||||||
|
cpu,
|
||||||
|
prev_nmi_count[cpu],
|
||||||
|
nmi_count(cpu));
|
||||||
nmi_active = 0;
|
nmi_active = 0;
|
||||||
lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG;
|
lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG;
|
||||||
|
kfree(prev_nmi_count);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
endflag = 1;
|
||||||
printk("OK.\n");
|
printk("OK.\n");
|
||||||
|
|
||||||
/* now that we know it works we can reduce NMI frequency to
|
/* now that we know it works we can reduce NMI frequency to
|
||||||
|
@ -136,6 +170,7 @@ static int __init check_nmi_watchdog(void)
|
||||||
if (nmi_watchdog == NMI_LOCAL_APIC)
|
if (nmi_watchdog == NMI_LOCAL_APIC)
|
||||||
nmi_hz = 1;
|
nmi_hz = 1;
|
||||||
|
|
||||||
|
kfree(prev_nmi_count);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* This needs to happen later in boot so counters are working */
|
/* This needs to happen later in boot so counters are working */
|
||||||
|
|
|
@ -354,7 +354,7 @@ ptrace_set_thread_area(struct task_struct *child,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
|
asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
|
||||||
{
|
{
|
||||||
struct task_struct *child;
|
struct task_struct *child;
|
||||||
struct user * dummy = NULL;
|
struct user * dummy = NULL;
|
||||||
|
|
|
@ -44,7 +44,7 @@ void mach_reboot_fixups(void)
|
||||||
|
|
||||||
for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
|
for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
|
||||||
cur = &(fixups_table[i]);
|
cur = &(fixups_table[i]);
|
||||||
dev = pci_get_device(cur->vendor, cur->device, 0);
|
dev = pci_get_device(cur->vendor, cur->device, NULL);
|
||||||
if (!dev)
|
if (!dev)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -389,14 +389,24 @@ static void __init limit_regions(unsigned long long size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < e820.nr_map; i++) {
|
for (i = 0; i < e820.nr_map; i++) {
|
||||||
if (e820.map[i].type == E820_RAM) {
|
current_addr = e820.map[i].addr + e820.map[i].size;
|
||||||
current_addr = e820.map[i].addr + e820.map[i].size;
|
if (current_addr < size)
|
||||||
if (current_addr >= size) {
|
continue;
|
||||||
e820.map[i].size -= current_addr-size;
|
|
||||||
e820.nr_map = i + 1;
|
if (e820.map[i].type != E820_RAM)
|
||||||
return;
|
continue;
|
||||||
}
|
|
||||||
|
if (e820.map[i].addr >= size) {
|
||||||
|
/*
|
||||||
|
* This region starts past the end of the
|
||||||
|
* requested size, skip it completely.
|
||||||
|
*/
|
||||||
|
e820.nr_map = i;
|
||||||
|
} else {
|
||||||
|
e820.nr_map = i + 1;
|
||||||
|
e820.map[i].size -= current_addr - size;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,11 @@ EXPORT_SYMBOL(cpu_online_map);
|
||||||
cpumask_t cpu_callin_map;
|
cpumask_t cpu_callin_map;
|
||||||
cpumask_t cpu_callout_map;
|
cpumask_t cpu_callout_map;
|
||||||
EXPORT_SYMBOL(cpu_callout_map);
|
EXPORT_SYMBOL(cpu_callout_map);
|
||||||
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
cpumask_t cpu_possible_map = CPU_MASK_ALL;
|
||||||
|
#else
|
||||||
cpumask_t cpu_possible_map;
|
cpumask_t cpu_possible_map;
|
||||||
|
#endif
|
||||||
EXPORT_SYMBOL(cpu_possible_map);
|
EXPORT_SYMBOL(cpu_possible_map);
|
||||||
static cpumask_t smp_commenced_mask;
|
static cpumask_t smp_commenced_mask;
|
||||||
|
|
||||||
|
@ -1074,6 +1078,16 @@ void *xquad_portio;
|
||||||
EXPORT_SYMBOL(xquad_portio);
|
EXPORT_SYMBOL(xquad_portio);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fall back to non SMP mode after errors.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static __init void disable_smp(void)
|
||||||
|
{
|
||||||
|
cpu_set(0, cpu_sibling_map[0]);
|
||||||
|
cpu_set(0, cpu_core_map[0]);
|
||||||
|
}
|
||||||
|
|
||||||
static void __init smp_boot_cpus(unsigned int max_cpus)
|
static void __init smp_boot_cpus(unsigned int max_cpus)
|
||||||
{
|
{
|
||||||
int apicid, cpu, bit, kicked;
|
int apicid, cpu, bit, kicked;
|
||||||
|
@ -1086,7 +1100,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
|
||||||
printk("CPU%d: ", 0);
|
printk("CPU%d: ", 0);
|
||||||
print_cpu_info(&cpu_data[0]);
|
print_cpu_info(&cpu_data[0]);
|
||||||
|
|
||||||
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
|
|
||||||
boot_cpu_logical_apicid = logical_smp_processor_id();
|
boot_cpu_logical_apicid = logical_smp_processor_id();
|
||||||
x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
|
x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
|
||||||
|
|
||||||
|
@ -1098,68 +1111,27 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
|
||||||
cpus_clear(cpu_core_map[0]);
|
cpus_clear(cpu_core_map[0]);
|
||||||
cpu_set(0, cpu_core_map[0]);
|
cpu_set(0, cpu_core_map[0]);
|
||||||
|
|
||||||
|
map_cpu_to_logical_apicid();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we couldn't find an SMP configuration at boot time,
|
* If we couldn't find an SMP configuration at boot time,
|
||||||
* get out of here now!
|
* get out of here now!
|
||||||
*/
|
*/
|
||||||
if (!smp_found_config && !acpi_lapic) {
|
if (!smp_found_config && !acpi_lapic) {
|
||||||
printk(KERN_NOTICE "SMP motherboard not detected.\n");
|
printk(KERN_NOTICE "SMP motherboard not detected.\n");
|
||||||
smpboot_clear_io_apic_irqs();
|
disable_smp();
|
||||||
phys_cpu_present_map = physid_mask_of_physid(0);
|
|
||||||
if (APIC_init_uniprocessor())
|
|
||||||
printk(KERN_NOTICE "Local APIC not detected."
|
|
||||||
" Using dummy APIC emulation.\n");
|
|
||||||
map_cpu_to_logical_apicid();
|
|
||||||
cpu_set(0, cpu_sibling_map[0]);
|
|
||||||
cpu_set(0, cpu_core_map[0]);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Should not be necessary because the MP table should list the boot
|
|
||||||
* CPU too, but we do it for the sake of robustness anyway.
|
|
||||||
* Makes no sense to do this check in clustered apic mode, so skip it
|
|
||||||
*/
|
|
||||||
if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
|
|
||||||
printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
|
|
||||||
boot_cpu_physical_apicid);
|
|
||||||
physid_set(hard_smp_processor_id(), phys_cpu_present_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we couldn't find a local APIC, then get out of here now!
|
|
||||||
*/
|
|
||||||
if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && !cpu_has_apic) {
|
|
||||||
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
|
|
||||||
boot_cpu_physical_apicid);
|
|
||||||
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
|
|
||||||
smpboot_clear_io_apic_irqs();
|
|
||||||
phys_cpu_present_map = physid_mask_of_physid(0);
|
|
||||||
cpu_set(0, cpu_sibling_map[0]);
|
|
||||||
cpu_set(0, cpu_core_map[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
verify_local_APIC();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If SMP should be disabled, then really disable it!
|
* If SMP should be disabled, then really disable it!
|
||||||
*/
|
*/
|
||||||
if (!max_cpus) {
|
if (!max_cpus || (enable_local_apic < 0)) {
|
||||||
smp_found_config = 0;
|
printk(KERN_INFO "SMP mode deactivated.\n");
|
||||||
printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
|
disable_smp();
|
||||||
smpboot_clear_io_apic_irqs();
|
|
||||||
phys_cpu_present_map = physid_mask_of_physid(0);
|
|
||||||
cpu_set(0, cpu_sibling_map[0]);
|
|
||||||
cpu_set(0, cpu_core_map[0]);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connect_bsp_APIC();
|
|
||||||
setup_local_APIC();
|
|
||||||
map_cpu_to_logical_apicid();
|
|
||||||
|
|
||||||
|
|
||||||
setup_portio_remap();
|
setup_portio_remap();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1240,10 +1212,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
|
||||||
cpu_set(0, cpu_sibling_map[0]);
|
cpu_set(0, cpu_sibling_map[0]);
|
||||||
cpu_set(0, cpu_core_map[0]);
|
cpu_set(0, cpu_core_map[0]);
|
||||||
|
|
||||||
smpboot_setup_io_apic();
|
|
||||||
|
|
||||||
setup_boot_APIC_clock();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Synchronize the TSC with the AP
|
* Synchronize the TSC with the AP
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -327,7 +327,12 @@ int __init get_memcfg_from_srat(void)
|
||||||
int tables = 0;
|
int tables = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING, rsdp_address);
|
if (ACPI_FAILURE(acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING,
|
||||||
|
rsdp_address))) {
|
||||||
|
printk("%s: System description tables not found\n",
|
||||||
|
__FUNCTION__);
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) {
|
if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) {
|
||||||
printk("%s: assigning address to rsdp\n", __FUNCTION__);
|
printk("%s: assigning address to rsdp\n", __FUNCTION__);
|
||||||
|
|
|
@ -74,10 +74,6 @@ int pit_latch_buggy; /* extern */
|
||||||
|
|
||||||
#include "do_timer.h"
|
#include "do_timer.h"
|
||||||
|
|
||||||
u64 jiffies_64 = INITIAL_JIFFIES;
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(jiffies_64);
|
|
||||||
|
|
||||||
unsigned int cpu_khz; /* Detected as we calibrate the TSC */
|
unsigned int cpu_khz; /* Detected as we calibrate the TSC */
|
||||||
EXPORT_SYMBOL(cpu_khz);
|
EXPORT_SYMBOL(cpu_khz);
|
||||||
|
|
||||||
|
@ -444,8 +440,8 @@ static int time_init_device(void)
|
||||||
|
|
||||||
device_initcall(time_init_device);
|
device_initcall(time_init_device);
|
||||||
|
|
||||||
#ifdef CONFIG_HPET_TIMER
|
|
||||||
extern void (*late_time_init)(void);
|
extern void (*late_time_init)(void);
|
||||||
|
#ifdef CONFIG_HPET_TIMER
|
||||||
/* Duplicate of time_init() below, with hpet_enable part added */
|
/* Duplicate of time_init() below, with hpet_enable part added */
|
||||||
static void __init hpet_time_init(void)
|
static void __init hpet_time_init(void)
|
||||||
{
|
{
|
||||||
|
@ -462,6 +458,11 @@ static void __init hpet_time_init(void)
|
||||||
printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
|
printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
|
||||||
|
|
||||||
time_init_hook();
|
time_init_hook();
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
|
if (enable_local_apic >= 0)
|
||||||
|
APIC_late_time_init();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -486,4 +487,9 @@ void __init time_init(void)
|
||||||
printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
|
printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
|
||||||
|
|
||||||
time_init_hook();
|
time_init_hook();
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
|
if (enable_local_apic >= 0)
|
||||||
|
late_time_init = APIC_late_time_init;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,6 +275,7 @@ static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
|
||||||
static unsigned long PIE_count;
|
static unsigned long PIE_count;
|
||||||
|
|
||||||
static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
|
static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
|
||||||
|
static unsigned int hpet_t1_cmp; /* cached comparator register */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Timer 1 for RTC, we do not use periodic interrupt feature,
|
* Timer 1 for RTC, we do not use periodic interrupt feature,
|
||||||
|
@ -306,10 +307,12 @@ int hpet_rtc_timer_init(void)
|
||||||
cnt = hpet_readl(HPET_COUNTER);
|
cnt = hpet_readl(HPET_COUNTER);
|
||||||
cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
|
cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
|
||||||
hpet_writel(cnt, HPET_T1_CMP);
|
hpet_writel(cnt, HPET_T1_CMP);
|
||||||
|
hpet_t1_cmp = cnt;
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
cfg = hpet_readl(HPET_T1_CFG);
|
cfg = hpet_readl(HPET_T1_CFG);
|
||||||
cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
|
cfg &= ~HPET_TN_PERIODIC;
|
||||||
|
cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
|
||||||
hpet_writel(cfg, HPET_T1_CFG);
|
hpet_writel(cfg, HPET_T1_CFG);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -319,8 +322,12 @@ static void hpet_rtc_timer_reinit(void)
|
||||||
{
|
{
|
||||||
unsigned int cfg, cnt;
|
unsigned int cfg, cnt;
|
||||||
|
|
||||||
if (!(PIE_on | AIE_on | UIE_on))
|
if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
|
||||||
|
cfg = hpet_readl(HPET_T1_CFG);
|
||||||
|
cfg &= ~HPET_TN_ENABLE;
|
||||||
|
hpet_writel(cfg, HPET_T1_CFG);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
|
if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
|
||||||
hpet_rtc_int_freq = PIE_freq;
|
hpet_rtc_int_freq = PIE_freq;
|
||||||
|
@ -328,15 +335,10 @@ static void hpet_rtc_timer_reinit(void)
|
||||||
hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
|
hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
|
||||||
|
|
||||||
/* It is more accurate to use the comparator value than current count.*/
|
/* It is more accurate to use the comparator value than current count.*/
|
||||||
cnt = hpet_readl(HPET_T1_CMP);
|
cnt = hpet_t1_cmp;
|
||||||
cnt += hpet_tick*HZ/hpet_rtc_int_freq;
|
cnt += hpet_tick*HZ/hpet_rtc_int_freq;
|
||||||
hpet_writel(cnt, HPET_T1_CMP);
|
hpet_writel(cnt, HPET_T1_CMP);
|
||||||
|
hpet_t1_cmp = cnt;
|
||||||
cfg = hpet_readl(HPET_T1_CFG);
|
|
||||||
cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
|
|
||||||
hpet_writel(cfg, HPET_T1_CFG);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -30,23 +30,28 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
|
||||||
* basic equation:
|
* basic equation:
|
||||||
* ns = cycles / (freq / ns_per_sec)
|
* ns = cycles / (freq / ns_per_sec)
|
||||||
* ns = cycles * (ns_per_sec / freq)
|
* ns = cycles * (ns_per_sec / freq)
|
||||||
* ns = cycles * (10^9 / (cpu_mhz * 10^6))
|
* ns = cycles * (10^9 / (cpu_khz * 10^3))
|
||||||
* ns = cycles * (10^3 / cpu_mhz)
|
* ns = cycles * (10^6 / cpu_khz)
|
||||||
*
|
*
|
||||||
* Then we use scaling math (suggested by george@mvista.com) to get:
|
* Then we use scaling math (suggested by george@mvista.com) to get:
|
||||||
* ns = cycles * (10^3 * SC / cpu_mhz) / SC
|
* ns = cycles * (10^6 * SC / cpu_khz) / SC
|
||||||
* ns = cycles * cyc2ns_scale / SC
|
* ns = cycles * cyc2ns_scale / SC
|
||||||
*
|
*
|
||||||
* And since SC is a constant power of two, we can convert the div
|
* And since SC is a constant power of two, we can convert the div
|
||||||
* into a shift.
|
* into a shift.
|
||||||
|
*
|
||||||
|
* We can use khz divisor instead of mhz to keep a better percision, since
|
||||||
|
* cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
|
||||||
|
* (mathieu.desnoyers@polymtl.ca)
|
||||||
|
*
|
||||||
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
|
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
|
||||||
*/
|
*/
|
||||||
static unsigned long cyc2ns_scale;
|
static unsigned long cyc2ns_scale;
|
||||||
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
|
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
|
||||||
|
|
||||||
static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
|
static inline void set_cyc2ns_scale(unsigned long cpu_khz)
|
||||||
{
|
{
|
||||||
cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
|
cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
|
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
|
||||||
|
@ -163,7 +168,7 @@ static int __init init_hpet(char* override)
|
||||||
printk("Detected %u.%03u MHz processor.\n",
|
printk("Detected %u.%03u MHz processor.\n",
|
||||||
cpu_khz / 1000, cpu_khz % 1000);
|
cpu_khz / 1000, cpu_khz % 1000);
|
||||||
}
|
}
|
||||||
set_cyc2ns_scale(cpu_khz/1000);
|
set_cyc2ns_scale(cpu_khz);
|
||||||
}
|
}
|
||||||
/* set this only when cpu_has_tsc */
|
/* set this only when cpu_has_tsc */
|
||||||
timer_hpet.read_timer = read_timer_tsc;
|
timer_hpet.read_timer = read_timer_tsc;
|
||||||
|
|
|
@ -49,23 +49,28 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
|
||||||
* basic equation:
|
* basic equation:
|
||||||
* ns = cycles / (freq / ns_per_sec)
|
* ns = cycles / (freq / ns_per_sec)
|
||||||
* ns = cycles * (ns_per_sec / freq)
|
* ns = cycles * (ns_per_sec / freq)
|
||||||
* ns = cycles * (10^9 / (cpu_mhz * 10^6))
|
* ns = cycles * (10^9 / (cpu_khz * 10^3))
|
||||||
* ns = cycles * (10^3 / cpu_mhz)
|
* ns = cycles * (10^6 / cpu_khz)
|
||||||
*
|
*
|
||||||
* Then we use scaling math (suggested by george@mvista.com) to get:
|
* Then we use scaling math (suggested by george@mvista.com) to get:
|
||||||
* ns = cycles * (10^3 * SC / cpu_mhz) / SC
|
* ns = cycles * (10^6 * SC / cpu_khz) / SC
|
||||||
* ns = cycles * cyc2ns_scale / SC
|
* ns = cycles * cyc2ns_scale / SC
|
||||||
*
|
*
|
||||||
* And since SC is a constant power of two, we can convert the div
|
* And since SC is a constant power of two, we can convert the div
|
||||||
* into a shift.
|
* into a shift.
|
||||||
|
*
|
||||||
|
* We can use khz divisor instead of mhz to keep a better percision, since
|
||||||
|
* cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
|
||||||
|
* (mathieu.desnoyers@polymtl.ca)
|
||||||
|
*
|
||||||
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
|
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
|
||||||
*/
|
*/
|
||||||
static unsigned long cyc2ns_scale;
|
static unsigned long cyc2ns_scale;
|
||||||
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
|
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
|
||||||
|
|
||||||
static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
|
static inline void set_cyc2ns_scale(unsigned long cpu_khz)
|
||||||
{
|
{
|
||||||
cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
|
cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
|
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
|
||||||
|
@ -286,7 +291,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
|
||||||
if (use_tsc) {
|
if (use_tsc) {
|
||||||
if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
|
if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
|
||||||
fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
|
fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
|
||||||
set_cyc2ns_scale(cpu_khz/1000);
|
set_cyc2ns_scale(cpu_khz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -536,7 +541,7 @@ static int __init init_tsc(char* override)
|
||||||
printk("Detected %u.%03u MHz processor.\n",
|
printk("Detected %u.%03u MHz processor.\n",
|
||||||
cpu_khz / 1000, cpu_khz % 1000);
|
cpu_khz / 1000, cpu_khz % 1000);
|
||||||
}
|
}
|
||||||
set_cyc2ns_scale(cpu_khz/1000);
|
set_cyc2ns_scale(cpu_khz);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,6 +488,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
|
||||||
tss->io_bitmap_max - thread->io_bitmap_max);
|
tss->io_bitmap_max - thread->io_bitmap_max);
|
||||||
tss->io_bitmap_max = thread->io_bitmap_max;
|
tss->io_bitmap_max = thread->io_bitmap_max;
|
||||||
tss->io_bitmap_base = IO_BITMAP_OFFSET;
|
tss->io_bitmap_base = IO_BITMAP_OFFSET;
|
||||||
|
tss->io_bitmap_owner = thread;
|
||||||
put_cpu();
|
put_cpu();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,15 @@
|
||||||
* http://www.unisys.com
|
* http://www.unisys.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ES7000 chipsets
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NON_UNISYS 0
|
||||||
|
#define ES7000_CLASSIC 1
|
||||||
|
#define ES7000_ZORRO 2
|
||||||
|
|
||||||
|
|
||||||
#define MIP_REG 1
|
#define MIP_REG 1
|
||||||
#define MIP_PSAI_REG 4
|
#define MIP_PSAI_REG 4
|
||||||
|
|
||||||
|
@ -106,6 +115,6 @@ struct mip_reg {
|
||||||
|
|
||||||
extern int parse_unisys_oem (char *oemptr);
|
extern int parse_unisys_oem (char *oemptr);
|
||||||
extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
|
extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
|
||||||
extern void setup_unisys ();
|
extern void setup_unisys(void);
|
||||||
extern int es7000_start_cpu(int cpu, unsigned long eip);
|
extern int es7000_start_cpu(int cpu, unsigned long eip);
|
||||||
extern void es7000_sw_apic(void);
|
extern void es7000_sw_apic(void);
|
||||||
|
|
|
@ -62,6 +62,9 @@ static unsigned int base;
|
||||||
static int
|
static int
|
||||||
es7000_rename_gsi(int ioapic, int gsi)
|
es7000_rename_gsi(int ioapic, int gsi)
|
||||||
{
|
{
|
||||||
|
if (es7000_plat == ES7000_ZORRO)
|
||||||
|
return gsi;
|
||||||
|
|
||||||
if (!base) {
|
if (!base) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nr_ioapics; i++)
|
for (i = 0; i < nr_ioapics; i++)
|
||||||
|
@ -76,7 +79,7 @@ es7000_rename_gsi(int ioapic, int gsi)
|
||||||
#endif /* (CONFIG_X86_IO_APIC) && (CONFIG_ACPI) */
|
#endif /* (CONFIG_X86_IO_APIC) && (CONFIG_ACPI) */
|
||||||
|
|
||||||
void __init
|
void __init
|
||||||
setup_unisys ()
|
setup_unisys(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Determine the generation of the ES7000 currently running.
|
* Determine the generation of the ES7000 currently running.
|
||||||
|
@ -86,9 +89,9 @@ setup_unisys ()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
|
if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
|
||||||
es7000_plat = 2;
|
es7000_plat = ES7000_ZORRO;
|
||||||
else
|
else
|
||||||
es7000_plat = 1;
|
es7000_plat = ES7000_CLASSIC;
|
||||||
ioapic_renumber_irq = es7000_rename_gsi;
|
ioapic_renumber_irq = es7000_rename_gsi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +154,7 @@ parse_unisys_oem (char *oemptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success < 2) {
|
if (success < 2) {
|
||||||
es7000_plat = 0;
|
es7000_plat = NON_UNISYS;
|
||||||
} else
|
} else
|
||||||
setup_unisys();
|
setup_unisys();
|
||||||
return es7000_plat;
|
return es7000_plat;
|
||||||
|
|
|
@ -108,7 +108,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs,
|
||||||
desc = (void *)desc + (seg & ~7);
|
desc = (void *)desc + (seg & ~7);
|
||||||
} else {
|
} else {
|
||||||
/* Must disable preemption while reading the GDT. */
|
/* Must disable preemption while reading the GDT. */
|
||||||
desc = (u32 *)&per_cpu(cpu_gdt_table, get_cpu());
|
desc = (u32 *)get_cpu_gdt_table(get_cpu());
|
||||||
desc = (void *)desc + (seg & ~7);
|
desc = (void *)desc + (seg & ~7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -547,31 +547,48 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
|
static __init int via_router_probe(struct irq_router *r,
|
||||||
|
struct pci_dev *router, u16 device)
|
||||||
{
|
{
|
||||||
/* FIXME: We should move some of the quirk fixup stuff here */
|
/* FIXME: We should move some of the quirk fixup stuff here */
|
||||||
|
|
||||||
if (router->device == PCI_DEVICE_ID_VIA_82C686 &&
|
/*
|
||||||
device == PCI_DEVICE_ID_VIA_82C586_0) {
|
* work arounds for some buggy BIOSes
|
||||||
/* Asus k7m bios wrongly reports 82C686A as 586-compatible */
|
*/
|
||||||
device = PCI_DEVICE_ID_VIA_82C686;
|
if (device == PCI_DEVICE_ID_VIA_82C586_0) {
|
||||||
|
switch(router->device) {
|
||||||
|
case PCI_DEVICE_ID_VIA_82C686:
|
||||||
|
/*
|
||||||
|
* Asus k7m bios wrongly reports 82C686A
|
||||||
|
* as 586-compatible
|
||||||
|
*/
|
||||||
|
device = PCI_DEVICE_ID_VIA_82C686;
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_VIA_8235:
|
||||||
|
/**
|
||||||
|
* Asus a7v-x bios wrongly reports 8235
|
||||||
|
* as 586-compatible
|
||||||
|
*/
|
||||||
|
device = PCI_DEVICE_ID_VIA_8235;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(device)
|
switch(device) {
|
||||||
{
|
case PCI_DEVICE_ID_VIA_82C586_0:
|
||||||
case PCI_DEVICE_ID_VIA_82C586_0:
|
r->name = "VIA";
|
||||||
r->name = "VIA";
|
r->get = pirq_via586_get;
|
||||||
r->get = pirq_via586_get;
|
r->set = pirq_via586_set;
|
||||||
r->set = pirq_via586_set;
|
return 1;
|
||||||
return 1;
|
case PCI_DEVICE_ID_VIA_82C596:
|
||||||
case PCI_DEVICE_ID_VIA_82C596:
|
case PCI_DEVICE_ID_VIA_82C686:
|
||||||
case PCI_DEVICE_ID_VIA_82C686:
|
case PCI_DEVICE_ID_VIA_8231:
|
||||||
case PCI_DEVICE_ID_VIA_8231:
|
case PCI_DEVICE_ID_VIA_8235:
|
||||||
/* FIXME: add new ones for 8233/5 */
|
/* FIXME: add new ones for 8233/5 */
|
||||||
r->name = "VIA";
|
r->name = "VIA";
|
||||||
r->get = pirq_via_get;
|
r->get = pirq_via_get;
|
||||||
r->set = pirq_via_set;
|
r->set = pirq_via_set;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,16 +51,14 @@ void save_processor_state(void)
|
||||||
__save_processor_state(&saved_context);
|
__save_processor_state(&saved_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void do_fpu_end(void)
|
||||||
do_fpu_end(void)
|
|
||||||
{
|
{
|
||||||
/* restore FPU regs if necessary */
|
/*
|
||||||
/* Do it out of line so that gcc does not move cr0 load to some stupid place */
|
* Restore FPU regs if necessary.
|
||||||
kernel_fpu_end();
|
*/
|
||||||
mxcsr_feature_mask_init();
|
kernel_fpu_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void fix_processor_context(void)
|
static void fix_processor_context(void)
|
||||||
{
|
{
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <linux/uio.h>
|
#include <linux/uio.h>
|
||||||
#include <linux/nfs_fs.h>
|
#include <linux/nfs_fs.h>
|
||||||
#include <linux/quota.h>
|
#include <linux/quota.h>
|
||||||
|
#include <linux/syscalls.h>
|
||||||
#include <linux/sunrpc/svc.h>
|
#include <linux/sunrpc/svc.h>
|
||||||
#include <linux/nfsd/nfsd.h>
|
#include <linux/nfsd/nfsd.h>
|
||||||
#include <linux/nfsd/cache.h>
|
#include <linux/nfsd/cache.h>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
#include <linux/timex.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
/* IBM Summit (EXA) Cyclone counter code*/
|
/* IBM Summit (EXA) Cyclone counter code*/
|
||||||
|
|
|
@ -32,10 +32,6 @@
|
||||||
|
|
||||||
extern unsigned long wall_jiffies;
|
extern unsigned long wall_jiffies;
|
||||||
|
|
||||||
u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(jiffies_64);
|
|
||||||
|
|
||||||
#define TIME_KEEPER_ID 0 /* smp_processor_id() of time-keeper */
|
#define TIME_KEEPER_ID 0 /* smp_processor_id() of time-keeper */
|
||||||
|
|
||||||
#ifdef CONFIG_IA64_DEBUG_IRQ
|
#ifdef CONFIG_IA64_DEBUG_IRQ
|
||||||
|
|
|
@ -653,8 +653,6 @@ ENTRY(rie_handler)
|
||||||
SAVE_ALL
|
SAVE_ALL
|
||||||
mvfc r0, bpc
|
mvfc r0, bpc
|
||||||
ld r1, @r0
|
ld r1, @r0
|
||||||
seth r0, #0xa0f0
|
|
||||||
st r1, @r0
|
|
||||||
ldi r1, #0x20 ; error_code
|
ldi r1, #0x20 ; error_code
|
||||||
mv r0, sp ; pt_regs
|
mv r0, sp ; pt_regs
|
||||||
bl do_rie_handler
|
bl do_rie_handler
|
||||||
|
|
|
@ -64,11 +64,11 @@ static inline void *__port2addr_ata(unsigned long port)
|
||||||
* from 0x10000000 to 0x13ffffff on physical address.
|
* from 0x10000000 to 0x13ffffff on physical address.
|
||||||
* The base address of LAN controller(LAN91C111) is 0x300.
|
* The base address of LAN controller(LAN91C111) is 0x300.
|
||||||
*/
|
*/
|
||||||
#define LAN_IOSTART 0x300
|
#define LAN_IOSTART 0xa0000300
|
||||||
#define LAN_IOEND 0x320
|
#define LAN_IOEND 0xa0000320
|
||||||
static inline void *_port2addr_ne(unsigned long port)
|
static inline void *_port2addr_ne(unsigned long port)
|
||||||
{
|
{
|
||||||
return (void *)(port + NONCACHE_OFFSET + 0x10000000);
|
return (void *)(port + 0x10000000);
|
||||||
}
|
}
|
||||||
static inline void *_port2addr_usb(unsigned long port)
|
static inline void *_port2addr_usb(unsigned long port)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,7 +31,7 @@ extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int);
|
||||||
|
|
||||||
static inline void *_port2addr(unsigned long port)
|
static inline void *_port2addr(unsigned long port)
|
||||||
{
|
{
|
||||||
return (void *)(port + NONCACHE_OFFSET);
|
return (void *)(port | (NONCACHE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *_port2addr_ne(unsigned long port)
|
static inline void *_port2addr_ne(unsigned long port)
|
||||||
|
|
|
@ -33,12 +33,9 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
|
||||||
|
|
||||||
static inline void *_port2addr(unsigned long port)
|
static inline void *_port2addr(unsigned long port)
|
||||||
{
|
{
|
||||||
return (void *)(port + NONCACHE_OFFSET);
|
return (void *)(port | (NONCACHE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LAN_IOSTART 0x300
|
|
||||||
#define LAN_IOEND 0x320
|
|
||||||
|
|
||||||
#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
|
#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
|
||||||
static inline void *__port2addr_ata(unsigned long port)
|
static inline void *__port2addr_ata(unsigned long port)
|
||||||
{
|
{
|
||||||
|
@ -59,15 +56,17 @@ static inline void *__port2addr_ata(unsigned long port)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define LAN_IOSTART 0xa0000300
|
||||||
|
#define LAN_IOEND 0xa0000320
|
||||||
#ifdef CONFIG_CHIP_OPSP
|
#ifdef CONFIG_CHIP_OPSP
|
||||||
static inline void *_port2addr_ne(unsigned long port)
|
static inline void *_port2addr_ne(unsigned long port)
|
||||||
{
|
{
|
||||||
return (void *)(port + NONCACHE_OFFSET + 0x10000000);
|
return (void *)(port + 0x10000000);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void *_port2addr_ne(unsigned long port)
|
static inline void *_port2addr_ne(unsigned long port)
|
||||||
{
|
{
|
||||||
return (void *)(port + NONCACHE_OFFSET + 0x04000000);
|
return (void *)(port + 0x04000000);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
static inline void *_port2addr_usb(unsigned long port)
|
static inline void *_port2addr_usb(unsigned long port)
|
||||||
|
|
|
@ -36,9 +36,6 @@ static inline void *_port2addr(unsigned long port)
|
||||||
return (void *)(port + NONCACHE_OFFSET);
|
return (void *)(port + NONCACHE_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LAN_IOSTART 0x300
|
|
||||||
#define LAN_IOEND 0x320
|
|
||||||
|
|
||||||
#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
|
#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
|
||||||
static inline void *__port2addr_ata(unsigned long port)
|
static inline void *__port2addr_ata(unsigned long port)
|
||||||
{
|
{
|
||||||
|
@ -59,9 +56,11 @@ static inline void *__port2addr_ata(unsigned long port)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define LAN_IOSTART 0xa0000300
|
||||||
|
#define LAN_IOEND 0xa0000320
|
||||||
static inline void *_port2addr_ne(unsigned long port)
|
static inline void *_port2addr_ne(unsigned long port)
|
||||||
{
|
{
|
||||||
return (void *)(port + NONCACHE_OFFSET + 0x10000000);
|
return (void *)(port + 0x10000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *_port2addr_usb(unsigned long port)
|
static inline void *_port2addr_usb(unsigned long port)
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
static inline void *_port2addr(unsigned long port)
|
static inline void *_port2addr(unsigned long port)
|
||||||
{
|
{
|
||||||
return (void *)(port + NONCACHE_OFFSET);
|
return (void *)(port | (NONCACHE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *_port2addr_ne(unsigned long port)
|
static inline void *_port2addr_ne(unsigned long port)
|
||||||
|
|
|
@ -36,7 +36,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
|
||||||
|
|
||||||
static inline void *_port2addr(unsigned long port)
|
static inline void *_port2addr(unsigned long port)
|
||||||
{
|
{
|
||||||
return (void *)(port + NONCACHE_OFFSET);
|
return (void *)(port | (NONCACHE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -44,11 +44,11 @@ static inline void *_port2addr(unsigned long port)
|
||||||
* from 0x10000000 to 0x13ffffff on physical address.
|
* from 0x10000000 to 0x13ffffff on physical address.
|
||||||
* The base address of LAN controller(LAN91C111) is 0x300.
|
* The base address of LAN controller(LAN91C111) is 0x300.
|
||||||
*/
|
*/
|
||||||
#define LAN_IOSTART 0x300
|
#define LAN_IOSTART 0xa0000300
|
||||||
#define LAN_IOEND 0x320
|
#define LAN_IOEND 0xa0000320
|
||||||
static inline void *_port2addr_ne(unsigned long port)
|
static inline void *_port2addr_ne(unsigned long port)
|
||||||
{
|
{
|
||||||
return (void *)(port + NONCACHE_OFFSET + 0x10000000);
|
return (void *)(port + 0x10000000);
|
||||||
}
|
}
|
||||||
static inline void *_port2addr_usb(unsigned long port)
|
static inline void *_port2addr_usb(unsigned long port)
|
||||||
{
|
{
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue