Merge commit 'tip/perfcounters-for-linus' into oprofile/master
Conflicts: arch/x86/oprofile/op_model_ppro.c Signed-off-by: Robert Richter <robert.richter@amd.com>
This commit is contained in:
commit
1241eb8f13
|
@ -0,0 +1,18 @@
|
||||||
|
What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
|
||||||
|
Date: August 2008
|
||||||
|
KernelVersion: 2.6.27
|
||||||
|
Contact: mark.langsdorf@amd.com
|
||||||
|
Description: These files exist in every cpu's cache index directories.
|
||||||
|
There are currently 2 cache_disable_# files in each
|
||||||
|
directory. Reading from these files on a supported
|
||||||
|
processor will return that cache disable index value
|
||||||
|
for that processor and node. Writing to one of these
|
||||||
|
files will cause the specificed cache index to be disabled.
|
||||||
|
|
||||||
|
Currently, only AMD Family 10h Processors support cache index
|
||||||
|
disable, and only for their L3 caches. See the BIOS and
|
||||||
|
Kernel Developer's Guide at
|
||||||
|
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116-Public-GH-BKDG_3.20_2-4-09.pdf
|
||||||
|
for formatting information and other details on the
|
||||||
|
cache index disable.
|
||||||
|
Users: joachim.deguara@amd.com
|
|
@ -704,12 +704,24 @@ this directory the following files can currently be found:
|
||||||
The current number of free dma_debug_entries
|
The current number of free dma_debug_entries
|
||||||
in the allocator.
|
in the allocator.
|
||||||
|
|
||||||
|
dma-api/driver-filter
|
||||||
|
You can write a name of a driver into this file
|
||||||
|
to limit the debug output to requests from that
|
||||||
|
particular driver. Write an empty string to
|
||||||
|
that file to disable the filter and see
|
||||||
|
all errors again.
|
||||||
|
|
||||||
If you have this code compiled into your kernel it will be enabled by default.
|
If you have this code compiled into your kernel it will be enabled by default.
|
||||||
If you want to boot without the bookkeeping anyway you can provide
|
If you want to boot without the bookkeeping anyway you can provide
|
||||||
'dma_debug=off' as a boot parameter. This will disable DMA-API debugging.
|
'dma_debug=off' as a boot parameter. This will disable DMA-API debugging.
|
||||||
Notice that you can not enable it again at runtime. You have to reboot to do
|
Notice that you can not enable it again at runtime. You have to reboot to do
|
||||||
so.
|
so.
|
||||||
|
|
||||||
|
If you want to see debug messages only for a special device driver you can
|
||||||
|
specify the dma_debug_driver=<drivername> parameter. This will enable the
|
||||||
|
driver filter at boot time. The debug code will only print errors for that
|
||||||
|
driver afterwards. This filter can be disabled or changed later using debugfs.
|
||||||
|
|
||||||
When the code disables itself at runtime this is most likely because it ran
|
When the code disables itself at runtime this is most likely because it ran
|
||||||
out of dma_debug_entries. These entries are preallocated at boot. The number
|
out of dma_debug_entries. These entries are preallocated at boot. The number
|
||||||
of preallocated entries is defined per architecture. If it is too low for you
|
of preallocated entries is defined per architecture. If it is too low for you
|
||||||
|
|
|
@ -13,7 +13,8 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
|
||||||
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
|
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
|
||||||
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
|
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
|
||||||
mac80211.xml debugobjects.xml sh.xml regulator.xml \
|
mac80211.xml debugobjects.xml sh.xml regulator.xml \
|
||||||
alsa-driver-api.xml writing-an-alsa-driver.xml
|
alsa-driver-api.xml writing-an-alsa-driver.xml \
|
||||||
|
tracepoint.xml
|
||||||
|
|
||||||
###
|
###
|
||||||
# The build process is as follows (targets):
|
# The build process is as follows (targets):
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
||||||
|
|
||||||
|
<book id="Tracepoints">
|
||||||
|
<bookinfo>
|
||||||
|
<title>The Linux Kernel Tracepoint API</title>
|
||||||
|
|
||||||
|
<authorgroup>
|
||||||
|
<author>
|
||||||
|
<firstname>Jason</firstname>
|
||||||
|
<surname>Baron</surname>
|
||||||
|
<affiliation>
|
||||||
|
<address>
|
||||||
|
<email>jbaron@redhat.com</email>
|
||||||
|
</address>
|
||||||
|
</affiliation>
|
||||||
|
</author>
|
||||||
|
</authorgroup>
|
||||||
|
|
||||||
|
<legalnotice>
|
||||||
|
<para>
|
||||||
|
This documentation is free software; you can redistribute
|
||||||
|
it and/or modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
This program is distributed in the hope that it will be
|
||||||
|
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License along with this program; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
MA 02111-1307 USA
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
For more details see the file COPYING in the source
|
||||||
|
distribution of Linux.
|
||||||
|
</para>
|
||||||
|
</legalnotice>
|
||||||
|
</bookinfo>
|
||||||
|
|
||||||
|
<toc></toc>
|
||||||
|
<chapter id="intro">
|
||||||
|
<title>Introduction</title>
|
||||||
|
<para>
|
||||||
|
Tracepoints are static probe points that are located in strategic points
|
||||||
|
throughout the kernel. 'Probes' register/unregister with tracepoints
|
||||||
|
via a callback mechanism. The 'probes' are strictly typed functions that
|
||||||
|
are passed a unique set of parameters defined by each tracepoint.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
From this simple callback mechanism, 'probes' can be used to profile, debug,
|
||||||
|
and understand kernel behavior. There are a number of tools that provide a
|
||||||
|
framework for using 'probes'. These tools include Systemtap, ftrace, and
|
||||||
|
LTTng.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Tracepoints are defined in a number of header files via various macros. Thus,
|
||||||
|
the purpose of this document is to provide a clear accounting of the available
|
||||||
|
tracepoints. The intention is to understand not only what tracepoints are
|
||||||
|
available but also to understand where future tracepoints might be added.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The API presented has functions of the form:
|
||||||
|
<function>trace_tracepointname(function parameters)</function>. These are the
|
||||||
|
tracepoints callbacks that are found throughout the code. Registering and
|
||||||
|
unregistering probes with these callback sites is covered in the
|
||||||
|
<filename>Documentation/trace/*</filename> directory.
|
||||||
|
</para>
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
<chapter id="irq">
|
||||||
|
<title>IRQ</title>
|
||||||
|
!Iinclude/trace/events/irq.h
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
</book>
|
|
@ -192,23 +192,24 @@ rcu/rcuhier (which displays the struct rcu_node hierarchy).
|
||||||
The output of "cat rcu/rcudata" looks as follows:
|
The output of "cat rcu/rcudata" looks as follows:
|
||||||
|
|
||||||
rcu:
|
rcu:
|
||||||
0 c=4011 g=4012 pq=1 pqc=4011 qp=0 rpfq=1 rp=3c2a dt=23301/73 dn=2 df=1882 of=0 ri=2126 ql=2 b=10
|
rcu:
|
||||||
1 c=4011 g=4012 pq=1 pqc=4011 qp=0 rpfq=3 rp=39a6 dt=78073/1 dn=2 df=1402 of=0 ri=1875 ql=46 b=10
|
0 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=10951/1 dn=0 df=1101 of=0 ri=36 ql=0 b=10
|
||||||
2 c=4010 g=4010 pq=1 pqc=4010 qp=0 rpfq=-5 rp=1d12 dt=16646/0 dn=2 df=3140 of=0 ri=2080 ql=0 b=10
|
1 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=16117/1 dn=0 df=1015 of=0 ri=0 ql=0 b=10
|
||||||
3 c=4012 g=4013 pq=1 pqc=4012 qp=1 rpfq=3 rp=2b50 dt=21159/1 dn=2 df=2230 of=0 ri=1923 ql=72 b=10
|
2 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=1445/1 dn=0 df=1839 of=0 ri=0 ql=0 b=10
|
||||||
4 c=4012 g=4013 pq=1 pqc=4012 qp=1 rpfq=3 rp=1644 dt=5783/1 dn=2 df=3348 of=0 ri=2805 ql=7 b=10
|
3 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=6681/1 dn=0 df=1545 of=0 ri=0 ql=0 b=10
|
||||||
5 c=4012 g=4013 pq=0 pqc=4011 qp=1 rpfq=3 rp=1aac dt=5879/1 dn=2 df=3140 of=0 ri=2066 ql=10 b=10
|
4 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=1003/1 dn=0 df=1992 of=0 ri=0 ql=0 b=10
|
||||||
6 c=4012 g=4013 pq=1 pqc=4012 qp=1 rpfq=3 rp=ed8 dt=5847/1 dn=2 df=3797 of=0 ri=1266 ql=10 b=10
|
5 c=17829 g=17830 pq=1 pqc=17829 qp=1 dt=3887/1 dn=0 df=3331 of=0 ri=4 ql=2 b=10
|
||||||
7 c=4012 g=4013 pq=1 pqc=4012 qp=1 rpfq=3 rp=1fa2 dt=6199/1 dn=2 df=2795 of=0 ri=2162 ql=28 b=10
|
6 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=859/1 dn=0 df=3224 of=0 ri=0 ql=0 b=10
|
||||||
|
7 c=17829 g=17830 pq=0 pqc=17829 qp=1 dt=3761/1 dn=0 df=1818 of=0 ri=0 ql=2 b=10
|
||||||
rcu_bh:
|
rcu_bh:
|
||||||
0 c=-268 g=-268 pq=1 pqc=-268 qp=0 rpfq=-145 rp=21d6 dt=23301/73 dn=2 df=0 of=0 ri=0 ql=0 b=10
|
0 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=10951/1 dn=0 df=0 of=0 ri=0 ql=0 b=10
|
||||||
1 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-170 rp=20ce dt=78073/1 dn=2 df=26 of=0 ri=5 ql=0 b=10
|
1 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=16117/1 dn=0 df=13 of=0 ri=0 ql=0 b=10
|
||||||
2 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-83 rp=fbd dt=16646/0 dn=2 df=28 of=0 ri=4 ql=0 b=10
|
2 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=1445/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
|
||||||
3 c=-268 g=-268 pq=1 pqc=-268 qp=0 rpfq=-105 rp=178c dt=21159/1 dn=2 df=28 of=0 ri=2 ql=0 b=10
|
3 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=6681/1 dn=0 df=9 of=0 ri=0 ql=0 b=10
|
||||||
4 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-30 rp=b54 dt=5783/1 dn=2 df=32 of=0 ri=0 ql=0 b=10
|
4 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=1003/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
|
||||||
5 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-29 rp=df5 dt=5879/1 dn=2 df=30 of=0 ri=3 ql=0 b=10
|
5 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=3887/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
|
||||||
6 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-28 rp=788 dt=5847/1 dn=2 df=32 of=0 ri=0 ql=0 b=10
|
6 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=859/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
|
||||||
7 c=-268 g=-268 pq=1 pqc=-268 qp=1 rpfq=-53 rp=1098 dt=6199/1 dn=2 df=30 of=0 ri=3 ql=0 b=10
|
7 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=3761/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
|
||||||
|
|
||||||
The first section lists the rcu_data structures for rcu, the second for
|
The first section lists the rcu_data structures for rcu, the second for
|
||||||
rcu_bh. Each section has one line per CPU, or eight for this 8-CPU system.
|
rcu_bh. Each section has one line per CPU, or eight for this 8-CPU system.
|
||||||
|
@ -253,12 +254,6 @@ o "pqc" indicates which grace period the last-observed quiescent
|
||||||
o "qp" indicates that RCU still expects a quiescent state from
|
o "qp" indicates that RCU still expects a quiescent state from
|
||||||
this CPU.
|
this CPU.
|
||||||
|
|
||||||
o "rpfq" is the number of rcu_pending() calls on this CPU required
|
|
||||||
to induce this CPU to invoke force_quiescent_state().
|
|
||||||
|
|
||||||
o "rp" is low-order four hex digits of the count of how many times
|
|
||||||
rcu_pending() has been invoked on this CPU.
|
|
||||||
|
|
||||||
o "dt" is the current value of the dyntick counter that is incremented
|
o "dt" is the current value of the dyntick counter that is incremented
|
||||||
when entering or leaving dynticks idle state, either by the
|
when entering or leaving dynticks idle state, either by the
|
||||||
scheduler or by irq. The number after the "/" is the interrupt
|
scheduler or by irq. The number after the "/" is the interrupt
|
||||||
|
@ -305,6 +300,9 @@ o "b" is the batch limit for this CPU. If more than this number
|
||||||
of RCU callbacks is ready to invoke, then the remainder will
|
of RCU callbacks is ready to invoke, then the remainder will
|
||||||
be deferred.
|
be deferred.
|
||||||
|
|
||||||
|
There is also an rcu/rcudata.csv file with the same information in
|
||||||
|
comma-separated-variable spreadsheet format.
|
||||||
|
|
||||||
|
|
||||||
The output of "cat rcu/rcugp" looks as follows:
|
The output of "cat rcu/rcugp" looks as follows:
|
||||||
|
|
||||||
|
@ -411,3 +409,63 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
|
||||||
For example, the first entry at the lowest level shows
|
For example, the first entry at the lowest level shows
|
||||||
"^0", indicating that it corresponds to bit zero in
|
"^0", indicating that it corresponds to bit zero in
|
||||||
the first entry at the middle level.
|
the first entry at the middle level.
|
||||||
|
|
||||||
|
|
||||||
|
The output of "cat rcu/rcu_pending" looks as follows:
|
||||||
|
|
||||||
|
rcu:
|
||||||
|
0 np=255892 qsp=53936 cbr=0 cng=14417 gpc=10033 gps=24320 nf=6445 nn=146741
|
||||||
|
1 np=261224 qsp=54638 cbr=0 cng=25723 gpc=16310 gps=2849 nf=5912 nn=155792
|
||||||
|
2 np=237496 qsp=49664 cbr=0 cng=2762 gpc=45478 gps=1762 nf=1201 nn=136629
|
||||||
|
3 np=236249 qsp=48766 cbr=0 cng=286 gpc=48049 gps=1218 nf=207 nn=137723
|
||||||
|
4 np=221310 qsp=46850 cbr=0 cng=26 gpc=43161 gps=4634 nf=3529 nn=123110
|
||||||
|
5 np=237332 qsp=48449 cbr=0 cng=54 gpc=47920 gps=3252 nf=201 nn=137456
|
||||||
|
6 np=219995 qsp=46718 cbr=0 cng=50 gpc=42098 gps=6093 nf=4202 nn=120834
|
||||||
|
7 np=249893 qsp=49390 cbr=0 cng=72 gpc=38400 gps=17102 nf=41 nn=144888
|
||||||
|
rcu_bh:
|
||||||
|
0 np=146741 qsp=1419 cbr=0 cng=6 gpc=0 gps=0 nf=2 nn=145314
|
||||||
|
1 np=155792 qsp=12597 cbr=0 cng=0 gpc=4 gps=8 nf=3 nn=143180
|
||||||
|
2 np=136629 qsp=18680 cbr=0 cng=0 gpc=7 gps=6 nf=0 nn=117936
|
||||||
|
3 np=137723 qsp=2843 cbr=0 cng=0 gpc=10 gps=7 nf=0 nn=134863
|
||||||
|
4 np=123110 qsp=12433 cbr=0 cng=0 gpc=4 gps=2 nf=0 nn=110671
|
||||||
|
5 np=137456 qsp=4210 cbr=0 cng=0 gpc=6 gps=5 nf=0 nn=133235
|
||||||
|
6 np=120834 qsp=9902 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
|
||||||
|
7 np=144888 qsp=26336 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
|
||||||
|
|
||||||
|
As always, this is once again split into "rcu" and "rcu_bh" portions.
|
||||||
|
The fields are as follows:
|
||||||
|
|
||||||
|
o "np" is the number of times that __rcu_pending() has been invoked
|
||||||
|
for the corresponding flavor of RCU.
|
||||||
|
|
||||||
|
o "qsp" is the number of times that the RCU was waiting for a
|
||||||
|
quiescent state from this CPU.
|
||||||
|
|
||||||
|
o "cbr" is the number of times that this CPU had RCU callbacks
|
||||||
|
that had passed through a grace period, and were thus ready
|
||||||
|
to be invoked.
|
||||||
|
|
||||||
|
o "cng" is the number of times that this CPU needed another
|
||||||
|
grace period while RCU was idle.
|
||||||
|
|
||||||
|
o "gpc" is the number of times that an old grace period had
|
||||||
|
completed, but this CPU was not yet aware of it.
|
||||||
|
|
||||||
|
o "gps" is the number of times that a new grace period had started,
|
||||||
|
but this CPU was not yet aware of it.
|
||||||
|
|
||||||
|
o "nf" is the number of times that this CPU suspected that the
|
||||||
|
current grace period had run for too long, and thus needed to
|
||||||
|
be forced.
|
||||||
|
|
||||||
|
Please note that "forcing" consists of sending resched IPIs
|
||||||
|
to holdout CPUs. If that CPU really still is in an old RCU
|
||||||
|
read-side critical section, then we really do have to wait for it.
|
||||||
|
The assumption behing "forcing" is that the CPU is not still in
|
||||||
|
an old RCU read-side critical section, but has not yet responded
|
||||||
|
for some other reason.
|
||||||
|
|
||||||
|
o "nn" is the number of times that this CPU needed nothing. Alert
|
||||||
|
readers will note that the rcu "nn" number for a given CPU very
|
||||||
|
closely matches the rcu_bh "np" number for that same CPU. This
|
||||||
|
is due to short-circuit evaluation in rcu_pending().
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
Futex Requeue PI
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Requeueing of tasks from a non-PI futex to a PI futex requires
|
||||||
|
special handling in order to ensure the underlying rt_mutex is never
|
||||||
|
left without an owner if it has waiters; doing so would break the PI
|
||||||
|
boosting logic [see rt-mutex-desgin.txt] For the purposes of
|
||||||
|
brevity, this action will be referred to as "requeue_pi" throughout
|
||||||
|
this document. Priority inheritance is abbreviated throughout as
|
||||||
|
"PI".
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
----------
|
||||||
|
|
||||||
|
Without requeue_pi, the glibc implementation of
|
||||||
|
pthread_cond_broadcast() must resort to waking all the tasks waiting
|
||||||
|
on a pthread_condvar and letting them try to sort out which task
|
||||||
|
gets to run first in classic thundering-herd formation. An ideal
|
||||||
|
implementation would wake the highest-priority waiter, and leave the
|
||||||
|
rest to the natural wakeup inherent in unlocking the mutex
|
||||||
|
associated with the condvar.
|
||||||
|
|
||||||
|
Consider the simplified glibc calls:
|
||||||
|
|
||||||
|
/* caller must lock mutex */
|
||||||
|
pthread_cond_wait(cond, mutex)
|
||||||
|
{
|
||||||
|
lock(cond->__data.__lock);
|
||||||
|
unlock(mutex);
|
||||||
|
do {
|
||||||
|
unlock(cond->__data.__lock);
|
||||||
|
futex_wait(cond->__data.__futex);
|
||||||
|
lock(cond->__data.__lock);
|
||||||
|
} while(...)
|
||||||
|
unlock(cond->__data.__lock);
|
||||||
|
lock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_cond_broadcast(cond)
|
||||||
|
{
|
||||||
|
lock(cond->__data.__lock);
|
||||||
|
unlock(cond->__data.__lock);
|
||||||
|
futex_requeue(cond->data.__futex, cond->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Once pthread_cond_broadcast() requeues the tasks, the cond->mutex
|
||||||
|
has waiters. Note that pthread_cond_wait() attempts to lock the
|
||||||
|
mutex only after it has returned to user space. This will leave the
|
||||||
|
underlying rt_mutex with waiters, and no owner, breaking the
|
||||||
|
previously mentioned PI-boosting algorithms.
|
||||||
|
|
||||||
|
In order to support PI-aware pthread_condvar's, the kernel needs to
|
||||||
|
be able to requeue tasks to PI futexes. This support implies that
|
||||||
|
upon a successful futex_wait system call, the caller would return to
|
||||||
|
user space already holding the PI futex. The glibc implementation
|
||||||
|
would be modified as follows:
|
||||||
|
|
||||||
|
|
||||||
|
/* caller must lock mutex */
|
||||||
|
pthread_cond_wait_pi(cond, mutex)
|
||||||
|
{
|
||||||
|
lock(cond->__data.__lock);
|
||||||
|
unlock(mutex);
|
||||||
|
do {
|
||||||
|
unlock(cond->__data.__lock);
|
||||||
|
futex_wait_requeue_pi(cond->__data.__futex);
|
||||||
|
lock(cond->__data.__lock);
|
||||||
|
} while(...)
|
||||||
|
unlock(cond->__data.__lock);
|
||||||
|
/* the kernel acquired the the mutex for us */
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_cond_broadcast_pi(cond)
|
||||||
|
{
|
||||||
|
lock(cond->__data.__lock);
|
||||||
|
unlock(cond->__data.__lock);
|
||||||
|
futex_requeue_pi(cond->data.__futex, cond->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
The actual glibc implementation will likely test for PI and make the
|
||||||
|
necessary changes inside the existing calls rather than creating new
|
||||||
|
calls for the PI cases. Similar changes are needed for
|
||||||
|
pthread_cond_timedwait() and pthread_cond_signal().
|
||||||
|
|
||||||
|
Implementation
|
||||||
|
--------------
|
||||||
|
|
||||||
|
In order to ensure the rt_mutex has an owner if it has waiters, it
|
||||||
|
is necessary for both the requeue code, as well as the waiting code,
|
||||||
|
to be able to acquire the rt_mutex before returning to user space.
|
||||||
|
The requeue code cannot simply wake the waiter and leave it to
|
||||||
|
acquire the rt_mutex as it would open a race window between the
|
||||||
|
requeue call returning to user space and the waiter waking and
|
||||||
|
starting to run. This is especially true in the uncontended case.
|
||||||
|
|
||||||
|
The solution involves two new rt_mutex helper routines,
|
||||||
|
rt_mutex_start_proxy_lock() and rt_mutex_finish_proxy_lock(), which
|
||||||
|
allow the requeue code to acquire an uncontended rt_mutex on behalf
|
||||||
|
of the waiter and to enqueue the waiter on a contended rt_mutex.
|
||||||
|
Two new system calls provide the kernel<->user interface to
|
||||||
|
requeue_pi: FUTEX_WAIT_REQUEUE_PI and FUTEX_REQUEUE_CMP_PI.
|
||||||
|
|
||||||
|
FUTEX_WAIT_REQUEUE_PI is called by the waiter (pthread_cond_wait()
|
||||||
|
and pthread_cond_timedwait()) to block on the initial futex and wait
|
||||||
|
to be requeued to a PI-aware futex. The implementation is the
|
||||||
|
result of a high-speed collision between futex_wait() and
|
||||||
|
futex_lock_pi(), with some extra logic to check for the additional
|
||||||
|
wake-up scenarios.
|
||||||
|
|
||||||
|
FUTEX_REQUEUE_CMP_PI is called by the waker
|
||||||
|
(pthread_cond_broadcast() and pthread_cond_signal()) to requeue and
|
||||||
|
possibly wake the waiting tasks. Internally, this system call is
|
||||||
|
still handled by futex_requeue (by passing requeue_pi=1). Before
|
||||||
|
requeueing, futex_requeue() attempts to acquire the requeue target
|
||||||
|
PI futex on behalf of the top waiter. If it can, this waiter is
|
||||||
|
woken. futex_requeue() then proceeds to requeue the remaining
|
||||||
|
nr_wake+nr_requeue tasks to the PI futex, calling
|
||||||
|
rt_mutex_start_proxy_lock() prior to each requeue to prepare the
|
||||||
|
task as a waiter on the underlying rt_mutex. It is possible that
|
||||||
|
the lock can be acquired at this stage as well, if so, the next
|
||||||
|
waiter is woken to finish the acquisition of the lock.
|
||||||
|
|
||||||
|
FUTEX_REQUEUE_PI accepts nr_wake and nr_requeue as arguments, but
|
||||||
|
their sum is all that really matters. futex_requeue() will wake or
|
||||||
|
requeue up to nr_wake + nr_requeue tasks. It will wake only as many
|
||||||
|
tasks as it can acquire the lock for, which in the majority of cases
|
||||||
|
should be 0 as good programming practice dictates that the caller of
|
||||||
|
either pthread_cond_broadcast() or pthread_cond_signal() acquire the
|
||||||
|
mutex prior to making the call. FUTEX_REQUEUE_PI requires that
|
||||||
|
nr_wake=1. nr_requeue should be INT_MAX for broadcast and 0 for
|
||||||
|
signal.
|
|
@ -56,7 +56,6 @@ parameter is applicable:
|
||||||
ISAPNP ISA PnP code is enabled.
|
ISAPNP ISA PnP code is enabled.
|
||||||
ISDN Appropriate ISDN support is enabled.
|
ISDN Appropriate ISDN support is enabled.
|
||||||
JOY Appropriate joystick support is enabled.
|
JOY Appropriate joystick support is enabled.
|
||||||
KMEMTRACE kmemtrace is enabled.
|
|
||||||
LIBATA Libata driver is enabled
|
LIBATA Libata driver is enabled
|
||||||
LP Printer support is enabled.
|
LP Printer support is enabled.
|
||||||
LOOP Loopback device support is enabled.
|
LOOP Loopback device support is enabled.
|
||||||
|
@ -329,11 +328,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
flushed before they will be reused, which
|
flushed before they will be reused, which
|
||||||
is a lot of faster
|
is a lot of faster
|
||||||
|
|
||||||
amd_iommu_size= [HW,X86-64]
|
|
||||||
Define the size of the aperture for the AMD IOMMU
|
|
||||||
driver. Possible values are:
|
|
||||||
'32M', '64M' (default), '128M', '256M', '512M', '1G'
|
|
||||||
|
|
||||||
amijoy.map= [HW,JOY] Amiga joystick support
|
amijoy.map= [HW,JOY] Amiga joystick support
|
||||||
Map of devices attached to JOY0DAT and JOY1DAT
|
Map of devices attached to JOY0DAT and JOY1DAT
|
||||||
Format: <a>,<b>
|
Format: <a>,<b>
|
||||||
|
@ -646,6 +640,13 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
DMA-API debugging code disables itself because the
|
DMA-API debugging code disables itself because the
|
||||||
architectural default is too low.
|
architectural default is too low.
|
||||||
|
|
||||||
|
dma_debug_driver=<driver_name>
|
||||||
|
With this option the DMA-API debugging driver
|
||||||
|
filter feature can be enabled at boot time. Just
|
||||||
|
pass the driver to filter for as the parameter.
|
||||||
|
The filter can be disabled or changed to another
|
||||||
|
driver later using sysfs.
|
||||||
|
|
||||||
dscc4.setup= [NET]
|
dscc4.setup= [NET]
|
||||||
|
|
||||||
dtc3181e= [HW,SCSI]
|
dtc3181e= [HW,SCSI]
|
||||||
|
@ -752,12 +753,25 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
ia64_pal_cache_flush instead of SAL_CACHE_FLUSH.
|
ia64_pal_cache_flush instead of SAL_CACHE_FLUSH.
|
||||||
|
|
||||||
ftrace=[tracer]
|
ftrace=[tracer]
|
||||||
[ftrace] will set and start the specified tracer
|
[FTRACE] will set and start the specified tracer
|
||||||
as early as possible in order to facilitate early
|
as early as possible in order to facilitate early
|
||||||
boot debugging.
|
boot debugging.
|
||||||
|
|
||||||
ftrace_dump_on_oops
|
ftrace_dump_on_oops
|
||||||
[ftrace] will dump the trace buffers on oops.
|
[FTRACE] will dump the trace buffers on oops.
|
||||||
|
|
||||||
|
ftrace_filter=[function-list]
|
||||||
|
[FTRACE] Limit the functions traced by the function
|
||||||
|
tracer at boot up. function-list is a comma separated
|
||||||
|
list of functions. This list can be changed at run
|
||||||
|
time by the set_ftrace_filter file in the debugfs
|
||||||
|
tracing directory.
|
||||||
|
|
||||||
|
ftrace_notrace=[function-list]
|
||||||
|
[FTRACE] Do not trace the functions specified in
|
||||||
|
function-list. This list can be changed at run time
|
||||||
|
by the set_ftrace_notrace file in the debugfs
|
||||||
|
tracing directory.
|
||||||
|
|
||||||
gamecon.map[2|3]=
|
gamecon.map[2|3]=
|
||||||
[HW,JOY] Multisystem joystick and NES/SNES/PSX pad
|
[HW,JOY] Multisystem joystick and NES/SNES/PSX pad
|
||||||
|
@ -1054,15 +1068,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
use the HighMem zone if it exists, and the Normal
|
use the HighMem zone if it exists, and the Normal
|
||||||
zone if it does not.
|
zone if it does not.
|
||||||
|
|
||||||
kmemtrace.enable= [KNL,KMEMTRACE] Format: { yes | no }
|
|
||||||
Controls whether kmemtrace is enabled
|
|
||||||
at boot-time.
|
|
||||||
|
|
||||||
kmemtrace.subbufs=n [KNL,KMEMTRACE] Overrides the number of
|
|
||||||
subbufs kmemtrace's relay channel has. Set this
|
|
||||||
higher than default (KMEMTRACE_N_SUBBUFS in code) if
|
|
||||||
you experience buffer overruns.
|
|
||||||
|
|
||||||
kgdboc= [HW] kgdb over consoles.
|
kgdboc= [HW] kgdb over consoles.
|
||||||
Requires a tty driver that supports console polling.
|
Requires a tty driver that supports console polling.
|
||||||
(only serial suported for now)
|
(only serial suported for now)
|
||||||
|
@ -1575,6 +1580,9 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
noinitrd [RAM] Tells the kernel not to load any configured
|
noinitrd [RAM] Tells the kernel not to load any configured
|
||||||
initial RAM disk.
|
initial RAM disk.
|
||||||
|
|
||||||
|
nointremap [X86-64, Intel-IOMMU] Do not enable interrupt
|
||||||
|
remapping.
|
||||||
|
|
||||||
nointroute [IA-64]
|
nointroute [IA-64]
|
||||||
|
|
||||||
nojitter [IA64] Disables jitter checking for ITC timers.
|
nojitter [IA64] Disables jitter checking for ITC timers.
|
||||||
|
|
|
@ -31,6 +31,7 @@ Contents:
|
||||||
|
|
||||||
- Locking functions.
|
- Locking functions.
|
||||||
- Interrupt disabling functions.
|
- Interrupt disabling functions.
|
||||||
|
- Sleep and wake-up functions.
|
||||||
- Miscellaneous functions.
|
- Miscellaneous functions.
|
||||||
|
|
||||||
(*) Inter-CPU locking barrier effects.
|
(*) Inter-CPU locking barrier effects.
|
||||||
|
@ -1217,6 +1218,132 @@ barriers are required in such a situation, they must be provided from some
|
||||||
other means.
|
other means.
|
||||||
|
|
||||||
|
|
||||||
|
SLEEP AND WAKE-UP FUNCTIONS
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Sleeping and waking on an event flagged in global data can be viewed as an
|
||||||
|
interaction between two pieces of data: the task state of the task waiting for
|
||||||
|
the event and the global data used to indicate the event. To make sure that
|
||||||
|
these appear to happen in the right order, the primitives to begin the process
|
||||||
|
of going to sleep, and the primitives to initiate a wake up imply certain
|
||||||
|
barriers.
|
||||||
|
|
||||||
|
Firstly, the sleeper normally follows something like this sequence of events:
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||||
|
if (event_indicated)
|
||||||
|
break;
|
||||||
|
schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
A general memory barrier is interpolated automatically by set_current_state()
|
||||||
|
after it has altered the task state:
|
||||||
|
|
||||||
|
CPU 1
|
||||||
|
===============================
|
||||||
|
set_current_state();
|
||||||
|
set_mb();
|
||||||
|
STORE current->state
|
||||||
|
<general barrier>
|
||||||
|
LOAD event_indicated
|
||||||
|
|
||||||
|
set_current_state() may be wrapped by:
|
||||||
|
|
||||||
|
prepare_to_wait();
|
||||||
|
prepare_to_wait_exclusive();
|
||||||
|
|
||||||
|
which therefore also imply a general memory barrier after setting the state.
|
||||||
|
The whole sequence above is available in various canned forms, all of which
|
||||||
|
interpolate the memory barrier in the right place:
|
||||||
|
|
||||||
|
wait_event();
|
||||||
|
wait_event_interruptible();
|
||||||
|
wait_event_interruptible_exclusive();
|
||||||
|
wait_event_interruptible_timeout();
|
||||||
|
wait_event_killable();
|
||||||
|
wait_event_timeout();
|
||||||
|
wait_on_bit();
|
||||||
|
wait_on_bit_lock();
|
||||||
|
|
||||||
|
|
||||||
|
Secondly, code that performs a wake up normally follows something like this:
|
||||||
|
|
||||||
|
event_indicated = 1;
|
||||||
|
wake_up(&event_wait_queue);
|
||||||
|
|
||||||
|
or:
|
||||||
|
|
||||||
|
event_indicated = 1;
|
||||||
|
wake_up_process(event_daemon);
|
||||||
|
|
||||||
|
A write memory barrier is implied by wake_up() and co. if and only if they wake
|
||||||
|
something up. The barrier occurs before the task state is cleared, and so sits
|
||||||
|
between the STORE to indicate the event and the STORE to set TASK_RUNNING:
|
||||||
|
|
||||||
|
CPU 1 CPU 2
|
||||||
|
=============================== ===============================
|
||||||
|
set_current_state(); STORE event_indicated
|
||||||
|
set_mb(); wake_up();
|
||||||
|
STORE current->state <write barrier>
|
||||||
|
<general barrier> STORE current->state
|
||||||
|
LOAD event_indicated
|
||||||
|
|
||||||
|
The available waker functions include:
|
||||||
|
|
||||||
|
complete();
|
||||||
|
wake_up();
|
||||||
|
wake_up_all();
|
||||||
|
wake_up_bit();
|
||||||
|
wake_up_interruptible();
|
||||||
|
wake_up_interruptible_all();
|
||||||
|
wake_up_interruptible_nr();
|
||||||
|
wake_up_interruptible_poll();
|
||||||
|
wake_up_interruptible_sync();
|
||||||
|
wake_up_interruptible_sync_poll();
|
||||||
|
wake_up_locked();
|
||||||
|
wake_up_locked_poll();
|
||||||
|
wake_up_nr();
|
||||||
|
wake_up_poll();
|
||||||
|
wake_up_process();
|
||||||
|
|
||||||
|
|
||||||
|
[!] Note that the memory barriers implied by the sleeper and the waker do _not_
|
||||||
|
order multiple stores before the wake-up with respect to loads of those stored
|
||||||
|
values after the sleeper has called set_current_state(). For instance, if the
|
||||||
|
sleeper does:
|
||||||
|
|
||||||
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
if (event_indicated)
|
||||||
|
break;
|
||||||
|
__set_current_state(TASK_RUNNING);
|
||||||
|
do_something(my_data);
|
||||||
|
|
||||||
|
and the waker does:
|
||||||
|
|
||||||
|
my_data = value;
|
||||||
|
event_indicated = 1;
|
||||||
|
wake_up(&event_wait_queue);
|
||||||
|
|
||||||
|
there's no guarantee that the change to event_indicated will be perceived by
|
||||||
|
the sleeper as coming after the change to my_data. In such a circumstance, the
|
||||||
|
code on both sides must interpolate its own memory barriers between the
|
||||||
|
separate data accesses. Thus the above sleeper ought to do:
|
||||||
|
|
||||||
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
if (event_indicated) {
|
||||||
|
smp_rmb();
|
||||||
|
do_something(my_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
and the waker should do:
|
||||||
|
|
||||||
|
my_data = value;
|
||||||
|
smp_wmb();
|
||||||
|
event_indicated = 1;
|
||||||
|
wake_up(&event_wait_queue);
|
||||||
|
|
||||||
|
|
||||||
MISCELLANEOUS FUNCTIONS
|
MISCELLANEOUS FUNCTIONS
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
@ -1366,7 +1493,7 @@ WHERE ARE MEMORY BARRIERS NEEDED?
|
||||||
|
|
||||||
Under normal operation, memory operation reordering is generally not going to
|
Under normal operation, memory operation reordering is generally not going to
|
||||||
be a problem as a single-threaded linear piece of code will still appear to
|
be a problem as a single-threaded linear piece of code will still appear to
|
||||||
work correctly, even if it's in an SMP kernel. There are, however, three
|
work correctly, even if it's in an SMP kernel. There are, however, four
|
||||||
circumstances in which reordering definitely _could_ be a problem:
|
circumstances in which reordering definitely _could_ be a problem:
|
||||||
|
|
||||||
(*) Interprocessor interaction.
|
(*) Interprocessor interaction.
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
CONTENTS
|
CONTENTS
|
||||||
========
|
========
|
||||||
|
|
||||||
|
0. WARNING
|
||||||
1. Overview
|
1. Overview
|
||||||
1.1 The problem
|
1.1 The problem
|
||||||
1.2 The solution
|
1.2 The solution
|
||||||
|
@ -14,6 +15,23 @@ CONTENTS
|
||||||
3. Future plans
|
3. Future plans
|
||||||
|
|
||||||
|
|
||||||
|
0. WARNING
|
||||||
|
==========
|
||||||
|
|
||||||
|
Fiddling with these settings can result in an unstable system, the knobs are
|
||||||
|
root only and assumes root knows what he is doing.
|
||||||
|
|
||||||
|
Most notable:
|
||||||
|
|
||||||
|
* very small values in sched_rt_period_us can result in an unstable
|
||||||
|
system when the period is smaller than either the available hrtimer
|
||||||
|
resolution, or the time it takes to handle the budget refresh itself.
|
||||||
|
|
||||||
|
* very small values in sched_rt_runtime_us can result in an unstable
|
||||||
|
system when the runtime is so small the system has difficulty making
|
||||||
|
forward progress (NOTE: the migration thread and kstopmachine both
|
||||||
|
are real-time processes).
|
||||||
|
|
||||||
1. Overview
|
1. Overview
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
@ -169,7 +187,7 @@ get their allocated time.
|
||||||
|
|
||||||
Implementing SCHED_EDF might take a while to complete. Priority Inheritance is
|
Implementing SCHED_EDF might take a while to complete. Priority Inheritance is
|
||||||
the biggest challenge as the current linux PI infrastructure is geared towards
|
the biggest challenge as the current linux PI infrastructure is geared towards
|
||||||
the limited static priority levels 0-139. With deadline scheduling you need to
|
the limited static priority levels 0-99. With deadline scheduling you need to
|
||||||
do deadline inheritance (since priority is inversely proportional to the
|
do deadline inheritance (since priority is inversely proportional to the
|
||||||
deadline delta (deadline - now).
|
deadline delta (deadline - now).
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
Event Tracing
|
||||||
|
|
||||||
|
Documentation written by Theodore Ts'o
|
||||||
|
Updated by Li Zefan
|
||||||
|
|
||||||
|
1. Introduction
|
||||||
|
===============
|
||||||
|
|
||||||
|
Tracepoints (see Documentation/trace/tracepoints.txt) can be used
|
||||||
|
without creating custom kernel modules to register probe functions
|
||||||
|
using the event tracing infrastructure.
|
||||||
|
|
||||||
|
Not all tracepoints can be traced using the event tracing system;
|
||||||
|
the kernel developer must provide code snippets which define how the
|
||||||
|
tracing information is saved into the tracing buffer, and how the
|
||||||
|
tracing information should be printed.
|
||||||
|
|
||||||
|
2. Using Event Tracing
|
||||||
|
======================
|
||||||
|
|
||||||
|
2.1 Via the 'set_event' interface
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
The events which are available for tracing can be found in the file
|
||||||
|
/debug/tracing/available_events.
|
||||||
|
|
||||||
|
To enable a particular event, such as 'sched_wakeup', simply echo it
|
||||||
|
to /debug/tracing/set_event. For example:
|
||||||
|
|
||||||
|
# echo sched_wakeup >> /debug/tracing/set_event
|
||||||
|
|
||||||
|
[ Note: '>>' is necessary, otherwise it will firstly disable
|
||||||
|
all the events. ]
|
||||||
|
|
||||||
|
To disable an event, echo the event name to the set_event file prefixed
|
||||||
|
with an exclamation point:
|
||||||
|
|
||||||
|
# echo '!sched_wakeup' >> /debug/tracing/set_event
|
||||||
|
|
||||||
|
To disable all events, echo an empty line to the set_event file:
|
||||||
|
|
||||||
|
# echo > /debug/tracing/set_event
|
||||||
|
|
||||||
|
To enable all events, echo '*:*' or '*:' to the set_event file:
|
||||||
|
|
||||||
|
# echo *:* > /debug/tracing/set_event
|
||||||
|
|
||||||
|
The events are organized into subsystems, such as ext4, irq, sched,
|
||||||
|
etc., and a full event name looks like this: <subsystem>:<event>. The
|
||||||
|
subsystem name is optional, but it is displayed in the available_events
|
||||||
|
file. All of the events in a subsystem can be specified via the syntax
|
||||||
|
"<subsystem>:*"; for example, to enable all irq events, you can use the
|
||||||
|
command:
|
||||||
|
|
||||||
|
# echo 'irq:*' > /debug/tracing/set_event
|
||||||
|
|
||||||
|
2.2 Via the 'enable' toggle
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
The events available are also listed in /debug/tracing/events/ hierarchy
|
||||||
|
of directories.
|
||||||
|
|
||||||
|
To enable event 'sched_wakeup':
|
||||||
|
|
||||||
|
# echo 1 > /debug/tracing/events/sched/sched_wakeup/enable
|
||||||
|
|
||||||
|
To disable it:
|
||||||
|
|
||||||
|
# echo 0 > /debug/tracing/events/sched/sched_wakeup/enable
|
||||||
|
|
||||||
|
To enable all events in sched subsystem:
|
||||||
|
|
||||||
|
# echo 1 > /debug/tracing/events/sched/enable
|
||||||
|
|
||||||
|
To eanble all events:
|
||||||
|
|
||||||
|
# echo 1 > /debug/tracing/events/enable
|
||||||
|
|
||||||
|
When reading one of these enable files, there are four results:
|
||||||
|
|
||||||
|
0 - all events this file affects are disabled
|
||||||
|
1 - all events this file affects are enabled
|
||||||
|
X - there is a mixture of events enabled and disabled
|
||||||
|
? - this file does not affect any event
|
||||||
|
|
||||||
|
3. Defining an event-enabled tracepoint
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
See The example provided in samples/trace_events
|
||||||
|
|
|
@ -179,7 +179,7 @@ Here is the list of current tracers that may be configured.
|
||||||
|
|
||||||
Function call tracer to trace all kernel functions.
|
Function call tracer to trace all kernel functions.
|
||||||
|
|
||||||
"function_graph_tracer"
|
"function_graph"
|
||||||
|
|
||||||
Similar to the function tracer except that the
|
Similar to the function tracer except that the
|
||||||
function tracer probes the functions on their entry
|
function tracer probes the functions on their entry
|
||||||
|
@ -518,9 +518,18 @@ priority with zero (0) being the highest priority and the nice
|
||||||
values starting at 100 (nice -20). Below is a quick chart to map
|
values starting at 100 (nice -20). Below is a quick chart to map
|
||||||
the kernel priority to user land priorities.
|
the kernel priority to user land priorities.
|
||||||
|
|
||||||
Kernel priority: 0 to 99 ==> user RT priority 99 to 0
|
Kernel Space User Space
|
||||||
Kernel priority: 100 to 139 ==> user nice -20 to 19
|
===============================================================
|
||||||
Kernel priority: 140 ==> idle task priority
|
0(high) to 98(low) user RT priority 99(high) to 1(low)
|
||||||
|
with SCHED_RR or SCHED_FIFO
|
||||||
|
---------------------------------------------------------------
|
||||||
|
99 sched_priority is not used in scheduling
|
||||||
|
decisions(it must be specified as 0)
|
||||||
|
---------------------------------------------------------------
|
||||||
|
100(high) to 139(low) user nice -20(high) to 19(low)
|
||||||
|
---------------------------------------------------------------
|
||||||
|
140 idle task priority
|
||||||
|
---------------------------------------------------------------
|
||||||
|
|
||||||
The task states are:
|
The task states are:
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
The power tracer collects detailed information about C-state and P-state
|
||||||
|
transitions, instead of just looking at the high-level "average"
|
||||||
|
information.
|
||||||
|
|
||||||
|
There is a helper script found in scrips/tracing/power.pl in the kernel
|
||||||
|
sources which can be used to parse this information and create a
|
||||||
|
Scalable Vector Graphics (SVG) picture from the trace data.
|
||||||
|
|
||||||
|
To use this tracer:
|
||||||
|
|
||||||
|
echo 0 > /sys/kernel/debug/tracing/tracing_enabled
|
||||||
|
echo power > /sys/kernel/debug/tracing/current_tracer
|
||||||
|
echo 1 > /sys/kernel/debug/tracing/tracing_enabled
|
||||||
|
sleep 1
|
||||||
|
echo 0 > /sys/kernel/debug/tracing/tracing_enabled
|
||||||
|
cat /sys/kernel/debug/tracing/trace | \
|
||||||
|
perl scripts/tracing/power.pl > out.sv
|
|
@ -50,6 +50,10 @@ Protocol 2.08: (Kernel 2.6.26) Added crc32 checksum and ELF format
|
||||||
Protocol 2.09: (Kernel 2.6.26) Added a field of 64-bit physical
|
Protocol 2.09: (Kernel 2.6.26) Added a field of 64-bit physical
|
||||||
pointer to single linked list of struct setup_data.
|
pointer to single linked list of struct setup_data.
|
||||||
|
|
||||||
|
Protocol 2.10: (Kernel 2.6.31) Added a protocol for relaxed alignment
|
||||||
|
beyond the kernel_alignment added, new init_size and
|
||||||
|
pref_address fields. Added extended boot loader IDs.
|
||||||
|
|
||||||
**** MEMORY LAYOUT
|
**** MEMORY LAYOUT
|
||||||
|
|
||||||
The traditional memory map for the kernel loader, used for Image or
|
The traditional memory map for the kernel loader, used for Image or
|
||||||
|
@ -168,12 +172,13 @@ Offset Proto Name Meaning
|
||||||
021C/4 2.00+ ramdisk_size initrd size (set by boot loader)
|
021C/4 2.00+ ramdisk_size initrd size (set by boot loader)
|
||||||
0220/4 2.00+ bootsect_kludge DO NOT USE - for bootsect.S use only
|
0220/4 2.00+ bootsect_kludge DO NOT USE - for bootsect.S use only
|
||||||
0224/2 2.01+ heap_end_ptr Free memory after setup end
|
0224/2 2.01+ heap_end_ptr Free memory after setup end
|
||||||
0226/2 N/A pad1 Unused
|
0226/1 2.02+(3 ext_loader_ver Extended boot loader version
|
||||||
|
0227/1 2.02+(3 ext_loader_type Extended boot loader ID
|
||||||
0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line
|
0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line
|
||||||
022C/4 2.03+ ramdisk_max Highest legal initrd address
|
022C/4 2.03+ ramdisk_max Highest legal initrd address
|
||||||
0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel
|
0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel
|
||||||
0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not
|
0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not
|
||||||
0235/1 N/A pad2 Unused
|
0235/1 2.10+ min_alignment Minimum alignment, as a power of two
|
||||||
0236/2 N/A pad3 Unused
|
0236/2 N/A pad3 Unused
|
||||||
0238/4 2.06+ cmdline_size Maximum size of the kernel command line
|
0238/4 2.06+ cmdline_size Maximum size of the kernel command line
|
||||||
023C/4 2.07+ hardware_subarch Hardware subarchitecture
|
023C/4 2.07+ hardware_subarch Hardware subarchitecture
|
||||||
|
@ -182,6 +187,8 @@ Offset Proto Name Meaning
|
||||||
024C/4 2.08+ payload_length Length of kernel payload
|
024C/4 2.08+ payload_length Length of kernel payload
|
||||||
0250/8 2.09+ setup_data 64-bit physical pointer to linked list
|
0250/8 2.09+ setup_data 64-bit physical pointer to linked list
|
||||||
of struct setup_data
|
of struct setup_data
|
||||||
|
0258/8 2.10+ pref_address Preferred loading address
|
||||||
|
0260/4 2.10+ init_size Linear memory required during initialization
|
||||||
|
|
||||||
(1) For backwards compatibility, if the setup_sects field contains 0, the
|
(1) For backwards compatibility, if the setup_sects field contains 0, the
|
||||||
real value is 4.
|
real value is 4.
|
||||||
|
@ -190,6 +197,8 @@ Offset Proto Name Meaning
|
||||||
field are unusable, which means the size of a bzImage kernel
|
field are unusable, which means the size of a bzImage kernel
|
||||||
cannot be determined.
|
cannot be determined.
|
||||||
|
|
||||||
|
(3) Ignored, but safe to set, for boot protocols 2.02-2.09.
|
||||||
|
|
||||||
If the "HdrS" (0x53726448) magic number is not found at offset 0x202,
|
If the "HdrS" (0x53726448) magic number is not found at offset 0x202,
|
||||||
the boot protocol version is "old". Loading an old kernel, the
|
the boot protocol version is "old". Loading an old kernel, the
|
||||||
following parameters should be assumed:
|
following parameters should be assumed:
|
||||||
|
@ -343,18 +352,32 @@ Protocol: 2.00+
|
||||||
0xTV here, where T is an identifier for the boot loader and V is
|
0xTV here, where T is an identifier for the boot loader and V is
|
||||||
a version number. Otherwise, enter 0xFF here.
|
a version number. Otherwise, enter 0xFF here.
|
||||||
|
|
||||||
|
For boot loader IDs above T = 0xD, write T = 0xE to this field and
|
||||||
|
write the extended ID minus 0x10 to the ext_loader_type field.
|
||||||
|
Similarly, the ext_loader_ver field can be used to provide more than
|
||||||
|
four bits for the bootloader version.
|
||||||
|
|
||||||
|
For example, for T = 0x15, V = 0x234, write:
|
||||||
|
|
||||||
|
type_of_loader <- 0xE4
|
||||||
|
ext_loader_type <- 0x05
|
||||||
|
ext_loader_ver <- 0x23
|
||||||
|
|
||||||
Assigned boot loader ids:
|
Assigned boot loader ids:
|
||||||
0 LILO (0x00 reserved for pre-2.00 bootloader)
|
0 LILO (0x00 reserved for pre-2.00 bootloader)
|
||||||
1 Loadlin
|
1 Loadlin
|
||||||
2 bootsect-loader (0x20, all other values reserved)
|
2 bootsect-loader (0x20, all other values reserved)
|
||||||
3 SYSLINUX
|
3 Syslinux
|
||||||
4 EtherBoot
|
4 Etherboot/gPXE
|
||||||
5 ELILO
|
5 ELILO
|
||||||
7 GRUB
|
7 GRUB
|
||||||
8 U-BOOT
|
8 U-Boot
|
||||||
9 Xen
|
9 Xen
|
||||||
A Gujin
|
A Gujin
|
||||||
B Qemu
|
B Qemu
|
||||||
|
C Arcturus Networks uCbootloader
|
||||||
|
E Extended (see ext_loader_type)
|
||||||
|
F Special (0xFF = undefined)
|
||||||
|
|
||||||
Please contact <hpa@zytor.com> if you need a bootloader ID
|
Please contact <hpa@zytor.com> if you need a bootloader ID
|
||||||
value assigned.
|
value assigned.
|
||||||
|
@ -453,6 +476,35 @@ Protocol: 2.01+
|
||||||
Set this field to the offset (from the beginning of the real-mode
|
Set this field to the offset (from the beginning of the real-mode
|
||||||
code) of the end of the setup stack/heap, minus 0x0200.
|
code) of the end of the setup stack/heap, minus 0x0200.
|
||||||
|
|
||||||
|
Field name: ext_loader_ver
|
||||||
|
Type: write (optional)
|
||||||
|
Offset/size: 0x226/1
|
||||||
|
Protocol: 2.02+
|
||||||
|
|
||||||
|
This field is used as an extension of the version number in the
|
||||||
|
type_of_loader field. The total version number is considered to be
|
||||||
|
(type_of_loader & 0x0f) + (ext_loader_ver << 4).
|
||||||
|
|
||||||
|
The use of this field is boot loader specific. If not written, it
|
||||||
|
is zero.
|
||||||
|
|
||||||
|
Kernels prior to 2.6.31 did not recognize this field, but it is safe
|
||||||
|
to write for protocol version 2.02 or higher.
|
||||||
|
|
||||||
|
Field name: ext_loader_type
|
||||||
|
Type: write (obligatory if (type_of_loader & 0xf0) == 0xe0)
|
||||||
|
Offset/size: 0x227/1
|
||||||
|
Protocol: 2.02+
|
||||||
|
|
||||||
|
This field is used as an extension of the type number in
|
||||||
|
type_of_loader field. If the type in type_of_loader is 0xE, then
|
||||||
|
the actual type is (ext_loader_type + 0x10).
|
||||||
|
|
||||||
|
This field is ignored if the type in type_of_loader is not 0xE.
|
||||||
|
|
||||||
|
Kernels prior to 2.6.31 did not recognize this field, but it is safe
|
||||||
|
to write for protocol version 2.02 or higher.
|
||||||
|
|
||||||
Field name: cmd_line_ptr
|
Field name: cmd_line_ptr
|
||||||
Type: write (obligatory)
|
Type: write (obligatory)
|
||||||
Offset/size: 0x228/4
|
Offset/size: 0x228/4
|
||||||
|
@ -482,11 +534,19 @@ Protocol: 2.03+
|
||||||
0x37FFFFFF, you can start your ramdisk at 0x37FE0000.)
|
0x37FFFFFF, you can start your ramdisk at 0x37FE0000.)
|
||||||
|
|
||||||
Field name: kernel_alignment
|
Field name: kernel_alignment
|
||||||
Type: read (reloc)
|
Type: read/modify (reloc)
|
||||||
Offset/size: 0x230/4
|
Offset/size: 0x230/4
|
||||||
Protocol: 2.05+
|
Protocol: 2.05+ (read), 2.10+ (modify)
|
||||||
|
|
||||||
Alignment unit required by the kernel (if relocatable_kernel is true.)
|
Alignment unit required by the kernel (if relocatable_kernel is
|
||||||
|
true.) A relocatable kernel that is loaded at an alignment
|
||||||
|
incompatible with the value in this field will be realigned during
|
||||||
|
kernel initialization.
|
||||||
|
|
||||||
|
Starting with protocol version 2.10, this reflects the kernel
|
||||||
|
alignment preferred for optimal performance; it is possible for the
|
||||||
|
loader to modify this field to permit a lesser alignment. See the
|
||||||
|
min_alignment and pref_address field below.
|
||||||
|
|
||||||
Field name: relocatable_kernel
|
Field name: relocatable_kernel
|
||||||
Type: read (reloc)
|
Type: read (reloc)
|
||||||
|
@ -498,6 +558,22 @@ Protocol: 2.05+
|
||||||
After loading, the boot loader must set the code32_start field to
|
After loading, the boot loader must set the code32_start field to
|
||||||
point to the loaded code, or to a boot loader hook.
|
point to the loaded code, or to a boot loader hook.
|
||||||
|
|
||||||
|
Field name: min_alignment
|
||||||
|
Type: read (reloc)
|
||||||
|
Offset/size: 0x235/1
|
||||||
|
Protocol: 2.10+
|
||||||
|
|
||||||
|
This field, if nonzero, indicates as a power of two the minimum
|
||||||
|
alignment required, as opposed to preferred, by the kernel to boot.
|
||||||
|
If a boot loader makes use of this field, it should update the
|
||||||
|
kernel_alignment field with the alignment unit desired; typically:
|
||||||
|
|
||||||
|
kernel_alignment = 1 << min_alignment
|
||||||
|
|
||||||
|
There may be a considerable performance cost with an excessively
|
||||||
|
misaligned kernel. Therefore, a loader should typically try each
|
||||||
|
power-of-two alignment from kernel_alignment down to this alignment.
|
||||||
|
|
||||||
Field name: cmdline_size
|
Field name: cmdline_size
|
||||||
Type: read
|
Type: read
|
||||||
Offset/size: 0x238/4
|
Offset/size: 0x238/4
|
||||||
|
@ -582,6 +658,36 @@ Protocol: 2.09+
|
||||||
sure to consider the case where the linked list already contains
|
sure to consider the case where the linked list already contains
|
||||||
entries.
|
entries.
|
||||||
|
|
||||||
|
Field name: pref_address
|
||||||
|
Type: read (reloc)
|
||||||
|
Offset/size: 0x258/8
|
||||||
|
Protocol: 2.10+
|
||||||
|
|
||||||
|
This field, if nonzero, represents a preferred load address for the
|
||||||
|
kernel. A relocating bootloader should attempt to load at this
|
||||||
|
address if possible.
|
||||||
|
|
||||||
|
A non-relocatable kernel will unconditionally move itself and to run
|
||||||
|
at this address.
|
||||||
|
|
||||||
|
Field name: init_size
|
||||||
|
Type: read
|
||||||
|
Offset/size: 0x25c/4
|
||||||
|
|
||||||
|
This field indicates the amount of linear contiguous memory starting
|
||||||
|
at the kernel runtime start address that the kernel needs before it
|
||||||
|
is capable of examining its memory map. This is not the same thing
|
||||||
|
as the total amount of memory the kernel needs to boot, but it can
|
||||||
|
be used by a relocating boot loader to help select a safe load
|
||||||
|
address for the kernel.
|
||||||
|
|
||||||
|
The kernel runtime start address is determined by the following algorithm:
|
||||||
|
|
||||||
|
if (relocatable_kernel)
|
||||||
|
runtime_start = align_up(load_address, kernel_alignment)
|
||||||
|
else
|
||||||
|
runtime_start = pref_address
|
||||||
|
|
||||||
|
|
||||||
**** THE IMAGE CHECKSUM
|
**** THE IMAGE CHECKSUM
|
||||||
|
|
||||||
|
|
|
@ -150,11 +150,6 @@ NUMA
|
||||||
Otherwise, the remaining system RAM is allocated to an
|
Otherwise, the remaining system RAM is allocated to an
|
||||||
additional node.
|
additional node.
|
||||||
|
|
||||||
numa=hotadd=percent
|
|
||||||
Only allow hotadd memory to preallocate page structures upto
|
|
||||||
percent of already available memory.
|
|
||||||
numa=hotadd=0 will disable hotadd memory.
|
|
||||||
|
|
||||||
ACPI
|
ACPI
|
||||||
|
|
||||||
acpi=off Don't enable ACPI
|
acpi=off Don't enable ACPI
|
||||||
|
|
|
@ -6,10 +6,11 @@ Virtual memory map with 4 level page tables:
|
||||||
0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm
|
0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm
|
||||||
hole caused by [48:63] sign extension
|
hole caused by [48:63] sign extension
|
||||||
ffff800000000000 - ffff80ffffffffff (=40 bits) guard hole
|
ffff800000000000 - ffff80ffffffffff (=40 bits) guard hole
|
||||||
ffff880000000000 - ffffc0ffffffffff (=57 TB) direct mapping of all phys. memory
|
ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory
|
||||||
ffffc10000000000 - ffffc1ffffffffff (=40 bits) hole
|
ffffc80000000000 - ffffc8ffffffffff (=40 bits) hole
|
||||||
ffffc20000000000 - ffffe1ffffffffff (=45 bits) vmalloc/ioremap space
|
ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
|
||||||
ffffe20000000000 - ffffe2ffffffffff (=40 bits) virtual memory map (1TB)
|
ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
|
||||||
|
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
|
||||||
... unused hole ...
|
... unused hole ...
|
||||||
ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
|
ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
|
||||||
ffffffffa0000000 - fffffffffff00000 (=1536 MB) module mapping space
|
ffffffffa0000000 - fffffffffff00000 (=1536 MB) module mapping space
|
||||||
|
|
10
MAINTAINERS
10
MAINTAINERS
|
@ -4392,6 +4392,16 @@ S: Maintained
|
||||||
F: include/linux/delayacct.h
|
F: include/linux/delayacct.h
|
||||||
F: kernel/delayacct.c
|
F: kernel/delayacct.c
|
||||||
|
|
||||||
|
PERFORMANCE COUNTER SUBSYSTEM
|
||||||
|
P: Peter Zijlstra
|
||||||
|
M: a.p.zijlstra@chello.nl
|
||||||
|
P: Paul Mackerras
|
||||||
|
M: paulus@samba.org
|
||||||
|
P: Ingo Molnar
|
||||||
|
M: mingo@elte.hu
|
||||||
|
L: linux-kernel@vger.kernel.org
|
||||||
|
S: Supported
|
||||||
|
|
||||||
PERSONALITY HANDLING
|
PERSONALITY HANDLING
|
||||||
P: Christoph Hellwig
|
P: Christoph Hellwig
|
||||||
M: hch@infradead.org
|
M: hch@infradead.org
|
||||||
|
|
|
@ -176,22 +176,26 @@ cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
dp264_set_affinity(unsigned int irq, const struct cpumask *affinity)
|
dp264_set_affinity(unsigned int irq, const struct cpumask *affinity)
|
||||||
{
|
{
|
||||||
spin_lock(&dp264_irq_lock);
|
spin_lock(&dp264_irq_lock);
|
||||||
cpu_set_irq_affinity(irq, *affinity);
|
cpu_set_irq_affinity(irq, *affinity);
|
||||||
tsunami_update_irq_hw(cached_irq_mask);
|
tsunami_update_irq_hw(cached_irq_mask);
|
||||||
spin_unlock(&dp264_irq_lock);
|
spin_unlock(&dp264_irq_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)
|
clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)
|
||||||
{
|
{
|
||||||
spin_lock(&dp264_irq_lock);
|
spin_lock(&dp264_irq_lock);
|
||||||
cpu_set_irq_affinity(irq - 16, *affinity);
|
cpu_set_irq_affinity(irq - 16, *affinity);
|
||||||
tsunami_update_irq_hw(cached_irq_mask);
|
tsunami_update_irq_hw(cached_irq_mask);
|
||||||
spin_unlock(&dp264_irq_lock);
|
spin_unlock(&dp264_irq_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hw_interrupt_type dp264_irq_type = {
|
static struct hw_interrupt_type dp264_irq_type = {
|
||||||
|
|
|
@ -157,13 +157,15 @@ titan_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
titan_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
|
titan_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
|
||||||
{
|
{
|
||||||
spin_lock(&titan_irq_lock);
|
spin_lock(&titan_irq_lock);
|
||||||
titan_cpu_set_irq_affinity(irq - 16, *affinity);
|
titan_cpu_set_irq_affinity(irq - 16, *affinity);
|
||||||
titan_update_irq_hw(titan_cached_irq_mask);
|
titan_update_irq_hw(titan_cached_irq_mask);
|
||||||
spin_unlock(&titan_irq_lock);
|
spin_unlock(&titan_irq_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -109,7 +109,7 @@ static void gic_unmask_irq(unsigned int irq)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
|
static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
|
||||||
{
|
{
|
||||||
void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3);
|
void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3);
|
||||||
unsigned int shift = (irq % 4) * 8;
|
unsigned int shift = (irq % 4) * 8;
|
||||||
|
@ -122,6 +122,8 @@ static void gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
|
||||||
val |= 1 << (cpu + shift);
|
val |= 1 << (cpu + shift);
|
||||||
writel(val, reg);
|
writel(val, reg);
|
||||||
spin_unlock(&irq_controller_lock);
|
spin_unlock(&irq_controller_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -325,12 +325,14 @@ static void end_crisv32_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_affinity_crisv32_irq(unsigned int irq, const struct cpumask *dest)
|
int set_affinity_crisv32_irq(unsigned int irq, const struct cpumask *dest)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
spin_lock_irqsave(&irq_lock, flags);
|
spin_lock_irqsave(&irq_lock, flags);
|
||||||
irq_allocations[irq - FIRST_IRQ].mask = *dest;
|
irq_allocations[irq - FIRST_IRQ].mask = *dest;
|
||||||
spin_unlock_irqrestore(&irq_lock, flags);
|
spin_unlock_irqrestore(&irq_lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct irq_chip crisv32_irq_type = {
|
static struct irq_chip crisv32_irq_type = {
|
||||||
|
|
|
@ -21,9 +21,10 @@ hpsim_irq_noop (unsigned int irq)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
hpsim_set_affinity_noop(unsigned int a, const struct cpumask *b)
|
hpsim_set_affinity_noop(unsigned int a, const struct cpumask *b)
|
||||||
{
|
{
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hw_interrupt_type irq_type_hp_sim = {
|
static struct hw_interrupt_type irq_type_hp_sim = {
|
||||||
|
|
|
@ -636,7 +636,7 @@ void __init acpi_numa_arch_fixup(void)
|
||||||
* success: return IRQ number (>=0)
|
* success: return IRQ number (>=0)
|
||||||
* failure: return < 0
|
* failure: return < 0
|
||||||
*/
|
*/
|
||||||
int acpi_register_gsi(u32 gsi, int triggering, int polarity)
|
int acpi_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity)
|
||||||
{
|
{
|
||||||
if (acpi_irq_model == ACPI_IRQ_MODEL_PLATFORM)
|
if (acpi_irq_model == ACPI_IRQ_MODEL_PLATFORM)
|
||||||
return gsi;
|
return gsi;
|
||||||
|
@ -678,7 +678,8 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
|
||||||
|
|
||||||
fadt = (struct acpi_table_fadt *)fadt_header;
|
fadt = (struct acpi_table_fadt *)fadt_header;
|
||||||
|
|
||||||
acpi_register_gsi(fadt->sci_interrupt, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
|
acpi_register_gsi(NULL, fadt->sci_interrupt, ACPI_LEVEL_SENSITIVE,
|
||||||
|
ACPI_ACTIVE_LOW);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -329,7 +329,7 @@ unmask_irq (unsigned int irq)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static int
|
||||||
iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
|
iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
@ -343,15 +343,15 @@ iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
|
|
||||||
cpu = cpumask_first_and(cpu_online_mask, mask);
|
cpu = cpumask_first_and(cpu_online_mask, mask);
|
||||||
if (cpu >= nr_cpu_ids)
|
if (cpu >= nr_cpu_ids)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
if (irq_prepare_move(irq, cpu))
|
if (irq_prepare_move(irq, cpu))
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
dest = cpu_physical_id(cpu);
|
dest = cpu_physical_id(cpu);
|
||||||
|
|
||||||
if (!iosapic_intr_info[irq].count)
|
if (!iosapic_intr_info[irq].count)
|
||||||
return; /* not an IOSAPIC interrupt */
|
return -1; /* not an IOSAPIC interrupt */
|
||||||
|
|
||||||
set_irq_affinity_info(irq, dest, redir);
|
set_irq_affinity_info(irq, dest, redir);
|
||||||
|
|
||||||
|
@ -376,7 +376,9 @@ iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
iosapic_write(iosapic, IOSAPIC_RTE_HIGH(rte_index), high32);
|
iosapic_write(iosapic, IOSAPIC_RTE_HIGH(rte_index), high32);
|
||||||
iosapic_write(iosapic, IOSAPIC_RTE_LOW(rte_index), low32);
|
iosapic_write(iosapic, IOSAPIC_RTE_LOW(rte_index), low32);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
static struct irq_chip ia64_msi_chip;
|
static struct irq_chip ia64_msi_chip;
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void ia64_set_msi_irq_affinity(unsigned int irq,
|
static int ia64_set_msi_irq_affinity(unsigned int irq,
|
||||||
const cpumask_t *cpu_mask)
|
const cpumask_t *cpu_mask)
|
||||||
{
|
{
|
||||||
struct msi_msg msg;
|
struct msi_msg msg;
|
||||||
|
@ -20,10 +20,10 @@ static void ia64_set_msi_irq_affinity(unsigned int irq,
|
||||||
int cpu = first_cpu(*cpu_mask);
|
int cpu = first_cpu(*cpu_mask);
|
||||||
|
|
||||||
if (!cpu_online(cpu))
|
if (!cpu_online(cpu))
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
if (irq_prepare_move(irq, cpu))
|
if (irq_prepare_move(irq, cpu))
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
read_msi_msg(irq, &msg);
|
read_msi_msg(irq, &msg);
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@ static void ia64_set_msi_irq_affinity(unsigned int irq,
|
||||||
|
|
||||||
write_msi_msg(irq, &msg);
|
write_msi_msg(irq, &msg);
|
||||||
cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
|
cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
|
@ -130,17 +132,17 @@ void arch_teardown_msi_irq(unsigned int irq)
|
||||||
|
|
||||||
#ifdef CONFIG_DMAR
|
#ifdef CONFIG_DMAR
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
|
static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
{
|
{
|
||||||
struct irq_cfg *cfg = irq_cfg + irq;
|
struct irq_cfg *cfg = irq_cfg + irq;
|
||||||
struct msi_msg msg;
|
struct msi_msg msg;
|
||||||
int cpu = cpumask_first(mask);
|
int cpu = cpumask_first(mask);
|
||||||
|
|
||||||
if (!cpu_online(cpu))
|
if (!cpu_online(cpu))
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
if (irq_prepare_move(irq, cpu))
|
if (irq_prepare_move(irq, cpu))
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
dmar_msi_read(irq, &msg);
|
dmar_msi_read(irq, &msg);
|
||||||
|
|
||||||
|
@ -151,6 +153,8 @@ static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
|
|
||||||
dmar_msi_write(irq, &msg);
|
dmar_msi_write(irq, &msg);
|
||||||
cpumask_copy(irq_desc[irq].affinity, mask);
|
cpumask_copy(irq_desc[irq].affinity, mask);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,7 @@ finish_up:
|
||||||
return new_irq_info;
|
return new_irq_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
|
static int sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
|
||||||
{
|
{
|
||||||
struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
|
struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
|
||||||
nasid_t nasid;
|
nasid_t nasid;
|
||||||
|
@ -239,6 +239,8 @@ static void sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
|
||||||
list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
|
list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
|
||||||
sn_irq_lh[irq], list)
|
sn_irq_lh[irq], list)
|
||||||
(void)sn_retarget_vector(sn_irq_info, nasid, slice);
|
(void)sn_retarget_vector(sn_irq_info, nasid, slice);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
|
|
@ -151,7 +151,7 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void sn_set_msi_irq_affinity(unsigned int irq,
|
static int sn_set_msi_irq_affinity(unsigned int irq,
|
||||||
const struct cpumask *cpu_mask)
|
const struct cpumask *cpu_mask)
|
||||||
{
|
{
|
||||||
struct msi_msg msg;
|
struct msi_msg msg;
|
||||||
|
@ -168,7 +168,7 @@ static void sn_set_msi_irq_affinity(unsigned int irq,
|
||||||
cpu = cpumask_first(cpu_mask);
|
cpu = cpumask_first(cpu_mask);
|
||||||
sn_irq_info = sn_msi_info[irq].sn_irq_info;
|
sn_irq_info = sn_msi_info[irq].sn_irq_info;
|
||||||
if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
|
if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release XIO resources for the old MSI PCI address
|
* Release XIO resources for the old MSI PCI address
|
||||||
|
@ -189,7 +189,7 @@ static void sn_set_msi_irq_affinity(unsigned int irq,
|
||||||
new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice);
|
new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice);
|
||||||
sn_msi_info[irq].sn_irq_info = new_irq_info;
|
sn_msi_info[irq].sn_irq_info = new_irq_info;
|
||||||
if (new_irq_info == NULL)
|
if (new_irq_info == NULL)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map the xio address into bus space
|
* Map the xio address into bus space
|
||||||
|
@ -206,6 +206,8 @@ static void sn_set_msi_irq_affinity(unsigned int irq,
|
||||||
|
|
||||||
write_msi_msg(irq, &msg);
|
write_msi_msg(irq, &msg);
|
||||||
cpumask_copy(irq_desc[irq].affinity, cpu_mask);
|
cpumask_copy(irq_desc[irq].affinity, cpu_mask);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,7 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
|
static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
|
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
|
||||||
|
@ -199,6 +199,8 @@ static void octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask
|
||||||
*/
|
*/
|
||||||
cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
|
cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
|
||||||
write_unlock(&octeon_irq_ciu0_rwlock);
|
write_unlock(&octeon_irq_ciu0_rwlock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -292,7 +294,7 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest)
|
static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
|
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
|
||||||
|
@ -315,6 +317,8 @@ static void octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask
|
||||||
*/
|
*/
|
||||||
cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
|
cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
|
||||||
write_unlock(&octeon_irq_ciu1_rwlock);
|
write_unlock(&octeon_irq_ciu1_rwlock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ static inline void smtc_im_ack_irq(unsigned int irq)
|
||||||
#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
|
#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
|
|
||||||
extern void plat_set_irq_affinity(unsigned int irq,
|
extern int plat_set_irq_affinity(unsigned int irq,
|
||||||
const struct cpumask *affinity);
|
const struct cpumask *affinity);
|
||||||
extern void smtc_forward_irq(unsigned int irq);
|
extern void smtc_forward_irq(unsigned int irq);
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ static void gic_unmask_irq(unsigned int irq)
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(gic_lock);
|
static DEFINE_SPINLOCK(gic_lock);
|
||||||
|
|
||||||
static void gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||||
{
|
{
|
||||||
cpumask_t tmp = CPU_MASK_NONE;
|
cpumask_t tmp = CPU_MASK_NONE;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -166,7 +166,7 @@ static void gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||||
|
|
||||||
cpumask_and(&tmp, cpumask, cpu_online_mask);
|
cpumask_and(&tmp, cpumask, cpu_online_mask);
|
||||||
if (cpus_empty(tmp))
|
if (cpus_empty(tmp))
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
/* Assumption : cpumask refers to a single CPU */
|
/* Assumption : cpumask refers to a single CPU */
|
||||||
spin_lock_irqsave(&gic_lock, flags);
|
spin_lock_irqsave(&gic_lock, flags);
|
||||||
|
@ -190,6 +190,7 @@ static void gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||||
cpumask_copy(irq_desc[irq].affinity, cpumask);
|
cpumask_copy(irq_desc[irq].affinity, cpumask);
|
||||||
spin_unlock_irqrestore(&gic_lock, flags);
|
spin_unlock_irqrestore(&gic_lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ struct plat_smp_ops msmtc_smp_ops = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
|
int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
|
||||||
{
|
{
|
||||||
cpumask_t tmask;
|
cpumask_t tmask;
|
||||||
int cpu = 0;
|
int cpu = 0;
|
||||||
|
@ -156,5 +156,7 @@ void plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
|
||||||
|
|
||||||
/* Do any generic SMTC IRQ affinity setup */
|
/* Do any generic SMTC IRQ affinity setup */
|
||||||
smtc_set_irq_affinity(irq, tmask);
|
smtc_set_irq_affinity(irq, tmask);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
|
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
|
||||||
|
|
|
@ -50,7 +50,7 @@ static void enable_bcm1480_irq(unsigned int irq);
|
||||||
static void disable_bcm1480_irq(unsigned int irq);
|
static void disable_bcm1480_irq(unsigned int irq);
|
||||||
static void ack_bcm1480_irq(unsigned int irq);
|
static void ack_bcm1480_irq(unsigned int irq);
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask);
|
static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
|
@ -109,7 +109,7 @@ void bcm1480_unmask_irq(int cpu, int irq)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
|
static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
{
|
{
|
||||||
int i = 0, old_cpu, cpu, int_on, k;
|
int i = 0, old_cpu, cpu, int_on, k;
|
||||||
u64 cur_ints;
|
u64 cur_ints;
|
||||||
|
@ -118,7 +118,7 @@ static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
|
|
||||||
if (cpumask_weight(mask) != 1) {
|
if (cpumask_weight(mask) != 1) {
|
||||||
printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
|
printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
i = cpumask_first(mask);
|
i = cpumask_first(mask);
|
||||||
|
|
||||||
|
@ -152,6 +152,8 @@ static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
|
spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ static void enable_sb1250_irq(unsigned int irq);
|
||||||
static void disable_sb1250_irq(unsigned int irq);
|
static void disable_sb1250_irq(unsigned int irq);
|
||||||
static void ack_sb1250_irq(unsigned int irq);
|
static void ack_sb1250_irq(unsigned int irq);
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask);
|
static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SIBYTE_HAS_LDT
|
#ifdef CONFIG_SIBYTE_HAS_LDT
|
||||||
|
@ -103,7 +103,7 @@ void sb1250_unmask_irq(int cpu, int irq)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
|
static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
{
|
{
|
||||||
int i = 0, old_cpu, cpu, int_on;
|
int i = 0, old_cpu, cpu, int_on;
|
||||||
u64 cur_ints;
|
u64 cur_ints;
|
||||||
|
@ -113,7 +113,7 @@ static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
|
|
||||||
if (cpumask_weight(mask) > 1) {
|
if (cpumask_weight(mask) > 1) {
|
||||||
printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
|
printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert logical CPU to physical CPU */
|
/* Convert logical CPU to physical CPU */
|
||||||
|
@ -143,6 +143,8 @@ static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||||
R_IMR_INTERRUPT_MASK));
|
R_IMR_INTERRUPT_MASK));
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&sb1250_imr_lock, flags);
|
spin_unlock_irqrestore(&sb1250_imr_lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -130,15 +130,17 @@ int cpu_check_affinity(unsigned int irq, const struct cpumask *dest)
|
||||||
return cpu_dest;
|
return cpu_dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest)
|
static int cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest)
|
||||||
{
|
{
|
||||||
int cpu_dest;
|
int cpu_dest;
|
||||||
|
|
||||||
cpu_dest = cpu_check_affinity(irq, dest);
|
cpu_dest = cpu_check_affinity(irq, dest);
|
||||||
if (cpu_dest < 0)
|
if (cpu_dest < 0)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
cpumask_copy(&irq_desc[irq].affinity, dest);
|
cpumask_copy(&irq_desc[irq].affinity, dest);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -131,5 +131,44 @@ static inline int irqs_disabled_flags(unsigned long flags)
|
||||||
*/
|
*/
|
||||||
struct irq_chip;
|
struct irq_chip;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PERF_COUNTERS
|
||||||
|
static inline unsigned long test_perf_counter_pending(void)
|
||||||
|
{
|
||||||
|
unsigned long x;
|
||||||
|
|
||||||
|
asm volatile("lbz %0,%1(13)"
|
||||||
|
: "=r" (x)
|
||||||
|
: "i" (offsetof(struct paca_struct, perf_counter_pending)));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_perf_counter_pending(void)
|
||||||
|
{
|
||||||
|
asm volatile("stb %0,%1(13)" : :
|
||||||
|
"r" (1),
|
||||||
|
"i" (offsetof(struct paca_struct, perf_counter_pending)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void clear_perf_counter_pending(void)
|
||||||
|
{
|
||||||
|
asm volatile("stb %0,%1(13)" : :
|
||||||
|
"r" (0),
|
||||||
|
"i" (offsetof(struct paca_struct, perf_counter_pending)));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void perf_counter_do_pending(void);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline unsigned long test_perf_counter_pending(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_perf_counter_pending(void) {}
|
||||||
|
static inline void clear_perf_counter_pending(void) {}
|
||||||
|
static inline void perf_counter_do_pending(void) {}
|
||||||
|
#endif /* CONFIG_PERF_COUNTERS */
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* _ASM_POWERPC_HW_IRQ_H */
|
#endif /* _ASM_POWERPC_HW_IRQ_H */
|
||||||
|
|
|
@ -99,6 +99,7 @@ struct paca_struct {
|
||||||
u8 soft_enabled; /* irq soft-enable flag */
|
u8 soft_enabled; /* irq soft-enable flag */
|
||||||
u8 hard_enabled; /* set if irqs are enabled in MSR */
|
u8 hard_enabled; /* set if irqs are enabled in MSR */
|
||||||
u8 io_sync; /* writel() needs spin_unlock sync */
|
u8 io_sync; /* writel() needs spin_unlock sync */
|
||||||
|
u8 perf_counter_pending; /* PM interrupt while soft-disabled */
|
||||||
|
|
||||||
/* Stuff for accurate time accounting */
|
/* Stuff for accurate time accounting */
|
||||||
u64 user_time; /* accumulated usermode TB ticks */
|
u64 user_time; /* accumulated usermode TB ticks */
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Performance counter support - PowerPC-specific definitions.
|
||||||
|
*
|
||||||
|
* Copyright 2008-2009 Paul Mackerras, IBM Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#define MAX_HWCOUNTERS 8
|
||||||
|
#define MAX_EVENT_ALTERNATIVES 8
|
||||||
|
#define MAX_LIMITED_HWCOUNTERS 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This struct provides the constants and functions needed to
|
||||||
|
* describe the PMU on a particular POWER-family CPU.
|
||||||
|
*/
|
||||||
|
struct power_pmu {
|
||||||
|
int n_counter;
|
||||||
|
int max_alternatives;
|
||||||
|
u64 add_fields;
|
||||||
|
u64 test_adder;
|
||||||
|
int (*compute_mmcr)(u64 events[], int n_ev,
|
||||||
|
unsigned int hwc[], u64 mmcr[]);
|
||||||
|
int (*get_constraint)(u64 event, u64 *mskp, u64 *valp);
|
||||||
|
int (*get_alternatives)(u64 event, unsigned int flags,
|
||||||
|
u64 alt[]);
|
||||||
|
void (*disable_pmc)(unsigned int pmc, u64 mmcr[]);
|
||||||
|
int (*limited_pmc_event)(u64 event);
|
||||||
|
u32 flags;
|
||||||
|
int n_generic;
|
||||||
|
int *generic_events;
|
||||||
|
int (*cache_events)[PERF_COUNT_HW_CACHE_MAX]
|
||||||
|
[PERF_COUNT_HW_CACHE_OP_MAX]
|
||||||
|
[PERF_COUNT_HW_CACHE_RESULT_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct power_pmu *ppmu;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values for power_pmu.flags
|
||||||
|
*/
|
||||||
|
#define PPMU_LIMITED_PMC5_6 1 /* PMC5/6 have limited function */
|
||||||
|
#define PPMU_ALT_SIPR 2 /* uses alternate posn for SIPR/HV */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values for flags to get_alternatives()
|
||||||
|
*/
|
||||||
|
#define PPMU_LIMITED_PMC_OK 1 /* can put this on a limited PMC */
|
||||||
|
#define PPMU_LIMITED_PMC_REQD 2 /* have to put this on a limited PMC */
|
||||||
|
#define PPMU_ONLY_COUNT_RUN 4 /* only counting in run state */
|
||||||
|
|
||||||
|
struct pt_regs;
|
||||||
|
extern unsigned long perf_misc_flags(struct pt_regs *regs);
|
||||||
|
#define perf_misc_flags(regs) perf_misc_flags(regs)
|
||||||
|
|
||||||
|
extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The power_pmu.get_constraint function returns a 64-bit value and
|
||||||
|
* a 64-bit mask that express the constraints between this event and
|
||||||
|
* other events.
|
||||||
|
*
|
||||||
|
* The value and mask are divided up into (non-overlapping) bitfields
|
||||||
|
* of three different types:
|
||||||
|
*
|
||||||
|
* Select field: this expresses the constraint that some set of bits
|
||||||
|
* in MMCR* needs to be set to a specific value for this event. For a
|
||||||
|
* select field, the mask contains 1s in every bit of the field, and
|
||||||
|
* the value contains a unique value for each possible setting of the
|
||||||
|
* MMCR* bits. The constraint checking code will ensure that two events
|
||||||
|
* that set the same field in their masks have the same value in their
|
||||||
|
* value dwords.
|
||||||
|
*
|
||||||
|
* Add field: this expresses the constraint that there can be at most
|
||||||
|
* N events in a particular class. A field of k bits can be used for
|
||||||
|
* N <= 2^(k-1) - 1. The mask has the most significant bit of the field
|
||||||
|
* set (and the other bits 0), and the value has only the least significant
|
||||||
|
* bit of the field set. In addition, the 'add_fields' and 'test_adder'
|
||||||
|
* in the struct power_pmu for this processor come into play. The
|
||||||
|
* add_fields value contains 1 in the LSB of the field, and the
|
||||||
|
* test_adder contains 2^(k-1) - 1 - N in the field.
|
||||||
|
*
|
||||||
|
* NAND field: this expresses the constraint that you may not have events
|
||||||
|
* in all of a set of classes. (For example, on PPC970, you can't select
|
||||||
|
* events from the FPU, ISU and IDU simultaneously, although any two are
|
||||||
|
* possible.) For N classes, the field is N+1 bits wide, and each class
|
||||||
|
* is assigned one bit from the least-significant N bits. The mask has
|
||||||
|
* only the most-significant bit set, and the value has only the bit
|
||||||
|
* for the event's class set. The test_adder has the least significant
|
||||||
|
* bit set in the field.
|
||||||
|
*
|
||||||
|
* If an event is not subject to the constraint expressed by a particular
|
||||||
|
* field, then it will have 0 in both the mask and value for that field.
|
||||||
|
*/
|
|
@ -492,11 +492,13 @@
|
||||||
#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
|
#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
|
||||||
#define SPRN_MMCR1 798
|
#define SPRN_MMCR1 798
|
||||||
#define SPRN_MMCRA 0x312
|
#define SPRN_MMCRA 0x312
|
||||||
|
#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
|
||||||
#define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */
|
#define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */
|
||||||
#define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */
|
#define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */
|
||||||
#define MMCRA_SLOT 0x07000000UL /* SLOT bits (37-39) */
|
#define MMCRA_SLOT 0x07000000UL /* SLOT bits (37-39) */
|
||||||
#define MMCRA_SLOT_SHIFT 24
|
#define MMCRA_SLOT_SHIFT 24
|
||||||
#define MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */
|
#define MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */
|
||||||
|
#define POWER6_MMCRA_SDSYNC 0x0000080000000000ULL /* SDAR/SIAR synced */
|
||||||
#define POWER6_MMCRA_SIHV 0x0000040000000000ULL
|
#define POWER6_MMCRA_SIHV 0x0000040000000000ULL
|
||||||
#define POWER6_MMCRA_SIPR 0x0000020000000000ULL
|
#define POWER6_MMCRA_SIPR 0x0000020000000000ULL
|
||||||
#define POWER6_MMCRA_THRM 0x00000020UL
|
#define POWER6_MMCRA_THRM 0x00000020UL
|
||||||
|
|
|
@ -322,6 +322,6 @@ SYSCALL_SPU(epoll_create1)
|
||||||
SYSCALL_SPU(dup3)
|
SYSCALL_SPU(dup3)
|
||||||
SYSCALL_SPU(pipe2)
|
SYSCALL_SPU(pipe2)
|
||||||
SYSCALL(inotify_init1)
|
SYSCALL(inotify_init1)
|
||||||
SYSCALL(ni_syscall)
|
SYSCALL_SPU(perf_counter_open)
|
||||||
COMPAT_SYS_SPU(preadv)
|
COMPAT_SYS_SPU(preadv)
|
||||||
COMPAT_SYS_SPU(pwritev)
|
COMPAT_SYS_SPU(pwritev)
|
||||||
|
|
|
@ -341,6 +341,7 @@
|
||||||
#define __NR_dup3 316
|
#define __NR_dup3 316
|
||||||
#define __NR_pipe2 317
|
#define __NR_pipe2 317
|
||||||
#define __NR_inotify_init1 318
|
#define __NR_inotify_init1 318
|
||||||
|
#define __NR_perf_counter_open 319
|
||||||
#define __NR_preadv 320
|
#define __NR_preadv 320
|
||||||
#define __NR_pwritev 321
|
#define __NR_pwritev 321
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,9 @@ obj64-$(CONFIG_AUDIT) += compat_audit.o
|
||||||
|
|
||||||
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
|
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
|
||||||
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
|
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
|
||||||
|
obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o power4-pmu.o ppc970-pmu.o \
|
||||||
|
power5-pmu.o power5+-pmu.o power6-pmu.o \
|
||||||
|
power7-pmu.o
|
||||||
|
|
||||||
obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o
|
obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,7 @@ int main(void)
|
||||||
DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
|
DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
|
||||||
DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
|
DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
|
||||||
DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
|
DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
|
||||||
|
DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_counter_pending));
|
||||||
DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
|
DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
|
||||||
DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
|
DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
|
||||||
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
|
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
|
||||||
|
|
|
@ -526,6 +526,15 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
|
||||||
2:
|
2:
|
||||||
TRACE_AND_RESTORE_IRQ(r5);
|
TRACE_AND_RESTORE_IRQ(r5);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PERF_COUNTERS
|
||||||
|
/* check paca->perf_counter_pending if we're enabling ints */
|
||||||
|
lbz r3,PACAPERFPEND(r13)
|
||||||
|
and. r3,r3,r5
|
||||||
|
beq 27f
|
||||||
|
bl .perf_counter_do_pending
|
||||||
|
27:
|
||||||
|
#endif /* CONFIG_PERF_COUNTERS */
|
||||||
|
|
||||||
/* extract EE bit and use it to restore paca->hard_enabled */
|
/* extract EE bit and use it to restore paca->hard_enabled */
|
||||||
ld r3,_MSR(r1)
|
ld r3,_MSR(r1)
|
||||||
rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
|
rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
|
||||||
|
|
|
@ -135,6 +135,11 @@ notrace void raw_local_irq_restore(unsigned long en)
|
||||||
iseries_handle_interrupts();
|
iseries_handle_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (test_perf_counter_pending()) {
|
||||||
|
clear_perf_counter_pending();
|
||||||
|
perf_counter_do_pending();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if (get_paca()->hard_enabled) return;
|
* if (get_paca()->hard_enabled) return;
|
||||||
* But again we need to take care that gcc gets hard_enabled directly
|
* But again we need to take care that gcc gets hard_enabled directly
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,598 @@
|
||||||
|
/*
|
||||||
|
* Performance counter support for POWER4 (GP) and POWER4+ (GQ) processors.
|
||||||
|
*
|
||||||
|
* Copyright 2009 Paul Mackerras, IBM Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/perf_counter.h>
|
||||||
|
#include <asm/reg.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in event code for POWER4
|
||||||
|
*/
|
||||||
|
#define PM_PMC_SH 12 /* PMC number (1-based) for direct events */
|
||||||
|
#define PM_PMC_MSK 0xf
|
||||||
|
#define PM_UNIT_SH 8 /* TTMMUX number and setting - unit select */
|
||||||
|
#define PM_UNIT_MSK 0xf
|
||||||
|
#define PM_LOWER_SH 6
|
||||||
|
#define PM_LOWER_MSK 1
|
||||||
|
#define PM_LOWER_MSKS 0x40
|
||||||
|
#define PM_BYTE_SH 4 /* Byte number of event bus to use */
|
||||||
|
#define PM_BYTE_MSK 3
|
||||||
|
#define PM_PMCSEL_MSK 7
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unit code values
|
||||||
|
*/
|
||||||
|
#define PM_FPU 1
|
||||||
|
#define PM_ISU1 2
|
||||||
|
#define PM_IFU 3
|
||||||
|
#define PM_IDU0 4
|
||||||
|
#define PM_ISU1_ALT 6
|
||||||
|
#define PM_ISU2 7
|
||||||
|
#define PM_IFU_ALT 8
|
||||||
|
#define PM_LSU0 9
|
||||||
|
#define PM_LSU1 0xc
|
||||||
|
#define PM_GPS 0xf
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCR0 for POWER4
|
||||||
|
*/
|
||||||
|
#define MMCR0_PMC1SEL_SH 8
|
||||||
|
#define MMCR0_PMC2SEL_SH 1
|
||||||
|
#define MMCR_PMCSEL_MSK 0x1f
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCR1 for POWER4
|
||||||
|
*/
|
||||||
|
#define MMCR1_TTM0SEL_SH 62
|
||||||
|
#define MMCR1_TTC0SEL_SH 61
|
||||||
|
#define MMCR1_TTM1SEL_SH 59
|
||||||
|
#define MMCR1_TTC1SEL_SH 58
|
||||||
|
#define MMCR1_TTM2SEL_SH 56
|
||||||
|
#define MMCR1_TTC2SEL_SH 55
|
||||||
|
#define MMCR1_TTM3SEL_SH 53
|
||||||
|
#define MMCR1_TTC3SEL_SH 52
|
||||||
|
#define MMCR1_TTMSEL_MSK 3
|
||||||
|
#define MMCR1_TD_CP_DBG0SEL_SH 50
|
||||||
|
#define MMCR1_TD_CP_DBG1SEL_SH 48
|
||||||
|
#define MMCR1_TD_CP_DBG2SEL_SH 46
|
||||||
|
#define MMCR1_TD_CP_DBG3SEL_SH 44
|
||||||
|
#define MMCR1_DEBUG0SEL_SH 43
|
||||||
|
#define MMCR1_DEBUG1SEL_SH 42
|
||||||
|
#define MMCR1_DEBUG2SEL_SH 41
|
||||||
|
#define MMCR1_DEBUG3SEL_SH 40
|
||||||
|
#define MMCR1_PMC1_ADDER_SEL_SH 39
|
||||||
|
#define MMCR1_PMC2_ADDER_SEL_SH 38
|
||||||
|
#define MMCR1_PMC6_ADDER_SEL_SH 37
|
||||||
|
#define MMCR1_PMC5_ADDER_SEL_SH 36
|
||||||
|
#define MMCR1_PMC8_ADDER_SEL_SH 35
|
||||||
|
#define MMCR1_PMC7_ADDER_SEL_SH 34
|
||||||
|
#define MMCR1_PMC3_ADDER_SEL_SH 33
|
||||||
|
#define MMCR1_PMC4_ADDER_SEL_SH 32
|
||||||
|
#define MMCR1_PMC3SEL_SH 27
|
||||||
|
#define MMCR1_PMC4SEL_SH 22
|
||||||
|
#define MMCR1_PMC5SEL_SH 17
|
||||||
|
#define MMCR1_PMC6SEL_SH 12
|
||||||
|
#define MMCR1_PMC7SEL_SH 7
|
||||||
|
#define MMCR1_PMC8SEL_SH 2 /* note bit 0 is in MMCRA for GP */
|
||||||
|
|
||||||
|
static short mmcr1_adder_bits[8] = {
|
||||||
|
MMCR1_PMC1_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC2_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC3_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC4_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC5_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC6_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC7_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC8_ADDER_SEL_SH
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCRA
|
||||||
|
*/
|
||||||
|
#define MMCRA_PMC8SEL0_SH 17 /* PMC8SEL bit 0 for GP */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Layout of constraint bits:
|
||||||
|
* 6666555555555544444444443333333333222222222211111111110000000000
|
||||||
|
* 3210987654321098765432109876543210987654321098765432109876543210
|
||||||
|
* |[ >[ >[ >|||[ >[ >< >< >< >< ><><><><><><><><>
|
||||||
|
* | UC1 UC2 UC3 ||| PS1 PS2 B0 B1 B2 B3 P1P2P3P4P5P6P7P8
|
||||||
|
* \SMPL ||\TTC3SEL
|
||||||
|
* |\TTC_IFU_SEL
|
||||||
|
* \TTM2SEL0
|
||||||
|
*
|
||||||
|
* SMPL - SAMPLE_ENABLE constraint
|
||||||
|
* 56: SAMPLE_ENABLE value 0x0100_0000_0000_0000
|
||||||
|
*
|
||||||
|
* UC1 - unit constraint 1: can't have all three of FPU/ISU1/IDU0|ISU2
|
||||||
|
* 55: UC1 error 0x0080_0000_0000_0000
|
||||||
|
* 54: FPU events needed 0x0040_0000_0000_0000
|
||||||
|
* 53: ISU1 events needed 0x0020_0000_0000_0000
|
||||||
|
* 52: IDU0|ISU2 events needed 0x0010_0000_0000_0000
|
||||||
|
*
|
||||||
|
* UC2 - unit constraint 2: can't have all three of FPU/IFU/LSU0
|
||||||
|
* 51: UC2 error 0x0008_0000_0000_0000
|
||||||
|
* 50: FPU events needed 0x0004_0000_0000_0000
|
||||||
|
* 49: IFU events needed 0x0002_0000_0000_0000
|
||||||
|
* 48: LSU0 events needed 0x0001_0000_0000_0000
|
||||||
|
*
|
||||||
|
* UC3 - unit constraint 3: can't have all four of LSU0/IFU/IDU0|ISU2/ISU1
|
||||||
|
* 47: UC3 error 0x8000_0000_0000
|
||||||
|
* 46: LSU0 events needed 0x4000_0000_0000
|
||||||
|
* 45: IFU events needed 0x2000_0000_0000
|
||||||
|
* 44: IDU0|ISU2 events needed 0x1000_0000_0000
|
||||||
|
* 43: ISU1 events needed 0x0800_0000_0000
|
||||||
|
*
|
||||||
|
* TTM2SEL0
|
||||||
|
* 42: 0 = IDU0 events needed
|
||||||
|
* 1 = ISU2 events needed 0x0400_0000_0000
|
||||||
|
*
|
||||||
|
* TTC_IFU_SEL
|
||||||
|
* 41: 0 = IFU.U events needed
|
||||||
|
* 1 = IFU.L events needed 0x0200_0000_0000
|
||||||
|
*
|
||||||
|
* TTC3SEL
|
||||||
|
* 40: 0 = LSU1.U events needed
|
||||||
|
* 1 = LSU1.L events needed 0x0100_0000_0000
|
||||||
|
*
|
||||||
|
* PS1
|
||||||
|
* 39: PS1 error 0x0080_0000_0000
|
||||||
|
* 36-38: count of events needing PMC1/2/5/6 0x0070_0000_0000
|
||||||
|
*
|
||||||
|
* PS2
|
||||||
|
* 35: PS2 error 0x0008_0000_0000
|
||||||
|
* 32-34: count of events needing PMC3/4/7/8 0x0007_0000_0000
|
||||||
|
*
|
||||||
|
* B0
|
||||||
|
* 28-31: Byte 0 event source 0xf000_0000
|
||||||
|
* 1 = FPU
|
||||||
|
* 2 = ISU1
|
||||||
|
* 3 = IFU
|
||||||
|
* 4 = IDU0
|
||||||
|
* 7 = ISU2
|
||||||
|
* 9 = LSU0
|
||||||
|
* c = LSU1
|
||||||
|
* f = GPS
|
||||||
|
*
|
||||||
|
* B1, B2, B3
|
||||||
|
* 24-27, 20-23, 16-19: Byte 1, 2, 3 event sources
|
||||||
|
*
|
||||||
|
* P8
|
||||||
|
* 15: P8 error 0x8000
|
||||||
|
* 14-15: Count of events needing PMC8
|
||||||
|
*
|
||||||
|
* P1..P7
|
||||||
|
* 0-13: Count of events needing PMC1..PMC7
|
||||||
|
*
|
||||||
|
* Note: this doesn't allow events using IFU.U to be combined with events
|
||||||
|
* using IFU.L, though that is feasible (using TTM0 and TTM2). However
|
||||||
|
* there are no listed events for IFU.L (they are debug events not
|
||||||
|
* verified for performance monitoring) so this shouldn't cause a
|
||||||
|
* problem.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct unitinfo {
|
||||||
|
u64 value, mask;
|
||||||
|
int unit;
|
||||||
|
int lowerbit;
|
||||||
|
} p4_unitinfo[16] = {
|
||||||
|
[PM_FPU] = { 0x44000000000000ull, 0x88000000000000ull, PM_FPU, 0 },
|
||||||
|
[PM_ISU1] = { 0x20080000000000ull, 0x88000000000000ull, PM_ISU1, 0 },
|
||||||
|
[PM_ISU1_ALT] =
|
||||||
|
{ 0x20080000000000ull, 0x88000000000000ull, PM_ISU1, 0 },
|
||||||
|
[PM_IFU] = { 0x02200000000000ull, 0x08820000000000ull, PM_IFU, 41 },
|
||||||
|
[PM_IFU_ALT] =
|
||||||
|
{ 0x02200000000000ull, 0x08820000000000ull, PM_IFU, 41 },
|
||||||
|
[PM_IDU0] = { 0x10100000000000ull, 0x80840000000000ull, PM_IDU0, 1 },
|
||||||
|
[PM_ISU2] = { 0x10140000000000ull, 0x80840000000000ull, PM_ISU2, 0 },
|
||||||
|
[PM_LSU0] = { 0x01400000000000ull, 0x08800000000000ull, PM_LSU0, 0 },
|
||||||
|
[PM_LSU1] = { 0x00000000000000ull, 0x00010000000000ull, PM_LSU1, 40 },
|
||||||
|
[PM_GPS] = { 0x00000000000000ull, 0x00000000000000ull, PM_GPS, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char direct_marked_event[8] = {
|
||||||
|
(1<<2) | (1<<3), /* PMC1: PM_MRK_GRP_DISP, PM_MRK_ST_CMPL */
|
||||||
|
(1<<3) | (1<<5), /* PMC2: PM_THRESH_TIMEO, PM_MRK_BRU_FIN */
|
||||||
|
(1<<3), /* PMC3: PM_MRK_ST_CMPL_INT */
|
||||||
|
(1<<4) | (1<<5), /* PMC4: PM_MRK_GRP_CMPL, PM_MRK_CRU_FIN */
|
||||||
|
(1<<4) | (1<<5), /* PMC5: PM_MRK_GRP_TIMEO */
|
||||||
|
(1<<3) | (1<<4) | (1<<5),
|
||||||
|
/* PMC6: PM_MRK_ST_GPS, PM_MRK_FXU_FIN, PM_MRK_GRP_ISSUED */
|
||||||
|
(1<<4) | (1<<5), /* PMC7: PM_MRK_FPU_FIN, PM_MRK_INST_FIN */
|
||||||
|
(1<<4), /* PMC8: PM_MRK_LSU_FIN */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if event counts things relating to marked instructions
|
||||||
|
* and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not.
|
||||||
|
*/
|
||||||
|
static int p4_marked_instr_event(u64 event)
|
||||||
|
{
|
||||||
|
int pmc, psel, unit, byte, bit;
|
||||||
|
unsigned int mask;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
psel = event & PM_PMCSEL_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (direct_marked_event[pmc - 1] & (1 << psel))
|
||||||
|
return 1;
|
||||||
|
if (psel == 0) /* add events */
|
||||||
|
bit = (pmc <= 4)? pmc - 1: 8 - pmc;
|
||||||
|
else if (psel == 6) /* decode events */
|
||||||
|
bit = 4;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
bit = psel;
|
||||||
|
|
||||||
|
byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
mask = 0;
|
||||||
|
switch (unit) {
|
||||||
|
case PM_LSU1:
|
||||||
|
if (event & PM_LOWER_MSKS)
|
||||||
|
mask = 1 << 28; /* byte 7 bit 4 */
|
||||||
|
else
|
||||||
|
mask = 6 << 24; /* byte 3 bits 1 and 2 */
|
||||||
|
break;
|
||||||
|
case PM_LSU0:
|
||||||
|
/* byte 3, bit 3; byte 2 bits 0,2,3,4,5; byte 1 */
|
||||||
|
mask = 0x083dff00;
|
||||||
|
}
|
||||||
|
return (mask >> (byte * 8 + bit)) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int p4_get_constraint(u64 event, u64 *maskp, u64 *valp)
|
||||||
|
{
|
||||||
|
int pmc, byte, unit, lower, sh;
|
||||||
|
u64 mask = 0, value = 0;
|
||||||
|
int grp = -1;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc > 8)
|
||||||
|
return -1;
|
||||||
|
sh = (pmc - 1) * 2;
|
||||||
|
mask |= 2 << sh;
|
||||||
|
value |= 1 << sh;
|
||||||
|
grp = ((pmc - 1) >> 1) & 1;
|
||||||
|
}
|
||||||
|
unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
if (unit) {
|
||||||
|
lower = (event >> PM_LOWER_SH) & PM_LOWER_MSK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bus events on bytes 0 and 2 can be counted
|
||||||
|
* on PMC1/2/5/6; bytes 1 and 3 on PMC3/4/7/8.
|
||||||
|
*/
|
||||||
|
if (!pmc)
|
||||||
|
grp = byte & 1;
|
||||||
|
|
||||||
|
if (!p4_unitinfo[unit].unit)
|
||||||
|
return -1;
|
||||||
|
mask |= p4_unitinfo[unit].mask;
|
||||||
|
value |= p4_unitinfo[unit].value;
|
||||||
|
sh = p4_unitinfo[unit].lowerbit;
|
||||||
|
if (sh > 1)
|
||||||
|
value |= (u64)lower << sh;
|
||||||
|
else if (lower != sh)
|
||||||
|
return -1;
|
||||||
|
unit = p4_unitinfo[unit].unit;
|
||||||
|
|
||||||
|
/* Set byte lane select field */
|
||||||
|
mask |= 0xfULL << (28 - 4 * byte);
|
||||||
|
value |= (u64)unit << (28 - 4 * byte);
|
||||||
|
}
|
||||||
|
if (grp == 0) {
|
||||||
|
/* increment PMC1/2/5/6 field */
|
||||||
|
mask |= 0x8000000000ull;
|
||||||
|
value |= 0x1000000000ull;
|
||||||
|
} else {
|
||||||
|
/* increment PMC3/4/7/8 field */
|
||||||
|
mask |= 0x800000000ull;
|
||||||
|
value |= 0x100000000ull;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Marked instruction events need sample_enable set */
|
||||||
|
if (p4_marked_instr_event(event)) {
|
||||||
|
mask |= 1ull << 56;
|
||||||
|
value |= 1ull << 56;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PMCSEL=6 decode events on byte 2 need sample_enable clear */
|
||||||
|
if (pmc && (event & PM_PMCSEL_MSK) == 6 && byte == 2)
|
||||||
|
mask |= 1ull << 56;
|
||||||
|
|
||||||
|
*maskp = mask;
|
||||||
|
*valp = value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int ppc_inst_cmpl[] = {
|
||||||
|
0x1001, 0x4001, 0x6001, 0x7001, 0x8001
|
||||||
|
};
|
||||||
|
|
||||||
|
static int p4_get_alternatives(u64 event, unsigned int flags, u64 alt[])
|
||||||
|
{
|
||||||
|
int i, j, na;
|
||||||
|
|
||||||
|
alt[0] = event;
|
||||||
|
na = 1;
|
||||||
|
|
||||||
|
/* 2 possibilities for PM_GRP_DISP_REJECT */
|
||||||
|
if (event == 0x8003 || event == 0x0224) {
|
||||||
|
alt[1] = event ^ (0x8003 ^ 0x0224);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2 possibilities for PM_ST_MISS_L1 */
|
||||||
|
if (event == 0x0c13 || event == 0x0c23) {
|
||||||
|
alt[1] = event ^ (0x0c13 ^ 0x0c23);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* several possibilities for PM_INST_CMPL */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ppc_inst_cmpl); ++i) {
|
||||||
|
if (event == ppc_inst_cmpl[i]) {
|
||||||
|
for (j = 0; j < ARRAY_SIZE(ppc_inst_cmpl); ++j)
|
||||||
|
if (j != i)
|
||||||
|
alt[na++] = ppc_inst_cmpl[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return na;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int p4_compute_mmcr(u64 event[], int n_ev,
|
||||||
|
unsigned int hwc[], u64 mmcr[])
|
||||||
|
{
|
||||||
|
u64 mmcr0 = 0, mmcr1 = 0, mmcra = 0;
|
||||||
|
unsigned int pmc, unit, byte, psel, lower;
|
||||||
|
unsigned int ttm, grp;
|
||||||
|
unsigned int pmc_inuse = 0;
|
||||||
|
unsigned int pmc_grp_use[2];
|
||||||
|
unsigned char busbyte[4];
|
||||||
|
unsigned char unituse[16];
|
||||||
|
unsigned int unitlower = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (n_ev > 8)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* First pass to count resource use */
|
||||||
|
pmc_grp_use[0] = pmc_grp_use[1] = 0;
|
||||||
|
memset(busbyte, 0, sizeof(busbyte));
|
||||||
|
memset(unituse, 0, sizeof(unituse));
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc_inuse & (1 << (pmc - 1)))
|
||||||
|
return -1;
|
||||||
|
pmc_inuse |= 1 << (pmc - 1);
|
||||||
|
/* count 1/2/5/6 vs 3/4/7/8 use */
|
||||||
|
++pmc_grp_use[((pmc - 1) >> 1) & 1];
|
||||||
|
}
|
||||||
|
unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
lower = (event[i] >> PM_LOWER_SH) & PM_LOWER_MSK;
|
||||||
|
if (unit) {
|
||||||
|
if (!pmc)
|
||||||
|
++pmc_grp_use[byte & 1];
|
||||||
|
if (unit == 6 || unit == 8)
|
||||||
|
/* map alt ISU1/IFU codes: 6->2, 8->3 */
|
||||||
|
unit = (unit >> 1) - 1;
|
||||||
|
if (busbyte[byte] && busbyte[byte] != unit)
|
||||||
|
return -1;
|
||||||
|
busbyte[byte] = unit;
|
||||||
|
lower <<= unit;
|
||||||
|
if (unituse[unit] && lower != (unitlower & lower))
|
||||||
|
return -1;
|
||||||
|
unituse[unit] = 1;
|
||||||
|
unitlower |= lower;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pmc_grp_use[0] > 4 || pmc_grp_use[1] > 4)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assign resources and set multiplexer selects.
|
||||||
|
*
|
||||||
|
* Units 1,2,3 are on TTM0, 4,6,7 on TTM1, 8,10 on TTM2.
|
||||||
|
* Each TTMx can only select one unit, but since
|
||||||
|
* units 2 and 6 are both ISU1, and 3 and 8 are both IFU,
|
||||||
|
* we have some choices.
|
||||||
|
*/
|
||||||
|
if (unituse[2] & (unituse[1] | (unituse[3] & unituse[9]))) {
|
||||||
|
unituse[6] = 1; /* Move 2 to 6 */
|
||||||
|
unituse[2] = 0;
|
||||||
|
}
|
||||||
|
if (unituse[3] & (unituse[1] | unituse[2])) {
|
||||||
|
unituse[8] = 1; /* Move 3 to 8 */
|
||||||
|
unituse[3] = 0;
|
||||||
|
unitlower = (unitlower & ~8) | ((unitlower & 8) << 5);
|
||||||
|
}
|
||||||
|
/* Check only one unit per TTMx */
|
||||||
|
if (unituse[1] + unituse[2] + unituse[3] > 1 ||
|
||||||
|
unituse[4] + unituse[6] + unituse[7] > 1 ||
|
||||||
|
unituse[8] + unituse[9] > 1 ||
|
||||||
|
(unituse[5] | unituse[10] | unituse[11] |
|
||||||
|
unituse[13] | unituse[14]))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Set TTMxSEL fields. Note, units 1-3 => TTM0SEL codes 0-2 */
|
||||||
|
mmcr1 |= (u64)(unituse[3] * 2 + unituse[2]) << MMCR1_TTM0SEL_SH;
|
||||||
|
mmcr1 |= (u64)(unituse[7] * 3 + unituse[6] * 2) << MMCR1_TTM1SEL_SH;
|
||||||
|
mmcr1 |= (u64)unituse[9] << MMCR1_TTM2SEL_SH;
|
||||||
|
|
||||||
|
/* Set TTCxSEL fields. */
|
||||||
|
if (unitlower & 0xe)
|
||||||
|
mmcr1 |= 1ull << MMCR1_TTC0SEL_SH;
|
||||||
|
if (unitlower & 0xf0)
|
||||||
|
mmcr1 |= 1ull << MMCR1_TTC1SEL_SH;
|
||||||
|
if (unitlower & 0xf00)
|
||||||
|
mmcr1 |= 1ull << MMCR1_TTC2SEL_SH;
|
||||||
|
if (unitlower & 0x7000)
|
||||||
|
mmcr1 |= 1ull << MMCR1_TTC3SEL_SH;
|
||||||
|
|
||||||
|
/* Set byte lane select fields. */
|
||||||
|
for (byte = 0; byte < 4; ++byte) {
|
||||||
|
unit = busbyte[byte];
|
||||||
|
if (!unit)
|
||||||
|
continue;
|
||||||
|
if (unit == 0xf) {
|
||||||
|
/* special case for GPS */
|
||||||
|
mmcr1 |= 1ull << (MMCR1_DEBUG0SEL_SH - byte);
|
||||||
|
} else {
|
||||||
|
if (!unituse[unit])
|
||||||
|
ttm = unit - 1; /* 2->1, 3->2 */
|
||||||
|
else
|
||||||
|
ttm = unit >> 2;
|
||||||
|
mmcr1 |= (u64)ttm << (MMCR1_TD_CP_DBG0SEL_SH - 2*byte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
psel = event[i] & PM_PMCSEL_MSK;
|
||||||
|
if (!pmc) {
|
||||||
|
/* Bus event or 00xxx direct event (off or cycles) */
|
||||||
|
if (unit)
|
||||||
|
psel |= 0x10 | ((byte & 2) << 2);
|
||||||
|
for (pmc = 0; pmc < 8; ++pmc) {
|
||||||
|
if (pmc_inuse & (1 << pmc))
|
||||||
|
continue;
|
||||||
|
grp = (pmc >> 1) & 1;
|
||||||
|
if (unit) {
|
||||||
|
if (grp == (byte & 1))
|
||||||
|
break;
|
||||||
|
} else if (pmc_grp_use[grp] < 4) {
|
||||||
|
++pmc_grp_use[grp];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pmc_inuse |= 1 << pmc;
|
||||||
|
} else {
|
||||||
|
/* Direct event */
|
||||||
|
--pmc;
|
||||||
|
if (psel == 0 && (byte & 2))
|
||||||
|
/* add events on higher-numbered bus */
|
||||||
|
mmcr1 |= 1ull << mmcr1_adder_bits[pmc];
|
||||||
|
else if (psel == 6 && byte == 3)
|
||||||
|
/* seem to need to set sample_enable here */
|
||||||
|
mmcra |= MMCRA_SAMPLE_ENABLE;
|
||||||
|
psel |= 8;
|
||||||
|
}
|
||||||
|
if (pmc <= 1)
|
||||||
|
mmcr0 |= psel << (MMCR0_PMC1SEL_SH - 7 * pmc);
|
||||||
|
else
|
||||||
|
mmcr1 |= psel << (MMCR1_PMC3SEL_SH - 5 * (pmc - 2));
|
||||||
|
if (pmc == 7) /* PMC8 */
|
||||||
|
mmcra |= (psel & 1) << MMCRA_PMC8SEL0_SH;
|
||||||
|
hwc[i] = pmc;
|
||||||
|
if (p4_marked_instr_event(event[i]))
|
||||||
|
mmcra |= MMCRA_SAMPLE_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pmc_inuse & 1)
|
||||||
|
mmcr0 |= MMCR0_PMC1CE;
|
||||||
|
if (pmc_inuse & 0xfe)
|
||||||
|
mmcr0 |= MMCR0_PMCjCE;
|
||||||
|
|
||||||
|
mmcra |= 0x2000; /* mark only one IOP per PPC instruction */
|
||||||
|
|
||||||
|
/* Return MMCRx values */
|
||||||
|
mmcr[0] = mmcr0;
|
||||||
|
mmcr[1] = mmcr1;
|
||||||
|
mmcr[2] = mmcra;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void p4_disable_pmc(unsigned int pmc, u64 mmcr[])
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Setting the PMCxSEL field to 0 disables PMC x.
|
||||||
|
* (Note that pmc is 0-based here, not 1-based.)
|
||||||
|
*/
|
||||||
|
if (pmc <= 1) {
|
||||||
|
mmcr[0] &= ~(0x1fUL << (MMCR0_PMC1SEL_SH - 7 * pmc));
|
||||||
|
} else {
|
||||||
|
mmcr[1] &= ~(0x1fUL << (MMCR1_PMC3SEL_SH - 5 * (pmc - 2)));
|
||||||
|
if (pmc == 7)
|
||||||
|
mmcr[2] &= ~(1UL << MMCRA_PMC8SEL0_SH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int p4_generic_events[] = {
|
||||||
|
[PERF_COUNT_HW_CPU_CYCLES] = 7,
|
||||||
|
[PERF_COUNT_HW_INSTRUCTIONS] = 0x1001,
|
||||||
|
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x8c10, /* PM_LD_REF_L1 */
|
||||||
|
[PERF_COUNT_HW_CACHE_MISSES] = 0x3c10, /* PM_LD_MISS_L1 */
|
||||||
|
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x330, /* PM_BR_ISSUED */
|
||||||
|
[PERF_COUNT_HW_BRANCH_MISSES] = 0x331, /* PM_BR_MPRED_CR */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define C(x) PERF_COUNT_HW_CACHE_##x
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table of generalized cache-related events.
|
||||||
|
* 0 means not supported, -1 means nonsensical, other values
|
||||||
|
* are event codes.
|
||||||
|
*/
|
||||||
|
static int power4_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
|
||||||
|
[C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x8c10, 0x3c10 },
|
||||||
|
[C(OP_WRITE)] = { 0x7c10, 0xc13 },
|
||||||
|
[C(OP_PREFETCH)] = { 0xc35, 0 },
|
||||||
|
},
|
||||||
|
[C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { 0, 0 },
|
||||||
|
},
|
||||||
|
[C(LL)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0 },
|
||||||
|
[C(OP_WRITE)] = { 0, 0 },
|
||||||
|
[C(OP_PREFETCH)] = { 0xc34, 0 },
|
||||||
|
},
|
||||||
|
[C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x904 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x900 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x330, 0x331 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct power_pmu power4_pmu = {
|
||||||
|
.n_counter = 8,
|
||||||
|
.max_alternatives = 5,
|
||||||
|
.add_fields = 0x0000001100005555ull,
|
||||||
|
.test_adder = 0x0011083300000000ull,
|
||||||
|
.compute_mmcr = p4_compute_mmcr,
|
||||||
|
.get_constraint = p4_get_constraint,
|
||||||
|
.get_alternatives = p4_get_alternatives,
|
||||||
|
.disable_pmc = p4_disable_pmc,
|
||||||
|
.n_generic = ARRAY_SIZE(p4_generic_events),
|
||||||
|
.generic_events = p4_generic_events,
|
||||||
|
.cache_events = &power4_cache_events,
|
||||||
|
};
|
|
@ -0,0 +1,671 @@
|
||||||
|
/*
|
||||||
|
* Performance counter support for POWER5+/++ (not POWER5) processors.
|
||||||
|
*
|
||||||
|
* Copyright 2009 Paul Mackerras, IBM Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/perf_counter.h>
|
||||||
|
#include <asm/reg.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in event code for POWER5+ (POWER5 GS) and POWER5++ (POWER5 GS DD3)
|
||||||
|
*/
|
||||||
|
#define PM_PMC_SH 20 /* PMC number (1-based) for direct events */
|
||||||
|
#define PM_PMC_MSK 0xf
|
||||||
|
#define PM_PMC_MSKS (PM_PMC_MSK << PM_PMC_SH)
|
||||||
|
#define PM_UNIT_SH 16 /* TTMMUX number and setting - unit select */
|
||||||
|
#define PM_UNIT_MSK 0xf
|
||||||
|
#define PM_BYTE_SH 12 /* Byte number of event bus to use */
|
||||||
|
#define PM_BYTE_MSK 7
|
||||||
|
#define PM_GRS_SH 8 /* Storage subsystem mux select */
|
||||||
|
#define PM_GRS_MSK 7
|
||||||
|
#define PM_BUSEVENT_MSK 0x80 /* Set if event uses event bus */
|
||||||
|
#define PM_PMCSEL_MSK 0x7f
|
||||||
|
|
||||||
|
/* Values in PM_UNIT field */
|
||||||
|
#define PM_FPU 0
|
||||||
|
#define PM_ISU0 1
|
||||||
|
#define PM_IFU 2
|
||||||
|
#define PM_ISU1 3
|
||||||
|
#define PM_IDU 4
|
||||||
|
#define PM_ISU0_ALT 6
|
||||||
|
#define PM_GRS 7
|
||||||
|
#define PM_LSU0 8
|
||||||
|
#define PM_LSU1 0xc
|
||||||
|
#define PM_LASTUNIT 0xc
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCR1 for POWER5+
|
||||||
|
*/
|
||||||
|
#define MMCR1_TTM0SEL_SH 62
|
||||||
|
#define MMCR1_TTM1SEL_SH 60
|
||||||
|
#define MMCR1_TTM2SEL_SH 58
|
||||||
|
#define MMCR1_TTM3SEL_SH 56
|
||||||
|
#define MMCR1_TTMSEL_MSK 3
|
||||||
|
#define MMCR1_TD_CP_DBG0SEL_SH 54
|
||||||
|
#define MMCR1_TD_CP_DBG1SEL_SH 52
|
||||||
|
#define MMCR1_TD_CP_DBG2SEL_SH 50
|
||||||
|
#define MMCR1_TD_CP_DBG3SEL_SH 48
|
||||||
|
#define MMCR1_GRS_L2SEL_SH 46
|
||||||
|
#define MMCR1_GRS_L2SEL_MSK 3
|
||||||
|
#define MMCR1_GRS_L3SEL_SH 44
|
||||||
|
#define MMCR1_GRS_L3SEL_MSK 3
|
||||||
|
#define MMCR1_GRS_MCSEL_SH 41
|
||||||
|
#define MMCR1_GRS_MCSEL_MSK 7
|
||||||
|
#define MMCR1_GRS_FABSEL_SH 39
|
||||||
|
#define MMCR1_GRS_FABSEL_MSK 3
|
||||||
|
#define MMCR1_PMC1_ADDER_SEL_SH 35
|
||||||
|
#define MMCR1_PMC2_ADDER_SEL_SH 34
|
||||||
|
#define MMCR1_PMC3_ADDER_SEL_SH 33
|
||||||
|
#define MMCR1_PMC4_ADDER_SEL_SH 32
|
||||||
|
#define MMCR1_PMC1SEL_SH 25
|
||||||
|
#define MMCR1_PMC2SEL_SH 17
|
||||||
|
#define MMCR1_PMC3SEL_SH 9
|
||||||
|
#define MMCR1_PMC4SEL_SH 1
|
||||||
|
#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8)
|
||||||
|
#define MMCR1_PMCSEL_MSK 0x7f
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCRA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Layout of constraint bits:
|
||||||
|
* 6666555555555544444444443333333333222222222211111111110000000000
|
||||||
|
* 3210987654321098765432109876543210987654321098765432109876543210
|
||||||
|
* [ ><><>< ><> <><>[ > < >< >< >< ><><><><><><>
|
||||||
|
* NC G0G1G2 G3 T0T1 UC B0 B1 B2 B3 P6P5P4P3P2P1
|
||||||
|
*
|
||||||
|
* NC - number of counters
|
||||||
|
* 51: NC error 0x0008_0000_0000_0000
|
||||||
|
* 48-50: number of events needing PMC1-4 0x0007_0000_0000_0000
|
||||||
|
*
|
||||||
|
* G0..G3 - GRS mux constraints
|
||||||
|
* 46-47: GRS_L2SEL value
|
||||||
|
* 44-45: GRS_L3SEL value
|
||||||
|
* 41-44: GRS_MCSEL value
|
||||||
|
* 39-40: GRS_FABSEL value
|
||||||
|
* Note that these match up with their bit positions in MMCR1
|
||||||
|
*
|
||||||
|
* T0 - TTM0 constraint
|
||||||
|
* 36-37: TTM0SEL value (0=FPU, 2=IFU, 3=ISU1) 0x30_0000_0000
|
||||||
|
*
|
||||||
|
* T1 - TTM1 constraint
|
||||||
|
* 34-35: TTM1SEL value (0=IDU, 3=GRS) 0x0c_0000_0000
|
||||||
|
*
|
||||||
|
* UC - unit constraint: can't have all three of FPU|IFU|ISU1, ISU0, IDU|GRS
|
||||||
|
* 33: UC3 error 0x02_0000_0000
|
||||||
|
* 32: FPU|IFU|ISU1 events needed 0x01_0000_0000
|
||||||
|
* 31: ISU0 events needed 0x01_8000_0000
|
||||||
|
* 30: IDU|GRS events needed 0x00_4000_0000
|
||||||
|
*
|
||||||
|
* B0
|
||||||
|
* 24-27: Byte 0 event source 0x0f00_0000
|
||||||
|
* Encoding as for the event code
|
||||||
|
*
|
||||||
|
* B1, B2, B3
|
||||||
|
* 20-23, 16-19, 12-15: Byte 1, 2, 3 event sources
|
||||||
|
*
|
||||||
|
* P6
|
||||||
|
* 11: P6 error 0x800
|
||||||
|
* 10-11: Count of events needing PMC6
|
||||||
|
*
|
||||||
|
* P1..P5
|
||||||
|
* 0-9: Count of events needing PMC1..PMC5
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const int grsel_shift[8] = {
|
||||||
|
MMCR1_GRS_L2SEL_SH, MMCR1_GRS_L2SEL_SH, MMCR1_GRS_L2SEL_SH,
|
||||||
|
MMCR1_GRS_L3SEL_SH, MMCR1_GRS_L3SEL_SH, MMCR1_GRS_L3SEL_SH,
|
||||||
|
MMCR1_GRS_MCSEL_SH, MMCR1_GRS_FABSEL_SH
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Masks and values for using events from the various units */
|
||||||
|
static u64 unit_cons[PM_LASTUNIT+1][2] = {
|
||||||
|
[PM_FPU] = { 0x3200000000ull, 0x0100000000ull },
|
||||||
|
[PM_ISU0] = { 0x0200000000ull, 0x0080000000ull },
|
||||||
|
[PM_ISU1] = { 0x3200000000ull, 0x3100000000ull },
|
||||||
|
[PM_IFU] = { 0x3200000000ull, 0x2100000000ull },
|
||||||
|
[PM_IDU] = { 0x0e00000000ull, 0x0040000000ull },
|
||||||
|
[PM_GRS] = { 0x0e00000000ull, 0x0c40000000ull },
|
||||||
|
};
|
||||||
|
|
||||||
|
static int power5p_get_constraint(u64 event, u64 *maskp, u64 *valp)
|
||||||
|
{
|
||||||
|
int pmc, byte, unit, sh;
|
||||||
|
int bit, fmask;
|
||||||
|
u64 mask = 0, value = 0;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc > 6)
|
||||||
|
return -1;
|
||||||
|
sh = (pmc - 1) * 2;
|
||||||
|
mask |= 2 << sh;
|
||||||
|
value |= 1 << sh;
|
||||||
|
if (pmc >= 5 && !(event == 0x500009 || event == 0x600005))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (event & PM_BUSEVENT_MSK) {
|
||||||
|
unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
if (unit > PM_LASTUNIT)
|
||||||
|
return -1;
|
||||||
|
if (unit == PM_ISU0_ALT)
|
||||||
|
unit = PM_ISU0;
|
||||||
|
mask |= unit_cons[unit][0];
|
||||||
|
value |= unit_cons[unit][1];
|
||||||
|
byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
if (byte >= 4) {
|
||||||
|
if (unit != PM_LSU1)
|
||||||
|
return -1;
|
||||||
|
/* Map LSU1 low word (bytes 4-7) to unit LSU1+1 */
|
||||||
|
++unit;
|
||||||
|
byte &= 3;
|
||||||
|
}
|
||||||
|
if (unit == PM_GRS) {
|
||||||
|
bit = event & 7;
|
||||||
|
fmask = (bit == 6)? 7: 3;
|
||||||
|
sh = grsel_shift[bit];
|
||||||
|
mask |= (u64)fmask << sh;
|
||||||
|
value |= (u64)((event >> PM_GRS_SH) & fmask) << sh;
|
||||||
|
}
|
||||||
|
/* Set byte lane select field */
|
||||||
|
mask |= 0xfULL << (24 - 4 * byte);
|
||||||
|
value |= (u64)unit << (24 - 4 * byte);
|
||||||
|
}
|
||||||
|
if (pmc < 5) {
|
||||||
|
/* need a counter from PMC1-4 set */
|
||||||
|
mask |= 0x8000000000000ull;
|
||||||
|
value |= 0x1000000000000ull;
|
||||||
|
}
|
||||||
|
*maskp = mask;
|
||||||
|
*valp = value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int power5p_limited_pmc_event(u64 event)
|
||||||
|
{
|
||||||
|
int pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
|
||||||
|
return pmc == 5 || pmc == 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_ALT 3 /* at most 3 alternatives for any event */
|
||||||
|
|
||||||
|
static const unsigned int event_alternatives[][MAX_ALT] = {
|
||||||
|
{ 0x100c0, 0x40001f }, /* PM_GCT_FULL_CYC */
|
||||||
|
{ 0x120e4, 0x400002 }, /* PM_GRP_DISP_REJECT */
|
||||||
|
{ 0x230e2, 0x323087 }, /* PM_BR_PRED_CR */
|
||||||
|
{ 0x230e3, 0x223087, 0x3230a0 }, /* PM_BR_PRED_TA */
|
||||||
|
{ 0x410c7, 0x441084 }, /* PM_THRD_L2MISS_BOTH_CYC */
|
||||||
|
{ 0x800c4, 0xc20e0 }, /* PM_DTLB_MISS */
|
||||||
|
{ 0xc50c6, 0xc60e0 }, /* PM_MRK_DTLB_MISS */
|
||||||
|
{ 0x100005, 0x600005 }, /* PM_RUN_CYC */
|
||||||
|
{ 0x100009, 0x200009 }, /* PM_INST_CMPL */
|
||||||
|
{ 0x200015, 0x300015 }, /* PM_LSU_LMQ_SRQ_EMPTY_CYC */
|
||||||
|
{ 0x300009, 0x400009 }, /* PM_INST_DISP */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan the alternatives table for a match and return the
|
||||||
|
* index into the alternatives table if found, else -1.
|
||||||
|
*/
|
||||||
|
static int find_alternative(unsigned int event)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(event_alternatives); ++i) {
|
||||||
|
if (event < event_alternatives[i][0])
|
||||||
|
break;
|
||||||
|
for (j = 0; j < MAX_ALT && event_alternatives[i][j]; ++j)
|
||||||
|
if (event == event_alternatives[i][j])
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned char bytedecode_alternatives[4][4] = {
|
||||||
|
/* PMC 1 */ { 0x21, 0x23, 0x25, 0x27 },
|
||||||
|
/* PMC 2 */ { 0x07, 0x17, 0x0e, 0x1e },
|
||||||
|
/* PMC 3 */ { 0x20, 0x22, 0x24, 0x26 },
|
||||||
|
/* PMC 4 */ { 0x07, 0x17, 0x0e, 0x1e }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some direct events for decodes of event bus byte 3 have alternative
|
||||||
|
* PMCSEL values on other counters. This returns the alternative
|
||||||
|
* event code for those that do, or -1 otherwise. This also handles
|
||||||
|
* alternative PCMSEL values for add events.
|
||||||
|
*/
|
||||||
|
static s64 find_alternative_bdecode(u64 event)
|
||||||
|
{
|
||||||
|
int pmc, altpmc, pp, j;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc == 0 || pmc > 4)
|
||||||
|
return -1;
|
||||||
|
altpmc = 5 - pmc; /* 1 <-> 4, 2 <-> 3 */
|
||||||
|
pp = event & PM_PMCSEL_MSK;
|
||||||
|
for (j = 0; j < 4; ++j) {
|
||||||
|
if (bytedecode_alternatives[pmc - 1][j] == pp) {
|
||||||
|
return (event & ~(PM_PMC_MSKS | PM_PMCSEL_MSK)) |
|
||||||
|
(altpmc << PM_PMC_SH) |
|
||||||
|
bytedecode_alternatives[altpmc - 1][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* new decode alternatives for power5+ */
|
||||||
|
if (pmc == 1 && (pp == 0x0d || pp == 0x0e))
|
||||||
|
return event + (2 << PM_PMC_SH) + (0x2e - 0x0d);
|
||||||
|
if (pmc == 3 && (pp == 0x2e || pp == 0x2f))
|
||||||
|
return event - (2 << PM_PMC_SH) - (0x2e - 0x0d);
|
||||||
|
|
||||||
|
/* alternative add event encodings */
|
||||||
|
if (pp == 0x10 || pp == 0x28)
|
||||||
|
return ((event ^ (0x10 ^ 0x28)) & ~PM_PMC_MSKS) |
|
||||||
|
(altpmc << PM_PMC_SH);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int power5p_get_alternatives(u64 event, unsigned int flags, u64 alt[])
|
||||||
|
{
|
||||||
|
int i, j, nalt = 1;
|
||||||
|
int nlim;
|
||||||
|
s64 ae;
|
||||||
|
|
||||||
|
alt[0] = event;
|
||||||
|
nalt = 1;
|
||||||
|
nlim = power5p_limited_pmc_event(event);
|
||||||
|
i = find_alternative(event);
|
||||||
|
if (i >= 0) {
|
||||||
|
for (j = 0; j < MAX_ALT; ++j) {
|
||||||
|
ae = event_alternatives[i][j];
|
||||||
|
if (ae && ae != event)
|
||||||
|
alt[nalt++] = ae;
|
||||||
|
nlim += power5p_limited_pmc_event(ae);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ae = find_alternative_bdecode(event);
|
||||||
|
if (ae > 0)
|
||||||
|
alt[nalt++] = ae;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & PPMU_ONLY_COUNT_RUN) {
|
||||||
|
/*
|
||||||
|
* We're only counting in RUN state,
|
||||||
|
* so PM_CYC is equivalent to PM_RUN_CYC
|
||||||
|
* and PM_INST_CMPL === PM_RUN_INST_CMPL.
|
||||||
|
* This doesn't include alternatives that don't provide
|
||||||
|
* any extra flexibility in assigning PMCs (e.g.
|
||||||
|
* 0x100005 for PM_RUN_CYC vs. 0xf for PM_CYC).
|
||||||
|
* Note that even with these additional alternatives
|
||||||
|
* we never end up with more than 3 alternatives for any event.
|
||||||
|
*/
|
||||||
|
j = nalt;
|
||||||
|
for (i = 0; i < nalt; ++i) {
|
||||||
|
switch (alt[i]) {
|
||||||
|
case 0xf: /* PM_CYC */
|
||||||
|
alt[j++] = 0x600005; /* PM_RUN_CYC */
|
||||||
|
++nlim;
|
||||||
|
break;
|
||||||
|
case 0x600005: /* PM_RUN_CYC */
|
||||||
|
alt[j++] = 0xf;
|
||||||
|
break;
|
||||||
|
case 0x100009: /* PM_INST_CMPL */
|
||||||
|
alt[j++] = 0x500009; /* PM_RUN_INST_CMPL */
|
||||||
|
++nlim;
|
||||||
|
break;
|
||||||
|
case 0x500009: /* PM_RUN_INST_CMPL */
|
||||||
|
alt[j++] = 0x100009; /* PM_INST_CMPL */
|
||||||
|
alt[j++] = 0x200009;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nalt = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(flags & PPMU_LIMITED_PMC_OK) && nlim) {
|
||||||
|
/* remove the limited PMC events */
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < nalt; ++i) {
|
||||||
|
if (!power5p_limited_pmc_event(alt[i])) {
|
||||||
|
alt[j] = alt[i];
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nalt = j;
|
||||||
|
} else if ((flags & PPMU_LIMITED_PMC_REQD) && nlim < nalt) {
|
||||||
|
/* remove all but the limited PMC events */
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < nalt; ++i) {
|
||||||
|
if (power5p_limited_pmc_event(alt[i])) {
|
||||||
|
alt[j] = alt[i];
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nalt = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nalt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map of which direct events on which PMCs are marked instruction events.
|
||||||
|
* Indexed by PMCSEL value, bit i (LE) set if PMC i is a marked event.
|
||||||
|
* Bit 0 is set if it is marked for all PMCs.
|
||||||
|
* The 0x80 bit indicates a byte decode PMCSEL value.
|
||||||
|
*/
|
||||||
|
static unsigned char direct_event_is_marked[0x28] = {
|
||||||
|
0, /* 00 */
|
||||||
|
0x1f, /* 01 PM_IOPS_CMPL */
|
||||||
|
0x2, /* 02 PM_MRK_GRP_DISP */
|
||||||
|
0xe, /* 03 PM_MRK_ST_CMPL, PM_MRK_ST_GPS, PM_MRK_ST_CMPL_INT */
|
||||||
|
0, /* 04 */
|
||||||
|
0x1c, /* 05 PM_MRK_BRU_FIN, PM_MRK_INST_FIN, PM_MRK_CRU_FIN */
|
||||||
|
0x80, /* 06 */
|
||||||
|
0x80, /* 07 */
|
||||||
|
0, 0, 0,/* 08 - 0a */
|
||||||
|
0x18, /* 0b PM_THRESH_TIMEO, PM_MRK_GRP_TIMEO */
|
||||||
|
0, /* 0c */
|
||||||
|
0x80, /* 0d */
|
||||||
|
0x80, /* 0e */
|
||||||
|
0, /* 0f */
|
||||||
|
0, /* 10 */
|
||||||
|
0x14, /* 11 PM_MRK_GRP_BR_REDIR, PM_MRK_GRP_IC_MISS */
|
||||||
|
0, /* 12 */
|
||||||
|
0x10, /* 13 PM_MRK_GRP_CMPL */
|
||||||
|
0x1f, /* 14 PM_GRP_MRK, PM_MRK_{FXU,FPU,LSU}_FIN */
|
||||||
|
0x2, /* 15 PM_MRK_GRP_ISSUED */
|
||||||
|
0x80, /* 16 */
|
||||||
|
0x80, /* 17 */
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
0x80, /* 1d */
|
||||||
|
0x80, /* 1e */
|
||||||
|
0, /* 1f */
|
||||||
|
0x80, /* 20 */
|
||||||
|
0x80, /* 21 */
|
||||||
|
0x80, /* 22 */
|
||||||
|
0x80, /* 23 */
|
||||||
|
0x80, /* 24 */
|
||||||
|
0x80, /* 25 */
|
||||||
|
0x80, /* 26 */
|
||||||
|
0x80, /* 27 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if event counts things relating to marked instructions
|
||||||
|
* and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not.
|
||||||
|
*/
|
||||||
|
static int power5p_marked_instr_event(u64 event)
|
||||||
|
{
|
||||||
|
int pmc, psel;
|
||||||
|
int bit, byte, unit;
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
psel = event & PM_PMCSEL_MSK;
|
||||||
|
if (pmc >= 5)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bit = -1;
|
||||||
|
if (psel < sizeof(direct_event_is_marked)) {
|
||||||
|
if (direct_event_is_marked[psel] & (1 << pmc))
|
||||||
|
return 1;
|
||||||
|
if (direct_event_is_marked[psel] & 0x80)
|
||||||
|
bit = 4;
|
||||||
|
else if (psel == 0x08)
|
||||||
|
bit = pmc - 1;
|
||||||
|
else if (psel == 0x10)
|
||||||
|
bit = 4 - pmc;
|
||||||
|
else if (psel == 0x1b && (pmc == 1 || pmc == 3))
|
||||||
|
bit = 4;
|
||||||
|
} else if ((psel & 0x48) == 0x40) {
|
||||||
|
bit = psel & 7;
|
||||||
|
} else if (psel == 0x28) {
|
||||||
|
bit = pmc - 1;
|
||||||
|
} else if (pmc == 3 && (psel == 0x2e || psel == 0x2f)) {
|
||||||
|
bit = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(event & PM_BUSEVENT_MSK) || bit == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
if (unit == PM_LSU0) {
|
||||||
|
/* byte 1 bits 0-7, byte 2 bits 0,2-4,6 */
|
||||||
|
mask = 0x5dff00;
|
||||||
|
} else if (unit == PM_LSU1 && byte >= 4) {
|
||||||
|
byte -= 4;
|
||||||
|
/* byte 5 bits 6-7, byte 6 bits 0,4, byte 7 bits 0-4,6 */
|
||||||
|
mask = 0x5f11c000;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (mask >> (byte * 8 + bit)) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int power5p_compute_mmcr(u64 event[], int n_ev,
|
||||||
|
unsigned int hwc[], u64 mmcr[])
|
||||||
|
{
|
||||||
|
u64 mmcr1 = 0;
|
||||||
|
u64 mmcra = 0;
|
||||||
|
unsigned int pmc, unit, byte, psel;
|
||||||
|
unsigned int ttm;
|
||||||
|
int i, isbus, bit, grsel;
|
||||||
|
unsigned int pmc_inuse = 0;
|
||||||
|
unsigned char busbyte[4];
|
||||||
|
unsigned char unituse[16];
|
||||||
|
int ttmuse;
|
||||||
|
|
||||||
|
if (n_ev > 6)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* First pass to count resource use */
|
||||||
|
memset(busbyte, 0, sizeof(busbyte));
|
||||||
|
memset(unituse, 0, sizeof(unituse));
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc > 6)
|
||||||
|
return -1;
|
||||||
|
if (pmc_inuse & (1 << (pmc - 1)))
|
||||||
|
return -1;
|
||||||
|
pmc_inuse |= 1 << (pmc - 1);
|
||||||
|
}
|
||||||
|
if (event[i] & PM_BUSEVENT_MSK) {
|
||||||
|
unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
if (unit > PM_LASTUNIT)
|
||||||
|
return -1;
|
||||||
|
if (unit == PM_ISU0_ALT)
|
||||||
|
unit = PM_ISU0;
|
||||||
|
if (byte >= 4) {
|
||||||
|
if (unit != PM_LSU1)
|
||||||
|
return -1;
|
||||||
|
++unit;
|
||||||
|
byte &= 3;
|
||||||
|
}
|
||||||
|
if (busbyte[byte] && busbyte[byte] != unit)
|
||||||
|
return -1;
|
||||||
|
busbyte[byte] = unit;
|
||||||
|
unituse[unit] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assign resources and set multiplexer selects.
|
||||||
|
*
|
||||||
|
* PM_ISU0 can go either on TTM0 or TTM1, but that's the only
|
||||||
|
* choice we have to deal with.
|
||||||
|
*/
|
||||||
|
if (unituse[PM_ISU0] &
|
||||||
|
(unituse[PM_FPU] | unituse[PM_IFU] | unituse[PM_ISU1])) {
|
||||||
|
unituse[PM_ISU0_ALT] = 1; /* move ISU to TTM1 */
|
||||||
|
unituse[PM_ISU0] = 0;
|
||||||
|
}
|
||||||
|
/* Set TTM[01]SEL fields. */
|
||||||
|
ttmuse = 0;
|
||||||
|
for (i = PM_FPU; i <= PM_ISU1; ++i) {
|
||||||
|
if (!unituse[i])
|
||||||
|
continue;
|
||||||
|
if (ttmuse++)
|
||||||
|
return -1;
|
||||||
|
mmcr1 |= (u64)i << MMCR1_TTM0SEL_SH;
|
||||||
|
}
|
||||||
|
ttmuse = 0;
|
||||||
|
for (; i <= PM_GRS; ++i) {
|
||||||
|
if (!unituse[i])
|
||||||
|
continue;
|
||||||
|
if (ttmuse++)
|
||||||
|
return -1;
|
||||||
|
mmcr1 |= (u64)(i & 3) << MMCR1_TTM1SEL_SH;
|
||||||
|
}
|
||||||
|
if (ttmuse > 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Set byte lane select fields, TTM[23]SEL and GRS_*SEL. */
|
||||||
|
for (byte = 0; byte < 4; ++byte) {
|
||||||
|
unit = busbyte[byte];
|
||||||
|
if (!unit)
|
||||||
|
continue;
|
||||||
|
if (unit == PM_ISU0 && unituse[PM_ISU0_ALT]) {
|
||||||
|
/* get ISU0 through TTM1 rather than TTM0 */
|
||||||
|
unit = PM_ISU0_ALT;
|
||||||
|
} else if (unit == PM_LSU1 + 1) {
|
||||||
|
/* select lower word of LSU1 for this byte */
|
||||||
|
mmcr1 |= 1ull << (MMCR1_TTM3SEL_SH + 3 - byte);
|
||||||
|
}
|
||||||
|
ttm = unit >> 2;
|
||||||
|
mmcr1 |= (u64)ttm << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
psel = event[i] & PM_PMCSEL_MSK;
|
||||||
|
isbus = event[i] & PM_BUSEVENT_MSK;
|
||||||
|
if (!pmc) {
|
||||||
|
/* Bus event or any-PMC direct event */
|
||||||
|
for (pmc = 0; pmc < 4; ++pmc) {
|
||||||
|
if (!(pmc_inuse & (1 << pmc)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pmc >= 4)
|
||||||
|
return -1;
|
||||||
|
pmc_inuse |= 1 << pmc;
|
||||||
|
} else if (pmc <= 4) {
|
||||||
|
/* Direct event */
|
||||||
|
--pmc;
|
||||||
|
if (isbus && (byte & 2) &&
|
||||||
|
(psel == 8 || psel == 0x10 || psel == 0x28))
|
||||||
|
/* add events on higher-numbered bus */
|
||||||
|
mmcr1 |= 1ull << (MMCR1_PMC1_ADDER_SEL_SH - pmc);
|
||||||
|
} else {
|
||||||
|
/* Instructions or run cycles on PMC5/6 */
|
||||||
|
--pmc;
|
||||||
|
}
|
||||||
|
if (isbus && unit == PM_GRS) {
|
||||||
|
bit = psel & 7;
|
||||||
|
grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK;
|
||||||
|
mmcr1 |= (u64)grsel << grsel_shift[bit];
|
||||||
|
}
|
||||||
|
if (power5p_marked_instr_event(event[i]))
|
||||||
|
mmcra |= MMCRA_SAMPLE_ENABLE;
|
||||||
|
if ((psel & 0x58) == 0x40 && (byte & 1) != ((pmc >> 1) & 1))
|
||||||
|
/* select alternate byte lane */
|
||||||
|
psel |= 0x10;
|
||||||
|
if (pmc <= 3)
|
||||||
|
mmcr1 |= psel << MMCR1_PMCSEL_SH(pmc);
|
||||||
|
hwc[i] = pmc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return MMCRx values */
|
||||||
|
mmcr[0] = 0;
|
||||||
|
if (pmc_inuse & 1)
|
||||||
|
mmcr[0] = MMCR0_PMC1CE;
|
||||||
|
if (pmc_inuse & 0x3e)
|
||||||
|
mmcr[0] |= MMCR0_PMCjCE;
|
||||||
|
mmcr[1] = mmcr1;
|
||||||
|
mmcr[2] = mmcra;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void power5p_disable_pmc(unsigned int pmc, u64 mmcr[])
|
||||||
|
{
|
||||||
|
if (pmc <= 3)
|
||||||
|
mmcr[1] &= ~(0x7fUL << MMCR1_PMCSEL_SH(pmc));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int power5p_generic_events[] = {
|
||||||
|
[PERF_COUNT_HW_CPU_CYCLES] = 0xf,
|
||||||
|
[PERF_COUNT_HW_INSTRUCTIONS] = 0x100009,
|
||||||
|
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x1c10a8, /* LD_REF_L1 */
|
||||||
|
[PERF_COUNT_HW_CACHE_MISSES] = 0x3c1088, /* LD_MISS_L1 */
|
||||||
|
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x230e4, /* BR_ISSUED */
|
||||||
|
[PERF_COUNT_HW_BRANCH_MISSES] = 0x230e5, /* BR_MPRED_CR */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define C(x) PERF_COUNT_HW_CACHE_##x
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table of generalized cache-related events.
|
||||||
|
* 0 means not supported, -1 means nonsensical, other values
|
||||||
|
* are event codes.
|
||||||
|
*/
|
||||||
|
static int power5p_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
|
||||||
|
[C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x1c10a8, 0x3c1088 },
|
||||||
|
[C(OP_WRITE)] = { 0x2c10a8, 0xc10c3 },
|
||||||
|
[C(OP_PREFETCH)] = { 0xc70e7, -1 },
|
||||||
|
},
|
||||||
|
[C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { 0, 0 },
|
||||||
|
},
|
||||||
|
[C(LL)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0 },
|
||||||
|
[C(OP_WRITE)] = { 0, 0 },
|
||||||
|
[C(OP_PREFETCH)] = { 0xc50c3, 0 },
|
||||||
|
},
|
||||||
|
[C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0xc20e4, 0x800c4 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x800c0 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x230e4, 0x230e5 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct power_pmu power5p_pmu = {
|
||||||
|
.n_counter = 6,
|
||||||
|
.max_alternatives = MAX_ALT,
|
||||||
|
.add_fields = 0x7000000000055ull,
|
||||||
|
.test_adder = 0x3000040000000ull,
|
||||||
|
.compute_mmcr = power5p_compute_mmcr,
|
||||||
|
.get_constraint = power5p_get_constraint,
|
||||||
|
.get_alternatives = power5p_get_alternatives,
|
||||||
|
.disable_pmc = power5p_disable_pmc,
|
||||||
|
.limited_pmc_event = power5p_limited_pmc_event,
|
||||||
|
.flags = PPMU_LIMITED_PMC5_6,
|
||||||
|
.n_generic = ARRAY_SIZE(power5p_generic_events),
|
||||||
|
.generic_events = power5p_generic_events,
|
||||||
|
.cache_events = &power5p_cache_events,
|
||||||
|
};
|
|
@ -0,0 +1,611 @@
|
||||||
|
/*
|
||||||
|
* Performance counter support for POWER5 (not POWER5++) processors.
|
||||||
|
*
|
||||||
|
* Copyright 2009 Paul Mackerras, IBM Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/perf_counter.h>
|
||||||
|
#include <asm/reg.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in event code for POWER5 (not POWER5++)
|
||||||
|
*/
|
||||||
|
#define PM_PMC_SH 20 /* PMC number (1-based) for direct events */
|
||||||
|
#define PM_PMC_MSK 0xf
|
||||||
|
#define PM_PMC_MSKS (PM_PMC_MSK << PM_PMC_SH)
|
||||||
|
#define PM_UNIT_SH 16 /* TTMMUX number and setting - unit select */
|
||||||
|
#define PM_UNIT_MSK 0xf
|
||||||
|
#define PM_BYTE_SH 12 /* Byte number of event bus to use */
|
||||||
|
#define PM_BYTE_MSK 7
|
||||||
|
#define PM_GRS_SH 8 /* Storage subsystem mux select */
|
||||||
|
#define PM_GRS_MSK 7
|
||||||
|
#define PM_BUSEVENT_MSK 0x80 /* Set if event uses event bus */
|
||||||
|
#define PM_PMCSEL_MSK 0x7f
|
||||||
|
|
||||||
|
/* Values in PM_UNIT field */
|
||||||
|
#define PM_FPU 0
|
||||||
|
#define PM_ISU0 1
|
||||||
|
#define PM_IFU 2
|
||||||
|
#define PM_ISU1 3
|
||||||
|
#define PM_IDU 4
|
||||||
|
#define PM_ISU0_ALT 6
|
||||||
|
#define PM_GRS 7
|
||||||
|
#define PM_LSU0 8
|
||||||
|
#define PM_LSU1 0xc
|
||||||
|
#define PM_LASTUNIT 0xc
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCR1 for POWER5
|
||||||
|
*/
|
||||||
|
#define MMCR1_TTM0SEL_SH 62
|
||||||
|
#define MMCR1_TTM1SEL_SH 60
|
||||||
|
#define MMCR1_TTM2SEL_SH 58
|
||||||
|
#define MMCR1_TTM3SEL_SH 56
|
||||||
|
#define MMCR1_TTMSEL_MSK 3
|
||||||
|
#define MMCR1_TD_CP_DBG0SEL_SH 54
|
||||||
|
#define MMCR1_TD_CP_DBG1SEL_SH 52
|
||||||
|
#define MMCR1_TD_CP_DBG2SEL_SH 50
|
||||||
|
#define MMCR1_TD_CP_DBG3SEL_SH 48
|
||||||
|
#define MMCR1_GRS_L2SEL_SH 46
|
||||||
|
#define MMCR1_GRS_L2SEL_MSK 3
|
||||||
|
#define MMCR1_GRS_L3SEL_SH 44
|
||||||
|
#define MMCR1_GRS_L3SEL_MSK 3
|
||||||
|
#define MMCR1_GRS_MCSEL_SH 41
|
||||||
|
#define MMCR1_GRS_MCSEL_MSK 7
|
||||||
|
#define MMCR1_GRS_FABSEL_SH 39
|
||||||
|
#define MMCR1_GRS_FABSEL_MSK 3
|
||||||
|
#define MMCR1_PMC1_ADDER_SEL_SH 35
|
||||||
|
#define MMCR1_PMC2_ADDER_SEL_SH 34
|
||||||
|
#define MMCR1_PMC3_ADDER_SEL_SH 33
|
||||||
|
#define MMCR1_PMC4_ADDER_SEL_SH 32
|
||||||
|
#define MMCR1_PMC1SEL_SH 25
|
||||||
|
#define MMCR1_PMC2SEL_SH 17
|
||||||
|
#define MMCR1_PMC3SEL_SH 9
|
||||||
|
#define MMCR1_PMC4SEL_SH 1
|
||||||
|
#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8)
|
||||||
|
#define MMCR1_PMCSEL_MSK 0x7f
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCRA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Layout of constraint bits:
|
||||||
|
* 6666555555555544444444443333333333222222222211111111110000000000
|
||||||
|
* 3210987654321098765432109876543210987654321098765432109876543210
|
||||||
|
* <><>[ ><><>< ><> [ >[ >[ >< >< >< >< ><><><><><><>
|
||||||
|
* T0T1 NC G0G1G2 G3 UC PS1PS2 B0 B1 B2 B3 P6P5P4P3P2P1
|
||||||
|
*
|
||||||
|
* T0 - TTM0 constraint
|
||||||
|
* 54-55: TTM0SEL value (0=FPU, 2=IFU, 3=ISU1) 0xc0_0000_0000_0000
|
||||||
|
*
|
||||||
|
* T1 - TTM1 constraint
|
||||||
|
* 52-53: TTM1SEL value (0=IDU, 3=GRS) 0x30_0000_0000_0000
|
||||||
|
*
|
||||||
|
* NC - number of counters
|
||||||
|
* 51: NC error 0x0008_0000_0000_0000
|
||||||
|
* 48-50: number of events needing PMC1-4 0x0007_0000_0000_0000
|
||||||
|
*
|
||||||
|
* G0..G3 - GRS mux constraints
|
||||||
|
* 46-47: GRS_L2SEL value
|
||||||
|
* 44-45: GRS_L3SEL value
|
||||||
|
* 41-44: GRS_MCSEL value
|
||||||
|
* 39-40: GRS_FABSEL value
|
||||||
|
* Note that these match up with their bit positions in MMCR1
|
||||||
|
*
|
||||||
|
* UC - unit constraint: can't have all three of FPU|IFU|ISU1, ISU0, IDU|GRS
|
||||||
|
* 37: UC3 error 0x20_0000_0000
|
||||||
|
* 36: FPU|IFU|ISU1 events needed 0x10_0000_0000
|
||||||
|
* 35: ISU0 events needed 0x08_0000_0000
|
||||||
|
* 34: IDU|GRS events needed 0x04_0000_0000
|
||||||
|
*
|
||||||
|
* PS1
|
||||||
|
* 33: PS1 error 0x2_0000_0000
|
||||||
|
* 31-32: count of events needing PMC1/2 0x1_8000_0000
|
||||||
|
*
|
||||||
|
* PS2
|
||||||
|
* 30: PS2 error 0x4000_0000
|
||||||
|
* 28-29: count of events needing PMC3/4 0x3000_0000
|
||||||
|
*
|
||||||
|
* B0
|
||||||
|
* 24-27: Byte 0 event source 0x0f00_0000
|
||||||
|
* Encoding as for the event code
|
||||||
|
*
|
||||||
|
* B1, B2, B3
|
||||||
|
* 20-23, 16-19, 12-15: Byte 1, 2, 3 event sources
|
||||||
|
*
|
||||||
|
* P1..P6
|
||||||
|
* 0-11: Count of events needing PMC1..PMC6
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const int grsel_shift[8] = {
|
||||||
|
MMCR1_GRS_L2SEL_SH, MMCR1_GRS_L2SEL_SH, MMCR1_GRS_L2SEL_SH,
|
||||||
|
MMCR1_GRS_L3SEL_SH, MMCR1_GRS_L3SEL_SH, MMCR1_GRS_L3SEL_SH,
|
||||||
|
MMCR1_GRS_MCSEL_SH, MMCR1_GRS_FABSEL_SH
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Masks and values for using events from the various units */
|
||||||
|
static u64 unit_cons[PM_LASTUNIT+1][2] = {
|
||||||
|
[PM_FPU] = { 0xc0002000000000ull, 0x00001000000000ull },
|
||||||
|
[PM_ISU0] = { 0x00002000000000ull, 0x00000800000000ull },
|
||||||
|
[PM_ISU1] = { 0xc0002000000000ull, 0xc0001000000000ull },
|
||||||
|
[PM_IFU] = { 0xc0002000000000ull, 0x80001000000000ull },
|
||||||
|
[PM_IDU] = { 0x30002000000000ull, 0x00000400000000ull },
|
||||||
|
[PM_GRS] = { 0x30002000000000ull, 0x30000400000000ull },
|
||||||
|
};
|
||||||
|
|
||||||
|
static int power5_get_constraint(u64 event, u64 *maskp, u64 *valp)
|
||||||
|
{
|
||||||
|
int pmc, byte, unit, sh;
|
||||||
|
int bit, fmask;
|
||||||
|
u64 mask = 0, value = 0;
|
||||||
|
int grp = -1;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc > 6)
|
||||||
|
return -1;
|
||||||
|
sh = (pmc - 1) * 2;
|
||||||
|
mask |= 2 << sh;
|
||||||
|
value |= 1 << sh;
|
||||||
|
if (pmc <= 4)
|
||||||
|
grp = (pmc - 1) >> 1;
|
||||||
|
else if (event != 0x500009 && event != 0x600005)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (event & PM_BUSEVENT_MSK) {
|
||||||
|
unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
if (unit > PM_LASTUNIT)
|
||||||
|
return -1;
|
||||||
|
if (unit == PM_ISU0_ALT)
|
||||||
|
unit = PM_ISU0;
|
||||||
|
mask |= unit_cons[unit][0];
|
||||||
|
value |= unit_cons[unit][1];
|
||||||
|
byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
if (byte >= 4) {
|
||||||
|
if (unit != PM_LSU1)
|
||||||
|
return -1;
|
||||||
|
/* Map LSU1 low word (bytes 4-7) to unit LSU1+1 */
|
||||||
|
++unit;
|
||||||
|
byte &= 3;
|
||||||
|
}
|
||||||
|
if (unit == PM_GRS) {
|
||||||
|
bit = event & 7;
|
||||||
|
fmask = (bit == 6)? 7: 3;
|
||||||
|
sh = grsel_shift[bit];
|
||||||
|
mask |= (u64)fmask << sh;
|
||||||
|
value |= (u64)((event >> PM_GRS_SH) & fmask) << sh;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Bus events on bytes 0 and 2 can be counted
|
||||||
|
* on PMC1/2; bytes 1 and 3 on PMC3/4.
|
||||||
|
*/
|
||||||
|
if (!pmc)
|
||||||
|
grp = byte & 1;
|
||||||
|
/* Set byte lane select field */
|
||||||
|
mask |= 0xfULL << (24 - 4 * byte);
|
||||||
|
value |= (u64)unit << (24 - 4 * byte);
|
||||||
|
}
|
||||||
|
if (grp == 0) {
|
||||||
|
/* increment PMC1/2 field */
|
||||||
|
mask |= 0x200000000ull;
|
||||||
|
value |= 0x080000000ull;
|
||||||
|
} else if (grp == 1) {
|
||||||
|
/* increment PMC3/4 field */
|
||||||
|
mask |= 0x40000000ull;
|
||||||
|
value |= 0x10000000ull;
|
||||||
|
}
|
||||||
|
if (pmc < 5) {
|
||||||
|
/* need a counter from PMC1-4 set */
|
||||||
|
mask |= 0x8000000000000ull;
|
||||||
|
value |= 0x1000000000000ull;
|
||||||
|
}
|
||||||
|
*maskp = mask;
|
||||||
|
*valp = value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_ALT 3 /* at most 3 alternatives for any event */
|
||||||
|
|
||||||
|
static const unsigned int event_alternatives[][MAX_ALT] = {
|
||||||
|
{ 0x120e4, 0x400002 }, /* PM_GRP_DISP_REJECT */
|
||||||
|
{ 0x410c7, 0x441084 }, /* PM_THRD_L2MISS_BOTH_CYC */
|
||||||
|
{ 0x100005, 0x600005 }, /* PM_RUN_CYC */
|
||||||
|
{ 0x100009, 0x200009, 0x500009 }, /* PM_INST_CMPL */
|
||||||
|
{ 0x300009, 0x400009 }, /* PM_INST_DISP */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan the alternatives table for a match and return the
|
||||||
|
* index into the alternatives table if found, else -1.
|
||||||
|
*/
|
||||||
|
static int find_alternative(u64 event)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(event_alternatives); ++i) {
|
||||||
|
if (event < event_alternatives[i][0])
|
||||||
|
break;
|
||||||
|
for (j = 0; j < MAX_ALT && event_alternatives[i][j]; ++j)
|
||||||
|
if (event == event_alternatives[i][j])
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned char bytedecode_alternatives[4][4] = {
|
||||||
|
/* PMC 1 */ { 0x21, 0x23, 0x25, 0x27 },
|
||||||
|
/* PMC 2 */ { 0x07, 0x17, 0x0e, 0x1e },
|
||||||
|
/* PMC 3 */ { 0x20, 0x22, 0x24, 0x26 },
|
||||||
|
/* PMC 4 */ { 0x07, 0x17, 0x0e, 0x1e }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some direct events for decodes of event bus byte 3 have alternative
|
||||||
|
* PMCSEL values on other counters. This returns the alternative
|
||||||
|
* event code for those that do, or -1 otherwise.
|
||||||
|
*/
|
||||||
|
static s64 find_alternative_bdecode(u64 event)
|
||||||
|
{
|
||||||
|
int pmc, altpmc, pp, j;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc == 0 || pmc > 4)
|
||||||
|
return -1;
|
||||||
|
altpmc = 5 - pmc; /* 1 <-> 4, 2 <-> 3 */
|
||||||
|
pp = event & PM_PMCSEL_MSK;
|
||||||
|
for (j = 0; j < 4; ++j) {
|
||||||
|
if (bytedecode_alternatives[pmc - 1][j] == pp) {
|
||||||
|
return (event & ~(PM_PMC_MSKS | PM_PMCSEL_MSK)) |
|
||||||
|
(altpmc << PM_PMC_SH) |
|
||||||
|
bytedecode_alternatives[altpmc - 1][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int power5_get_alternatives(u64 event, unsigned int flags, u64 alt[])
|
||||||
|
{
|
||||||
|
int i, j, nalt = 1;
|
||||||
|
s64 ae;
|
||||||
|
|
||||||
|
alt[0] = event;
|
||||||
|
nalt = 1;
|
||||||
|
i = find_alternative(event);
|
||||||
|
if (i >= 0) {
|
||||||
|
for (j = 0; j < MAX_ALT; ++j) {
|
||||||
|
ae = event_alternatives[i][j];
|
||||||
|
if (ae && ae != event)
|
||||||
|
alt[nalt++] = ae;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ae = find_alternative_bdecode(event);
|
||||||
|
if (ae > 0)
|
||||||
|
alt[nalt++] = ae;
|
||||||
|
}
|
||||||
|
return nalt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map of which direct events on which PMCs are marked instruction events.
|
||||||
|
* Indexed by PMCSEL value, bit i (LE) set if PMC i is a marked event.
|
||||||
|
* Bit 0 is set if it is marked for all PMCs.
|
||||||
|
* The 0x80 bit indicates a byte decode PMCSEL value.
|
||||||
|
*/
|
||||||
|
static unsigned char direct_event_is_marked[0x28] = {
|
||||||
|
0, /* 00 */
|
||||||
|
0x1f, /* 01 PM_IOPS_CMPL */
|
||||||
|
0x2, /* 02 PM_MRK_GRP_DISP */
|
||||||
|
0xe, /* 03 PM_MRK_ST_CMPL, PM_MRK_ST_GPS, PM_MRK_ST_CMPL_INT */
|
||||||
|
0, /* 04 */
|
||||||
|
0x1c, /* 05 PM_MRK_BRU_FIN, PM_MRK_INST_FIN, PM_MRK_CRU_FIN */
|
||||||
|
0x80, /* 06 */
|
||||||
|
0x80, /* 07 */
|
||||||
|
0, 0, 0,/* 08 - 0a */
|
||||||
|
0x18, /* 0b PM_THRESH_TIMEO, PM_MRK_GRP_TIMEO */
|
||||||
|
0, /* 0c */
|
||||||
|
0x80, /* 0d */
|
||||||
|
0x80, /* 0e */
|
||||||
|
0, /* 0f */
|
||||||
|
0, /* 10 */
|
||||||
|
0x14, /* 11 PM_MRK_GRP_BR_REDIR, PM_MRK_GRP_IC_MISS */
|
||||||
|
0, /* 12 */
|
||||||
|
0x10, /* 13 PM_MRK_GRP_CMPL */
|
||||||
|
0x1f, /* 14 PM_GRP_MRK, PM_MRK_{FXU,FPU,LSU}_FIN */
|
||||||
|
0x2, /* 15 PM_MRK_GRP_ISSUED */
|
||||||
|
0x80, /* 16 */
|
||||||
|
0x80, /* 17 */
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
0x80, /* 1d */
|
||||||
|
0x80, /* 1e */
|
||||||
|
0, /* 1f */
|
||||||
|
0x80, /* 20 */
|
||||||
|
0x80, /* 21 */
|
||||||
|
0x80, /* 22 */
|
||||||
|
0x80, /* 23 */
|
||||||
|
0x80, /* 24 */
|
||||||
|
0x80, /* 25 */
|
||||||
|
0x80, /* 26 */
|
||||||
|
0x80, /* 27 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if event counts things relating to marked instructions
|
||||||
|
* and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not.
|
||||||
|
*/
|
||||||
|
static int power5_marked_instr_event(u64 event)
|
||||||
|
{
|
||||||
|
int pmc, psel;
|
||||||
|
int bit, byte, unit;
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
psel = event & PM_PMCSEL_MSK;
|
||||||
|
if (pmc >= 5)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bit = -1;
|
||||||
|
if (psel < sizeof(direct_event_is_marked)) {
|
||||||
|
if (direct_event_is_marked[psel] & (1 << pmc))
|
||||||
|
return 1;
|
||||||
|
if (direct_event_is_marked[psel] & 0x80)
|
||||||
|
bit = 4;
|
||||||
|
else if (psel == 0x08)
|
||||||
|
bit = pmc - 1;
|
||||||
|
else if (psel == 0x10)
|
||||||
|
bit = 4 - pmc;
|
||||||
|
else if (psel == 0x1b && (pmc == 1 || pmc == 3))
|
||||||
|
bit = 4;
|
||||||
|
} else if ((psel & 0x58) == 0x40)
|
||||||
|
bit = psel & 7;
|
||||||
|
|
||||||
|
if (!(event & PM_BUSEVENT_MSK))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
if (unit == PM_LSU0) {
|
||||||
|
/* byte 1 bits 0-7, byte 2 bits 0,2-4,6 */
|
||||||
|
mask = 0x5dff00;
|
||||||
|
} else if (unit == PM_LSU1 && byte >= 4) {
|
||||||
|
byte -= 4;
|
||||||
|
/* byte 4 bits 1,3,5,7, byte 5 bits 6-7, byte 7 bits 0-4,6 */
|
||||||
|
mask = 0x5f00c0aa;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (mask >> (byte * 8 + bit)) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int power5_compute_mmcr(u64 event[], int n_ev,
|
||||||
|
unsigned int hwc[], u64 mmcr[])
|
||||||
|
{
|
||||||
|
u64 mmcr1 = 0;
|
||||||
|
u64 mmcra = 0;
|
||||||
|
unsigned int pmc, unit, byte, psel;
|
||||||
|
unsigned int ttm, grp;
|
||||||
|
int i, isbus, bit, grsel;
|
||||||
|
unsigned int pmc_inuse = 0;
|
||||||
|
unsigned int pmc_grp_use[2];
|
||||||
|
unsigned char busbyte[4];
|
||||||
|
unsigned char unituse[16];
|
||||||
|
int ttmuse;
|
||||||
|
|
||||||
|
if (n_ev > 6)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* First pass to count resource use */
|
||||||
|
pmc_grp_use[0] = pmc_grp_use[1] = 0;
|
||||||
|
memset(busbyte, 0, sizeof(busbyte));
|
||||||
|
memset(unituse, 0, sizeof(unituse));
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc > 6)
|
||||||
|
return -1;
|
||||||
|
if (pmc_inuse & (1 << (pmc - 1)))
|
||||||
|
return -1;
|
||||||
|
pmc_inuse |= 1 << (pmc - 1);
|
||||||
|
/* count 1/2 vs 3/4 use */
|
||||||
|
if (pmc <= 4)
|
||||||
|
++pmc_grp_use[(pmc - 1) >> 1];
|
||||||
|
}
|
||||||
|
if (event[i] & PM_BUSEVENT_MSK) {
|
||||||
|
unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
if (unit > PM_LASTUNIT)
|
||||||
|
return -1;
|
||||||
|
if (unit == PM_ISU0_ALT)
|
||||||
|
unit = PM_ISU0;
|
||||||
|
if (byte >= 4) {
|
||||||
|
if (unit != PM_LSU1)
|
||||||
|
return -1;
|
||||||
|
++unit;
|
||||||
|
byte &= 3;
|
||||||
|
}
|
||||||
|
if (!pmc)
|
||||||
|
++pmc_grp_use[byte & 1];
|
||||||
|
if (busbyte[byte] && busbyte[byte] != unit)
|
||||||
|
return -1;
|
||||||
|
busbyte[byte] = unit;
|
||||||
|
unituse[unit] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pmc_grp_use[0] > 2 || pmc_grp_use[1] > 2)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assign resources and set multiplexer selects.
|
||||||
|
*
|
||||||
|
* PM_ISU0 can go either on TTM0 or TTM1, but that's the only
|
||||||
|
* choice we have to deal with.
|
||||||
|
*/
|
||||||
|
if (unituse[PM_ISU0] &
|
||||||
|
(unituse[PM_FPU] | unituse[PM_IFU] | unituse[PM_ISU1])) {
|
||||||
|
unituse[PM_ISU0_ALT] = 1; /* move ISU to TTM1 */
|
||||||
|
unituse[PM_ISU0] = 0;
|
||||||
|
}
|
||||||
|
/* Set TTM[01]SEL fields. */
|
||||||
|
ttmuse = 0;
|
||||||
|
for (i = PM_FPU; i <= PM_ISU1; ++i) {
|
||||||
|
if (!unituse[i])
|
||||||
|
continue;
|
||||||
|
if (ttmuse++)
|
||||||
|
return -1;
|
||||||
|
mmcr1 |= (u64)i << MMCR1_TTM0SEL_SH;
|
||||||
|
}
|
||||||
|
ttmuse = 0;
|
||||||
|
for (; i <= PM_GRS; ++i) {
|
||||||
|
if (!unituse[i])
|
||||||
|
continue;
|
||||||
|
if (ttmuse++)
|
||||||
|
return -1;
|
||||||
|
mmcr1 |= (u64)(i & 3) << MMCR1_TTM1SEL_SH;
|
||||||
|
}
|
||||||
|
if (ttmuse > 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Set byte lane select fields, TTM[23]SEL and GRS_*SEL. */
|
||||||
|
for (byte = 0; byte < 4; ++byte) {
|
||||||
|
unit = busbyte[byte];
|
||||||
|
if (!unit)
|
||||||
|
continue;
|
||||||
|
if (unit == PM_ISU0 && unituse[PM_ISU0_ALT]) {
|
||||||
|
/* get ISU0 through TTM1 rather than TTM0 */
|
||||||
|
unit = PM_ISU0_ALT;
|
||||||
|
} else if (unit == PM_LSU1 + 1) {
|
||||||
|
/* select lower word of LSU1 for this byte */
|
||||||
|
mmcr1 |= 1ull << (MMCR1_TTM3SEL_SH + 3 - byte);
|
||||||
|
}
|
||||||
|
ttm = unit >> 2;
|
||||||
|
mmcr1 |= (u64)ttm << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
psel = event[i] & PM_PMCSEL_MSK;
|
||||||
|
isbus = event[i] & PM_BUSEVENT_MSK;
|
||||||
|
if (!pmc) {
|
||||||
|
/* Bus event or any-PMC direct event */
|
||||||
|
for (pmc = 0; pmc < 4; ++pmc) {
|
||||||
|
if (pmc_inuse & (1 << pmc))
|
||||||
|
continue;
|
||||||
|
grp = (pmc >> 1) & 1;
|
||||||
|
if (isbus) {
|
||||||
|
if (grp == (byte & 1))
|
||||||
|
break;
|
||||||
|
} else if (pmc_grp_use[grp] < 2) {
|
||||||
|
++pmc_grp_use[grp];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pmc_inuse |= 1 << pmc;
|
||||||
|
} else if (pmc <= 4) {
|
||||||
|
/* Direct event */
|
||||||
|
--pmc;
|
||||||
|
if ((psel == 8 || psel == 0x10) && isbus && (byte & 2))
|
||||||
|
/* add events on higher-numbered bus */
|
||||||
|
mmcr1 |= 1ull << (MMCR1_PMC1_ADDER_SEL_SH - pmc);
|
||||||
|
} else {
|
||||||
|
/* Instructions or run cycles on PMC5/6 */
|
||||||
|
--pmc;
|
||||||
|
}
|
||||||
|
if (isbus && unit == PM_GRS) {
|
||||||
|
bit = psel & 7;
|
||||||
|
grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK;
|
||||||
|
mmcr1 |= (u64)grsel << grsel_shift[bit];
|
||||||
|
}
|
||||||
|
if (power5_marked_instr_event(event[i]))
|
||||||
|
mmcra |= MMCRA_SAMPLE_ENABLE;
|
||||||
|
if (pmc <= 3)
|
||||||
|
mmcr1 |= psel << MMCR1_PMCSEL_SH(pmc);
|
||||||
|
hwc[i] = pmc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return MMCRx values */
|
||||||
|
mmcr[0] = 0;
|
||||||
|
if (pmc_inuse & 1)
|
||||||
|
mmcr[0] = MMCR0_PMC1CE;
|
||||||
|
if (pmc_inuse & 0x3e)
|
||||||
|
mmcr[0] |= MMCR0_PMCjCE;
|
||||||
|
mmcr[1] = mmcr1;
|
||||||
|
mmcr[2] = mmcra;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void power5_disable_pmc(unsigned int pmc, u64 mmcr[])
|
||||||
|
{
|
||||||
|
if (pmc <= 3)
|
||||||
|
mmcr[1] &= ~(0x7fUL << MMCR1_PMCSEL_SH(pmc));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int power5_generic_events[] = {
|
||||||
|
[PERF_COUNT_HW_CPU_CYCLES] = 0xf,
|
||||||
|
[PERF_COUNT_HW_INSTRUCTIONS] = 0x100009,
|
||||||
|
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x4c1090, /* LD_REF_L1 */
|
||||||
|
[PERF_COUNT_HW_CACHE_MISSES] = 0x3c1088, /* LD_MISS_L1 */
|
||||||
|
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x230e4, /* BR_ISSUED */
|
||||||
|
[PERF_COUNT_HW_BRANCH_MISSES] = 0x230e5, /* BR_MPRED_CR */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define C(x) PERF_COUNT_HW_CACHE_##x
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table of generalized cache-related events.
|
||||||
|
* 0 means not supported, -1 means nonsensical, other values
|
||||||
|
* are event codes.
|
||||||
|
*/
|
||||||
|
static int power5_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
|
||||||
|
[C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x4c1090, 0x3c1088 },
|
||||||
|
[C(OP_WRITE)] = { 0x3c1090, 0xc10c3 },
|
||||||
|
[C(OP_PREFETCH)] = { 0xc70e7, 0 },
|
||||||
|
},
|
||||||
|
[C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { 0, 0 },
|
||||||
|
},
|
||||||
|
[C(LL)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x3c309b },
|
||||||
|
[C(OP_WRITE)] = { 0, 0 },
|
||||||
|
[C(OP_PREFETCH)] = { 0xc50c3, 0 },
|
||||||
|
},
|
||||||
|
[C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x2c4090, 0x800c4 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x800c0 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x230e4, 0x230e5 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct power_pmu power5_pmu = {
|
||||||
|
.n_counter = 6,
|
||||||
|
.max_alternatives = MAX_ALT,
|
||||||
|
.add_fields = 0x7000090000555ull,
|
||||||
|
.test_adder = 0x3000490000000ull,
|
||||||
|
.compute_mmcr = power5_compute_mmcr,
|
||||||
|
.get_constraint = power5_get_constraint,
|
||||||
|
.get_alternatives = power5_get_alternatives,
|
||||||
|
.disable_pmc = power5_disable_pmc,
|
||||||
|
.n_generic = ARRAY_SIZE(power5_generic_events),
|
||||||
|
.generic_events = power5_generic_events,
|
||||||
|
.cache_events = &power5_cache_events,
|
||||||
|
};
|
|
@ -0,0 +1,532 @@
|
||||||
|
/*
|
||||||
|
* Performance counter support for POWER6 processors.
|
||||||
|
*
|
||||||
|
* Copyright 2008-2009 Paul Mackerras, IBM Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/perf_counter.h>
|
||||||
|
#include <asm/reg.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in event code for POWER6
|
||||||
|
*/
|
||||||
|
#define PM_PMC_SH 20 /* PMC number (1-based) for direct events */
|
||||||
|
#define PM_PMC_MSK 0x7
|
||||||
|
#define PM_PMC_MSKS (PM_PMC_MSK << PM_PMC_SH)
|
||||||
|
#define PM_UNIT_SH 16 /* Unit event comes (TTMxSEL encoding) */
|
||||||
|
#define PM_UNIT_MSK 0xf
|
||||||
|
#define PM_UNIT_MSKS (PM_UNIT_MSK << PM_UNIT_SH)
|
||||||
|
#define PM_LLAV 0x8000 /* Load lookahead match value */
|
||||||
|
#define PM_LLA 0x4000 /* Load lookahead match enable */
|
||||||
|
#define PM_BYTE_SH 12 /* Byte of event bus to use */
|
||||||
|
#define PM_BYTE_MSK 3
|
||||||
|
#define PM_SUBUNIT_SH 8 /* Subunit event comes from (NEST_SEL enc.) */
|
||||||
|
#define PM_SUBUNIT_MSK 7
|
||||||
|
#define PM_SUBUNIT_MSKS (PM_SUBUNIT_MSK << PM_SUBUNIT_SH)
|
||||||
|
#define PM_PMCSEL_MSK 0xff /* PMCxSEL value */
|
||||||
|
#define PM_BUSEVENT_MSK 0xf3700
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCR1 for POWER6
|
||||||
|
*/
|
||||||
|
#define MMCR1_TTM0SEL_SH 60
|
||||||
|
#define MMCR1_TTMSEL_SH(n) (MMCR1_TTM0SEL_SH - (n) * 4)
|
||||||
|
#define MMCR1_TTMSEL_MSK 0xf
|
||||||
|
#define MMCR1_TTMSEL(m, n) (((m) >> MMCR1_TTMSEL_SH(n)) & MMCR1_TTMSEL_MSK)
|
||||||
|
#define MMCR1_NESTSEL_SH 45
|
||||||
|
#define MMCR1_NESTSEL_MSK 0x7
|
||||||
|
#define MMCR1_NESTSEL(m) (((m) >> MMCR1_NESTSEL_SH) & MMCR1_NESTSEL_MSK)
|
||||||
|
#define MMCR1_PMC1_LLA ((u64)1 << 44)
|
||||||
|
#define MMCR1_PMC1_LLA_VALUE ((u64)1 << 39)
|
||||||
|
#define MMCR1_PMC1_ADDR_SEL ((u64)1 << 35)
|
||||||
|
#define MMCR1_PMC1SEL_SH 24
|
||||||
|
#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8)
|
||||||
|
#define MMCR1_PMCSEL_MSK 0xff
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map of which direct events on which PMCs are marked instruction events.
|
||||||
|
* Indexed by PMCSEL value >> 1.
|
||||||
|
* Bottom 4 bits are a map of which PMCs are interesting,
|
||||||
|
* top 4 bits say what sort of event:
|
||||||
|
* 0 = direct marked event,
|
||||||
|
* 1 = byte decode event,
|
||||||
|
* 4 = add/and event (PMC1 -> bits 0 & 4),
|
||||||
|
* 5 = add/and event (PMC1 -> bits 1 & 5),
|
||||||
|
* 6 = add/and event (PMC1 -> bits 2 & 6),
|
||||||
|
* 7 = add/and event (PMC1 -> bits 3 & 7).
|
||||||
|
*/
|
||||||
|
static unsigned char direct_event_is_marked[0x60 >> 1] = {
|
||||||
|
0, /* 00 */
|
||||||
|
0, /* 02 */
|
||||||
|
0, /* 04 */
|
||||||
|
0x07, /* 06 PM_MRK_ST_CMPL, PM_MRK_ST_GPS, PM_MRK_ST_CMPL_INT */
|
||||||
|
0x04, /* 08 PM_MRK_DFU_FIN */
|
||||||
|
0x06, /* 0a PM_MRK_IFU_FIN, PM_MRK_INST_FIN */
|
||||||
|
0, /* 0c */
|
||||||
|
0, /* 0e */
|
||||||
|
0x02, /* 10 PM_MRK_INST_DISP */
|
||||||
|
0x08, /* 12 PM_MRK_LSU_DERAT_MISS */
|
||||||
|
0, /* 14 */
|
||||||
|
0, /* 16 */
|
||||||
|
0x0c, /* 18 PM_THRESH_TIMEO, PM_MRK_INST_FIN */
|
||||||
|
0x0f, /* 1a PM_MRK_INST_DISP, PM_MRK_{FXU,FPU,LSU}_FIN */
|
||||||
|
0x01, /* 1c PM_MRK_INST_ISSUED */
|
||||||
|
0, /* 1e */
|
||||||
|
0, /* 20 */
|
||||||
|
0, /* 22 */
|
||||||
|
0, /* 24 */
|
||||||
|
0, /* 26 */
|
||||||
|
0x15, /* 28 PM_MRK_DATA_FROM_L2MISS, PM_MRK_DATA_FROM_L3MISS */
|
||||||
|
0, /* 2a */
|
||||||
|
0, /* 2c */
|
||||||
|
0, /* 2e */
|
||||||
|
0x4f, /* 30 */
|
||||||
|
0x7f, /* 32 */
|
||||||
|
0x4f, /* 34 */
|
||||||
|
0x5f, /* 36 */
|
||||||
|
0x6f, /* 38 */
|
||||||
|
0x4f, /* 3a */
|
||||||
|
0, /* 3c */
|
||||||
|
0x08, /* 3e PM_MRK_INST_TIMEO */
|
||||||
|
0x1f, /* 40 */
|
||||||
|
0x1f, /* 42 */
|
||||||
|
0x1f, /* 44 */
|
||||||
|
0x1f, /* 46 */
|
||||||
|
0x1f, /* 48 */
|
||||||
|
0x1f, /* 4a */
|
||||||
|
0x1f, /* 4c */
|
||||||
|
0x1f, /* 4e */
|
||||||
|
0, /* 50 */
|
||||||
|
0x05, /* 52 PM_MRK_BR_TAKEN, PM_MRK_BR_MPRED */
|
||||||
|
0x1c, /* 54 PM_MRK_PTEG_FROM_L3MISS, PM_MRK_PTEG_FROM_L2MISS */
|
||||||
|
0x02, /* 56 PM_MRK_LD_MISS_L1 */
|
||||||
|
0, /* 58 */
|
||||||
|
0, /* 5a */
|
||||||
|
0, /* 5c */
|
||||||
|
0, /* 5e */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Masks showing for each unit which bits are marked events.
|
||||||
|
* These masks are in LE order, i.e. 0x00000001 is byte 0, bit 0.
|
||||||
|
*/
|
||||||
|
static u32 marked_bus_events[16] = {
|
||||||
|
0x01000000, /* direct events set 1: byte 3 bit 0 */
|
||||||
|
0x00010000, /* direct events set 2: byte 2 bit 0 */
|
||||||
|
0, 0, 0, 0, /* IDU, IFU, nest: nothing */
|
||||||
|
0x00000088, /* VMX set 1: byte 0 bits 3, 7 */
|
||||||
|
0x000000c0, /* VMX set 2: byte 0 bits 4-7 */
|
||||||
|
0x04010000, /* LSU set 1: byte 2 bit 0, byte 3 bit 2 */
|
||||||
|
0xff010000u, /* LSU set 2: byte 2 bit 0, all of byte 3 */
|
||||||
|
0, /* LSU set 3 */
|
||||||
|
0x00000010, /* VMX set 3: byte 0 bit 4 */
|
||||||
|
0, /* BFP set 1 */
|
||||||
|
0x00000022, /* BFP set 2: byte 0 bits 1, 5 */
|
||||||
|
0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if event counts things relating to marked instructions
|
||||||
|
* and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not.
|
||||||
|
*/
|
||||||
|
static int power6_marked_instr_event(u64 event)
|
||||||
|
{
|
||||||
|
int pmc, psel, ptype;
|
||||||
|
int bit, byte, unit;
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
psel = (event & PM_PMCSEL_MSK) >> 1; /* drop edge/level bit */
|
||||||
|
if (pmc >= 5)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bit = -1;
|
||||||
|
if (psel < sizeof(direct_event_is_marked)) {
|
||||||
|
ptype = direct_event_is_marked[psel];
|
||||||
|
if (pmc == 0 || !(ptype & (1 << (pmc - 1))))
|
||||||
|
return 0;
|
||||||
|
ptype >>= 4;
|
||||||
|
if (ptype == 0)
|
||||||
|
return 1;
|
||||||
|
if (ptype == 1)
|
||||||
|
bit = 0;
|
||||||
|
else
|
||||||
|
bit = ptype ^ (pmc - 1);
|
||||||
|
} else if ((psel & 0x48) == 0x40)
|
||||||
|
bit = psel & 7;
|
||||||
|
|
||||||
|
if (!(event & PM_BUSEVENT_MSK) || bit == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
mask = marked_bus_events[unit];
|
||||||
|
return (mask >> (byte * 8 + bit)) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assign PMC numbers and compute MMCR1 value for a set of events
|
||||||
|
*/
|
||||||
|
static int p6_compute_mmcr(u64 event[], int n_ev,
|
||||||
|
unsigned int hwc[], u64 mmcr[])
|
||||||
|
{
|
||||||
|
u64 mmcr1 = 0;
|
||||||
|
u64 mmcra = 0;
|
||||||
|
int i;
|
||||||
|
unsigned int pmc, ev, b, u, s, psel;
|
||||||
|
unsigned int ttmset = 0;
|
||||||
|
unsigned int pmc_inuse = 0;
|
||||||
|
|
||||||
|
if (n_ev > 6)
|
||||||
|
return -1;
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc_inuse & (1 << (pmc - 1)))
|
||||||
|
return -1; /* collision! */
|
||||||
|
pmc_inuse |= 1 << (pmc - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
ev = event[i];
|
||||||
|
pmc = (ev >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
--pmc;
|
||||||
|
} else {
|
||||||
|
/* can go on any PMC; find a free one */
|
||||||
|
for (pmc = 0; pmc < 4; ++pmc)
|
||||||
|
if (!(pmc_inuse & (1 << pmc)))
|
||||||
|
break;
|
||||||
|
if (pmc >= 4)
|
||||||
|
return -1;
|
||||||
|
pmc_inuse |= 1 << pmc;
|
||||||
|
}
|
||||||
|
hwc[i] = pmc;
|
||||||
|
psel = ev & PM_PMCSEL_MSK;
|
||||||
|
if (ev & PM_BUSEVENT_MSK) {
|
||||||
|
/* this event uses the event bus */
|
||||||
|
b = (ev >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
u = (ev >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
/* check for conflict on this byte of event bus */
|
||||||
|
if ((ttmset & (1 << b)) && MMCR1_TTMSEL(mmcr1, b) != u)
|
||||||
|
return -1;
|
||||||
|
mmcr1 |= (u64)u << MMCR1_TTMSEL_SH(b);
|
||||||
|
ttmset |= 1 << b;
|
||||||
|
if (u == 5) {
|
||||||
|
/* Nest events have a further mux */
|
||||||
|
s = (ev >> PM_SUBUNIT_SH) & PM_SUBUNIT_MSK;
|
||||||
|
if ((ttmset & 0x10) &&
|
||||||
|
MMCR1_NESTSEL(mmcr1) != s)
|
||||||
|
return -1;
|
||||||
|
ttmset |= 0x10;
|
||||||
|
mmcr1 |= (u64)s << MMCR1_NESTSEL_SH;
|
||||||
|
}
|
||||||
|
if (0x30 <= psel && psel <= 0x3d) {
|
||||||
|
/* these need the PMCx_ADDR_SEL bits */
|
||||||
|
if (b >= 2)
|
||||||
|
mmcr1 |= MMCR1_PMC1_ADDR_SEL >> pmc;
|
||||||
|
}
|
||||||
|
/* bus select values are different for PMC3/4 */
|
||||||
|
if (pmc >= 2 && (psel & 0x90) == 0x80)
|
||||||
|
psel ^= 0x20;
|
||||||
|
}
|
||||||
|
if (ev & PM_LLA) {
|
||||||
|
mmcr1 |= MMCR1_PMC1_LLA >> pmc;
|
||||||
|
if (ev & PM_LLAV)
|
||||||
|
mmcr1 |= MMCR1_PMC1_LLA_VALUE >> pmc;
|
||||||
|
}
|
||||||
|
if (power6_marked_instr_event(event[i]))
|
||||||
|
mmcra |= MMCRA_SAMPLE_ENABLE;
|
||||||
|
if (pmc < 4)
|
||||||
|
mmcr1 |= (u64)psel << MMCR1_PMCSEL_SH(pmc);
|
||||||
|
}
|
||||||
|
mmcr[0] = 0;
|
||||||
|
if (pmc_inuse & 1)
|
||||||
|
mmcr[0] = MMCR0_PMC1CE;
|
||||||
|
if (pmc_inuse & 0xe)
|
||||||
|
mmcr[0] |= MMCR0_PMCjCE;
|
||||||
|
mmcr[1] = mmcr1;
|
||||||
|
mmcr[2] = mmcra;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Layout of constraint bits:
|
||||||
|
*
|
||||||
|
* 0-1 add field: number of uses of PMC1 (max 1)
|
||||||
|
* 2-3, 4-5, 6-7, 8-9, 10-11: ditto for PMC2, 3, 4, 5, 6
|
||||||
|
* 12-15 add field: number of uses of PMC1-4 (max 4)
|
||||||
|
* 16-19 select field: unit on byte 0 of event bus
|
||||||
|
* 20-23, 24-27, 28-31 ditto for bytes 1, 2, 3
|
||||||
|
* 32-34 select field: nest (subunit) event selector
|
||||||
|
*/
|
||||||
|
static int p6_get_constraint(u64 event, u64 *maskp, u64 *valp)
|
||||||
|
{
|
||||||
|
int pmc, byte, sh, subunit;
|
||||||
|
u64 mask = 0, value = 0;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc > 4 && !(event == 0x500009 || event == 0x600005))
|
||||||
|
return -1;
|
||||||
|
sh = (pmc - 1) * 2;
|
||||||
|
mask |= 2 << sh;
|
||||||
|
value |= 1 << sh;
|
||||||
|
}
|
||||||
|
if (event & PM_BUSEVENT_MSK) {
|
||||||
|
byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
sh = byte * 4 + (16 - PM_UNIT_SH);
|
||||||
|
mask |= PM_UNIT_MSKS << sh;
|
||||||
|
value |= (u64)(event & PM_UNIT_MSKS) << sh;
|
||||||
|
if ((event & PM_UNIT_MSKS) == (5 << PM_UNIT_SH)) {
|
||||||
|
subunit = (event >> PM_SUBUNIT_SH) & PM_SUBUNIT_MSK;
|
||||||
|
mask |= (u64)PM_SUBUNIT_MSK << 32;
|
||||||
|
value |= (u64)subunit << 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pmc <= 4) {
|
||||||
|
mask |= 0x8000; /* add field for count of PMC1-4 uses */
|
||||||
|
value |= 0x1000;
|
||||||
|
}
|
||||||
|
*maskp = mask;
|
||||||
|
*valp = value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int p6_limited_pmc_event(u64 event)
|
||||||
|
{
|
||||||
|
int pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
|
||||||
|
return pmc == 5 || pmc == 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_ALT 4 /* at most 4 alternatives for any event */
|
||||||
|
|
||||||
|
static const unsigned int event_alternatives[][MAX_ALT] = {
|
||||||
|
{ 0x0130e8, 0x2000f6, 0x3000fc }, /* PM_PTEG_RELOAD_VALID */
|
||||||
|
{ 0x080080, 0x10000d, 0x30000c, 0x4000f0 }, /* PM_LD_MISS_L1 */
|
||||||
|
{ 0x080088, 0x200054, 0x3000f0 }, /* PM_ST_MISS_L1 */
|
||||||
|
{ 0x10000a, 0x2000f4, 0x600005 }, /* PM_RUN_CYC */
|
||||||
|
{ 0x10000b, 0x2000f5 }, /* PM_RUN_COUNT */
|
||||||
|
{ 0x10000e, 0x400010 }, /* PM_PURR */
|
||||||
|
{ 0x100010, 0x4000f8 }, /* PM_FLUSH */
|
||||||
|
{ 0x10001a, 0x200010 }, /* PM_MRK_INST_DISP */
|
||||||
|
{ 0x100026, 0x3000f8 }, /* PM_TB_BIT_TRANS */
|
||||||
|
{ 0x100054, 0x2000f0 }, /* PM_ST_FIN */
|
||||||
|
{ 0x100056, 0x2000fc }, /* PM_L1_ICACHE_MISS */
|
||||||
|
{ 0x1000f0, 0x40000a }, /* PM_INST_IMC_MATCH_CMPL */
|
||||||
|
{ 0x1000f8, 0x200008 }, /* PM_GCT_EMPTY_CYC */
|
||||||
|
{ 0x1000fc, 0x400006 }, /* PM_LSU_DERAT_MISS_CYC */
|
||||||
|
{ 0x20000e, 0x400007 }, /* PM_LSU_DERAT_MISS */
|
||||||
|
{ 0x200012, 0x300012 }, /* PM_INST_DISP */
|
||||||
|
{ 0x2000f2, 0x3000f2 }, /* PM_INST_DISP */
|
||||||
|
{ 0x2000f8, 0x300010 }, /* PM_EXT_INT */
|
||||||
|
{ 0x2000fe, 0x300056 }, /* PM_DATA_FROM_L2MISS */
|
||||||
|
{ 0x2d0030, 0x30001a }, /* PM_MRK_FPU_FIN */
|
||||||
|
{ 0x30000a, 0x400018 }, /* PM_MRK_INST_FIN */
|
||||||
|
{ 0x3000f6, 0x40000e }, /* PM_L1_DCACHE_RELOAD_VALID */
|
||||||
|
{ 0x3000fe, 0x400056 }, /* PM_DATA_FROM_L3MISS */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This could be made more efficient with a binary search on
|
||||||
|
* a presorted list, if necessary
|
||||||
|
*/
|
||||||
|
static int find_alternatives_list(u64 event)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
unsigned int alt;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(event_alternatives); ++i) {
|
||||||
|
if (event < event_alternatives[i][0])
|
||||||
|
return -1;
|
||||||
|
for (j = 0; j < MAX_ALT; ++j) {
|
||||||
|
alt = event_alternatives[i][j];
|
||||||
|
if (!alt || event < alt)
|
||||||
|
break;
|
||||||
|
if (event == alt)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int p6_get_alternatives(u64 event, unsigned int flags, u64 alt[])
|
||||||
|
{
|
||||||
|
int i, j, nlim;
|
||||||
|
unsigned int psel, pmc;
|
||||||
|
unsigned int nalt = 1;
|
||||||
|
u64 aevent;
|
||||||
|
|
||||||
|
alt[0] = event;
|
||||||
|
nlim = p6_limited_pmc_event(event);
|
||||||
|
|
||||||
|
/* check the alternatives table */
|
||||||
|
i = find_alternatives_list(event);
|
||||||
|
if (i >= 0) {
|
||||||
|
/* copy out alternatives from list */
|
||||||
|
for (j = 0; j < MAX_ALT; ++j) {
|
||||||
|
aevent = event_alternatives[i][j];
|
||||||
|
if (!aevent)
|
||||||
|
break;
|
||||||
|
if (aevent != event)
|
||||||
|
alt[nalt++] = aevent;
|
||||||
|
nlim += p6_limited_pmc_event(aevent);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Check for alternative ways of computing sum events */
|
||||||
|
/* PMCSEL 0x32 counter N == PMCSEL 0x34 counter 5-N */
|
||||||
|
psel = event & (PM_PMCSEL_MSK & ~1); /* ignore edge bit */
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc && (psel == 0x32 || psel == 0x34))
|
||||||
|
alt[nalt++] = ((event ^ 0x6) & ~PM_PMC_MSKS) |
|
||||||
|
((5 - pmc) << PM_PMC_SH);
|
||||||
|
|
||||||
|
/* PMCSEL 0x38 counter N == PMCSEL 0x3a counter N+/-2 */
|
||||||
|
if (pmc && (psel == 0x38 || psel == 0x3a))
|
||||||
|
alt[nalt++] = ((event ^ 0x2) & ~PM_PMC_MSKS) |
|
||||||
|
((pmc > 2? pmc - 2: pmc + 2) << PM_PMC_SH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & PPMU_ONLY_COUNT_RUN) {
|
||||||
|
/*
|
||||||
|
* We're only counting in RUN state,
|
||||||
|
* so PM_CYC is equivalent to PM_RUN_CYC,
|
||||||
|
* PM_INST_CMPL === PM_RUN_INST_CMPL, PM_PURR === PM_RUN_PURR.
|
||||||
|
* This doesn't include alternatives that don't provide
|
||||||
|
* any extra flexibility in assigning PMCs (e.g.
|
||||||
|
* 0x10000a for PM_RUN_CYC vs. 0x1e for PM_CYC).
|
||||||
|
* Note that even with these additional alternatives
|
||||||
|
* we never end up with more than 4 alternatives for any event.
|
||||||
|
*/
|
||||||
|
j = nalt;
|
||||||
|
for (i = 0; i < nalt; ++i) {
|
||||||
|
switch (alt[i]) {
|
||||||
|
case 0x1e: /* PM_CYC */
|
||||||
|
alt[j++] = 0x600005; /* PM_RUN_CYC */
|
||||||
|
++nlim;
|
||||||
|
break;
|
||||||
|
case 0x10000a: /* PM_RUN_CYC */
|
||||||
|
alt[j++] = 0x1e; /* PM_CYC */
|
||||||
|
break;
|
||||||
|
case 2: /* PM_INST_CMPL */
|
||||||
|
alt[j++] = 0x500009; /* PM_RUN_INST_CMPL */
|
||||||
|
++nlim;
|
||||||
|
break;
|
||||||
|
case 0x500009: /* PM_RUN_INST_CMPL */
|
||||||
|
alt[j++] = 2; /* PM_INST_CMPL */
|
||||||
|
break;
|
||||||
|
case 0x10000e: /* PM_PURR */
|
||||||
|
alt[j++] = 0x4000f4; /* PM_RUN_PURR */
|
||||||
|
break;
|
||||||
|
case 0x4000f4: /* PM_RUN_PURR */
|
||||||
|
alt[j++] = 0x10000e; /* PM_PURR */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nalt = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(flags & PPMU_LIMITED_PMC_OK) && nlim) {
|
||||||
|
/* remove the limited PMC events */
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < nalt; ++i) {
|
||||||
|
if (!p6_limited_pmc_event(alt[i])) {
|
||||||
|
alt[j] = alt[i];
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nalt = j;
|
||||||
|
} else if ((flags & PPMU_LIMITED_PMC_REQD) && nlim < nalt) {
|
||||||
|
/* remove all but the limited PMC events */
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < nalt; ++i) {
|
||||||
|
if (p6_limited_pmc_event(alt[i])) {
|
||||||
|
alt[j] = alt[i];
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nalt = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nalt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void p6_disable_pmc(unsigned int pmc, u64 mmcr[])
|
||||||
|
{
|
||||||
|
/* Set PMCxSEL to 0 to disable PMCx */
|
||||||
|
if (pmc <= 3)
|
||||||
|
mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SH(pmc));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int power6_generic_events[] = {
|
||||||
|
[PERF_COUNT_HW_CPU_CYCLES] = 0x1e,
|
||||||
|
[PERF_COUNT_HW_INSTRUCTIONS] = 2,
|
||||||
|
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x280030, /* LD_REF_L1 */
|
||||||
|
[PERF_COUNT_HW_CACHE_MISSES] = 0x30000c, /* LD_MISS_L1 */
|
||||||
|
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x410a0, /* BR_PRED */
|
||||||
|
[PERF_COUNT_HW_BRANCH_MISSES] = 0x400052, /* BR_MPRED */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define C(x) PERF_COUNT_HW_CACHE_##x
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table of generalized cache-related events.
|
||||||
|
* 0 means not supported, -1 means nonsensical, other values
|
||||||
|
* are event codes.
|
||||||
|
* The "DTLB" and "ITLB" events relate to the DERAT and IERAT.
|
||||||
|
*/
|
||||||
|
static int power6_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
|
||||||
|
[C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x80082, 0x80080 },
|
||||||
|
[C(OP_WRITE)] = { 0x80086, 0x80088 },
|
||||||
|
[C(OP_PREFETCH)] = { 0x810a4, 0 },
|
||||||
|
},
|
||||||
|
[C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x100056 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { 0x4008c, 0 },
|
||||||
|
},
|
||||||
|
[C(LL)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x150730, 0x250532 },
|
||||||
|
[C(OP_WRITE)] = { 0x250432, 0x150432 },
|
||||||
|
[C(OP_PREFETCH)] = { 0x810a6, 0 },
|
||||||
|
},
|
||||||
|
[C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x20000e },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x420ce },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x430e6, 0x400052 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct power_pmu power6_pmu = {
|
||||||
|
.n_counter = 6,
|
||||||
|
.max_alternatives = MAX_ALT,
|
||||||
|
.add_fields = 0x1555,
|
||||||
|
.test_adder = 0x3000,
|
||||||
|
.compute_mmcr = p6_compute_mmcr,
|
||||||
|
.get_constraint = p6_get_constraint,
|
||||||
|
.get_alternatives = p6_get_alternatives,
|
||||||
|
.disable_pmc = p6_disable_pmc,
|
||||||
|
.limited_pmc_event = p6_limited_pmc_event,
|
||||||
|
.flags = PPMU_LIMITED_PMC5_6 | PPMU_ALT_SIPR,
|
||||||
|
.n_generic = ARRAY_SIZE(power6_generic_events),
|
||||||
|
.generic_events = power6_generic_events,
|
||||||
|
.cache_events = &power6_cache_events,
|
||||||
|
};
|
|
@ -0,0 +1,357 @@
|
||||||
|
/*
|
||||||
|
* Performance counter support for POWER7 processors.
|
||||||
|
*
|
||||||
|
* Copyright 2009 Paul Mackerras, IBM Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/perf_counter.h>
|
||||||
|
#include <asm/reg.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in event code for POWER7
|
||||||
|
*/
|
||||||
|
#define PM_PMC_SH 16 /* PMC number (1-based) for direct events */
|
||||||
|
#define PM_PMC_MSK 0xf
|
||||||
|
#define PM_PMC_MSKS (PM_PMC_MSK << PM_PMC_SH)
|
||||||
|
#define PM_UNIT_SH 12 /* TTMMUX number and setting - unit select */
|
||||||
|
#define PM_UNIT_MSK 0xf
|
||||||
|
#define PM_COMBINE_SH 11 /* Combined event bit */
|
||||||
|
#define PM_COMBINE_MSK 1
|
||||||
|
#define PM_COMBINE_MSKS 0x800
|
||||||
|
#define PM_L2SEL_SH 8 /* L2 event select */
|
||||||
|
#define PM_L2SEL_MSK 7
|
||||||
|
#define PM_PMCSEL_MSK 0xff
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCR1 for POWER7
|
||||||
|
*/
|
||||||
|
#define MMCR1_TTM0SEL_SH 60
|
||||||
|
#define MMCR1_TTM1SEL_SH 56
|
||||||
|
#define MMCR1_TTM2SEL_SH 52
|
||||||
|
#define MMCR1_TTM3SEL_SH 48
|
||||||
|
#define MMCR1_TTMSEL_MSK 0xf
|
||||||
|
#define MMCR1_L2SEL_SH 45
|
||||||
|
#define MMCR1_L2SEL_MSK 7
|
||||||
|
#define MMCR1_PMC1_COMBINE_SH 35
|
||||||
|
#define MMCR1_PMC2_COMBINE_SH 34
|
||||||
|
#define MMCR1_PMC3_COMBINE_SH 33
|
||||||
|
#define MMCR1_PMC4_COMBINE_SH 32
|
||||||
|
#define MMCR1_PMC1SEL_SH 24
|
||||||
|
#define MMCR1_PMC2SEL_SH 16
|
||||||
|
#define MMCR1_PMC3SEL_SH 8
|
||||||
|
#define MMCR1_PMC4SEL_SH 0
|
||||||
|
#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8)
|
||||||
|
#define MMCR1_PMCSEL_MSK 0xff
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCRA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Layout of constraint bits:
|
||||||
|
* 6666555555555544444444443333333333222222222211111111110000000000
|
||||||
|
* 3210987654321098765432109876543210987654321098765432109876543210
|
||||||
|
* [ ><><><><><><>
|
||||||
|
* NC P6P5P4P3P2P1
|
||||||
|
*
|
||||||
|
* NC - number of counters
|
||||||
|
* 15: NC error 0x8000
|
||||||
|
* 12-14: number of events needing PMC1-4 0x7000
|
||||||
|
*
|
||||||
|
* P6
|
||||||
|
* 11: P6 error 0x800
|
||||||
|
* 10-11: Count of events needing PMC6
|
||||||
|
*
|
||||||
|
* P1..P5
|
||||||
|
* 0-9: Count of events needing PMC1..PMC5
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int power7_get_constraint(u64 event, u64 *maskp, u64 *valp)
|
||||||
|
{
|
||||||
|
int pmc, sh;
|
||||||
|
u64 mask = 0, value = 0;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc > 6)
|
||||||
|
return -1;
|
||||||
|
sh = (pmc - 1) * 2;
|
||||||
|
mask |= 2 << sh;
|
||||||
|
value |= 1 << sh;
|
||||||
|
if (pmc >= 5 && !(event == 0x500fa || event == 0x600f4))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (pmc < 5) {
|
||||||
|
/* need a counter from PMC1-4 set */
|
||||||
|
mask |= 0x8000;
|
||||||
|
value |= 0x1000;
|
||||||
|
}
|
||||||
|
*maskp = mask;
|
||||||
|
*valp = value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_ALT 2 /* at most 2 alternatives for any event */
|
||||||
|
|
||||||
|
static const unsigned int event_alternatives[][MAX_ALT] = {
|
||||||
|
{ 0x200f2, 0x300f2 }, /* PM_INST_DISP */
|
||||||
|
{ 0x200f4, 0x600f4 }, /* PM_RUN_CYC */
|
||||||
|
{ 0x400fa, 0x500fa }, /* PM_RUN_INST_CMPL */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan the alternatives table for a match and return the
|
||||||
|
* index into the alternatives table if found, else -1.
|
||||||
|
*/
|
||||||
|
static int find_alternative(u64 event)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(event_alternatives); ++i) {
|
||||||
|
if (event < event_alternatives[i][0])
|
||||||
|
break;
|
||||||
|
for (j = 0; j < MAX_ALT && event_alternatives[i][j]; ++j)
|
||||||
|
if (event == event_alternatives[i][j])
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s64 find_alternative_decode(u64 event)
|
||||||
|
{
|
||||||
|
int pmc, psel;
|
||||||
|
|
||||||
|
/* this only handles the 4x decode events */
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
psel = event & PM_PMCSEL_MSK;
|
||||||
|
if ((pmc == 2 || pmc == 4) && (psel & ~7) == 0x40)
|
||||||
|
return event - (1 << PM_PMC_SH) + 8;
|
||||||
|
if ((pmc == 1 || pmc == 3) && (psel & ~7) == 0x48)
|
||||||
|
return event + (1 << PM_PMC_SH) - 8;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int power7_get_alternatives(u64 event, unsigned int flags, u64 alt[])
|
||||||
|
{
|
||||||
|
int i, j, nalt = 1;
|
||||||
|
s64 ae;
|
||||||
|
|
||||||
|
alt[0] = event;
|
||||||
|
nalt = 1;
|
||||||
|
i = find_alternative(event);
|
||||||
|
if (i >= 0) {
|
||||||
|
for (j = 0; j < MAX_ALT; ++j) {
|
||||||
|
ae = event_alternatives[i][j];
|
||||||
|
if (ae && ae != event)
|
||||||
|
alt[nalt++] = ae;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ae = find_alternative_decode(event);
|
||||||
|
if (ae > 0)
|
||||||
|
alt[nalt++] = ae;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & PPMU_ONLY_COUNT_RUN) {
|
||||||
|
/*
|
||||||
|
* We're only counting in RUN state,
|
||||||
|
* so PM_CYC is equivalent to PM_RUN_CYC
|
||||||
|
* and PM_INST_CMPL === PM_RUN_INST_CMPL.
|
||||||
|
* This doesn't include alternatives that don't provide
|
||||||
|
* any extra flexibility in assigning PMCs.
|
||||||
|
*/
|
||||||
|
j = nalt;
|
||||||
|
for (i = 0; i < nalt; ++i) {
|
||||||
|
switch (alt[i]) {
|
||||||
|
case 0x1e: /* PM_CYC */
|
||||||
|
alt[j++] = 0x600f4; /* PM_RUN_CYC */
|
||||||
|
break;
|
||||||
|
case 0x600f4: /* PM_RUN_CYC */
|
||||||
|
alt[j++] = 0x1e;
|
||||||
|
break;
|
||||||
|
case 0x2: /* PM_PPC_CMPL */
|
||||||
|
alt[j++] = 0x500fa; /* PM_RUN_INST_CMPL */
|
||||||
|
break;
|
||||||
|
case 0x500fa: /* PM_RUN_INST_CMPL */
|
||||||
|
alt[j++] = 0x2; /* PM_PPC_CMPL */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nalt = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nalt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if event counts things relating to marked instructions
|
||||||
|
* and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not.
|
||||||
|
*/
|
||||||
|
static int power7_marked_instr_event(u64 event)
|
||||||
|
{
|
||||||
|
int pmc, psel;
|
||||||
|
int unit;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
psel = event & PM_PMCSEL_MSK & ~1; /* trim off edge/level bit */
|
||||||
|
if (pmc >= 5)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (psel >> 4) {
|
||||||
|
case 2:
|
||||||
|
return pmc == 2 || pmc == 4;
|
||||||
|
case 3:
|
||||||
|
if (psel == 0x3c)
|
||||||
|
return pmc == 1;
|
||||||
|
if (psel == 0x3e)
|
||||||
|
return pmc != 2;
|
||||||
|
return 1;
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
return unit == 0xd;
|
||||||
|
case 6:
|
||||||
|
if (psel == 0x64)
|
||||||
|
return pmc >= 3;
|
||||||
|
case 8:
|
||||||
|
return unit == 0xd;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int power7_compute_mmcr(u64 event[], int n_ev,
|
||||||
|
unsigned int hwc[], u64 mmcr[])
|
||||||
|
{
|
||||||
|
u64 mmcr1 = 0;
|
||||||
|
u64 mmcra = 0;
|
||||||
|
unsigned int pmc, unit, combine, l2sel, psel;
|
||||||
|
unsigned int pmc_inuse = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* First pass to count resource use */
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc > 6)
|
||||||
|
return -1;
|
||||||
|
if (pmc_inuse & (1 << (pmc - 1)))
|
||||||
|
return -1;
|
||||||
|
pmc_inuse |= 1 << (pmc - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second pass: assign PMCs, set all MMCR1 fields */
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
combine = (event[i] >> PM_COMBINE_SH) & PM_COMBINE_MSK;
|
||||||
|
l2sel = (event[i] >> PM_L2SEL_SH) & PM_L2SEL_MSK;
|
||||||
|
psel = event[i] & PM_PMCSEL_MSK;
|
||||||
|
if (!pmc) {
|
||||||
|
/* Bus event or any-PMC direct event */
|
||||||
|
for (pmc = 0; pmc < 4; ++pmc) {
|
||||||
|
if (!(pmc_inuse & (1 << pmc)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pmc >= 4)
|
||||||
|
return -1;
|
||||||
|
pmc_inuse |= 1 << pmc;
|
||||||
|
} else {
|
||||||
|
/* Direct or decoded event */
|
||||||
|
--pmc;
|
||||||
|
}
|
||||||
|
if (pmc <= 3) {
|
||||||
|
mmcr1 |= (u64) unit << (MMCR1_TTM0SEL_SH - 4 * pmc);
|
||||||
|
mmcr1 |= (u64) combine << (MMCR1_PMC1_COMBINE_SH - pmc);
|
||||||
|
mmcr1 |= psel << MMCR1_PMCSEL_SH(pmc);
|
||||||
|
if (unit == 6) /* L2 events */
|
||||||
|
mmcr1 |= (u64) l2sel << MMCR1_L2SEL_SH;
|
||||||
|
}
|
||||||
|
if (power7_marked_instr_event(event[i]))
|
||||||
|
mmcra |= MMCRA_SAMPLE_ENABLE;
|
||||||
|
hwc[i] = pmc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return MMCRx values */
|
||||||
|
mmcr[0] = 0;
|
||||||
|
if (pmc_inuse & 1)
|
||||||
|
mmcr[0] = MMCR0_PMC1CE;
|
||||||
|
if (pmc_inuse & 0x3e)
|
||||||
|
mmcr[0] |= MMCR0_PMCjCE;
|
||||||
|
mmcr[1] = mmcr1;
|
||||||
|
mmcr[2] = mmcra;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void power7_disable_pmc(unsigned int pmc, u64 mmcr[])
|
||||||
|
{
|
||||||
|
if (pmc <= 3)
|
||||||
|
mmcr[1] &= ~(0xffULL << MMCR1_PMCSEL_SH(pmc));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int power7_generic_events[] = {
|
||||||
|
[PERF_COUNT_CPU_CYCLES] = 0x1e,
|
||||||
|
[PERF_COUNT_INSTRUCTIONS] = 2,
|
||||||
|
[PERF_COUNT_CACHE_REFERENCES] = 0xc880, /* LD_REF_L1_LSU */
|
||||||
|
[PERF_COUNT_CACHE_MISSES] = 0x400f0, /* LD_MISS_L1 */
|
||||||
|
[PERF_COUNT_BRANCH_INSTRUCTIONS] = 0x10068, /* BRU_FIN */
|
||||||
|
[PERF_COUNT_BRANCH_MISSES] = 0x400f6, /* BR_MPRED */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define C(x) PERF_COUNT_HW_CACHE_##x
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table of generalized cache-related events.
|
||||||
|
* 0 means not supported, -1 means nonsensical, other values
|
||||||
|
* are event codes.
|
||||||
|
*/
|
||||||
|
static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
|
||||||
|
[C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x400f0, 0xc880 },
|
||||||
|
[C(OP_WRITE)] = { 0, 0x300f0 },
|
||||||
|
[C(OP_PREFETCH)] = { 0xd8b8, 0 },
|
||||||
|
},
|
||||||
|
[C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x200fc },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { 0x408a, 0 },
|
||||||
|
},
|
||||||
|
[C(LL)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x6080, 0x6084 },
|
||||||
|
[C(OP_WRITE)] = { 0x6082, 0x6086 },
|
||||||
|
[C(OP_PREFETCH)] = { 0, 0 },
|
||||||
|
},
|
||||||
|
[C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x300fc },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x400fc },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x10068, 0x400f6 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct power_pmu power7_pmu = {
|
||||||
|
.n_counter = 6,
|
||||||
|
.max_alternatives = MAX_ALT + 1,
|
||||||
|
.add_fields = 0x1555ull,
|
||||||
|
.test_adder = 0x3000ull,
|
||||||
|
.compute_mmcr = power7_compute_mmcr,
|
||||||
|
.get_constraint = power7_get_constraint,
|
||||||
|
.get_alternatives = power7_get_alternatives,
|
||||||
|
.disable_pmc = power7_disable_pmc,
|
||||||
|
.n_generic = ARRAY_SIZE(power7_generic_events),
|
||||||
|
.generic_events = power7_generic_events,
|
||||||
|
.cache_events = &power7_cache_events,
|
||||||
|
};
|
|
@ -0,0 +1,482 @@
|
||||||
|
/*
|
||||||
|
* Performance counter support for PPC970-family processors.
|
||||||
|
*
|
||||||
|
* Copyright 2008-2009 Paul Mackerras, IBM Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/perf_counter.h>
|
||||||
|
#include <asm/reg.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in event code for PPC970
|
||||||
|
*/
|
||||||
|
#define PM_PMC_SH 12 /* PMC number (1-based) for direct events */
|
||||||
|
#define PM_PMC_MSK 0xf
|
||||||
|
#define PM_UNIT_SH 8 /* TTMMUX number and setting - unit select */
|
||||||
|
#define PM_UNIT_MSK 0xf
|
||||||
|
#define PM_SPCSEL_SH 6
|
||||||
|
#define PM_SPCSEL_MSK 3
|
||||||
|
#define PM_BYTE_SH 4 /* Byte number of event bus to use */
|
||||||
|
#define PM_BYTE_MSK 3
|
||||||
|
#define PM_PMCSEL_MSK 0xf
|
||||||
|
|
||||||
|
/* Values in PM_UNIT field */
|
||||||
|
#define PM_NONE 0
|
||||||
|
#define PM_FPU 1
|
||||||
|
#define PM_VPU 2
|
||||||
|
#define PM_ISU 3
|
||||||
|
#define PM_IFU 4
|
||||||
|
#define PM_IDU 5
|
||||||
|
#define PM_STS 6
|
||||||
|
#define PM_LSU0 7
|
||||||
|
#define PM_LSU1U 8
|
||||||
|
#define PM_LSU1L 9
|
||||||
|
#define PM_LASTUNIT 9
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCR0 for PPC970
|
||||||
|
*/
|
||||||
|
#define MMCR0_PMC1SEL_SH 8
|
||||||
|
#define MMCR0_PMC2SEL_SH 1
|
||||||
|
#define MMCR_PMCSEL_MSK 0x1f
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCR1 for PPC970
|
||||||
|
*/
|
||||||
|
#define MMCR1_TTM0SEL_SH 62
|
||||||
|
#define MMCR1_TTM1SEL_SH 59
|
||||||
|
#define MMCR1_TTM3SEL_SH 53
|
||||||
|
#define MMCR1_TTMSEL_MSK 3
|
||||||
|
#define MMCR1_TD_CP_DBG0SEL_SH 50
|
||||||
|
#define MMCR1_TD_CP_DBG1SEL_SH 48
|
||||||
|
#define MMCR1_TD_CP_DBG2SEL_SH 46
|
||||||
|
#define MMCR1_TD_CP_DBG3SEL_SH 44
|
||||||
|
#define MMCR1_PMC1_ADDER_SEL_SH 39
|
||||||
|
#define MMCR1_PMC2_ADDER_SEL_SH 38
|
||||||
|
#define MMCR1_PMC6_ADDER_SEL_SH 37
|
||||||
|
#define MMCR1_PMC5_ADDER_SEL_SH 36
|
||||||
|
#define MMCR1_PMC8_ADDER_SEL_SH 35
|
||||||
|
#define MMCR1_PMC7_ADDER_SEL_SH 34
|
||||||
|
#define MMCR1_PMC3_ADDER_SEL_SH 33
|
||||||
|
#define MMCR1_PMC4_ADDER_SEL_SH 32
|
||||||
|
#define MMCR1_PMC3SEL_SH 27
|
||||||
|
#define MMCR1_PMC4SEL_SH 22
|
||||||
|
#define MMCR1_PMC5SEL_SH 17
|
||||||
|
#define MMCR1_PMC6SEL_SH 12
|
||||||
|
#define MMCR1_PMC7SEL_SH 7
|
||||||
|
#define MMCR1_PMC8SEL_SH 2
|
||||||
|
|
||||||
|
static short mmcr1_adder_bits[8] = {
|
||||||
|
MMCR1_PMC1_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC2_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC3_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC4_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC5_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC6_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC7_ADDER_SEL_SH,
|
||||||
|
MMCR1_PMC8_ADDER_SEL_SH
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in MMCRA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Layout of constraint bits:
|
||||||
|
* 6666555555555544444444443333333333222222222211111111110000000000
|
||||||
|
* 3210987654321098765432109876543210987654321098765432109876543210
|
||||||
|
* <><><>[ >[ >[ >< >< >< >< ><><><><><><><><>
|
||||||
|
* SPT0T1 UC PS1 PS2 B0 B1 B2 B3 P1P2P3P4P5P6P7P8
|
||||||
|
*
|
||||||
|
* SP - SPCSEL constraint
|
||||||
|
* 48-49: SPCSEL value 0x3_0000_0000_0000
|
||||||
|
*
|
||||||
|
* T0 - TTM0 constraint
|
||||||
|
* 46-47: TTM0SEL value (0=FPU, 2=IFU, 3=VPU) 0xC000_0000_0000
|
||||||
|
*
|
||||||
|
* T1 - TTM1 constraint
|
||||||
|
* 44-45: TTM1SEL value (0=IDU, 3=STS) 0x3000_0000_0000
|
||||||
|
*
|
||||||
|
* UC - unit constraint: can't have all three of FPU|IFU|VPU, ISU, IDU|STS
|
||||||
|
* 43: UC3 error 0x0800_0000_0000
|
||||||
|
* 42: FPU|IFU|VPU events needed 0x0400_0000_0000
|
||||||
|
* 41: ISU events needed 0x0200_0000_0000
|
||||||
|
* 40: IDU|STS events needed 0x0100_0000_0000
|
||||||
|
*
|
||||||
|
* PS1
|
||||||
|
* 39: PS1 error 0x0080_0000_0000
|
||||||
|
* 36-38: count of events needing PMC1/2/5/6 0x0070_0000_0000
|
||||||
|
*
|
||||||
|
* PS2
|
||||||
|
* 35: PS2 error 0x0008_0000_0000
|
||||||
|
* 32-34: count of events needing PMC3/4/7/8 0x0007_0000_0000
|
||||||
|
*
|
||||||
|
* B0
|
||||||
|
* 28-31: Byte 0 event source 0xf000_0000
|
||||||
|
* Encoding as for the event code
|
||||||
|
*
|
||||||
|
* B1, B2, B3
|
||||||
|
* 24-27, 20-23, 16-19: Byte 1, 2, 3 event sources
|
||||||
|
*
|
||||||
|
* P1
|
||||||
|
* 15: P1 error 0x8000
|
||||||
|
* 14-15: Count of events needing PMC1
|
||||||
|
*
|
||||||
|
* P2..P8
|
||||||
|
* 0-13: Count of events needing PMC2..PMC8
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned char direct_marked_event[8] = {
|
||||||
|
(1<<2) | (1<<3), /* PMC1: PM_MRK_GRP_DISP, PM_MRK_ST_CMPL */
|
||||||
|
(1<<3) | (1<<5), /* PMC2: PM_THRESH_TIMEO, PM_MRK_BRU_FIN */
|
||||||
|
(1<<3) | (1<<5), /* PMC3: PM_MRK_ST_CMPL_INT, PM_MRK_VMX_FIN */
|
||||||
|
(1<<4) | (1<<5), /* PMC4: PM_MRK_GRP_CMPL, PM_MRK_CRU_FIN */
|
||||||
|
(1<<4) | (1<<5), /* PMC5: PM_GRP_MRK, PM_MRK_GRP_TIMEO */
|
||||||
|
(1<<3) | (1<<4) | (1<<5),
|
||||||
|
/* PMC6: PM_MRK_ST_STS, PM_MRK_FXU_FIN, PM_MRK_GRP_ISSUED */
|
||||||
|
(1<<4) | (1<<5), /* PMC7: PM_MRK_FPU_FIN, PM_MRK_INST_FIN */
|
||||||
|
(1<<4) /* PMC8: PM_MRK_LSU_FIN */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if event counts things relating to marked instructions
|
||||||
|
* and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not.
|
||||||
|
*/
|
||||||
|
static int p970_marked_instr_event(u64 event)
|
||||||
|
{
|
||||||
|
int pmc, psel, unit, byte, bit;
|
||||||
|
unsigned int mask;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
psel = event & PM_PMCSEL_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (direct_marked_event[pmc - 1] & (1 << psel))
|
||||||
|
return 1;
|
||||||
|
if (psel == 0) /* add events */
|
||||||
|
bit = (pmc <= 4)? pmc - 1: 8 - pmc;
|
||||||
|
else if (psel == 7 || psel == 13) /* decode events */
|
||||||
|
bit = 4;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
bit = psel;
|
||||||
|
|
||||||
|
byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
mask = 0;
|
||||||
|
switch (unit) {
|
||||||
|
case PM_VPU:
|
||||||
|
mask = 0x4c; /* byte 0 bits 2,3,6 */
|
||||||
|
case PM_LSU0:
|
||||||
|
/* byte 2 bits 0,2,3,4,6; all of byte 1 */
|
||||||
|
mask = 0x085dff00;
|
||||||
|
case PM_LSU1L:
|
||||||
|
mask = 0x50 << 24; /* byte 3 bits 4,6 */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (mask >> (byte * 8 + bit)) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Masks and values for using events from the various units */
|
||||||
|
static u64 unit_cons[PM_LASTUNIT+1][2] = {
|
||||||
|
[PM_FPU] = { 0xc80000000000ull, 0x040000000000ull },
|
||||||
|
[PM_VPU] = { 0xc80000000000ull, 0xc40000000000ull },
|
||||||
|
[PM_ISU] = { 0x080000000000ull, 0x020000000000ull },
|
||||||
|
[PM_IFU] = { 0xc80000000000ull, 0x840000000000ull },
|
||||||
|
[PM_IDU] = { 0x380000000000ull, 0x010000000000ull },
|
||||||
|
[PM_STS] = { 0x380000000000ull, 0x310000000000ull },
|
||||||
|
};
|
||||||
|
|
||||||
|
static int p970_get_constraint(u64 event, u64 *maskp, u64 *valp)
|
||||||
|
{
|
||||||
|
int pmc, byte, unit, sh, spcsel;
|
||||||
|
u64 mask = 0, value = 0;
|
||||||
|
int grp = -1;
|
||||||
|
|
||||||
|
pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc > 8)
|
||||||
|
return -1;
|
||||||
|
sh = (pmc - 1) * 2;
|
||||||
|
mask |= 2 << sh;
|
||||||
|
value |= 1 << sh;
|
||||||
|
grp = ((pmc - 1) >> 1) & 1;
|
||||||
|
}
|
||||||
|
unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
if (unit) {
|
||||||
|
if (unit > PM_LASTUNIT)
|
||||||
|
return -1;
|
||||||
|
mask |= unit_cons[unit][0];
|
||||||
|
value |= unit_cons[unit][1];
|
||||||
|
byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
/*
|
||||||
|
* Bus events on bytes 0 and 2 can be counted
|
||||||
|
* on PMC1/2/5/6; bytes 1 and 3 on PMC3/4/7/8.
|
||||||
|
*/
|
||||||
|
if (!pmc)
|
||||||
|
grp = byte & 1;
|
||||||
|
/* Set byte lane select field */
|
||||||
|
mask |= 0xfULL << (28 - 4 * byte);
|
||||||
|
value |= (u64)unit << (28 - 4 * byte);
|
||||||
|
}
|
||||||
|
if (grp == 0) {
|
||||||
|
/* increment PMC1/2/5/6 field */
|
||||||
|
mask |= 0x8000000000ull;
|
||||||
|
value |= 0x1000000000ull;
|
||||||
|
} else if (grp == 1) {
|
||||||
|
/* increment PMC3/4/7/8 field */
|
||||||
|
mask |= 0x800000000ull;
|
||||||
|
value |= 0x100000000ull;
|
||||||
|
}
|
||||||
|
spcsel = (event >> PM_SPCSEL_SH) & PM_SPCSEL_MSK;
|
||||||
|
if (spcsel) {
|
||||||
|
mask |= 3ull << 48;
|
||||||
|
value |= (u64)spcsel << 48;
|
||||||
|
}
|
||||||
|
*maskp = mask;
|
||||||
|
*valp = value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int p970_get_alternatives(u64 event, unsigned int flags, u64 alt[])
|
||||||
|
{
|
||||||
|
alt[0] = event;
|
||||||
|
|
||||||
|
/* 2 alternatives for LSU empty */
|
||||||
|
if (event == 0x2002 || event == 0x3002) {
|
||||||
|
alt[1] = event ^ 0x1000;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int p970_compute_mmcr(u64 event[], int n_ev,
|
||||||
|
unsigned int hwc[], u64 mmcr[])
|
||||||
|
{
|
||||||
|
u64 mmcr0 = 0, mmcr1 = 0, mmcra = 0;
|
||||||
|
unsigned int pmc, unit, byte, psel;
|
||||||
|
unsigned int ttm, grp;
|
||||||
|
unsigned int pmc_inuse = 0;
|
||||||
|
unsigned int pmc_grp_use[2];
|
||||||
|
unsigned char busbyte[4];
|
||||||
|
unsigned char unituse[16];
|
||||||
|
unsigned char unitmap[] = { 0, 0<<3, 3<<3, 1<<3, 2<<3, 0|4, 3|4 };
|
||||||
|
unsigned char ttmuse[2];
|
||||||
|
unsigned char pmcsel[8];
|
||||||
|
int i;
|
||||||
|
int spcsel;
|
||||||
|
|
||||||
|
if (n_ev > 8)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* First pass to count resource use */
|
||||||
|
pmc_grp_use[0] = pmc_grp_use[1] = 0;
|
||||||
|
memset(busbyte, 0, sizeof(busbyte));
|
||||||
|
memset(unituse, 0, sizeof(unituse));
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
if (pmc) {
|
||||||
|
if (pmc_inuse & (1 << (pmc - 1)))
|
||||||
|
return -1;
|
||||||
|
pmc_inuse |= 1 << (pmc - 1);
|
||||||
|
/* count 1/2/5/6 vs 3/4/7/8 use */
|
||||||
|
++pmc_grp_use[((pmc - 1) >> 1) & 1];
|
||||||
|
}
|
||||||
|
unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
if (unit) {
|
||||||
|
if (unit > PM_LASTUNIT)
|
||||||
|
return -1;
|
||||||
|
if (!pmc)
|
||||||
|
++pmc_grp_use[byte & 1];
|
||||||
|
if (busbyte[byte] && busbyte[byte] != unit)
|
||||||
|
return -1;
|
||||||
|
busbyte[byte] = unit;
|
||||||
|
unituse[unit] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pmc_grp_use[0] > 4 || pmc_grp_use[1] > 4)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assign resources and set multiplexer selects.
|
||||||
|
*
|
||||||
|
* PM_ISU can go either on TTM0 or TTM1, but that's the only
|
||||||
|
* choice we have to deal with.
|
||||||
|
*/
|
||||||
|
if (unituse[PM_ISU] &
|
||||||
|
(unituse[PM_FPU] | unituse[PM_IFU] | unituse[PM_VPU]))
|
||||||
|
unitmap[PM_ISU] = 2 | 4; /* move ISU to TTM1 */
|
||||||
|
/* Set TTM[01]SEL fields. */
|
||||||
|
ttmuse[0] = ttmuse[1] = 0;
|
||||||
|
for (i = PM_FPU; i <= PM_STS; ++i) {
|
||||||
|
if (!unituse[i])
|
||||||
|
continue;
|
||||||
|
ttm = unitmap[i];
|
||||||
|
++ttmuse[(ttm >> 2) & 1];
|
||||||
|
mmcr1 |= (u64)(ttm & ~4) << MMCR1_TTM1SEL_SH;
|
||||||
|
}
|
||||||
|
/* Check only one unit per TTMx */
|
||||||
|
if (ttmuse[0] > 1 || ttmuse[1] > 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Set byte lane select fields and TTM3SEL. */
|
||||||
|
for (byte = 0; byte < 4; ++byte) {
|
||||||
|
unit = busbyte[byte];
|
||||||
|
if (!unit)
|
||||||
|
continue;
|
||||||
|
if (unit <= PM_STS)
|
||||||
|
ttm = (unitmap[unit] >> 2) & 1;
|
||||||
|
else if (unit == PM_LSU0)
|
||||||
|
ttm = 2;
|
||||||
|
else {
|
||||||
|
ttm = 3;
|
||||||
|
if (unit == PM_LSU1L && byte >= 2)
|
||||||
|
mmcr1 |= 1ull << (MMCR1_TTM3SEL_SH + 3 - byte);
|
||||||
|
}
|
||||||
|
mmcr1 |= (u64)ttm << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */
|
||||||
|
memset(pmcsel, 0x8, sizeof(pmcsel)); /* 8 means don't count */
|
||||||
|
for (i = 0; i < n_ev; ++i) {
|
||||||
|
pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
|
||||||
|
unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
|
||||||
|
byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK;
|
||||||
|
psel = event[i] & PM_PMCSEL_MSK;
|
||||||
|
if (!pmc) {
|
||||||
|
/* Bus event or any-PMC direct event */
|
||||||
|
if (unit)
|
||||||
|
psel |= 0x10 | ((byte & 2) << 2);
|
||||||
|
else
|
||||||
|
psel |= 8;
|
||||||
|
for (pmc = 0; pmc < 8; ++pmc) {
|
||||||
|
if (pmc_inuse & (1 << pmc))
|
||||||
|
continue;
|
||||||
|
grp = (pmc >> 1) & 1;
|
||||||
|
if (unit) {
|
||||||
|
if (grp == (byte & 1))
|
||||||
|
break;
|
||||||
|
} else if (pmc_grp_use[grp] < 4) {
|
||||||
|
++pmc_grp_use[grp];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pmc_inuse |= 1 << pmc;
|
||||||
|
} else {
|
||||||
|
/* Direct event */
|
||||||
|
--pmc;
|
||||||
|
if (psel == 0 && (byte & 2))
|
||||||
|
/* add events on higher-numbered bus */
|
||||||
|
mmcr1 |= 1ull << mmcr1_adder_bits[pmc];
|
||||||
|
}
|
||||||
|
pmcsel[pmc] = psel;
|
||||||
|
hwc[i] = pmc;
|
||||||
|
spcsel = (event[i] >> PM_SPCSEL_SH) & PM_SPCSEL_MSK;
|
||||||
|
mmcr1 |= spcsel;
|
||||||
|
if (p970_marked_instr_event(event[i]))
|
||||||
|
mmcra |= MMCRA_SAMPLE_ENABLE;
|
||||||
|
}
|
||||||
|
for (pmc = 0; pmc < 2; ++pmc)
|
||||||
|
mmcr0 |= pmcsel[pmc] << (MMCR0_PMC1SEL_SH - 7 * pmc);
|
||||||
|
for (; pmc < 8; ++pmc)
|
||||||
|
mmcr1 |= (u64)pmcsel[pmc] << (MMCR1_PMC3SEL_SH - 5 * (pmc - 2));
|
||||||
|
if (pmc_inuse & 1)
|
||||||
|
mmcr0 |= MMCR0_PMC1CE;
|
||||||
|
if (pmc_inuse & 0xfe)
|
||||||
|
mmcr0 |= MMCR0_PMCjCE;
|
||||||
|
|
||||||
|
mmcra |= 0x2000; /* mark only one IOP per PPC instruction */
|
||||||
|
|
||||||
|
/* Return MMCRx values */
|
||||||
|
mmcr[0] = mmcr0;
|
||||||
|
mmcr[1] = mmcr1;
|
||||||
|
mmcr[2] = mmcra;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void p970_disable_pmc(unsigned int pmc, u64 mmcr[])
|
||||||
|
{
|
||||||
|
int shift, i;
|
||||||
|
|
||||||
|
if (pmc <= 1) {
|
||||||
|
shift = MMCR0_PMC1SEL_SH - 7 * pmc;
|
||||||
|
i = 0;
|
||||||
|
} else {
|
||||||
|
shift = MMCR1_PMC3SEL_SH - 5 * (pmc - 2);
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Setting the PMCxSEL field to 0x08 disables PMC x.
|
||||||
|
*/
|
||||||
|
mmcr[i] = (mmcr[i] & ~(0x1fUL << shift)) | (0x08UL << shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ppc970_generic_events[] = {
|
||||||
|
[PERF_COUNT_HW_CPU_CYCLES] = 7,
|
||||||
|
[PERF_COUNT_HW_INSTRUCTIONS] = 1,
|
||||||
|
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x8810, /* PM_LD_REF_L1 */
|
||||||
|
[PERF_COUNT_HW_CACHE_MISSES] = 0x3810, /* PM_LD_MISS_L1 */
|
||||||
|
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x431, /* PM_BR_ISSUED */
|
||||||
|
[PERF_COUNT_HW_BRANCH_MISSES] = 0x327, /* PM_GRP_BR_MPRED */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define C(x) PERF_COUNT_HW_CACHE_##x
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table of generalized cache-related events.
|
||||||
|
* 0 means not supported, -1 means nonsensical, other values
|
||||||
|
* are event codes.
|
||||||
|
*/
|
||||||
|
static int ppc970_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
|
||||||
|
[C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x8810, 0x3810 },
|
||||||
|
[C(OP_WRITE)] = { 0x7810, 0x813 },
|
||||||
|
[C(OP_PREFETCH)] = { 0x731, 0 },
|
||||||
|
},
|
||||||
|
[C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { 0, 0 },
|
||||||
|
},
|
||||||
|
[C(LL)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0 },
|
||||||
|
[C(OP_WRITE)] = { 0, 0 },
|
||||||
|
[C(OP_PREFETCH)] = { 0x733, 0 },
|
||||||
|
},
|
||||||
|
[C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x704 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0, 0x700 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
[C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */
|
||||||
|
[C(OP_READ)] = { 0x431, 0x327 },
|
||||||
|
[C(OP_WRITE)] = { -1, -1 },
|
||||||
|
[C(OP_PREFETCH)] = { -1, -1 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct power_pmu ppc970_pmu = {
|
||||||
|
.n_counter = 8,
|
||||||
|
.max_alternatives = 2,
|
||||||
|
.add_fields = 0x001100005555ull,
|
||||||
|
.test_adder = 0x013300000000ull,
|
||||||
|
.compute_mmcr = p970_compute_mmcr,
|
||||||
|
.get_constraint = p970_get_constraint,
|
||||||
|
.get_alternatives = p970_get_alternatives,
|
||||||
|
.disable_pmc = p970_disable_pmc,
|
||||||
|
.n_generic = ARRAY_SIZE(ppc970_generic_events),
|
||||||
|
.generic_events = ppc970_generic_events,
|
||||||
|
.cache_events = &ppc970_cache_events,
|
||||||
|
};
|
|
@ -29,6 +29,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/kprobes.h>
|
#include <linux/kprobes.h>
|
||||||
#include <linux/kdebug.h>
|
#include <linux/kdebug.h>
|
||||||
|
#include <linux/perf_counter.h>
|
||||||
|
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
|
@ -170,6 +171,8 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
|
||||||
die("Weird page fault", regs, SIGSEGV);
|
die("Weird page fault", regs, SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
|
||||||
|
|
||||||
/* When running in the kernel we expect faults to occur only to
|
/* When running in the kernel we expect faults to occur only to
|
||||||
* addresses in user space. All other faults represent errors in the
|
* addresses in user space. All other faults represent errors in the
|
||||||
* kernel and should generate an OOPS. Unfortunately, in the case of an
|
* kernel and should generate an OOPS. Unfortunately, in the case of an
|
||||||
|
@ -309,6 +312,8 @@ good_area:
|
||||||
}
|
}
|
||||||
if (ret & VM_FAULT_MAJOR) {
|
if (ret & VM_FAULT_MAJOR) {
|
||||||
current->maj_flt++;
|
current->maj_flt++;
|
||||||
|
perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
|
||||||
|
regs, address);
|
||||||
#ifdef CONFIG_PPC_SMLPAR
|
#ifdef CONFIG_PPC_SMLPAR
|
||||||
if (firmware_has_feature(FW_FEATURE_CMO)) {
|
if (firmware_has_feature(FW_FEATURE_CMO)) {
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
|
@ -316,8 +321,11 @@ good_area:
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else
|
} else {
|
||||||
current->min_flt++;
|
current->min_flt++;
|
||||||
|
perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
|
||||||
|
regs, address);
|
||||||
|
}
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
config PPC64
|
config PPC64
|
||||||
bool "64-bit kernel"
|
bool "64-bit kernel"
|
||||||
default n
|
default n
|
||||||
|
select HAVE_PERF_COUNTERS
|
||||||
help
|
help
|
||||||
This option selects whether a 32-bit or a 64-bit kernel
|
This option selects whether a 32-bit or a 64-bit kernel
|
||||||
will be built.
|
will be built.
|
||||||
|
|
|
@ -333,7 +333,7 @@ static void xics_eoi_lpar(unsigned int virq)
|
||||||
lpar_xirr_info_set((0xff << 24) | irq);
|
lpar_xirr_info_set((0xff << 24) | irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
|
static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
|
||||||
{
|
{
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
int status;
|
int status;
|
||||||
|
@ -342,14 +342,14 @@ static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
|
||||||
|
|
||||||
irq = (unsigned int)irq_map[virq].hwirq;
|
irq = (unsigned int)irq_map[virq].hwirq;
|
||||||
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
|
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
|
status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
|
printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
|
||||||
__func__, irq, status);
|
__func__, irq, status);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -363,7 +363,7 @@ static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"%s: No online cpus in the mask %s for irq %d\n",
|
"%s: No online cpus in the mask %s for irq %d\n",
|
||||||
__func__, cpulist, virq);
|
__func__, cpulist, virq);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = rtas_call(ibm_set_xive, 3, 1, NULL,
|
status = rtas_call(ibm_set_xive, 3, 1, NULL,
|
||||||
|
@ -372,8 +372,10 @@ static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
|
||||||
if (status) {
|
if (status) {
|
||||||
printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
|
printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
|
||||||
__func__, irq, status);
|
__func__, irq, status);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct irq_chip xics_pic_direct = {
|
static struct irq_chip xics_pic_direct = {
|
||||||
|
|
|
@ -807,7 +807,7 @@ static void mpic_end_ipi(unsigned int irq)
|
||||||
|
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
void mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||||
{
|
{
|
||||||
struct mpic *mpic = mpic_from_irq(irq);
|
struct mpic *mpic = mpic_from_irq(irq);
|
||||||
unsigned int src = mpic_irq_to_hw(irq);
|
unsigned int src = mpic_irq_to_hw(irq);
|
||||||
|
@ -824,6 +824,8 @@ void mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||||
mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
|
mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
|
||||||
mpic_physmask(cpus_addr(tmp)[0]));
|
mpic_physmask(cpus_addr(tmp)[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
|
static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
|
||||||
|
|
|
@ -36,6 +36,6 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
|
||||||
|
|
||||||
extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
|
extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
|
||||||
extern void mpic_set_vector(unsigned int virq, unsigned int vector);
|
extern void mpic_set_vector(unsigned int virq, unsigned int vector);
|
||||||
extern void mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
|
extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
|
||||||
|
|
||||||
#endif /* _POWERPC_SYSDEV_MPIC_H */
|
#endif /* _POWERPC_SYSDEV_MPIC_H */
|
||||||
|
|
|
@ -102,8 +102,8 @@ struct thread_info {
|
||||||
#define TI_KERN_CNTD1 0x00000488
|
#define TI_KERN_CNTD1 0x00000488
|
||||||
#define TI_PCR 0x00000490
|
#define TI_PCR 0x00000490
|
||||||
#define TI_RESTART_BLOCK 0x00000498
|
#define TI_RESTART_BLOCK 0x00000498
|
||||||
#define TI_KUNA_REGS 0x000004c0
|
#define TI_KUNA_REGS 0x000004c8
|
||||||
#define TI_KUNA_INSN 0x000004c8
|
#define TI_KUNA_INSN 0x000004d0
|
||||||
#define TI_FPREGS 0x00000500
|
#define TI_FPREGS 0x00000500
|
||||||
|
|
||||||
/* We embed this in the uppermost byte of thread_info->flags */
|
/* We embed this in the uppermost byte of thread_info->flags */
|
||||||
|
|
|
@ -318,10 +318,12 @@ static void sun4u_irq_enable(unsigned int virt_irq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sun4u_set_affinity(unsigned int virt_irq,
|
static int sun4u_set_affinity(unsigned int virt_irq,
|
||||||
const struct cpumask *mask)
|
const struct cpumask *mask)
|
||||||
{
|
{
|
||||||
sun4u_irq_enable(virt_irq);
|
sun4u_irq_enable(virt_irq);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't do anything. The desc->status check for IRQ_DISABLED in
|
/* Don't do anything. The desc->status check for IRQ_DISABLED in
|
||||||
|
@ -377,7 +379,7 @@ static void sun4v_irq_enable(unsigned int virt_irq)
|
||||||
ino, err);
|
ino, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sun4v_set_affinity(unsigned int virt_irq,
|
static int sun4v_set_affinity(unsigned int virt_irq,
|
||||||
const struct cpumask *mask)
|
const struct cpumask *mask)
|
||||||
{
|
{
|
||||||
unsigned int ino = virt_irq_table[virt_irq].dev_ino;
|
unsigned int ino = virt_irq_table[virt_irq].dev_ino;
|
||||||
|
@ -388,6 +390,8 @@ static void sun4v_set_affinity(unsigned int virt_irq,
|
||||||
if (err != HV_EOK)
|
if (err != HV_EOK)
|
||||||
printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
|
printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
|
||||||
"err(%d)\n", ino, cpuid, err);
|
"err(%d)\n", ino, cpuid, err);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sun4v_irq_disable(unsigned int virt_irq)
|
static void sun4v_irq_disable(unsigned int virt_irq)
|
||||||
|
@ -445,7 +449,7 @@ static void sun4v_virq_enable(unsigned int virt_irq)
|
||||||
dev_handle, dev_ino, err);
|
dev_handle, dev_ino, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sun4v_virt_set_affinity(unsigned int virt_irq,
|
static int sun4v_virt_set_affinity(unsigned int virt_irq,
|
||||||
const struct cpumask *mask)
|
const struct cpumask *mask)
|
||||||
{
|
{
|
||||||
unsigned long cpuid, dev_handle, dev_ino;
|
unsigned long cpuid, dev_handle, dev_ino;
|
||||||
|
@ -461,6 +465,8 @@ static void sun4v_virt_set_affinity(unsigned int virt_irq,
|
||||||
printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): "
|
printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): "
|
||||||
"err(%d)\n",
|
"err(%d)\n",
|
||||||
dev_handle, dev_ino, cpuid, err);
|
dev_handle, dev_ino, cpuid, err);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sun4v_virq_disable(unsigned int virt_irq)
|
static void sun4v_virq_disable(unsigned int virt_irq)
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
obj-$(CONFIG_KVM) += kvm/
|
||||||
|
|
||||||
|
# Xen paravirtualization support
|
||||||
|
obj-$(CONFIG_XEN) += xen/
|
||||||
|
|
||||||
|
# lguest paravirtualization support
|
||||||
|
obj-$(CONFIG_LGUEST_GUEST) += lguest/
|
||||||
|
|
||||||
|
obj-y += kernel/
|
||||||
|
obj-y += mm/
|
||||||
|
|
||||||
|
obj-y += crypto/
|
||||||
|
obj-y += vdso/
|
||||||
|
obj-$(CONFIG_IA32_EMULATION) += ia32/
|
||||||
|
|
|
@ -47,6 +47,11 @@ config X86
|
||||||
select HAVE_KERNEL_BZIP2
|
select HAVE_KERNEL_BZIP2
|
||||||
select HAVE_KERNEL_LZMA
|
select HAVE_KERNEL_LZMA
|
||||||
|
|
||||||
|
config OUTPUT_FORMAT
|
||||||
|
string
|
||||||
|
default "elf32-i386" if X86_32
|
||||||
|
default "elf64-x86-64" if X86_64
|
||||||
|
|
||||||
config ARCH_DEFCONFIG
|
config ARCH_DEFCONFIG
|
||||||
string
|
string
|
||||||
default "arch/x86/configs/i386_defconfig" if X86_32
|
default "arch/x86/configs/i386_defconfig" if X86_32
|
||||||
|
@ -274,15 +279,9 @@ config SPARSE_IRQ
|
||||||
|
|
||||||
If you don't know what to do here, say N.
|
If you don't know what to do here, say N.
|
||||||
|
|
||||||
config NUMA_MIGRATE_IRQ_DESC
|
config NUMA_IRQ_DESC
|
||||||
bool "Move irq desc when changing irq smp_affinity"
|
def_bool y
|
||||||
depends on SPARSE_IRQ && NUMA
|
depends on SPARSE_IRQ && NUMA
|
||||||
depends on BROKEN
|
|
||||||
default n
|
|
||||||
---help---
|
|
||||||
This enables moving irq_desc to cpu/node that irq will use handled.
|
|
||||||
|
|
||||||
If you don't know what to do here, say N.
|
|
||||||
|
|
||||||
config X86_MPPARSE
|
config X86_MPPARSE
|
||||||
bool "Enable MPS table" if ACPI
|
bool "Enable MPS table" if ACPI
|
||||||
|
@ -355,7 +354,7 @@ config X86_UV
|
||||||
depends on X86_64
|
depends on X86_64
|
||||||
depends on X86_EXTENDED_PLATFORM
|
depends on X86_EXTENDED_PLATFORM
|
||||||
depends on NUMA
|
depends on NUMA
|
||||||
select X86_X2APIC
|
depends on X86_X2APIC
|
||||||
---help---
|
---help---
|
||||||
This option is needed in order to support SGI Ultraviolet systems.
|
This option is needed in order to support SGI Ultraviolet systems.
|
||||||
If you don't have one of these, you should say N here.
|
If you don't have one of these, you should say N here.
|
||||||
|
@ -740,6 +739,7 @@ config X86_UP_IOAPIC
|
||||||
config X86_LOCAL_APIC
|
config X86_LOCAL_APIC
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC
|
depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC
|
||||||
|
select HAVE_PERF_COUNTERS if (!M386 && !M486)
|
||||||
|
|
||||||
config X86_IO_APIC
|
config X86_IO_APIC
|
||||||
def_bool y
|
def_bool y
|
||||||
|
@ -1466,9 +1466,7 @@ config KEXEC_JUMP
|
||||||
|
|
||||||
config PHYSICAL_START
|
config PHYSICAL_START
|
||||||
hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
|
hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
|
||||||
default "0x1000000" if X86_NUMAQ
|
default "0x1000000"
|
||||||
default "0x200000" if X86_64
|
|
||||||
default "0x100000"
|
|
||||||
---help---
|
---help---
|
||||||
This gives the physical address where the kernel is loaded.
|
This gives the physical address where the kernel is loaded.
|
||||||
|
|
||||||
|
@ -1487,15 +1485,15 @@ config PHYSICAL_START
|
||||||
to be specifically compiled to run from a specific memory area
|
to be specifically compiled to run from a specific memory area
|
||||||
(normally a reserved region) and this option comes handy.
|
(normally a reserved region) and this option comes handy.
|
||||||
|
|
||||||
So if you are using bzImage for capturing the crash dump, leave
|
So if you are using bzImage for capturing the crash dump,
|
||||||
the value here unchanged to 0x100000 and set CONFIG_RELOCATABLE=y.
|
leave the value here unchanged to 0x1000000 and set
|
||||||
Otherwise if you plan to use vmlinux for capturing the crash dump
|
CONFIG_RELOCATABLE=y. Otherwise if you plan to use vmlinux
|
||||||
change this value to start of the reserved region (Typically 16MB
|
for capturing the crash dump change this value to start of
|
||||||
0x1000000). In other words, it can be set based on the "X" value as
|
the reserved region. In other words, it can be set based on
|
||||||
specified in the "crashkernel=YM@XM" command line boot parameter
|
the "X" value as specified in the "crashkernel=YM@XM"
|
||||||
passed to the panic-ed kernel. Typically this parameter is set as
|
command line boot parameter passed to the panic-ed
|
||||||
crashkernel=64M@16M. Please take a look at
|
kernel. Please take a look at Documentation/kdump/kdump.txt
|
||||||
Documentation/kdump/kdump.txt for more details about crash dumps.
|
for more details about crash dumps.
|
||||||
|
|
||||||
Usage of bzImage for capturing the crash dump is recommended as
|
Usage of bzImage for capturing the crash dump is recommended as
|
||||||
one does not have to build two kernels. Same kernel can be used
|
one does not have to build two kernels. Same kernel can be used
|
||||||
|
@ -1508,8 +1506,8 @@ config PHYSICAL_START
|
||||||
Don't change this unless you know what you are doing.
|
Don't change this unless you know what you are doing.
|
||||||
|
|
||||||
config RELOCATABLE
|
config RELOCATABLE
|
||||||
bool "Build a relocatable kernel (EXPERIMENTAL)"
|
bool "Build a relocatable kernel"
|
||||||
depends on EXPERIMENTAL
|
default y
|
||||||
---help---
|
---help---
|
||||||
This builds a kernel image that retains relocation information
|
This builds a kernel image that retains relocation information
|
||||||
so it can be loaded someplace besides the default 1MB.
|
so it can be loaded someplace besides the default 1MB.
|
||||||
|
@ -1524,12 +1522,16 @@ config RELOCATABLE
|
||||||
it has been loaded at and the compile time physical address
|
it has been loaded at and the compile time physical address
|
||||||
(CONFIG_PHYSICAL_START) is ignored.
|
(CONFIG_PHYSICAL_START) is ignored.
|
||||||
|
|
||||||
|
# Relocation on x86-32 needs some additional build support
|
||||||
|
config X86_NEED_RELOCS
|
||||||
|
def_bool y
|
||||||
|
depends on X86_32 && RELOCATABLE
|
||||||
|
|
||||||
config PHYSICAL_ALIGN
|
config PHYSICAL_ALIGN
|
||||||
hex
|
hex
|
||||||
prompt "Alignment value to which kernel should be aligned" if X86_32
|
prompt "Alignment value to which kernel should be aligned" if X86_32
|
||||||
default "0x100000" if X86_32
|
default "0x1000000"
|
||||||
default "0x200000" if X86_64
|
range 0x2000 0x1000000
|
||||||
range 0x2000 0x400000
|
|
||||||
---help---
|
---help---
|
||||||
This value puts the alignment restrictions on physical address
|
This value puts the alignment restrictions on physical address
|
||||||
where kernel is loaded and run from. Kernel is compiled for an
|
where kernel is loaded and run from. Kernel is compiled for an
|
||||||
|
|
|
@ -159,14 +159,30 @@ config IOMMU_DEBUG
|
||||||
options. See Documentation/x86_64/boot-options.txt for more
|
options. See Documentation/x86_64/boot-options.txt for more
|
||||||
details.
|
details.
|
||||||
|
|
||||||
|
config IOMMU_STRESS
|
||||||
|
bool "Enable IOMMU stress-test mode"
|
||||||
|
---help---
|
||||||
|
This option disables various optimizations in IOMMU related
|
||||||
|
code to do real stress testing of the IOMMU code. This option
|
||||||
|
will cause a performance drop and should only be enabled for
|
||||||
|
testing.
|
||||||
|
|
||||||
config IOMMU_LEAK
|
config IOMMU_LEAK
|
||||||
bool "IOMMU leak tracing"
|
bool "IOMMU leak tracing"
|
||||||
depends on DEBUG_KERNEL
|
depends on IOMMU_DEBUG && DMA_API_DEBUG
|
||||||
depends on IOMMU_DEBUG
|
|
||||||
---help---
|
---help---
|
||||||
Add a simple leak tracer to the IOMMU code. This is useful when you
|
Add a simple leak tracer to the IOMMU code. This is useful when you
|
||||||
are debugging a buggy device driver that leaks IOMMU mappings.
|
are debugging a buggy device driver that leaks IOMMU mappings.
|
||||||
|
|
||||||
|
config X86_DS_SELFTEST
|
||||||
|
bool "DS selftest"
|
||||||
|
default y
|
||||||
|
depends on DEBUG_KERNEL
|
||||||
|
depends on X86_DS
|
||||||
|
---help---
|
||||||
|
Perform Debug Store selftests at boot time.
|
||||||
|
If in doubt, say "N".
|
||||||
|
|
||||||
config HAVE_MMIOTRACE_SUPPORT
|
config HAVE_MMIOTRACE_SUPPORT
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,6 @@ else
|
||||||
KBUILD_DEFCONFIG := $(ARCH)_defconfig
|
KBUILD_DEFCONFIG := $(ARCH)_defconfig
|
||||||
endif
|
endif
|
||||||
|
|
||||||
core-$(CONFIG_KVM) += arch/x86/kvm/
|
|
||||||
|
|
||||||
# BITS is used as extension for files which are available in a 32 bit
|
# BITS is used as extension for files which are available in a 32 bit
|
||||||
# and a 64 bit version to simplify shared Makefiles.
|
# and a 64 bit version to simplify shared Makefiles.
|
||||||
# e.g.: obj-y += foo_$(BITS).o
|
# e.g.: obj-y += foo_$(BITS).o
|
||||||
|
@ -118,21 +116,8 @@ head-y += arch/x86/kernel/init_task.o
|
||||||
|
|
||||||
libs-y += arch/x86/lib/
|
libs-y += arch/x86/lib/
|
||||||
|
|
||||||
# Sub architecture files that needs linking first
|
# See arch/x86/Kbuild for content of core part of the kernel
|
||||||
core-y += $(fcore-y)
|
core-y += arch/x86/
|
||||||
|
|
||||||
# Xen paravirtualization support
|
|
||||||
core-$(CONFIG_XEN) += arch/x86/xen/
|
|
||||||
|
|
||||||
# lguest paravirtualization support
|
|
||||||
core-$(CONFIG_LGUEST_GUEST) += arch/x86/lguest/
|
|
||||||
|
|
||||||
core-y += arch/x86/kernel/
|
|
||||||
core-y += arch/x86/mm/
|
|
||||||
|
|
||||||
core-y += arch/x86/crypto/
|
|
||||||
core-y += arch/x86/vdso/
|
|
||||||
core-$(CONFIG_IA32_EMULATION) += arch/x86/ia32/
|
|
||||||
|
|
||||||
# drivers-y are linked after core-y
|
# drivers-y are linked after core-y
|
||||||
drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
|
drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
|
||||||
|
|
|
@ -3,6 +3,8 @@ bzImage
|
||||||
cpustr.h
|
cpustr.h
|
||||||
mkcpustr
|
mkcpustr
|
||||||
offsets.h
|
offsets.h
|
||||||
|
voffset.h
|
||||||
|
zoffset.h
|
||||||
setup
|
setup
|
||||||
setup.bin
|
setup.bin
|
||||||
setup.elf
|
setup.elf
|
||||||
|
|
|
@ -26,9 +26,10 @@ targets := vmlinux.bin setup.bin setup.elf bzImage
|
||||||
targets += fdimage fdimage144 fdimage288 image.iso mtools.conf
|
targets += fdimage fdimage144 fdimage288 image.iso mtools.conf
|
||||||
subdir- := compressed
|
subdir- := compressed
|
||||||
|
|
||||||
setup-y += a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o
|
setup-y += a20.o bioscall.o cmdline.o copy.o cpu.o cpucheck.o edd.o
|
||||||
setup-y += header.o main.o mca.o memory.o pm.o pmjump.o
|
setup-y += header.o main.o mca.o memory.o pm.o pmjump.o
|
||||||
setup-y += printf.o string.o tty.o video.o video-mode.o version.o
|
setup-y += printf.o regs.o string.o tty.o video.o video-mode.o
|
||||||
|
setup-y += version.o
|
||||||
setup-$(CONFIG_X86_APM_BOOT) += apm.o
|
setup-$(CONFIG_X86_APM_BOOT) += apm.o
|
||||||
|
|
||||||
# The link order of the video-*.o modules can matter. In particular,
|
# The link order of the video-*.o modules can matter. In particular,
|
||||||
|
@ -86,19 +87,27 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
|
||||||
|
|
||||||
SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
|
SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
|
||||||
|
|
||||||
sed-offsets := -e 's/^00*/0/' \
|
sed-voffset := -e 's/^\([0-9a-fA-F]*\) . \(_text\|_end\)$$/\#define VO_\2 0x\1/p'
|
||||||
-e 's/^\([0-9a-fA-F]*\) . \(input_data\|input_data_end\)$$/\#define \2 0x\1/p'
|
|
||||||
|
|
||||||
quiet_cmd_offsets = OFFSETS $@
|
quiet_cmd_voffset = VOFFSET $@
|
||||||
cmd_offsets = $(NM) $< | sed -n $(sed-offsets) > $@
|
cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@
|
||||||
|
|
||||||
$(obj)/offsets.h: $(obj)/compressed/vmlinux FORCE
|
targets += voffset.h
|
||||||
$(call if_changed,offsets)
|
$(obj)/voffset.h: vmlinux FORCE
|
||||||
|
$(call if_changed,voffset)
|
||||||
|
|
||||||
|
sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
|
||||||
|
|
||||||
|
quiet_cmd_zoffset = ZOFFSET $@
|
||||||
|
cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
|
||||||
|
|
||||||
|
targets += zoffset.h
|
||||||
|
$(obj)/zoffset.h: $(obj)/compressed/vmlinux FORCE
|
||||||
|
$(call if_changed,zoffset)
|
||||||
|
|
||||||
targets += offsets.h
|
|
||||||
|
|
||||||
AFLAGS_header.o += -I$(obj)
|
AFLAGS_header.o += -I$(obj)
|
||||||
$(obj)/header.o: $(obj)/offsets.h
|
$(obj)/header.o: $(obj)/voffset.h $(obj)/zoffset.h
|
||||||
|
|
||||||
LDFLAGS_setup.elf := -T
|
LDFLAGS_setup.elf := -T
|
||||||
$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
|
$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright 2007-2008 rPath, Inc. - All Rights Reserved
|
* Copyright 2007-2008 rPath, Inc. - All Rights Reserved
|
||||||
* Copyright 2009 Intel Corporation
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
*
|
*
|
||||||
* This file is part of the Linux kernel, and is made available under
|
* This file is part of the Linux kernel, and is made available under
|
||||||
* the terms of the GNU General Public License version 2.
|
* the terms of the GNU General Public License version 2.
|
||||||
|
@ -90,8 +90,11 @@ static int a20_test_long(void)
|
||||||
|
|
||||||
static void enable_a20_bios(void)
|
static void enable_a20_bios(void)
|
||||||
{
|
{
|
||||||
asm volatile("pushfl; int $0x15; popfl"
|
struct biosregs ireg;
|
||||||
: : "a" ((u16)0x2401));
|
|
||||||
|
initregs(&ireg);
|
||||||
|
ireg.ax = 0x2401;
|
||||||
|
intcall(0x15, &ireg, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enable_a20_kbc(void)
|
static void enable_a20_kbc(void)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
*
|
*
|
||||||
* Original APM BIOS checking by Stephen Rothwell, May 1994
|
* Original APM BIOS checking by Stephen Rothwell, May 1994
|
||||||
* (sfr@canb.auug.org.au)
|
* (sfr@canb.auug.org.au)
|
||||||
|
@ -19,75 +20,56 @@
|
||||||
|
|
||||||
int query_apm_bios(void)
|
int query_apm_bios(void)
|
||||||
{
|
{
|
||||||
u16 ax, bx, cx, dx, di;
|
struct biosregs ireg, oreg;
|
||||||
u32 ebx, esi;
|
|
||||||
u8 err;
|
|
||||||
|
|
||||||
/* APM BIOS installation check */
|
/* APM BIOS installation check */
|
||||||
ax = 0x5300;
|
initregs(&ireg);
|
||||||
bx = cx = 0;
|
ireg.ah = 0x53;
|
||||||
asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
|
intcall(0x15, &ireg, &oreg);
|
||||||
: "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
|
|
||||||
: : "esi", "edi");
|
|
||||||
|
|
||||||
if (err)
|
if (oreg.flags & X86_EFLAGS_CF)
|
||||||
return -1; /* No APM BIOS */
|
return -1; /* No APM BIOS */
|
||||||
|
|
||||||
if (bx != 0x504d) /* "PM" signature */
|
if (oreg.bx != 0x504d) /* "PM" signature */
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!(cx & 0x02)) /* 32 bits supported? */
|
if (!(oreg.cx & 0x02)) /* 32 bits supported? */
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Disconnect first, just in case */
|
/* Disconnect first, just in case */
|
||||||
ax = 0x5304;
|
ireg.al = 0x04;
|
||||||
bx = 0;
|
intcall(0x15, &ireg, NULL);
|
||||||
asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
|
|
||||||
: "+a" (ax), "+b" (bx)
|
|
||||||
: : "ecx", "edx", "esi", "edi");
|
|
||||||
|
|
||||||
/* Paranoia */
|
|
||||||
ebx = esi = 0;
|
|
||||||
cx = dx = di = 0;
|
|
||||||
|
|
||||||
/* 32-bit connect */
|
/* 32-bit connect */
|
||||||
asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
|
ireg.al = 0x03;
|
||||||
: "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
|
intcall(0x15, &ireg, &oreg);
|
||||||
"+S" (esi), "+D" (di), "=m" (err)
|
|
||||||
: "a" (0x5303));
|
|
||||||
|
|
||||||
boot_params.apm_bios_info.cseg = ax;
|
boot_params.apm_bios_info.cseg = oreg.ax;
|
||||||
boot_params.apm_bios_info.offset = ebx;
|
boot_params.apm_bios_info.offset = oreg.ebx;
|
||||||
boot_params.apm_bios_info.cseg_16 = cx;
|
boot_params.apm_bios_info.cseg_16 = oreg.cx;
|
||||||
boot_params.apm_bios_info.dseg = dx;
|
boot_params.apm_bios_info.dseg = oreg.dx;
|
||||||
boot_params.apm_bios_info.cseg_len = (u16)esi;
|
boot_params.apm_bios_info.cseg_len = oreg.si;
|
||||||
boot_params.apm_bios_info.cseg_16_len = esi >> 16;
|
boot_params.apm_bios_info.cseg_16_len = oreg.hsi;
|
||||||
boot_params.apm_bios_info.dseg_len = di;
|
boot_params.apm_bios_info.dseg_len = oreg.di;
|
||||||
|
|
||||||
if (err)
|
if (oreg.flags & X86_EFLAGS_CF)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Redo the installation check as the 32-bit connect;
|
/* Redo the installation check as the 32-bit connect;
|
||||||
some BIOSes return different flags this way... */
|
some BIOSes return different flags this way... */
|
||||||
|
|
||||||
ax = 0x5300;
|
ireg.al = 0x00;
|
||||||
bx = cx = 0;
|
intcall(0x15, &ireg, &oreg);
|
||||||
asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
|
|
||||||
: "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
|
|
||||||
: : "esi", "edi");
|
|
||||||
|
|
||||||
if (err || bx != 0x504d) {
|
if ((oreg.eflags & X86_EFLAGS_CF) || oreg.bx != 0x504d) {
|
||||||
/* Failure with 32-bit connect, try to disconect and ignore */
|
/* Failure with 32-bit connect, try to disconect and ignore */
|
||||||
ax = 0x5304;
|
ireg.al = 0x04;
|
||||||
bx = 0;
|
intcall(0x15, &ireg, NULL);
|
||||||
asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
|
|
||||||
: "+a" (ax), "+b" (bx)
|
|
||||||
: : "ecx", "edx", "esi", "edi");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
boot_params.apm_bios_info.version = ax;
|
boot_params.apm_bios_info.version = oreg.ax;
|
||||||
boot_params.apm_bios_info.flags = cx;
|
boot_params.apm_bios_info.flags = oreg.cx;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
|
*
|
||||||
|
* This file is part of the Linux kernel, and is made available under
|
||||||
|
* the terms of the GNU General Public License version 2 or (at your
|
||||||
|
* option) any later version; incorporated herein by reference.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "Glove box" for BIOS calls. Avoids the constant problems with BIOSes
|
||||||
|
* touching registers they shouldn't be.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.code16
|
||||||
|
.text
|
||||||
|
.globl intcall
|
||||||
|
.type intcall, @function
|
||||||
|
intcall:
|
||||||
|
/* Self-modify the INT instruction. Ugly, but works. */
|
||||||
|
cmpb %al, 3f
|
||||||
|
je 1f
|
||||||
|
movb %al, 3f
|
||||||
|
jmp 1f /* Synchronize pipeline */
|
||||||
|
1:
|
||||||
|
/* Save state */
|
||||||
|
pushfl
|
||||||
|
pushw %fs
|
||||||
|
pushw %gs
|
||||||
|
pushal
|
||||||
|
|
||||||
|
/* Copy input state to stack frame */
|
||||||
|
subw $44, %sp
|
||||||
|
movw %dx, %si
|
||||||
|
movw %sp, %di
|
||||||
|
movw $11, %cx
|
||||||
|
rep; movsd
|
||||||
|
|
||||||
|
/* Pop full state from the stack */
|
||||||
|
popal
|
||||||
|
popw %gs
|
||||||
|
popw %fs
|
||||||
|
popw %es
|
||||||
|
popw %ds
|
||||||
|
popfl
|
||||||
|
|
||||||
|
/* Actual INT */
|
||||||
|
.byte 0xcd /* INT opcode */
|
||||||
|
3: .byte 0
|
||||||
|
|
||||||
|
/* Push full state to the stack */
|
||||||
|
pushfl
|
||||||
|
pushw %ds
|
||||||
|
pushw %es
|
||||||
|
pushw %fs
|
||||||
|
pushw %gs
|
||||||
|
pushal
|
||||||
|
|
||||||
|
/* Re-establish C environment invariants */
|
||||||
|
cld
|
||||||
|
movzwl %sp, %esp
|
||||||
|
movw %cs, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %es
|
||||||
|
|
||||||
|
/* Copy output state from stack frame */
|
||||||
|
movw 68(%esp), %di /* Original %cx == 3rd argument */
|
||||||
|
andw %di, %di
|
||||||
|
jz 4f
|
||||||
|
movw %sp, %si
|
||||||
|
movw $11, %cx
|
||||||
|
rep; movsd
|
||||||
|
4: addw $44, %sp
|
||||||
|
|
||||||
|
/* Restore state and return */
|
||||||
|
popal
|
||||||
|
popw %gs
|
||||||
|
popw %fs
|
||||||
|
popfl
|
||||||
|
retl
|
||||||
|
.size intcall, .-intcall
|
|
@ -2,6 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
*
|
*
|
||||||
* This file is part of the Linux kernel, and is made available under
|
* This file is part of the Linux kernel, and is made available under
|
||||||
* the terms of the GNU General Public License version 2.
|
* the terms of the GNU General Public License version 2.
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include "bitops.h"
|
#include "bitops.h"
|
||||||
#include <asm/cpufeature.h>
|
#include <asm/cpufeature.h>
|
||||||
|
#include <asm/processor-flags.h>
|
||||||
|
|
||||||
/* Useful macros */
|
/* Useful macros */
|
||||||
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
|
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
|
||||||
|
@ -241,6 +243,49 @@ int enable_a20(void);
|
||||||
/* apm.c */
|
/* apm.c */
|
||||||
int query_apm_bios(void);
|
int query_apm_bios(void);
|
||||||
|
|
||||||
|
/* bioscall.c */
|
||||||
|
struct biosregs {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
u32 edi;
|
||||||
|
u32 esi;
|
||||||
|
u32 ebp;
|
||||||
|
u32 _esp;
|
||||||
|
u32 ebx;
|
||||||
|
u32 edx;
|
||||||
|
u32 ecx;
|
||||||
|
u32 eax;
|
||||||
|
u32 _fsgs;
|
||||||
|
u32 _dses;
|
||||||
|
u32 eflags;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
u16 di, hdi;
|
||||||
|
u16 si, hsi;
|
||||||
|
u16 bp, hbp;
|
||||||
|
u16 _sp, _hsp;
|
||||||
|
u16 bx, hbx;
|
||||||
|
u16 dx, hdx;
|
||||||
|
u16 cx, hcx;
|
||||||
|
u16 ax, hax;
|
||||||
|
u16 gs, fs;
|
||||||
|
u16 es, ds;
|
||||||
|
u16 flags, hflags;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
u8 dil, dih, edi2, edi3;
|
||||||
|
u8 sil, sih, esi2, esi3;
|
||||||
|
u8 bpl, bph, ebp2, ebp3;
|
||||||
|
u8 _spl, _sph, _esp2, _esp3;
|
||||||
|
u8 bl, bh, ebx2, ebx3;
|
||||||
|
u8 dl, dh, edx2, edx3;
|
||||||
|
u8 cl, ch, ecx2, ecx3;
|
||||||
|
u8 al, ah, eax2, eax3;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
void intcall(u8 int_no, const struct biosregs *ireg, struct biosregs *oreg);
|
||||||
|
|
||||||
/* cmdline.c */
|
/* cmdline.c */
|
||||||
int cmdline_find_option(const char *option, char *buffer, int bufsize);
|
int cmdline_find_option(const char *option, char *buffer, int bufsize);
|
||||||
int cmdline_find_option_bool(const char *option);
|
int cmdline_find_option_bool(const char *option);
|
||||||
|
@ -279,6 +324,9 @@ int sprintf(char *buf, const char *fmt, ...);
|
||||||
int vsprintf(char *buf, const char *fmt, va_list args);
|
int vsprintf(char *buf, const char *fmt, va_list args);
|
||||||
int printf(const char *fmt, ...);
|
int printf(const char *fmt, ...);
|
||||||
|
|
||||||
|
/* regs.c */
|
||||||
|
void initregs(struct biosregs *regs);
|
||||||
|
|
||||||
/* string.c */
|
/* string.c */
|
||||||
int strcmp(const char *str1, const char *str2);
|
int strcmp(const char *str1, const char *str2);
|
||||||
size_t strnlen(const char *s, size_t maxlen);
|
size_t strnlen(const char *s, size_t maxlen);
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
relocs
|
relocs
|
||||||
vmlinux.bin.all
|
vmlinux.bin.all
|
||||||
vmlinux.relocs
|
vmlinux.relocs
|
||||||
|
vmlinux.lds
|
||||||
|
mkpiggy
|
||||||
|
piggy.S
|
||||||
|
|
|
@ -19,7 +19,9 @@ KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
|
||||||
LDFLAGS := -m elf_$(UTS_MACHINE)
|
LDFLAGS := -m elf_$(UTS_MACHINE)
|
||||||
LDFLAGS_vmlinux := -T
|
LDFLAGS_vmlinux := -T
|
||||||
|
|
||||||
$(obj)/vmlinux: $(src)/vmlinux_$(BITS).lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/piggy.o FORCE
|
hostprogs-y := mkpiggy
|
||||||
|
|
||||||
|
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/piggy.o FORCE
|
||||||
$(call if_changed,ld)
|
$(call if_changed,ld)
|
||||||
@:
|
@:
|
||||||
|
|
||||||
|
@ -29,7 +31,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE
|
||||||
|
|
||||||
|
|
||||||
targets += vmlinux.bin.all vmlinux.relocs relocs
|
targets += vmlinux.bin.all vmlinux.relocs relocs
|
||||||
hostprogs-$(CONFIG_X86_32) += relocs
|
hostprogs-$(CONFIG_X86_NEED_RELOCS) += relocs
|
||||||
|
|
||||||
quiet_cmd_relocs = RELOCS $@
|
quiet_cmd_relocs = RELOCS $@
|
||||||
cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $<
|
cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $<
|
||||||
|
@ -37,46 +39,22 @@ $(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE
|
||||||
$(call if_changed,relocs)
|
$(call if_changed,relocs)
|
||||||
|
|
||||||
vmlinux.bin.all-y := $(obj)/vmlinux.bin
|
vmlinux.bin.all-y := $(obj)/vmlinux.bin
|
||||||
vmlinux.bin.all-$(CONFIG_RELOCATABLE) += $(obj)/vmlinux.relocs
|
vmlinux.bin.all-$(CONFIG_X86_NEED_RELOCS) += $(obj)/vmlinux.relocs
|
||||||
quiet_cmd_relocbin = BUILD $@
|
|
||||||
cmd_relocbin = cat $(filter-out FORCE,$^) > $@
|
|
||||||
$(obj)/vmlinux.bin.all: $(vmlinux.bin.all-y) FORCE
|
|
||||||
$(call if_changed,relocbin)
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_X86_32),y)
|
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
|
||||||
|
|
||||||
ifdef CONFIG_RELOCATABLE
|
|
||||||
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE
|
|
||||||
$(call if_changed,gzip)
|
$(call if_changed,gzip)
|
||||||
$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin.all FORCE
|
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
|
||||||
$(call if_changed,bzip2)
|
$(call if_changed,bzip2)
|
||||||
$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin.all FORCE
|
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
|
||||||
$(call if_changed,lzma)
|
|
||||||
else
|
|
||||||
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
|
|
||||||
$(call if_changed,gzip)
|
|
||||||
$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
|
|
||||||
$(call if_changed,bzip2)
|
|
||||||
$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
|
|
||||||
$(call if_changed,lzma)
|
|
||||||
endif
|
|
||||||
LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
|
|
||||||
$(call if_changed,gzip)
|
|
||||||
$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
|
|
||||||
$(call if_changed,bzip2)
|
|
||||||
$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
|
|
||||||
$(call if_changed,lzma)
|
$(call if_changed,lzma)
|
||||||
|
|
||||||
LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T
|
suffix-$(CONFIG_KERNEL_GZIP) := gz
|
||||||
endif
|
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
|
||||||
|
suffix-$(CONFIG_KERNEL_LZMA) := lzma
|
||||||
|
|
||||||
suffix_$(CONFIG_KERNEL_GZIP) = gz
|
quiet_cmd_mkpiggy = MKPIGGY $@
|
||||||
suffix_$(CONFIG_KERNEL_BZIP2) = bz2
|
cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false )
|
||||||
suffix_$(CONFIG_KERNEL_LZMA) = lzma
|
|
||||||
|
|
||||||
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE
|
targets += piggy.S
|
||||||
$(call if_changed,ld)
|
$(obj)/piggy.S: $(obj)/vmlinux.bin.$(suffix-y) $(obj)/mkpiggy FORCE
|
||||||
|
$(call if_changed,mkpiggy)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
/*
|
/*
|
||||||
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
|
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
|
||||||
*/
|
*/
|
||||||
.text
|
.text
|
||||||
|
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <asm/segment.h>
|
#include <asm/segment.h>
|
||||||
|
@ -29,161 +29,151 @@
|
||||||
#include <asm/boot.h>
|
#include <asm/boot.h>
|
||||||
#include <asm/asm-offsets.h>
|
#include <asm/asm-offsets.h>
|
||||||
|
|
||||||
.section ".text.head","ax",@progbits
|
.section ".text.head","ax",@progbits
|
||||||
ENTRY(startup_32)
|
ENTRY(startup_32)
|
||||||
cld
|
cld
|
||||||
/* test KEEP_SEGMENTS flag to see if the bootloader is asking
|
/*
|
||||||
* us to not reload segments */
|
* Test KEEP_SEGMENTS flag to see if the bootloader is asking
|
||||||
testb $(1<<6), BP_loadflags(%esi)
|
* us to not reload segments
|
||||||
jnz 1f
|
*/
|
||||||
|
testb $(1<<6), BP_loadflags(%esi)
|
||||||
|
jnz 1f
|
||||||
|
|
||||||
cli
|
cli
|
||||||
movl $(__BOOT_DS),%eax
|
movl $__BOOT_DS, %eax
|
||||||
movl %eax,%ds
|
movl %eax, %ds
|
||||||
movl %eax,%es
|
movl %eax, %es
|
||||||
movl %eax,%fs
|
movl %eax, %fs
|
||||||
movl %eax,%gs
|
movl %eax, %gs
|
||||||
movl %eax,%ss
|
movl %eax, %ss
|
||||||
1:
|
1:
|
||||||
|
|
||||||
/* Calculate the delta between where we were compiled to run
|
/*
|
||||||
|
* Calculate the delta between where we were compiled to run
|
||||||
* at and where we were actually loaded at. This can only be done
|
* at and where we were actually loaded at. This can only be done
|
||||||
* with a short local call on x86. Nothing else will tell us what
|
* with a short local call on x86. Nothing else will tell us what
|
||||||
* address we are running at. The reserved chunk of the real-mode
|
* address we are running at. The reserved chunk of the real-mode
|
||||||
* data at 0x1e4 (defined as a scratch field) are used as the stack
|
* data at 0x1e4 (defined as a scratch field) are used as the stack
|
||||||
* for this calculation. Only 4 bytes are needed.
|
* for this calculation. Only 4 bytes are needed.
|
||||||
*/
|
*/
|
||||||
leal (0x1e4+4)(%esi), %esp
|
leal (BP_scratch+4)(%esi), %esp
|
||||||
call 1f
|
call 1f
|
||||||
1: popl %ebp
|
1: popl %ebp
|
||||||
subl $1b, %ebp
|
subl $1b, %ebp
|
||||||
|
|
||||||
/* %ebp contains the address we are loaded at by the boot loader and %ebx
|
/*
|
||||||
|
* %ebp contains the address we are loaded at by the boot loader and %ebx
|
||||||
* contains the address where we should move the kernel image temporarily
|
* contains the address where we should move the kernel image temporarily
|
||||||
* for safe in-place decompression.
|
* for safe in-place decompression.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_RELOCATABLE
|
#ifdef CONFIG_RELOCATABLE
|
||||||
movl %ebp, %ebx
|
movl %ebp, %ebx
|
||||||
addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
|
movl BP_kernel_alignment(%esi), %eax
|
||||||
andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
|
decl %eax
|
||||||
|
addl %eax, %ebx
|
||||||
|
notl %eax
|
||||||
|
andl %eax, %ebx
|
||||||
#else
|
#else
|
||||||
movl $LOAD_PHYSICAL_ADDR, %ebx
|
movl $LOAD_PHYSICAL_ADDR, %ebx
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Replace the compressed data size with the uncompressed size */
|
/* Target address to relocate to for decompression */
|
||||||
subl input_len(%ebp), %ebx
|
addl $z_extract_offset, %ebx
|
||||||
movl output_len(%ebp), %eax
|
|
||||||
addl %eax, %ebx
|
|
||||||
/* Add 8 bytes for every 32K input block */
|
|
||||||
shrl $12, %eax
|
|
||||||
addl %eax, %ebx
|
|
||||||
/* Add 32K + 18 bytes of extra slack */
|
|
||||||
addl $(32768 + 18), %ebx
|
|
||||||
/* Align on a 4K boundary */
|
|
||||||
addl $4095, %ebx
|
|
||||||
andl $~4095, %ebx
|
|
||||||
|
|
||||||
/* Copy the compressed kernel to the end of our buffer
|
/* Set up the stack */
|
||||||
|
leal boot_stack_end(%ebx), %esp
|
||||||
|
|
||||||
|
/* Zero EFLAGS */
|
||||||
|
pushl $0
|
||||||
|
popfl
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the compressed kernel to the end of our buffer
|
||||||
* where decompression in place becomes safe.
|
* where decompression in place becomes safe.
|
||||||
*/
|
*/
|
||||||
pushl %esi
|
pushl %esi
|
||||||
leal _end(%ebp), %esi
|
leal (_bss-4)(%ebp), %esi
|
||||||
leal _end(%ebx), %edi
|
leal (_bss-4)(%ebx), %edi
|
||||||
movl $(_end - startup_32), %ecx
|
movl $(_bss - startup_32), %ecx
|
||||||
|
shrl $2, %ecx
|
||||||
std
|
std
|
||||||
rep
|
rep movsl
|
||||||
movsb
|
|
||||||
cld
|
cld
|
||||||
popl %esi
|
popl %esi
|
||||||
|
|
||||||
/* Compute the kernel start address.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_RELOCATABLE
|
|
||||||
addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
|
|
||||||
andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
|
|
||||||
#else
|
|
||||||
movl $LOAD_PHYSICAL_ADDR, %ebp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Jump to the relocated address.
|
* Jump to the relocated address.
|
||||||
*/
|
*/
|
||||||
leal relocated(%ebx), %eax
|
leal relocated(%ebx), %eax
|
||||||
jmp *%eax
|
jmp *%eax
|
||||||
ENDPROC(startup_32)
|
ENDPROC(startup_32)
|
||||||
|
|
||||||
.section ".text"
|
.text
|
||||||
relocated:
|
relocated:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear BSS
|
* Clear BSS (stack is currently empty)
|
||||||
*/
|
*/
|
||||||
xorl %eax,%eax
|
xorl %eax, %eax
|
||||||
leal _edata(%ebx),%edi
|
leal _bss(%ebx), %edi
|
||||||
leal _end(%ebx), %ecx
|
leal _ebss(%ebx), %ecx
|
||||||
subl %edi,%ecx
|
subl %edi, %ecx
|
||||||
cld
|
shrl $2, %ecx
|
||||||
rep
|
rep stosl
|
||||||
stosb
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup the stack for the decompressor
|
|
||||||
*/
|
|
||||||
leal boot_stack_end(%ebx), %esp
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the decompression, and jump to the new kernel..
|
* Do the decompression, and jump to the new kernel..
|
||||||
*/
|
*/
|
||||||
movl output_len(%ebx), %eax
|
leal z_extract_offset_negative(%ebx), %ebp
|
||||||
pushl %eax
|
/* push arguments for decompress_kernel: */
|
||||||
# push arguments for decompress_kernel:
|
pushl %ebp /* output address */
|
||||||
pushl %ebp # output address
|
pushl $z_input_len /* input_len */
|
||||||
movl input_len(%ebx), %eax
|
leal input_data(%ebx), %eax
|
||||||
pushl %eax # input_len
|
pushl %eax /* input_data */
|
||||||
leal input_data(%ebx), %eax
|
leal boot_heap(%ebx), %eax
|
||||||
pushl %eax # input_data
|
pushl %eax /* heap area */
|
||||||
leal boot_heap(%ebx), %eax
|
pushl %esi /* real mode pointer */
|
||||||
pushl %eax # heap area
|
call decompress_kernel
|
||||||
pushl %esi # real mode pointer
|
addl $20, %esp
|
||||||
call decompress_kernel
|
|
||||||
addl $20, %esp
|
|
||||||
popl %ecx
|
|
||||||
|
|
||||||
#if CONFIG_RELOCATABLE
|
#if CONFIG_RELOCATABLE
|
||||||
/* Find the address of the relocations.
|
/*
|
||||||
|
* Find the address of the relocations.
|
||||||
*/
|
*/
|
||||||
movl %ebp, %edi
|
leal z_output_len(%ebp), %edi
|
||||||
addl %ecx, %edi
|
|
||||||
|
|
||||||
/* Calculate the delta between where vmlinux was compiled to run
|
/*
|
||||||
|
* Calculate the delta between where vmlinux was compiled to run
|
||||||
* and where it was actually loaded.
|
* and where it was actually loaded.
|
||||||
*/
|
*/
|
||||||
movl %ebp, %ebx
|
movl %ebp, %ebx
|
||||||
subl $LOAD_PHYSICAL_ADDR, %ebx
|
subl $LOAD_PHYSICAL_ADDR, %ebx
|
||||||
jz 2f /* Nothing to be done if loaded at compiled addr. */
|
jz 2f /* Nothing to be done if loaded at compiled addr. */
|
||||||
/*
|
/*
|
||||||
* Process relocations.
|
* Process relocations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
1: subl $4, %edi
|
1: subl $4, %edi
|
||||||
movl 0(%edi), %ecx
|
movl (%edi), %ecx
|
||||||
testl %ecx, %ecx
|
testl %ecx, %ecx
|
||||||
jz 2f
|
jz 2f
|
||||||
addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
|
addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
|
||||||
jmp 1b
|
jmp 1b
|
||||||
2:
|
2:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Jump to the decompressed kernel.
|
* Jump to the decompressed kernel.
|
||||||
*/
|
*/
|
||||||
xorl %ebx,%ebx
|
xorl %ebx, %ebx
|
||||||
jmp *%ebp
|
jmp *%ebp
|
||||||
|
|
||||||
.bss
|
/*
|
||||||
/* Stack and heap for uncompression */
|
* Stack and heap for uncompression
|
||||||
.balign 4
|
*/
|
||||||
|
.bss
|
||||||
|
.balign 4
|
||||||
boot_heap:
|
boot_heap:
|
||||||
.fill BOOT_HEAP_SIZE, 1, 0
|
.fill BOOT_HEAP_SIZE, 1, 0
|
||||||
boot_stack:
|
boot_stack:
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
/*
|
/*
|
||||||
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
|
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
|
||||||
*/
|
*/
|
||||||
.code32
|
.code32
|
||||||
.text
|
.text
|
||||||
|
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <asm/segment.h>
|
#include <asm/segment.h>
|
||||||
|
@ -33,12 +33,14 @@
|
||||||
#include <asm/processor-flags.h>
|
#include <asm/processor-flags.h>
|
||||||
#include <asm/asm-offsets.h>
|
#include <asm/asm-offsets.h>
|
||||||
|
|
||||||
.section ".text.head"
|
.section ".text.head"
|
||||||
.code32
|
.code32
|
||||||
ENTRY(startup_32)
|
ENTRY(startup_32)
|
||||||
cld
|
cld
|
||||||
/* test KEEP_SEGMENTS flag to see if the bootloader is asking
|
/*
|
||||||
* us to not reload segments */
|
* Test KEEP_SEGMENTS flag to see if the bootloader is asking
|
||||||
|
* us to not reload segments
|
||||||
|
*/
|
||||||
testb $(1<<6), BP_loadflags(%esi)
|
testb $(1<<6), BP_loadflags(%esi)
|
||||||
jnz 1f
|
jnz 1f
|
||||||
|
|
||||||
|
@ -49,14 +51,15 @@ ENTRY(startup_32)
|
||||||
movl %eax, %ss
|
movl %eax, %ss
|
||||||
1:
|
1:
|
||||||
|
|
||||||
/* Calculate the delta between where we were compiled to run
|
/*
|
||||||
|
* Calculate the delta between where we were compiled to run
|
||||||
* at and where we were actually loaded at. This can only be done
|
* at and where we were actually loaded at. This can only be done
|
||||||
* with a short local call on x86. Nothing else will tell us what
|
* with a short local call on x86. Nothing else will tell us what
|
||||||
* address we are running at. The reserved chunk of the real-mode
|
* address we are running at. The reserved chunk of the real-mode
|
||||||
* data at 0x1e4 (defined as a scratch field) are used as the stack
|
* data at 0x1e4 (defined as a scratch field) are used as the stack
|
||||||
* for this calculation. Only 4 bytes are needed.
|
* for this calculation. Only 4 bytes are needed.
|
||||||
*/
|
*/
|
||||||
leal (0x1e4+4)(%esi), %esp
|
leal (BP_scratch+4)(%esi), %esp
|
||||||
call 1f
|
call 1f
|
||||||
1: popl %ebp
|
1: popl %ebp
|
||||||
subl $1b, %ebp
|
subl $1b, %ebp
|
||||||
|
@ -70,32 +73,28 @@ ENTRY(startup_32)
|
||||||
testl %eax, %eax
|
testl %eax, %eax
|
||||||
jnz no_longmode
|
jnz no_longmode
|
||||||
|
|
||||||
/* Compute the delta between where we were compiled to run at
|
/*
|
||||||
|
* Compute the delta between where we were compiled to run at
|
||||||
* and where the code will actually run at.
|
* and where the code will actually run at.
|
||||||
*/
|
*
|
||||||
/* %ebp contains the address we are loaded at by the boot loader and %ebx
|
* %ebp contains the address we are loaded at by the boot loader and %ebx
|
||||||
* contains the address where we should move the kernel image temporarily
|
* contains the address where we should move the kernel image temporarily
|
||||||
* for safe in-place decompression.
|
* for safe in-place decompression.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_RELOCATABLE
|
#ifdef CONFIG_RELOCATABLE
|
||||||
movl %ebp, %ebx
|
movl %ebp, %ebx
|
||||||
addl $(PMD_PAGE_SIZE -1), %ebx
|
movl BP_kernel_alignment(%esi), %eax
|
||||||
andl $PMD_PAGE_MASK, %ebx
|
decl %eax
|
||||||
|
addl %eax, %ebx
|
||||||
|
notl %eax
|
||||||
|
andl %eax, %ebx
|
||||||
#else
|
#else
|
||||||
movl $CONFIG_PHYSICAL_START, %ebx
|
movl $LOAD_PHYSICAL_ADDR, %ebx
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Replace the compressed data size with the uncompressed size */
|
/* Target address to relocate to for decompression */
|
||||||
subl input_len(%ebp), %ebx
|
addl $z_extract_offset, %ebx
|
||||||
movl output_len(%ebp), %eax
|
|
||||||
addl %eax, %ebx
|
|
||||||
/* Add 8 bytes for every 32K input block */
|
|
||||||
shrl $12, %eax
|
|
||||||
addl %eax, %ebx
|
|
||||||
/* Add 32K + 18 bytes of extra slack and align on a 4K boundary */
|
|
||||||
addl $(32768 + 18 + 4095), %ebx
|
|
||||||
andl $~4095, %ebx
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare for entering 64 bit mode
|
* Prepare for entering 64 bit mode
|
||||||
|
@ -114,7 +113,7 @@ ENTRY(startup_32)
|
||||||
/*
|
/*
|
||||||
* Build early 4G boot pagetable
|
* Build early 4G boot pagetable
|
||||||
*/
|
*/
|
||||||
/* Initialize Page tables to 0*/
|
/* Initialize Page tables to 0 */
|
||||||
leal pgtable(%ebx), %edi
|
leal pgtable(%ebx), %edi
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
movl $((4096*6)/4), %ecx
|
movl $((4096*6)/4), %ecx
|
||||||
|
@ -155,7 +154,8 @@ ENTRY(startup_32)
|
||||||
btsl $_EFER_LME, %eax
|
btsl $_EFER_LME, %eax
|
||||||
wrmsr
|
wrmsr
|
||||||
|
|
||||||
/* Setup for the jump to 64bit mode
|
/*
|
||||||
|
* Setup for the jump to 64bit mode
|
||||||
*
|
*
|
||||||
* When the jump is performend we will be in long mode but
|
* When the jump is performend we will be in long mode but
|
||||||
* in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1
|
* in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1
|
||||||
|
@ -184,7 +184,8 @@ no_longmode:
|
||||||
|
|
||||||
#include "../../kernel/verify_cpu_64.S"
|
#include "../../kernel/verify_cpu_64.S"
|
||||||
|
|
||||||
/* Be careful here startup_64 needs to be at a predictable
|
/*
|
||||||
|
* Be careful here startup_64 needs to be at a predictable
|
||||||
* address so I can export it in an ELF header. Bootloaders
|
* address so I can export it in an ELF header. Bootloaders
|
||||||
* should look at the ELF header to find this address, as
|
* should look at the ELF header to find this address, as
|
||||||
* it may change in the future.
|
* it may change in the future.
|
||||||
|
@ -192,7 +193,8 @@ no_longmode:
|
||||||
.code64
|
.code64
|
||||||
.org 0x200
|
.org 0x200
|
||||||
ENTRY(startup_64)
|
ENTRY(startup_64)
|
||||||
/* We come here either from startup_32 or directly from a
|
/*
|
||||||
|
* We come here either from startup_32 or directly from a
|
||||||
* 64bit bootloader. If we come here from a bootloader we depend on
|
* 64bit bootloader. If we come here from a bootloader we depend on
|
||||||
* an identity mapped page table being provied that maps our
|
* an identity mapped page table being provied that maps our
|
||||||
* entire text+data+bss and hopefully all of memory.
|
* entire text+data+bss and hopefully all of memory.
|
||||||
|
@ -209,50 +211,54 @@ ENTRY(startup_64)
|
||||||
movl $0x20, %eax
|
movl $0x20, %eax
|
||||||
ltr %ax
|
ltr %ax
|
||||||
|
|
||||||
/* Compute the decompressed kernel start address. It is where
|
/*
|
||||||
|
* Compute the decompressed kernel start address. It is where
|
||||||
* we were loaded at aligned to a 2M boundary. %rbp contains the
|
* we were loaded at aligned to a 2M boundary. %rbp contains the
|
||||||
* decompressed kernel start address.
|
* decompressed kernel start address.
|
||||||
*
|
*
|
||||||
* If it is a relocatable kernel then decompress and run the kernel
|
* If it is a relocatable kernel then decompress and run the kernel
|
||||||
* from load address aligned to 2MB addr, otherwise decompress and
|
* from load address aligned to 2MB addr, otherwise decompress and
|
||||||
* run the kernel from CONFIG_PHYSICAL_START
|
* run the kernel from LOAD_PHYSICAL_ADDR
|
||||||
|
*
|
||||||
|
* We cannot rely on the calculation done in 32-bit mode, since we
|
||||||
|
* may have been invoked via the 64-bit entry point.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Start with the delta to where the kernel will run at. */
|
/* Start with the delta to where the kernel will run at. */
|
||||||
#ifdef CONFIG_RELOCATABLE
|
#ifdef CONFIG_RELOCATABLE
|
||||||
leaq startup_32(%rip) /* - $startup_32 */, %rbp
|
leaq startup_32(%rip) /* - $startup_32 */, %rbp
|
||||||
addq $(PMD_PAGE_SIZE - 1), %rbp
|
movl BP_kernel_alignment(%rsi), %eax
|
||||||
andq $PMD_PAGE_MASK, %rbp
|
decl %eax
|
||||||
movq %rbp, %rbx
|
addq %rax, %rbp
|
||||||
|
notq %rax
|
||||||
|
andq %rax, %rbp
|
||||||
#else
|
#else
|
||||||
movq $CONFIG_PHYSICAL_START, %rbp
|
movq $LOAD_PHYSICAL_ADDR, %rbp
|
||||||
movq %rbp, %rbx
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Replace the compressed data size with the uncompressed size */
|
/* Target address to relocate to for decompression */
|
||||||
movl input_len(%rip), %eax
|
leaq z_extract_offset(%rbp), %rbx
|
||||||
subq %rax, %rbx
|
|
||||||
movl output_len(%rip), %eax
|
|
||||||
addq %rax, %rbx
|
|
||||||
/* Add 8 bytes for every 32K input block */
|
|
||||||
shrq $12, %rax
|
|
||||||
addq %rax, %rbx
|
|
||||||
/* Add 32K + 18 bytes of extra slack and align on a 4K boundary */
|
|
||||||
addq $(32768 + 18 + 4095), %rbx
|
|
||||||
andq $~4095, %rbx
|
|
||||||
|
|
||||||
/* Copy the compressed kernel to the end of our buffer
|
/* Set up the stack */
|
||||||
|
leaq boot_stack_end(%rbx), %rsp
|
||||||
|
|
||||||
|
/* Zero EFLAGS */
|
||||||
|
pushq $0
|
||||||
|
popfq
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the compressed kernel to the end of our buffer
|
||||||
* where decompression in place becomes safe.
|
* where decompression in place becomes safe.
|
||||||
*/
|
*/
|
||||||
leaq _end_before_pgt(%rip), %r8
|
pushq %rsi
|
||||||
leaq _end_before_pgt(%rbx), %r9
|
leaq (_bss-8)(%rip), %rsi
|
||||||
movq $_end_before_pgt /* - $startup_32 */, %rcx
|
leaq (_bss-8)(%rbx), %rdi
|
||||||
1: subq $8, %r8
|
movq $_bss /* - $startup_32 */, %rcx
|
||||||
subq $8, %r9
|
shrq $3, %rcx
|
||||||
movq 0(%r8), %rax
|
std
|
||||||
movq %rax, 0(%r9)
|
rep movsq
|
||||||
subq $8, %rcx
|
cld
|
||||||
jnz 1b
|
popq %rsi
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Jump to the relocated address.
|
* Jump to the relocated address.
|
||||||
|
@ -260,37 +266,28 @@ ENTRY(startup_64)
|
||||||
leaq relocated(%rbx), %rax
|
leaq relocated(%rbx), %rax
|
||||||
jmp *%rax
|
jmp *%rax
|
||||||
|
|
||||||
.section ".text"
|
.text
|
||||||
relocated:
|
relocated:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear BSS
|
* Clear BSS (stack is currently empty)
|
||||||
*/
|
*/
|
||||||
xorq %rax, %rax
|
xorl %eax, %eax
|
||||||
leaq _edata(%rbx), %rdi
|
leaq _bss(%rip), %rdi
|
||||||
leaq _end_before_pgt(%rbx), %rcx
|
leaq _ebss(%rip), %rcx
|
||||||
subq %rdi, %rcx
|
subq %rdi, %rcx
|
||||||
cld
|
shrq $3, %rcx
|
||||||
rep
|
rep stosq
|
||||||
stosb
|
|
||||||
|
|
||||||
/* Setup the stack */
|
|
||||||
leaq boot_stack_end(%rip), %rsp
|
|
||||||
|
|
||||||
/* zero EFLAGS after setting rsp */
|
|
||||||
pushq $0
|
|
||||||
popfq
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the decompression, and jump to the new kernel..
|
* Do the decompression, and jump to the new kernel..
|
||||||
*/
|
*/
|
||||||
pushq %rsi # Save the real mode argument
|
pushq %rsi /* Save the real mode argument */
|
||||||
movq %rsi, %rdi # real mode address
|
movq %rsi, %rdi /* real mode address */
|
||||||
leaq boot_heap(%rip), %rsi # malloc area for uncompression
|
leaq boot_heap(%rip), %rsi /* malloc area for uncompression */
|
||||||
leaq input_data(%rip), %rdx # input_data
|
leaq input_data(%rip), %rdx /* input_data */
|
||||||
movl input_len(%rip), %eax
|
movl $z_input_len, %ecx /* input_len */
|
||||||
movq %rax, %rcx # input_len
|
movq %rbp, %r8 /* output target address */
|
||||||
movq %rbp, %r8 # output
|
|
||||||
call decompress_kernel
|
call decompress_kernel
|
||||||
popq %rsi
|
popq %rsi
|
||||||
|
|
||||||
|
@ -311,11 +308,21 @@ gdt:
|
||||||
.quad 0x0000000000000000 /* TS continued */
|
.quad 0x0000000000000000 /* TS continued */
|
||||||
gdt_end:
|
gdt_end:
|
||||||
|
|
||||||
.bss
|
/*
|
||||||
/* Stack and heap for uncompression */
|
* Stack and heap for uncompression
|
||||||
.balign 4
|
*/
|
||||||
|
.bss
|
||||||
|
.balign 4
|
||||||
boot_heap:
|
boot_heap:
|
||||||
.fill BOOT_HEAP_SIZE, 1, 0
|
.fill BOOT_HEAP_SIZE, 1, 0
|
||||||
boot_stack:
|
boot_stack:
|
||||||
.fill BOOT_STACK_SIZE, 1, 0
|
.fill BOOT_STACK_SIZE, 1, 0
|
||||||
boot_stack_end:
|
boot_stack_end:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Space for page tables (not in .bss so not zeroed)
|
||||||
|
*/
|
||||||
|
.section ".pgtable","a",@nobits
|
||||||
|
.balign 4096
|
||||||
|
pgtable:
|
||||||
|
.fill 6*4096, 1, 0
|
||||||
|
|
|
@ -325,20 +325,18 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
|
||||||
free_mem_ptr = heap; /* Heap */
|
free_mem_ptr = heap; /* Heap */
|
||||||
free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
|
free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
|
||||||
|
|
||||||
|
if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1))
|
||||||
|
error("Destination address inappropriately aligned");
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
if ((unsigned long)output & (__KERNEL_ALIGN - 1))
|
if (heap > 0x3fffffffffffUL)
|
||||||
error("Destination address not 2M aligned");
|
|
||||||
if ((unsigned long)output >= 0xffffffffffUL)
|
|
||||||
error("Destination address too large");
|
error("Destination address too large");
|
||||||
#else
|
#else
|
||||||
if ((u32)output & (CONFIG_PHYSICAL_ALIGN - 1))
|
|
||||||
error("Destination address not CONFIG_PHYSICAL_ALIGN aligned");
|
|
||||||
if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
|
if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
|
||||||
error("Destination address too large");
|
error("Destination address too large");
|
||||||
#ifndef CONFIG_RELOCATABLE
|
|
||||||
if ((u32)output != LOAD_PHYSICAL_ADDR)
|
|
||||||
error("Wrong destination address");
|
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef CONFIG_RELOCATABLE
|
||||||
|
if ((unsigned long)output != LOAD_PHYSICAL_ADDR)
|
||||||
|
error("Wrong destination address");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/* ----------------------------------------------------------------------- *
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Intel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License version
|
||||||
|
* 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* H. Peter Anvin <hpa@linux.intel.com>
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the desired load offset from a compressed program; outputs
|
||||||
|
* a small assembly wrapper with the appropriate symbols defined.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
static uint32_t getle32(const void *p)
|
||||||
|
{
|
||||||
|
const uint8_t *cp = p;
|
||||||
|
|
||||||
|
return (uint32_t)cp[0] + ((uint32_t)cp[1] << 8) +
|
||||||
|
((uint32_t)cp[2] << 16) + ((uint32_t)cp[3] << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
uint32_t olen;
|
||||||
|
long ilen;
|
||||||
|
unsigned long offs;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr, "Usage: %s compressed_file\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the information for the compressed kernel image first */
|
||||||
|
|
||||||
|
f = fopen(argv[1], "r");
|
||||||
|
if (!f) {
|
||||||
|
perror(argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (fseek(f, -4L, SEEK_END)) {
|
||||||
|
perror(argv[1]);
|
||||||
|
}
|
||||||
|
fread(&olen, sizeof olen, 1, f);
|
||||||
|
ilen = ftell(f);
|
||||||
|
olen = getle32(&olen);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now we have the input (compressed) and output (uncompressed)
|
||||||
|
* sizes, compute the necessary decompression offset...
|
||||||
|
*/
|
||||||
|
|
||||||
|
offs = (olen > ilen) ? olen - ilen : 0;
|
||||||
|
offs += olen >> 12; /* Add 8 bytes for each 32K block */
|
||||||
|
offs += 32*1024 + 18; /* Add 32K + 18 bytes slack */
|
||||||
|
offs = (offs+4095) & ~4095; /* Round to a 4K boundary */
|
||||||
|
|
||||||
|
printf(".section \".rodata.compressed\",\"a\",@progbits\n");
|
||||||
|
printf(".globl z_input_len\n");
|
||||||
|
printf("z_input_len = %lu\n", ilen);
|
||||||
|
printf(".globl z_output_len\n");
|
||||||
|
printf("z_output_len = %lu\n", (unsigned long)olen);
|
||||||
|
printf(".globl z_extract_offset\n");
|
||||||
|
printf("z_extract_offset = 0x%lx\n", offs);
|
||||||
|
/* z_extract_offset_negative allows simplification of head_32.S */
|
||||||
|
printf(".globl z_extract_offset_negative\n");
|
||||||
|
printf("z_extract_offset_negative = -0x%lx\n", offs);
|
||||||
|
|
||||||
|
printf(".globl input_data, input_data_end\n");
|
||||||
|
printf("input_data:\n");
|
||||||
|
printf(".incbin \"%s\"\n", argv[1]);
|
||||||
|
printf("input_data_end:\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,6 +1,17 @@
|
||||||
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
|
OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT)
|
||||||
|
|
||||||
|
#undef i386
|
||||||
|
|
||||||
|
#include <asm/page_types.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
OUTPUT_ARCH(i386:x86-64)
|
OUTPUT_ARCH(i386:x86-64)
|
||||||
ENTRY(startup_64)
|
ENTRY(startup_64)
|
||||||
|
#else
|
||||||
|
OUTPUT_ARCH(i386)
|
||||||
|
ENTRY(startup_32)
|
||||||
|
#endif
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
/* Be careful parts of head_64.S assume startup_32 is at
|
/* Be careful parts of head_64.S assume startup_32 is at
|
||||||
|
@ -33,16 +44,22 @@ SECTIONS
|
||||||
*(.data.*)
|
*(.data.*)
|
||||||
_edata = . ;
|
_edata = . ;
|
||||||
}
|
}
|
||||||
|
. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
|
||||||
.bss : {
|
.bss : {
|
||||||
_bss = . ;
|
_bss = . ;
|
||||||
*(.bss)
|
*(.bss)
|
||||||
*(.bss.*)
|
*(.bss.*)
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
. = ALIGN(8);
|
. = ALIGN(8); /* For convenience during zeroing */
|
||||||
_end_before_pgt = . ;
|
|
||||||
. = ALIGN(4096);
|
|
||||||
pgtable = . ;
|
|
||||||
. = . + 4096 * 6;
|
|
||||||
_ebss = .;
|
_ebss = .;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
. = ALIGN(PAGE_SIZE);
|
||||||
|
.pgtable : {
|
||||||
|
_pgtable = . ;
|
||||||
|
*(.pgtable)
|
||||||
|
_epgtable = . ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
_end = .;
|
||||||
}
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
.rodata.compressed : {
|
|
||||||
input_len = .;
|
|
||||||
LONG(input_data_end - input_data) input_data = .;
|
|
||||||
*(.data)
|
|
||||||
output_len = . - 4;
|
|
||||||
input_data_end = .;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
|
||||||
OUTPUT_ARCH(i386)
|
|
||||||
ENTRY(startup_32)
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
/* Be careful parts of head_32.S assume startup_32 is at
|
|
||||||
* address 0.
|
|
||||||
*/
|
|
||||||
. = 0;
|
|
||||||
.text.head : {
|
|
||||||
_head = . ;
|
|
||||||
*(.text.head)
|
|
||||||
_ehead = . ;
|
|
||||||
}
|
|
||||||
.rodata.compressed : {
|
|
||||||
*(.rodata.compressed)
|
|
||||||
}
|
|
||||||
.text : {
|
|
||||||
_text = .; /* Text */
|
|
||||||
*(.text)
|
|
||||||
*(.text.*)
|
|
||||||
_etext = . ;
|
|
||||||
}
|
|
||||||
.rodata : {
|
|
||||||
_rodata = . ;
|
|
||||||
*(.rodata) /* read-only data */
|
|
||||||
*(.rodata.*)
|
|
||||||
_erodata = . ;
|
|
||||||
}
|
|
||||||
.data : {
|
|
||||||
_data = . ;
|
|
||||||
*(.data)
|
|
||||||
*(.data.*)
|
|
||||||
_edata = . ;
|
|
||||||
}
|
|
||||||
.bss : {
|
|
||||||
_bss = . ;
|
|
||||||
*(.bss)
|
|
||||||
*(.bss.*)
|
|
||||||
*(COMMON)
|
|
||||||
_end = . ;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
*
|
*
|
||||||
* This file is part of the Linux kernel, and is made available under
|
* This file is part of the Linux kernel, and is made available under
|
||||||
* the terms of the GNU General Public License version 2.
|
* the terms of the GNU General Public License version 2.
|
||||||
|
@ -22,17 +23,17 @@
|
||||||
*/
|
*/
|
||||||
static int read_mbr(u8 devno, void *buf)
|
static int read_mbr(u8 devno, void *buf)
|
||||||
{
|
{
|
||||||
u16 ax, bx, cx, dx;
|
struct biosregs ireg, oreg;
|
||||||
|
|
||||||
ax = 0x0201; /* Legacy Read, one sector */
|
initregs(&ireg);
|
||||||
cx = 0x0001; /* Sector 0-0-1 */
|
ireg.ax = 0x0201; /* Legacy Read, one sector */
|
||||||
dx = devno;
|
ireg.cx = 0x0001; /* Sector 0-0-1 */
|
||||||
bx = (size_t)buf;
|
ireg.dl = devno;
|
||||||
asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
|
ireg.bx = (size_t)buf;
|
||||||
: "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
|
|
||||||
: : "esi", "edi", "memory");
|
|
||||||
|
|
||||||
return -(u8)ax; /* 0 or -1 */
|
intcall(0x13, &ireg, &oreg);
|
||||||
|
|
||||||
|
return -(oreg.eflags & X86_EFLAGS_CF); /* 0 or -1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig)
|
static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig)
|
||||||
|
@ -72,56 +73,46 @@ static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig)
|
||||||
|
|
||||||
static int get_edd_info(u8 devno, struct edd_info *ei)
|
static int get_edd_info(u8 devno, struct edd_info *ei)
|
||||||
{
|
{
|
||||||
u16 ax, bx, cx, dx, di;
|
struct biosregs ireg, oreg;
|
||||||
|
|
||||||
memset(ei, 0, sizeof *ei);
|
memset(ei, 0, sizeof *ei);
|
||||||
|
|
||||||
/* Check Extensions Present */
|
/* Check Extensions Present */
|
||||||
|
|
||||||
ax = 0x4100;
|
initregs(&ireg);
|
||||||
bx = EDDMAGIC1;
|
ireg.ah = 0x41;
|
||||||
dx = devno;
|
ireg.bx = EDDMAGIC1;
|
||||||
asm("pushfl; stc; int $0x13; setc %%al; popfl"
|
ireg.dl = devno;
|
||||||
: "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
|
intcall(0x13, &ireg, &oreg);
|
||||||
: : "esi", "edi");
|
|
||||||
|
|
||||||
if ((u8)ax)
|
if (oreg.eflags & X86_EFLAGS_CF)
|
||||||
return -1; /* No extended information */
|
return -1; /* No extended information */
|
||||||
|
|
||||||
if (bx != EDDMAGIC2)
|
if (oreg.bx != EDDMAGIC2)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ei->device = devno;
|
ei->device = devno;
|
||||||
ei->version = ax >> 8; /* EDD version number */
|
ei->version = oreg.ah; /* EDD version number */
|
||||||
ei->interface_support = cx; /* EDD functionality subsets */
|
ei->interface_support = oreg.cx; /* EDD functionality subsets */
|
||||||
|
|
||||||
/* Extended Get Device Parameters */
|
/* Extended Get Device Parameters */
|
||||||
|
|
||||||
ei->params.length = sizeof(ei->params);
|
ei->params.length = sizeof(ei->params);
|
||||||
ax = 0x4800;
|
ireg.ah = 0x48;
|
||||||
dx = devno;
|
ireg.si = (size_t)&ei->params;
|
||||||
asm("pushfl; int $0x13; popfl"
|
intcall(0x13, &ireg, &oreg);
|
||||||
: "+a" (ax), "+d" (dx), "=m" (ei->params)
|
|
||||||
: "S" (&ei->params)
|
|
||||||
: "ebx", "ecx", "edi");
|
|
||||||
|
|
||||||
/* Get legacy CHS parameters */
|
/* Get legacy CHS parameters */
|
||||||
|
|
||||||
/* Ralf Brown recommends setting ES:DI to 0:0 */
|
/* Ralf Brown recommends setting ES:DI to 0:0 */
|
||||||
ax = 0x0800;
|
ireg.ah = 0x08;
|
||||||
dx = devno;
|
ireg.es = 0;
|
||||||
di = 0;
|
intcall(0x13, &ireg, &oreg);
|
||||||
asm("pushw %%es; "
|
|
||||||
"movw %%di,%%es; "
|
|
||||||
"pushfl; stc; int $0x13; setc %%al; popfl; "
|
|
||||||
"popw %%es"
|
|
||||||
: "+a" (ax), "=b" (bx), "=c" (cx), "+d" (dx), "+D" (di)
|
|
||||||
: : "esi");
|
|
||||||
|
|
||||||
if ((u8)ax == 0) {
|
if (!(oreg.eflags & X86_EFLAGS_CF)) {
|
||||||
ei->legacy_max_cylinder = (cx >> 8) + ((cx & 0xc0) << 2);
|
ei->legacy_max_cylinder = oreg.ch + ((oreg.cl & 0xc0) << 2);
|
||||||
ei->legacy_max_head = dx >> 8;
|
ei->legacy_max_head = oreg.dh;
|
||||||
ei->legacy_sectors_per_track = cx & 0x3f;
|
ei->legacy_sectors_per_track = oreg.cl & 0x3f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
#include <asm/page_types.h>
|
#include <asm/page_types.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
#include "offsets.h"
|
#include "voffset.h"
|
||||||
|
#include "zoffset.h"
|
||||||
|
|
||||||
BOOTSEG = 0x07C0 /* original address of boot-sector */
|
BOOTSEG = 0x07C0 /* original address of boot-sector */
|
||||||
SYSSEG = 0x1000 /* historical load address >> 4 */
|
SYSSEG = 0x1000 /* historical load address >> 4 */
|
||||||
|
@ -115,7 +116,7 @@ _start:
|
||||||
# Part 2 of the header, from the old setup.S
|
# Part 2 of the header, from the old setup.S
|
||||||
|
|
||||||
.ascii "HdrS" # header signature
|
.ascii "HdrS" # header signature
|
||||||
.word 0x0209 # header version number (>= 0x0105)
|
.word 0x020a # header version number (>= 0x0105)
|
||||||
# or else old loadlin-1.5 will fail)
|
# or else old loadlin-1.5 will fail)
|
||||||
.globl realmode_swtch
|
.globl realmode_swtch
|
||||||
realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
|
realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
|
||||||
|
@ -168,7 +169,11 @@ heap_end_ptr: .word _end+STACK_SIZE-512
|
||||||
# end of setup code can be used by setup
|
# end of setup code can be used by setup
|
||||||
# for local heap purposes.
|
# for local heap purposes.
|
||||||
|
|
||||||
pad1: .word 0
|
ext_loader_ver:
|
||||||
|
.byte 0 # Extended boot loader version
|
||||||
|
ext_loader_type:
|
||||||
|
.byte 0 # Extended boot loader type
|
||||||
|
|
||||||
cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
|
cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
|
||||||
# If nonzero, a 32-bit pointer
|
# If nonzero, a 32-bit pointer
|
||||||
# to the kernel command line.
|
# to the kernel command line.
|
||||||
|
@ -200,7 +205,7 @@ relocatable_kernel: .byte 1
|
||||||
#else
|
#else
|
||||||
relocatable_kernel: .byte 0
|
relocatable_kernel: .byte 0
|
||||||
#endif
|
#endif
|
||||||
pad2: .byte 0
|
min_alignment: .byte MIN_KERNEL_ALIGN_LG2 # minimum alignment
|
||||||
pad3: .word 0
|
pad3: .word 0
|
||||||
|
|
||||||
cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
|
cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
|
||||||
|
@ -212,16 +217,27 @@ hardware_subarch: .long 0 # subarchitecture, added with 2.07
|
||||||
|
|
||||||
hardware_subarch_data: .quad 0
|
hardware_subarch_data: .quad 0
|
||||||
|
|
||||||
payload_offset: .long input_data
|
payload_offset: .long ZO_input_data
|
||||||
payload_length: .long input_data_end-input_data
|
payload_length: .long ZO_z_input_len
|
||||||
|
|
||||||
setup_data: .quad 0 # 64-bit physical pointer to
|
setup_data: .quad 0 # 64-bit physical pointer to
|
||||||
# single linked list of
|
# single linked list of
|
||||||
# struct setup_data
|
# struct setup_data
|
||||||
|
|
||||||
|
pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
|
||||||
|
|
||||||
|
#define ZO_INIT_SIZE (ZO__end - ZO_startup_32 + ZO_z_extract_offset)
|
||||||
|
#define VO_INIT_SIZE (VO__end - VO__text)
|
||||||
|
#if ZO_INIT_SIZE > VO_INIT_SIZE
|
||||||
|
#define INIT_SIZE ZO_INIT_SIZE
|
||||||
|
#else
|
||||||
|
#define INIT_SIZE VO_INIT_SIZE
|
||||||
|
#endif
|
||||||
|
init_size: .long INIT_SIZE # kernel initialization size
|
||||||
|
|
||||||
# End of setup header #####################################################
|
# End of setup header #####################################################
|
||||||
|
|
||||||
.section ".inittext", "ax"
|
.section ".entrytext", "ax"
|
||||||
start_of_setup:
|
start_of_setup:
|
||||||
#ifdef SAFE_RESET_DISK_CONTROLLER
|
#ifdef SAFE_RESET_DISK_CONTROLLER
|
||||||
# Reset the disk controller.
|
# Reset the disk controller.
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
*
|
*
|
||||||
* This file is part of the Linux kernel, and is made available under
|
* This file is part of the Linux kernel, and is made available under
|
||||||
* the terms of the GNU General Public License version 2.
|
* the terms of the GNU General Public License version 2.
|
||||||
|
@ -61,11 +62,10 @@ static void copy_boot_params(void)
|
||||||
*/
|
*/
|
||||||
static void keyboard_set_repeat(void)
|
static void keyboard_set_repeat(void)
|
||||||
{
|
{
|
||||||
u16 ax = 0x0305;
|
struct biosregs ireg;
|
||||||
u16 bx = 0;
|
initregs(&ireg);
|
||||||
asm volatile("int $0x16"
|
ireg.ax = 0x0305;
|
||||||
: "+a" (ax), "+b" (bx)
|
intcall(0x16, &ireg, NULL);
|
||||||
: : "ecx", "edx", "esi", "edi");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -73,18 +73,22 @@ static void keyboard_set_repeat(void)
|
||||||
*/
|
*/
|
||||||
static void query_ist(void)
|
static void query_ist(void)
|
||||||
{
|
{
|
||||||
|
struct biosregs ireg, oreg;
|
||||||
|
|
||||||
/* Some older BIOSes apparently crash on this call, so filter
|
/* Some older BIOSes apparently crash on this call, so filter
|
||||||
it from machines too old to have SpeedStep at all. */
|
it from machines too old to have SpeedStep at all. */
|
||||||
if (cpu.level < 6)
|
if (cpu.level < 6)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
asm("int $0x15"
|
initregs(&ireg);
|
||||||
: "=a" (boot_params.ist_info.signature),
|
ireg.ax = 0xe980; /* IST Support */
|
||||||
"=b" (boot_params.ist_info.command),
|
ireg.edx = 0x47534943; /* Request value */
|
||||||
"=c" (boot_params.ist_info.event),
|
intcall(0x15, &ireg, &oreg);
|
||||||
"=d" (boot_params.ist_info.perf_level)
|
|
||||||
: "a" (0x0000e980), /* IST Support */
|
boot_params.ist_info.signature = oreg.eax;
|
||||||
"d" (0x47534943)); /* Request value */
|
boot_params.ist_info.command = oreg.ebx;
|
||||||
|
boot_params.ist_info.event = oreg.ecx;
|
||||||
|
boot_params.ist_info.perf_level = oreg.edx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -93,13 +97,12 @@ static void query_ist(void)
|
||||||
static void set_bios_mode(void)
|
static void set_bios_mode(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
u32 eax, ebx;
|
struct biosregs ireg;
|
||||||
|
|
||||||
eax = 0xec00;
|
initregs(&ireg);
|
||||||
ebx = 2;
|
ireg.ax = 0xec00;
|
||||||
asm volatile("int $0x15"
|
ireg.bx = 2;
|
||||||
: "+a" (eax), "+b" (ebx)
|
intcall(0x15, &ireg, NULL);
|
||||||
: : "ecx", "edx", "esi", "edi");
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
*
|
*
|
||||||
* This file is part of the Linux kernel, and is made available under
|
* This file is part of the Linux kernel, and is made available under
|
||||||
* the terms of the GNU General Public License version 2.
|
* the terms of the GNU General Public License version 2.
|
||||||
|
@ -16,26 +17,22 @@
|
||||||
|
|
||||||
int query_mca(void)
|
int query_mca(void)
|
||||||
{
|
{
|
||||||
u8 err;
|
struct biosregs ireg, oreg;
|
||||||
u16 es, bx, len;
|
u16 len;
|
||||||
|
|
||||||
asm("pushw %%es ; "
|
initregs(&ireg);
|
||||||
"int $0x15 ; "
|
ireg.ah = 0xc0;
|
||||||
"setc %0 ; "
|
intcall(0x15, &ireg, &oreg);
|
||||||
"movw %%es, %1 ; "
|
|
||||||
"popw %%es"
|
|
||||||
: "=acd" (err), "=acdSD" (es), "=b" (bx)
|
|
||||||
: "a" (0xc000));
|
|
||||||
|
|
||||||
if (err)
|
if (oreg.eflags & X86_EFLAGS_CF)
|
||||||
return -1; /* No MCA present */
|
return -1; /* No MCA present */
|
||||||
|
|
||||||
set_fs(es);
|
set_fs(oreg.es);
|
||||||
len = rdfs16(bx);
|
len = rdfs16(oreg.bx);
|
||||||
|
|
||||||
if (len > sizeof(boot_params.sys_desc_table))
|
if (len > sizeof(boot_params.sys_desc_table))
|
||||||
len = sizeof(boot_params.sys_desc_table);
|
len = sizeof(boot_params.sys_desc_table);
|
||||||
|
|
||||||
copy_from_fs(&boot_params.sys_desc_table, bx, len);
|
copy_from_fs(&boot_params.sys_desc_table, oreg.bx, len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,16 @@
|
||||||
static int detect_memory_e820(void)
|
static int detect_memory_e820(void)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
u32 next = 0;
|
struct biosregs ireg, oreg;
|
||||||
u32 size, id, edi;
|
|
||||||
u8 err;
|
|
||||||
struct e820entry *desc = boot_params.e820_map;
|
struct e820entry *desc = boot_params.e820_map;
|
||||||
static struct e820entry buf; /* static so it is zeroed */
|
static struct e820entry buf; /* static so it is zeroed */
|
||||||
|
|
||||||
|
initregs(&ireg);
|
||||||
|
ireg.ax = 0xe820;
|
||||||
|
ireg.cx = sizeof buf;
|
||||||
|
ireg.edx = SMAP;
|
||||||
|
ireg.di = (size_t)&buf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: at least one BIOS is known which assumes that the
|
* Note: at least one BIOS is known which assumes that the
|
||||||
* buffer pointed to by one e820 call is the same one as
|
* buffer pointed to by one e820 call is the same one as
|
||||||
|
@ -41,22 +45,13 @@ static int detect_memory_e820(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
do {
|
do {
|
||||||
size = sizeof buf;
|
intcall(0x15, &ireg, &oreg);
|
||||||
|
ireg.ebx = oreg.ebx; /* for next iteration... */
|
||||||
/* Important: %edx and %esi are clobbered by some BIOSes,
|
|
||||||
so they must be either used for the error output
|
|
||||||
or explicitly marked clobbered. Given that, assume there
|
|
||||||
is something out there clobbering %ebp and %edi, too. */
|
|
||||||
asm("pushl %%ebp; int $0x15; popl %%ebp; setc %0"
|
|
||||||
: "=d" (err), "+b" (next), "=a" (id), "+c" (size),
|
|
||||||
"=D" (edi), "+m" (buf)
|
|
||||||
: "D" (&buf), "d" (SMAP), "a" (0xe820)
|
|
||||||
: "esi");
|
|
||||||
|
|
||||||
/* BIOSes which terminate the chain with CF = 1 as opposed
|
/* BIOSes which terminate the chain with CF = 1 as opposed
|
||||||
to %ebx = 0 don't always report the SMAP signature on
|
to %ebx = 0 don't always report the SMAP signature on
|
||||||
the final, failing, probe. */
|
the final, failing, probe. */
|
||||||
if (err)
|
if (oreg.eflags & X86_EFLAGS_CF)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Some BIOSes stop returning SMAP in the middle of
|
/* Some BIOSes stop returning SMAP in the middle of
|
||||||
|
@ -64,60 +59,64 @@ static int detect_memory_e820(void)
|
||||||
screwed up the map at that point, we might have a
|
screwed up the map at that point, we might have a
|
||||||
partial map, the full map, or complete garbage, so
|
partial map, the full map, or complete garbage, so
|
||||||
just return failure. */
|
just return failure. */
|
||||||
if (id != SMAP) {
|
if (oreg.eax != SMAP) {
|
||||||
count = 0;
|
count = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*desc++ = buf;
|
*desc++ = buf;
|
||||||
count++;
|
count++;
|
||||||
} while (next && count < ARRAY_SIZE(boot_params.e820_map));
|
} while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_map));
|
||||||
|
|
||||||
return boot_params.e820_entries = count;
|
return boot_params.e820_entries = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int detect_memory_e801(void)
|
static int detect_memory_e801(void)
|
||||||
{
|
{
|
||||||
u16 ax, bx, cx, dx;
|
struct biosregs ireg, oreg;
|
||||||
u8 err;
|
|
||||||
|
|
||||||
bx = cx = dx = 0;
|
initregs(&ireg);
|
||||||
ax = 0xe801;
|
ireg.ax = 0xe801;
|
||||||
asm("stc; int $0x15; setc %0"
|
intcall(0x15, &ireg, &oreg);
|
||||||
: "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
|
|
||||||
|
|
||||||
if (err)
|
if (oreg.eflags & X86_EFLAGS_CF)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Do we really need to do this? */
|
/* Do we really need to do this? */
|
||||||
if (cx || dx) {
|
if (oreg.cx || oreg.dx) {
|
||||||
ax = cx;
|
oreg.ax = oreg.cx;
|
||||||
bx = dx;
|
oreg.bx = oreg.dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ax > 15*1024)
|
if (oreg.ax > 15*1024) {
|
||||||
return -1; /* Bogus! */
|
return -1; /* Bogus! */
|
||||||
|
} else if (oreg.ax == 15*1024) {
|
||||||
/* This ignores memory above 16MB if we have a memory hole
|
boot_params.alt_mem_k = (oreg.dx << 6) + oreg.ax;
|
||||||
there. If someone actually finds a machine with a memory
|
} else {
|
||||||
hole at 16MB and no support for 0E820h they should probably
|
/*
|
||||||
generate a fake e820 map. */
|
* This ignores memory above 16MB if we have a memory
|
||||||
boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax;
|
* hole there. If someone actually finds a machine
|
||||||
|
* with a memory hole at 16MB and no support for
|
||||||
|
* 0E820h they should probably generate a fake e820
|
||||||
|
* map.
|
||||||
|
*/
|
||||||
|
boot_params.alt_mem_k = oreg.ax;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int detect_memory_88(void)
|
static int detect_memory_88(void)
|
||||||
{
|
{
|
||||||
u16 ax;
|
struct biosregs ireg, oreg;
|
||||||
u8 err;
|
|
||||||
|
|
||||||
ax = 0x8800;
|
initregs(&ireg);
|
||||||
asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
|
ireg.ah = 0x88;
|
||||||
|
intcall(0x15, &ireg, &oreg);
|
||||||
|
|
||||||
boot_params.screen_info.ext_mem_k = ax;
|
boot_params.screen_info.ext_mem_k = oreg.ax;
|
||||||
|
|
||||||
return -err;
|
return -(oreg.eflags & X86_EFLAGS_CF); /* 0 or -1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
int detect_memory(void)
|
int detect_memory(void)
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
|
*
|
||||||
|
* This file is part of the Linux kernel, and is made available under
|
||||||
|
* the terms of the GNU General Public License version 2 or (at your
|
||||||
|
* option) any later version; incorporated herein by reference.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple helper function for initializing a register set.
|
||||||
|
*
|
||||||
|
* Note that this sets EFLAGS_CF in the input register set; this
|
||||||
|
* makes it easier to catch functions which do nothing but don't
|
||||||
|
* explicitly set CF.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "boot.h"
|
||||||
|
|
||||||
|
void initregs(struct biosregs *reg)
|
||||||
|
{
|
||||||
|
memset(reg, 0, sizeof *reg);
|
||||||
|
reg->eflags |= X86_EFLAGS_CF;
|
||||||
|
reg->ds = ds();
|
||||||
|
reg->es = ds();
|
||||||
|
reg->fs = fs();
|
||||||
|
reg->gs = gs();
|
||||||
|
}
|
|
@ -15,8 +15,11 @@ SECTIONS
|
||||||
|
|
||||||
. = 497;
|
. = 497;
|
||||||
.header : { *(.header) }
|
.header : { *(.header) }
|
||||||
|
.entrytext : { *(.entrytext) }
|
||||||
.inittext : { *(.inittext) }
|
.inittext : { *(.inittext) }
|
||||||
.initdata : { *(.initdata) }
|
.initdata : { *(.initdata) }
|
||||||
|
__end_init = .;
|
||||||
|
|
||||||
.text : { *(.text) }
|
.text : { *(.text) }
|
||||||
.text32 : { *(.text32) }
|
.text32 : { *(.text32) }
|
||||||
|
|
||||||
|
@ -52,4 +55,7 @@ SECTIONS
|
||||||
|
|
||||||
. = ASSERT(_end <= 0x8000, "Setup too big!");
|
. = ASSERT(_end <= 0x8000, "Setup too big!");
|
||||||
. = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
|
. = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
|
||||||
|
/* Necessary for the very-old-loader check to work... */
|
||||||
|
. = ASSERT(__end_init <= 5*512, "init sections too big!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
*
|
*
|
||||||
* This file is part of the Linux kernel, and is made available under
|
* This file is part of the Linux kernel, and is made available under
|
||||||
* the terms of the GNU General Public License version 2.
|
* the terms of the GNU General Public License version 2.
|
||||||
|
@ -22,24 +23,23 @@
|
||||||
|
|
||||||
void __attribute__((section(".inittext"))) putchar(int ch)
|
void __attribute__((section(".inittext"))) putchar(int ch)
|
||||||
{
|
{
|
||||||
unsigned char c = ch;
|
struct biosregs ireg;
|
||||||
|
|
||||||
if (c == '\n')
|
if (ch == '\n')
|
||||||
putchar('\r'); /* \n -> \r\n */
|
putchar('\r'); /* \n -> \r\n */
|
||||||
|
|
||||||
/* int $0x10 is known to have bugs involving touching registers
|
initregs(&ireg);
|
||||||
it shouldn't. Be extra conservative... */
|
ireg.bx = 0x0007;
|
||||||
asm volatile("pushal; pushw %%ds; int $0x10; popw %%ds; popal"
|
ireg.cx = 0x0001;
|
||||||
: : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
|
ireg.ah = 0x0e;
|
||||||
|
ireg.al = ch;
|
||||||
|
intcall(0x10, &ireg, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((section(".inittext"))) puts(const char *str)
|
void __attribute__((section(".inittext"))) puts(const char *str)
|
||||||
{
|
{
|
||||||
int n = 0;
|
while (*str)
|
||||||
while (*str) {
|
|
||||||
putchar(*str++);
|
putchar(*str++);
|
||||||
n++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -49,14 +49,13 @@ void __attribute__((section(".inittext"))) puts(const char *str)
|
||||||
|
|
||||||
static u8 gettime(void)
|
static u8 gettime(void)
|
||||||
{
|
{
|
||||||
u16 ax = 0x0200;
|
struct biosregs ireg, oreg;
|
||||||
u16 cx, dx;
|
|
||||||
|
|
||||||
asm volatile("int $0x1a"
|
initregs(&ireg);
|
||||||
: "+a" (ax), "=c" (cx), "=d" (dx)
|
ireg.ah = 0x02;
|
||||||
: : "ebx", "esi", "edi");
|
intcall(0x1a, &ireg, &oreg);
|
||||||
|
|
||||||
return dx >> 8;
|
return oreg.dh;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -64,19 +63,24 @@ static u8 gettime(void)
|
||||||
*/
|
*/
|
||||||
int getchar(void)
|
int getchar(void)
|
||||||
{
|
{
|
||||||
u16 ax = 0;
|
struct biosregs ireg, oreg;
|
||||||
asm volatile("int $0x16" : "+a" (ax));
|
|
||||||
|
|
||||||
return ax & 0xff;
|
initregs(&ireg);
|
||||||
|
/* ireg.ah = 0x00; */
|
||||||
|
intcall(0x16, &ireg, &oreg);
|
||||||
|
|
||||||
|
return oreg.al;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kbd_pending(void)
|
static int kbd_pending(void)
|
||||||
{
|
{
|
||||||
u8 pending;
|
struct biosregs ireg, oreg;
|
||||||
asm volatile("int $0x16; setnz %0"
|
|
||||||
: "=qm" (pending)
|
initregs(&ireg);
|
||||||
: "a" (0x0100));
|
ireg.ah = 0x01;
|
||||||
return pending;
|
intcall(0x16, &ireg, &oreg);
|
||||||
|
|
||||||
|
return !(oreg.eflags & X86_EFLAGS_ZF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kbd_flush(void)
|
void kbd_flush(void)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
*
|
*
|
||||||
* This file is part of the Linux kernel, and is made available under
|
* This file is part of the Linux kernel, and is made available under
|
||||||
* the terms of the GNU General Public License version 2.
|
* the terms of the GNU General Public License version 2.
|
||||||
|
@ -29,21 +30,21 @@ static int bios_set_mode(struct mode_info *mi)
|
||||||
|
|
||||||
static int set_bios_mode(u8 mode)
|
static int set_bios_mode(u8 mode)
|
||||||
{
|
{
|
||||||
u16 ax;
|
struct biosregs ireg, oreg;
|
||||||
u8 new_mode;
|
u8 new_mode;
|
||||||
|
|
||||||
ax = mode; /* AH=0x00 Set Video Mode */
|
initregs(&ireg);
|
||||||
asm volatile(INT10
|
ireg.al = mode; /* AH=0x00 Set Video Mode */
|
||||||
: "+a" (ax)
|
intcall(0x10, &ireg, NULL);
|
||||||
: : "ebx", "ecx", "edx", "esi", "edi");
|
|
||||||
|
|
||||||
ax = 0x0f00; /* Get Current Video Mode */
|
|
||||||
asm volatile(INT10
|
ireg.ah = 0x0f; /* Get Current Video Mode */
|
||||||
: "+a" (ax)
|
intcall(0x10, &ireg, &oreg);
|
||||||
: : "ebx", "ecx", "edx", "esi", "edi");
|
|
||||||
|
|
||||||
do_restore = 1; /* Assume video contents were lost */
|
do_restore = 1; /* Assume video contents were lost */
|
||||||
new_mode = ax & 0x7f; /* Not all BIOSes are clean with the top bit */
|
|
||||||
|
/* Not all BIOSes are clean with the top bit */
|
||||||
|
new_mode = ireg.al & 0x7f;
|
||||||
|
|
||||||
if (new_mode == mode)
|
if (new_mode == mode)
|
||||||
return 0; /* Mode change OK */
|
return 0; /* Mode change OK */
|
||||||
|
@ -53,10 +54,8 @@ static int set_bios_mode(u8 mode)
|
||||||
/* Mode setting failed, but we didn't end up where we
|
/* Mode setting failed, but we didn't end up where we
|
||||||
started. That's bad. Try to revert to the original
|
started. That's bad. Try to revert to the original
|
||||||
video mode. */
|
video mode. */
|
||||||
ax = boot_params.screen_info.orig_video_mode;
|
ireg.ax = boot_params.screen_info.orig_video_mode;
|
||||||
asm volatile(INT10
|
intcall(0x10, &ireg, NULL);
|
||||||
: "+a" (ax)
|
|
||||||
: : "ebx", "ecx", "edx", "esi", "edi");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
*
|
*
|
||||||
* This file is part of the Linux kernel, and is made available under
|
* This file is part of the Linux kernel, and is made available under
|
||||||
* the terms of the GNU General Public License version 2.
|
* the terms of the GNU General Public License version 2.
|
||||||
|
@ -31,7 +32,7 @@ static inline void vesa_store_mode_params_graphics(void) {}
|
||||||
static int vesa_probe(void)
|
static int vesa_probe(void)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
|
#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
|
||||||
u16 ax, cx, di;
|
struct biosregs ireg, oreg;
|
||||||
u16 mode;
|
u16 mode;
|
||||||
addr_t mode_ptr;
|
addr_t mode_ptr;
|
||||||
struct mode_info *mi;
|
struct mode_info *mi;
|
||||||
|
@ -39,13 +40,12 @@ static int vesa_probe(void)
|
||||||
|
|
||||||
video_vesa.modes = GET_HEAP(struct mode_info, 0);
|
video_vesa.modes = GET_HEAP(struct mode_info, 0);
|
||||||
|
|
||||||
ax = 0x4f00;
|
initregs(&ireg);
|
||||||
di = (size_t)&vginfo;
|
ireg.ax = 0x4f00;
|
||||||
asm(INT10
|
ireg.di = (size_t)&vginfo;
|
||||||
: "+a" (ax), "+D" (di), "=m" (vginfo)
|
intcall(0x10, &ireg, &oreg);
|
||||||
: : "ebx", "ecx", "edx", "esi");
|
|
||||||
|
|
||||||
if (ax != 0x004f ||
|
if (ireg.ax != 0x004f ||
|
||||||
vginfo.signature != VESA_MAGIC ||
|
vginfo.signature != VESA_MAGIC ||
|
||||||
vginfo.version < 0x0102)
|
vginfo.version < 0x0102)
|
||||||
return 0; /* Not present */
|
return 0; /* Not present */
|
||||||
|
@ -65,14 +65,12 @@ static int vesa_probe(void)
|
||||||
|
|
||||||
memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
|
memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
|
||||||
|
|
||||||
ax = 0x4f01;
|
ireg.ax = 0x4f01;
|
||||||
cx = mode;
|
ireg.cx = mode;
|
||||||
di = (size_t)&vminfo;
|
ireg.di = (size_t)&vminfo;
|
||||||
asm(INT10
|
intcall(0x10, &ireg, &oreg);
|
||||||
: "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
|
|
||||||
: : "ebx", "edx", "esi");
|
|
||||||
|
|
||||||
if (ax != 0x004f)
|
if (ireg.ax != 0x004f)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((vminfo.mode_attr & 0x15) == 0x05) {
|
if ((vminfo.mode_attr & 0x15) == 0x05) {
|
||||||
|
@ -111,20 +109,19 @@ static int vesa_probe(void)
|
||||||
|
|
||||||
static int vesa_set_mode(struct mode_info *mode)
|
static int vesa_set_mode(struct mode_info *mode)
|
||||||
{
|
{
|
||||||
u16 ax, bx, cx, di;
|
struct biosregs ireg, oreg;
|
||||||
int is_graphic;
|
int is_graphic;
|
||||||
u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
|
u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
|
||||||
|
|
||||||
memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
|
memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
|
||||||
|
|
||||||
ax = 0x4f01;
|
initregs(&ireg);
|
||||||
cx = vesa_mode;
|
ireg.ax = 0x4f01;
|
||||||
di = (size_t)&vminfo;
|
ireg.cx = vesa_mode;
|
||||||
asm(INT10
|
ireg.di = (size_t)&vminfo;
|
||||||
: "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
|
intcall(0x10, &ireg, &oreg);
|
||||||
: : "ebx", "edx", "esi");
|
|
||||||
|
|
||||||
if (ax != 0x004f)
|
if (oreg.ax != 0x004f)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((vminfo.mode_attr & 0x15) == 0x05) {
|
if ((vminfo.mode_attr & 0x15) == 0x05) {
|
||||||
|
@ -141,14 +138,12 @@ static int vesa_set_mode(struct mode_info *mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ax = 0x4f02;
|
initregs(&ireg);
|
||||||
bx = vesa_mode;
|
ireg.ax = 0x4f02;
|
||||||
di = 0;
|
ireg.bx = vesa_mode;
|
||||||
asm volatile(INT10
|
intcall(0x10, &ireg, &oreg);
|
||||||
: "+a" (ax), "+b" (bx), "+D" (di)
|
|
||||||
: : "ecx", "edx", "esi");
|
|
||||||
|
|
||||||
if (ax != 0x004f)
|
if (oreg.ax != 0x004f)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
graphic_mode = is_graphic;
|
graphic_mode = is_graphic;
|
||||||
|
@ -171,50 +166,45 @@ static int vesa_set_mode(struct mode_info *mode)
|
||||||
/* Switch DAC to 8-bit mode */
|
/* Switch DAC to 8-bit mode */
|
||||||
static void vesa_dac_set_8bits(void)
|
static void vesa_dac_set_8bits(void)
|
||||||
{
|
{
|
||||||
|
struct biosregs ireg, oreg;
|
||||||
u8 dac_size = 6;
|
u8 dac_size = 6;
|
||||||
|
|
||||||
/* If possible, switch the DAC to 8-bit mode */
|
/* If possible, switch the DAC to 8-bit mode */
|
||||||
if (vginfo.capabilities & 1) {
|
if (vginfo.capabilities & 1) {
|
||||||
u16 ax, bx;
|
initregs(&ireg);
|
||||||
|
ireg.ax = 0x4f08;
|
||||||
ax = 0x4f08;
|
ireg.bh = 0x08;
|
||||||
bx = 0x0800;
|
intcall(0x10, &ireg, &oreg);
|
||||||
asm volatile(INT10
|
if (oreg.ax == 0x004f)
|
||||||
: "+a" (ax), "+b" (bx)
|
dac_size = oreg.bh;
|
||||||
: : "ecx", "edx", "esi", "edi");
|
|
||||||
|
|
||||||
if (ax == 0x004f)
|
|
||||||
dac_size = bx >> 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the color sizes to the DAC size, and offsets to 0 */
|
/* Set the color sizes to the DAC size, and offsets to 0 */
|
||||||
boot_params.screen_info.red_size = dac_size;
|
boot_params.screen_info.red_size = dac_size;
|
||||||
boot_params.screen_info.green_size = dac_size;
|
boot_params.screen_info.green_size = dac_size;
|
||||||
boot_params.screen_info.blue_size = dac_size;
|
boot_params.screen_info.blue_size = dac_size;
|
||||||
boot_params.screen_info.rsvd_size = dac_size;
|
boot_params.screen_info.rsvd_size = dac_size;
|
||||||
|
|
||||||
boot_params.screen_info.red_pos = 0;
|
boot_params.screen_info.red_pos = 0;
|
||||||
boot_params.screen_info.green_pos = 0;
|
boot_params.screen_info.green_pos = 0;
|
||||||
boot_params.screen_info.blue_pos = 0;
|
boot_params.screen_info.blue_pos = 0;
|
||||||
boot_params.screen_info.rsvd_pos = 0;
|
boot_params.screen_info.rsvd_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the VESA protected mode info */
|
/* Save the VESA protected mode info */
|
||||||
static void vesa_store_pm_info(void)
|
static void vesa_store_pm_info(void)
|
||||||
{
|
{
|
||||||
u16 ax, bx, di, es;
|
struct biosregs ireg, oreg;
|
||||||
|
|
||||||
ax = 0x4f0a;
|
initregs(&ireg);
|
||||||
bx = di = 0;
|
ireg.ax = 0x4f0a;
|
||||||
asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
|
intcall(0x10, &ireg, &oreg);
|
||||||
: "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
|
|
||||||
: : "ecx", "esi");
|
|
||||||
|
|
||||||
if (ax != 0x004f)
|
if (oreg.ax != 0x004f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
boot_params.screen_info.vesapm_seg = es;
|
boot_params.screen_info.vesapm_seg = oreg.es;
|
||||||
boot_params.screen_info.vesapm_off = di;
|
boot_params.screen_info.vesapm_off = oreg.di;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -252,7 +242,7 @@ static void vesa_store_mode_params_graphics(void)
|
||||||
void vesa_store_edid(void)
|
void vesa_store_edid(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_FIRMWARE_EDID
|
#ifdef CONFIG_FIRMWARE_EDID
|
||||||
u16 ax, bx, cx, dx, di;
|
struct biosregs ireg, oreg;
|
||||||
|
|
||||||
/* Apparently used as a nonsense token... */
|
/* Apparently used as a nonsense token... */
|
||||||
memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
|
memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
|
||||||
|
@ -260,33 +250,26 @@ void vesa_store_edid(void)
|
||||||
if (vginfo.version < 0x0200)
|
if (vginfo.version < 0x0200)
|
||||||
return; /* EDID requires VBE 2.0+ */
|
return; /* EDID requires VBE 2.0+ */
|
||||||
|
|
||||||
ax = 0x4f15; /* VBE DDC */
|
initregs(&ireg);
|
||||||
bx = 0x0000; /* Report DDC capabilities */
|
ireg.ax = 0x4f15; /* VBE DDC */
|
||||||
cx = 0; /* Controller 0 */
|
/* ireg.bx = 0x0000; */ /* Report DDC capabilities */
|
||||||
di = 0; /* ES:DI must be 0 by spec */
|
/* ireg.cx = 0; */ /* Controller 0 */
|
||||||
|
ireg.es = 0; /* ES:DI must be 0 by spec */
|
||||||
|
intcall(0x10, &ireg, &oreg);
|
||||||
|
|
||||||
/* Note: The VBE DDC spec is different from the main VESA spec;
|
if (oreg.ax != 0x004f)
|
||||||
we genuinely have to assume all registers are destroyed here. */
|
|
||||||
|
|
||||||
asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
|
|
||||||
: "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
|
|
||||||
: : "esi", "edx");
|
|
||||||
|
|
||||||
if (ax != 0x004f)
|
|
||||||
return; /* No EDID */
|
return; /* No EDID */
|
||||||
|
|
||||||
/* BH = time in seconds to transfer EDD information */
|
/* BH = time in seconds to transfer EDD information */
|
||||||
/* BL = DDC level supported */
|
/* BL = DDC level supported */
|
||||||
|
|
||||||
ax = 0x4f15; /* VBE DDC */
|
ireg.ax = 0x4f15; /* VBE DDC */
|
||||||
bx = 0x0001; /* Read EDID */
|
ireg.bx = 0x0001; /* Read EDID */
|
||||||
cx = 0; /* Controller 0 */
|
/* ireg.cx = 0; */ /* Controller 0 */
|
||||||
dx = 0; /* EDID block number */
|
/* ireg.dx = 0; */ /* EDID block number */
|
||||||
di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
|
ireg.es = ds();
|
||||||
asm(INT10
|
ireg.di =(size_t)&boot_params.edid_info; /* (ES:)Pointer to block */
|
||||||
: "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info),
|
intcall(0x10, &ireg, &oreg);
|
||||||
"+c" (cx), "+D" (di)
|
|
||||||
: : "esi");
|
|
||||||
#endif /* CONFIG_FIRMWARE_EDID */
|
#endif /* CONFIG_FIRMWARE_EDID */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
*
|
*
|
||||||
* This file is part of the Linux kernel, and is made available under
|
* This file is part of the Linux kernel, and is made available under
|
||||||
* the terms of the GNU General Public License version 2.
|
* the terms of the GNU General Public License version 2.
|
||||||
|
@ -39,30 +40,30 @@ static __videocard video_vga;
|
||||||
/* Set basic 80x25 mode */
|
/* Set basic 80x25 mode */
|
||||||
static u8 vga_set_basic_mode(void)
|
static u8 vga_set_basic_mode(void)
|
||||||
{
|
{
|
||||||
|
struct biosregs ireg, oreg;
|
||||||
u16 ax;
|
u16 ax;
|
||||||
u8 rows;
|
u8 rows;
|
||||||
u8 mode;
|
u8 mode;
|
||||||
|
|
||||||
|
initregs(&ireg);
|
||||||
|
|
||||||
#ifdef CONFIG_VIDEO_400_HACK
|
#ifdef CONFIG_VIDEO_400_HACK
|
||||||
if (adapter >= ADAPTER_VGA) {
|
if (adapter >= ADAPTER_VGA) {
|
||||||
asm volatile(INT10
|
ireg.ax = 0x1202;
|
||||||
: : "a" (0x1202), "b" (0x0030)
|
ireg.bx = 0x0030;
|
||||||
: "ecx", "edx", "esi", "edi");
|
intcall(0x10, &ireg, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ax = 0x0f00;
|
ax = 0x0f00;
|
||||||
asm volatile(INT10
|
intcall(0x10, &ireg, &oreg);
|
||||||
: "+a" (ax)
|
mode = oreg.al;
|
||||||
: : "ebx", "ecx", "edx", "esi", "edi");
|
|
||||||
|
|
||||||
mode = (u8)ax;
|
|
||||||
|
|
||||||
set_fs(0);
|
set_fs(0);
|
||||||
rows = rdfs8(0x484); /* rows minus one */
|
rows = rdfs8(0x484); /* rows minus one */
|
||||||
|
|
||||||
#ifndef CONFIG_VIDEO_400_HACK
|
#ifndef CONFIG_VIDEO_400_HACK
|
||||||
if ((ax == 0x5003 || ax == 0x5007) &&
|
if ((oreg.ax == 0x5003 || oreg.ax == 0x5007) &&
|
||||||
(rows == 0 || rows == 24))
|
(rows == 0 || rows == 24))
|
||||||
return mode;
|
return mode;
|
||||||
#endif
|
#endif
|
||||||
|
@ -71,10 +72,8 @@ static u8 vga_set_basic_mode(void)
|
||||||
mode = 3;
|
mode = 3;
|
||||||
|
|
||||||
/* Set the mode */
|
/* Set the mode */
|
||||||
ax = mode;
|
ireg.ax = mode; /* AH=0: set mode */
|
||||||
asm volatile(INT10
|
intcall(0x10, &ireg, NULL);
|
||||||
: "+a" (ax)
|
|
||||||
: : "ebx", "ecx", "edx", "esi", "edi");
|
|
||||||
do_restore = 1;
|
do_restore = 1;
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
@ -82,43 +81,69 @@ static u8 vga_set_basic_mode(void)
|
||||||
static void vga_set_8font(void)
|
static void vga_set_8font(void)
|
||||||
{
|
{
|
||||||
/* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
|
/* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
|
||||||
|
struct biosregs ireg;
|
||||||
|
|
||||||
|
initregs(&ireg);
|
||||||
|
|
||||||
/* Set 8x8 font */
|
/* Set 8x8 font */
|
||||||
asm volatile(INT10 : : "a" (0x1112), "b" (0));
|
ireg.ax = 0x1112;
|
||||||
|
/* ireg.bl = 0; */
|
||||||
|
intcall(0x10, &ireg, NULL);
|
||||||
|
|
||||||
/* Use alternate print screen */
|
/* Use alternate print screen */
|
||||||
asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
|
ireg.ax = 0x1200;
|
||||||
|
ireg.bl = 0x20;
|
||||||
|
intcall(0x10, &ireg, NULL);
|
||||||
|
|
||||||
/* Turn off cursor emulation */
|
/* Turn off cursor emulation */
|
||||||
asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
|
ireg.ax = 0x1201;
|
||||||
|
ireg.bl = 0x34;
|
||||||
|
intcall(0x10, &ireg, NULL);
|
||||||
|
|
||||||
/* Cursor is scan lines 6-7 */
|
/* Cursor is scan lines 6-7 */
|
||||||
asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
|
ireg.ax = 0x0100;
|
||||||
|
ireg.cx = 0x0607;
|
||||||
|
intcall(0x10, &ireg, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vga_set_14font(void)
|
static void vga_set_14font(void)
|
||||||
{
|
{
|
||||||
/* Set 9x14 font - 80x28 on VGA */
|
/* Set 9x14 font - 80x28 on VGA */
|
||||||
|
struct biosregs ireg;
|
||||||
|
|
||||||
|
initregs(&ireg);
|
||||||
|
|
||||||
/* Set 9x14 font */
|
/* Set 9x14 font */
|
||||||
asm volatile(INT10 : : "a" (0x1111), "b" (0));
|
ireg.ax = 0x1111;
|
||||||
|
/* ireg.bl = 0; */
|
||||||
|
intcall(0x10, &ireg, NULL);
|
||||||
|
|
||||||
/* Turn off cursor emulation */
|
/* Turn off cursor emulation */
|
||||||
asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
|
ireg.ax = 0x1201;
|
||||||
|
ireg.bl = 0x34;
|
||||||
|
intcall(0x10, &ireg, NULL);
|
||||||
|
|
||||||
/* Cursor is scan lines 11-12 */
|
/* Cursor is scan lines 11-12 */
|
||||||
asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
|
ireg.ax = 0x0100;
|
||||||
|
ireg.cx = 0x0b0c;
|
||||||
|
intcall(0x10, &ireg, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vga_set_80x43(void)
|
static void vga_set_80x43(void)
|
||||||
{
|
{
|
||||||
/* Set 80x43 mode on VGA (not EGA) */
|
/* Set 80x43 mode on VGA (not EGA) */
|
||||||
|
struct biosregs ireg;
|
||||||
|
|
||||||
|
initregs(&ireg);
|
||||||
|
|
||||||
/* Set 350 scans */
|
/* Set 350 scans */
|
||||||
asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
|
ireg.ax = 0x1201;
|
||||||
|
ireg.bl = 0x30;
|
||||||
|
intcall(0x10, &ireg, NULL);
|
||||||
|
|
||||||
/* Reset video mode */
|
/* Reset video mode */
|
||||||
asm volatile(INT10 : : "a" (0x0003));
|
ireg.ax = 0x0003;
|
||||||
|
intcall(0x10, &ireg, NULL);
|
||||||
|
|
||||||
vga_set_8font();
|
vga_set_8font();
|
||||||
}
|
}
|
||||||
|
@ -225,8 +250,6 @@ static int vga_set_mode(struct mode_info *mode)
|
||||||
*/
|
*/
|
||||||
static int vga_probe(void)
|
static int vga_probe(void)
|
||||||
{
|
{
|
||||||
u16 ega_bx;
|
|
||||||
|
|
||||||
static const char *card_name[] = {
|
static const char *card_name[] = {
|
||||||
"CGA/MDA/HGC", "EGA", "VGA"
|
"CGA/MDA/HGC", "EGA", "VGA"
|
||||||
};
|
};
|
||||||
|
@ -240,26 +263,26 @@ static int vga_probe(void)
|
||||||
sizeof(ega_modes)/sizeof(struct mode_info),
|
sizeof(ega_modes)/sizeof(struct mode_info),
|
||||||
sizeof(vga_modes)/sizeof(struct mode_info),
|
sizeof(vga_modes)/sizeof(struct mode_info),
|
||||||
};
|
};
|
||||||
u8 vga_flag;
|
|
||||||
|
|
||||||
asm(INT10
|
struct biosregs ireg, oreg;
|
||||||
: "=b" (ega_bx)
|
|
||||||
: "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
|
initregs(&ireg);
|
||||||
: "ecx", "edx", "esi", "edi");
|
|
||||||
|
ireg.ax = 0x1200;
|
||||||
|
ireg.bl = 0x10; /* Check EGA/VGA */
|
||||||
|
intcall(0x10, &ireg, &oreg);
|
||||||
|
|
||||||
#ifndef _WAKEUP
|
#ifndef _WAKEUP
|
||||||
boot_params.screen_info.orig_video_ega_bx = ega_bx;
|
boot_params.screen_info.orig_video_ega_bx = oreg.bx;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
|
/* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
|
||||||
if ((u8)ega_bx != 0x10) {
|
if (oreg.bl != 0x10) {
|
||||||
/* EGA/VGA */
|
/* EGA/VGA */
|
||||||
asm(INT10
|
ireg.ax = 0x1a00;
|
||||||
: "=a" (vga_flag)
|
intcall(0x10, &ireg, &oreg);
|
||||||
: "a" (0x1a00)
|
|
||||||
: "ebx", "ecx", "edx", "esi", "edi");
|
|
||||||
|
|
||||||
if (vga_flag == 0x1a) {
|
if (oreg.al == 0x1a) {
|
||||||
adapter = ADAPTER_VGA;
|
adapter = ADAPTER_VGA;
|
||||||
#ifndef _WAKEUP
|
#ifndef _WAKEUP
|
||||||
boot_params.screen_info.orig_video_isVGA = 1;
|
boot_params.screen_info.orig_video_isVGA = 1;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
* Copyright 2007 rPath, Inc. - All Rights Reserved
|
||||||
|
* Copyright 2009 Intel Corporation; author H. Peter Anvin
|
||||||
*
|
*
|
||||||
* This file is part of the Linux kernel, and is made available under
|
* This file is part of the Linux kernel, and is made available under
|
||||||
* the terms of the GNU General Public License version 2.
|
* the terms of the GNU General Public License version 2.
|
||||||
|
@ -18,33 +19,29 @@
|
||||||
|
|
||||||
static void store_cursor_position(void)
|
static void store_cursor_position(void)
|
||||||
{
|
{
|
||||||
u16 curpos;
|
struct biosregs ireg, oreg;
|
||||||
u16 ax, bx;
|
|
||||||
|
|
||||||
ax = 0x0300;
|
initregs(&ireg);
|
||||||
bx = 0;
|
ireg.ah = 0x03;
|
||||||
asm(INT10
|
intcall(0x10, &ireg, &oreg);
|
||||||
: "=d" (curpos), "+a" (ax), "+b" (bx)
|
|
||||||
: : "ecx", "esi", "edi");
|
|
||||||
|
|
||||||
boot_params.screen_info.orig_x = curpos;
|
boot_params.screen_info.orig_x = oreg.dl;
|
||||||
boot_params.screen_info.orig_y = curpos >> 8;
|
boot_params.screen_info.orig_y = oreg.dh;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void store_video_mode(void)
|
static void store_video_mode(void)
|
||||||
{
|
{
|
||||||
u16 ax, page;
|
struct biosregs ireg, oreg;
|
||||||
|
|
||||||
/* N.B.: the saving of the video page here is a bit silly,
|
/* N.B.: the saving of the video page here is a bit silly,
|
||||||
since we pretty much assume page 0 everywhere. */
|
since we pretty much assume page 0 everywhere. */
|
||||||
ax = 0x0f00;
|
initregs(&ireg);
|
||||||
asm(INT10
|
ireg.ah = 0x0f;
|
||||||
: "+a" (ax), "=b" (page)
|
intcall(0x10, &ireg, &oreg);
|
||||||
: : "ecx", "edx", "esi", "edi");
|
|
||||||
|
|
||||||
/* Not all BIOSes are clean with respect to the top bit */
|
/* Not all BIOSes are clean with respect to the top bit */
|
||||||
boot_params.screen_info.orig_video_mode = ax & 0x7f;
|
boot_params.screen_info.orig_video_mode = oreg.al & 0x7f;
|
||||||
boot_params.screen_info.orig_video_page = page >> 8;
|
boot_params.screen_info.orig_video_page = oreg.bh;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -257,7 +254,7 @@ static void restore_screen(void)
|
||||||
int y;
|
int y;
|
||||||
addr_t dst = 0;
|
addr_t dst = 0;
|
||||||
u16 *src = saved.data;
|
u16 *src = saved.data;
|
||||||
u16 ax, bx, dx;
|
struct biosregs ireg;
|
||||||
|
|
||||||
if (graphic_mode)
|
if (graphic_mode)
|
||||||
return; /* Can't restore onto a graphic mode */
|
return; /* Can't restore onto a graphic mode */
|
||||||
|
@ -296,12 +293,11 @@ static void restore_screen(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore cursor position */
|
/* Restore cursor position */
|
||||||
ax = 0x0200; /* Set cursor position */
|
initregs(&ireg);
|
||||||
bx = 0; /* Page number (<< 8) */
|
ireg.ah = 0x02; /* Set cursor position */
|
||||||
dx = (saved.cury << 8)+saved.curx;
|
ireg.dh = saved.cury;
|
||||||
asm volatile(INT10
|
ireg.dl = saved.curx;
|
||||||
: "+a" (ax), "+b" (bx), "+d" (dx)
|
intcall(0x10, &ireg, NULL);
|
||||||
: : "ecx", "esi", "edi");
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define save_screen() ((void)0)
|
#define save_screen() ((void)0)
|
||||||
|
|
|
@ -112,20 +112,6 @@ extern int force_x, force_y; /* Don't query the BIOS for cols/rows */
|
||||||
extern int do_restore; /* Restore screen contents */
|
extern int do_restore; /* Restore screen contents */
|
||||||
extern int graphic_mode; /* Graphics mode with linear frame buffer */
|
extern int graphic_mode; /* Graphics mode with linear frame buffer */
|
||||||
|
|
||||||
/*
|
|
||||||
* int $0x10 is notorious for touching registers it shouldn't.
|
|
||||||
* gcc doesn't like %ebp being clobbered, so define it as a push/pop
|
|
||||||
* sequence here.
|
|
||||||
*
|
|
||||||
* A number of systems, including the original PC can clobber %bp in
|
|
||||||
* certain circumstances, like when scrolling. There exists at least
|
|
||||||
* one Trident video card which could clobber DS under a set of
|
|
||||||
* circumstances that we are unlikely to encounter (scrolling when
|
|
||||||
* using an extended graphics mode of more than 800x600 pixels), but
|
|
||||||
* it's cheap insurance to deal with that here.
|
|
||||||
*/
|
|
||||||
#define INT10 "pushl %%ebp; pushw %%ds; int $0x10; popw %%ds; popl %%ebp"
|
|
||||||
|
|
||||||
/* Accessing VGA indexed registers */
|
/* Accessing VGA indexed registers */
|
||||||
static inline u8 in_idx(u16 port, u8 index)
|
static inline u8 in_idx(u16 port, u8 index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#
|
#
|
||||||
# Automatically generated make config: don't edit
|
# Automatically generated make config: don't edit
|
||||||
# Linux kernel version: 2.6.29-rc4
|
# Linux kernel version: 2.6.30-rc2
|
||||||
# Tue Feb 24 15:50:58 2009
|
# Mon May 11 16:21:55 2009
|
||||||
#
|
#
|
||||||
# CONFIG_64BIT is not set
|
# CONFIG_64BIT is not set
|
||||||
CONFIG_X86_32=y
|
CONFIG_X86_32=y
|
||||||
# CONFIG_X86_64 is not set
|
# CONFIG_X86_64 is not set
|
||||||
CONFIG_X86=y
|
CONFIG_X86=y
|
||||||
|
CONFIG_OUTPUT_FORMAT="elf32-i386"
|
||||||
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
|
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
|
||||||
CONFIG_GENERIC_TIME=y
|
CONFIG_GENERIC_TIME=y
|
||||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||||
|
@ -33,6 +34,7 @@ CONFIG_ARCH_HAS_CPU_RELAX=y
|
||||||
CONFIG_ARCH_HAS_DEFAULT_IDLE=y
|
CONFIG_ARCH_HAS_DEFAULT_IDLE=y
|
||||||
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
|
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
|
||||||
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
|
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
|
||||||
|
CONFIG_HAVE_DYNAMIC_PER_CPU_AREA=y
|
||||||
# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
|
# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
|
||||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||||
|
@ -40,15 +42,16 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||||
CONFIG_ARCH_POPULATES_NODE_MAP=y
|
CONFIG_ARCH_POPULATES_NODE_MAP=y
|
||||||
# CONFIG_AUDIT_ARCH is not set
|
# CONFIG_AUDIT_ARCH is not set
|
||||||
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
|
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
|
||||||
|
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
|
||||||
CONFIG_GENERIC_HARDIRQS=y
|
CONFIG_GENERIC_HARDIRQS=y
|
||||||
|
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
|
||||||
CONFIG_GENERIC_IRQ_PROBE=y
|
CONFIG_GENERIC_IRQ_PROBE=y
|
||||||
CONFIG_GENERIC_PENDING_IRQ=y
|
CONFIG_GENERIC_PENDING_IRQ=y
|
||||||
CONFIG_X86_SMP=y
|
|
||||||
CONFIG_USE_GENERIC_SMP_HELPERS=y
|
CONFIG_USE_GENERIC_SMP_HELPERS=y
|
||||||
CONFIG_X86_32_SMP=y
|
CONFIG_X86_32_SMP=y
|
||||||
CONFIG_X86_HT=y
|
CONFIG_X86_HT=y
|
||||||
CONFIG_X86_BIOS_REBOOT=y
|
|
||||||
CONFIG_X86_TRAMPOLINE=y
|
CONFIG_X86_TRAMPOLINE=y
|
||||||
|
CONFIG_X86_32_LAZY_GS=y
|
||||||
CONFIG_KTIME_SCALAR=y
|
CONFIG_KTIME_SCALAR=y
|
||||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||||
|
|
||||||
|
@ -60,10 +63,17 @@ CONFIG_LOCK_KERNEL=y
|
||||||
CONFIG_INIT_ENV_ARG_LIMIT=32
|
CONFIG_INIT_ENV_ARG_LIMIT=32
|
||||||
CONFIG_LOCALVERSION=""
|
CONFIG_LOCALVERSION=""
|
||||||
# CONFIG_LOCALVERSION_AUTO is not set
|
# CONFIG_LOCALVERSION_AUTO is not set
|
||||||
|
CONFIG_HAVE_KERNEL_GZIP=y
|
||||||
|
CONFIG_HAVE_KERNEL_BZIP2=y
|
||||||
|
CONFIG_HAVE_KERNEL_LZMA=y
|
||||||
|
CONFIG_KERNEL_GZIP=y
|
||||||
|
# CONFIG_KERNEL_BZIP2 is not set
|
||||||
|
# CONFIG_KERNEL_LZMA is not set
|
||||||
CONFIG_SWAP=y
|
CONFIG_SWAP=y
|
||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_SYSVIPC_SYSCTL=y
|
CONFIG_SYSVIPC_SYSCTL=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
|
CONFIG_POSIX_MQUEUE_SYSCTL=y
|
||||||
CONFIG_BSD_PROCESS_ACCT=y
|
CONFIG_BSD_PROCESS_ACCT=y
|
||||||
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
|
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
|
||||||
CONFIG_TASKSTATS=y
|
CONFIG_TASKSTATS=y
|
||||||
|
@ -113,23 +123,26 @@ CONFIG_PID_NS=y
|
||||||
CONFIG_NET_NS=y
|
CONFIG_NET_NS=y
|
||||||
CONFIG_BLK_DEV_INITRD=y
|
CONFIG_BLK_DEV_INITRD=y
|
||||||
CONFIG_INITRAMFS_SOURCE=""
|
CONFIG_INITRAMFS_SOURCE=""
|
||||||
|
CONFIG_RD_GZIP=y
|
||||||
|
CONFIG_RD_BZIP2=y
|
||||||
|
CONFIG_RD_LZMA=y
|
||||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||||
CONFIG_SYSCTL=y
|
CONFIG_SYSCTL=y
|
||||||
|
CONFIG_ANON_INODES=y
|
||||||
# CONFIG_EMBEDDED is not set
|
# CONFIG_EMBEDDED is not set
|
||||||
CONFIG_UID16=y
|
CONFIG_UID16=y
|
||||||
CONFIG_SYSCTL_SYSCALL=y
|
CONFIG_SYSCTL_SYSCALL=y
|
||||||
CONFIG_KALLSYMS=y
|
CONFIG_KALLSYMS=y
|
||||||
CONFIG_KALLSYMS_ALL=y
|
CONFIG_KALLSYMS_ALL=y
|
||||||
CONFIG_KALLSYMS_EXTRA_PASS=y
|
CONFIG_KALLSYMS_EXTRA_PASS=y
|
||||||
|
# CONFIG_STRIP_ASM_SYMS is not set
|
||||||
CONFIG_HOTPLUG=y
|
CONFIG_HOTPLUG=y
|
||||||
CONFIG_PRINTK=y
|
CONFIG_PRINTK=y
|
||||||
CONFIG_BUG=y
|
CONFIG_BUG=y
|
||||||
CONFIG_ELF_CORE=y
|
CONFIG_ELF_CORE=y
|
||||||
CONFIG_PCSPKR_PLATFORM=y
|
CONFIG_PCSPKR_PLATFORM=y
|
||||||
# CONFIG_COMPAT_BRK is not set
|
|
||||||
CONFIG_BASE_FULL=y
|
CONFIG_BASE_FULL=y
|
||||||
CONFIG_FUTEX=y
|
CONFIG_FUTEX=y
|
||||||
CONFIG_ANON_INODES=y
|
|
||||||
CONFIG_EPOLL=y
|
CONFIG_EPOLL=y
|
||||||
CONFIG_SIGNALFD=y
|
CONFIG_SIGNALFD=y
|
||||||
CONFIG_TIMERFD=y
|
CONFIG_TIMERFD=y
|
||||||
|
@ -139,6 +152,7 @@ CONFIG_AIO=y
|
||||||
CONFIG_VM_EVENT_COUNTERS=y
|
CONFIG_VM_EVENT_COUNTERS=y
|
||||||
CONFIG_PCI_QUIRKS=y
|
CONFIG_PCI_QUIRKS=y
|
||||||
CONFIG_SLUB_DEBUG=y
|
CONFIG_SLUB_DEBUG=y
|
||||||
|
# CONFIG_COMPAT_BRK is not set
|
||||||
# CONFIG_SLAB is not set
|
# CONFIG_SLAB is not set
|
||||||
CONFIG_SLUB=y
|
CONFIG_SLUB=y
|
||||||
# CONFIG_SLOB is not set
|
# CONFIG_SLOB is not set
|
||||||
|
@ -154,6 +168,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
|
||||||
CONFIG_HAVE_KPROBES=y
|
CONFIG_HAVE_KPROBES=y
|
||||||
CONFIG_HAVE_KRETPROBES=y
|
CONFIG_HAVE_KRETPROBES=y
|
||||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||||
|
CONFIG_HAVE_DMA_API_DEBUG=y
|
||||||
|
# CONFIG_SLOW_WORK is not set
|
||||||
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
|
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
|
||||||
CONFIG_SLABINFO=y
|
CONFIG_SLABINFO=y
|
||||||
CONFIG_RT_MUTEXES=y
|
CONFIG_RT_MUTEXES=y
|
||||||
|
@ -167,7 +183,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
|
||||||
CONFIG_STOP_MACHINE=y
|
CONFIG_STOP_MACHINE=y
|
||||||
CONFIG_BLOCK=y
|
CONFIG_BLOCK=y
|
||||||
# CONFIG_LBD is not set
|
# CONFIG_LBD is not set
|
||||||
CONFIG_BLK_DEV_IO_TRACE=y
|
|
||||||
CONFIG_BLK_DEV_BSG=y
|
CONFIG_BLK_DEV_BSG=y
|
||||||
# CONFIG_BLK_DEV_INTEGRITY is not set
|
# CONFIG_BLK_DEV_INTEGRITY is not set
|
||||||
|
|
||||||
|
@ -194,12 +209,12 @@ CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
||||||
CONFIG_SMP=y
|
CONFIG_SMP=y
|
||||||
CONFIG_SPARSE_IRQ=y
|
CONFIG_SPARSE_IRQ=y
|
||||||
CONFIG_X86_FIND_SMP_CONFIG=y
|
|
||||||
CONFIG_X86_MPPARSE=y
|
CONFIG_X86_MPPARSE=y
|
||||||
|
# CONFIG_X86_BIGSMP is not set
|
||||||
|
CONFIG_X86_EXTENDED_PLATFORM=y
|
||||||
# CONFIG_X86_ELAN is not set
|
# CONFIG_X86_ELAN is not set
|
||||||
# CONFIG_X86_GENERICARCH is not set
|
|
||||||
# CONFIG_X86_VSMP is not set
|
|
||||||
# CONFIG_X86_RDC321X is not set
|
# CONFIG_X86_RDC321X is not set
|
||||||
|
# CONFIG_X86_32_NON_STANDARD is not set
|
||||||
CONFIG_SCHED_OMIT_FRAME_POINTER=y
|
CONFIG_SCHED_OMIT_FRAME_POINTER=y
|
||||||
# CONFIG_PARAVIRT_GUEST is not set
|
# CONFIG_PARAVIRT_GUEST is not set
|
||||||
# CONFIG_MEMTEST is not set
|
# CONFIG_MEMTEST is not set
|
||||||
|
@ -230,8 +245,10 @@ CONFIG_M686=y
|
||||||
# CONFIG_GENERIC_CPU is not set
|
# CONFIG_GENERIC_CPU is not set
|
||||||
CONFIG_X86_GENERIC=y
|
CONFIG_X86_GENERIC=y
|
||||||
CONFIG_X86_CPU=y
|
CONFIG_X86_CPU=y
|
||||||
|
CONFIG_X86_L1_CACHE_BYTES=64
|
||||||
|
CONFIG_X86_INTERNODE_CACHE_BYTES=64
|
||||||
CONFIG_X86_CMPXCHG=y
|
CONFIG_X86_CMPXCHG=y
|
||||||
CONFIG_X86_L1_CACHE_SHIFT=7
|
CONFIG_X86_L1_CACHE_SHIFT=5
|
||||||
CONFIG_X86_XADD=y
|
CONFIG_X86_XADD=y
|
||||||
# CONFIG_X86_PPRO_FENCE is not set
|
# CONFIG_X86_PPRO_FENCE is not set
|
||||||
CONFIG_X86_WP_WORKS_OK=y
|
CONFIG_X86_WP_WORKS_OK=y
|
||||||
|
@ -247,7 +264,7 @@ CONFIG_X86_DEBUGCTLMSR=y
|
||||||
CONFIG_CPU_SUP_INTEL=y
|
CONFIG_CPU_SUP_INTEL=y
|
||||||
CONFIG_CPU_SUP_CYRIX_32=y
|
CONFIG_CPU_SUP_CYRIX_32=y
|
||||||
CONFIG_CPU_SUP_AMD=y
|
CONFIG_CPU_SUP_AMD=y
|
||||||
CONFIG_CPU_SUP_CENTAUR_32=y
|
CONFIG_CPU_SUP_CENTAUR=y
|
||||||
CONFIG_CPU_SUP_TRANSMETA_32=y
|
CONFIG_CPU_SUP_TRANSMETA_32=y
|
||||||
CONFIG_CPU_SUP_UMC_32=y
|
CONFIG_CPU_SUP_UMC_32=y
|
||||||
CONFIG_X86_DS=y
|
CONFIG_X86_DS=y
|
||||||
|
@ -279,6 +296,7 @@ CONFIG_MICROCODE_AMD=y
|
||||||
CONFIG_MICROCODE_OLD_INTERFACE=y
|
CONFIG_MICROCODE_OLD_INTERFACE=y
|
||||||
CONFIG_X86_MSR=y
|
CONFIG_X86_MSR=y
|
||||||
CONFIG_X86_CPUID=y
|
CONFIG_X86_CPUID=y
|
||||||
|
# CONFIG_X86_CPU_DEBUG is not set
|
||||||
# CONFIG_NOHIGHMEM is not set
|
# CONFIG_NOHIGHMEM is not set
|
||||||
CONFIG_HIGHMEM4G=y
|
CONFIG_HIGHMEM4G=y
|
||||||
# CONFIG_HIGHMEM64G is not set
|
# CONFIG_HIGHMEM64G is not set
|
||||||
|
@ -302,6 +320,8 @@ CONFIG_ZONE_DMA_FLAG=1
|
||||||
CONFIG_BOUNCE=y
|
CONFIG_BOUNCE=y
|
||||||
CONFIG_VIRT_TO_BUS=y
|
CONFIG_VIRT_TO_BUS=y
|
||||||
CONFIG_UNEVICTABLE_LRU=y
|
CONFIG_UNEVICTABLE_LRU=y
|
||||||
|
CONFIG_HAVE_MLOCK=y
|
||||||
|
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
|
||||||
CONFIG_HIGHPTE=y
|
CONFIG_HIGHPTE=y
|
||||||
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
|
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
|
||||||
CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
|
CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
|
||||||
|
@ -312,6 +332,7 @@ CONFIG_MTRR=y
|
||||||
CONFIG_X86_PAT=y
|
CONFIG_X86_PAT=y
|
||||||
CONFIG_EFI=y
|
CONFIG_EFI=y
|
||||||
CONFIG_SECCOMP=y
|
CONFIG_SECCOMP=y
|
||||||
|
# CONFIG_CC_STACKPROTECTOR is not set
|
||||||
# CONFIG_HZ_100 is not set
|
# CONFIG_HZ_100 is not set
|
||||||
# CONFIG_HZ_250 is not set
|
# CONFIG_HZ_250 is not set
|
||||||
# CONFIG_HZ_300 is not set
|
# CONFIG_HZ_300 is not set
|
||||||
|
@ -322,8 +343,9 @@ CONFIG_KEXEC=y
|
||||||
CONFIG_CRASH_DUMP=y
|
CONFIG_CRASH_DUMP=y
|
||||||
# CONFIG_KEXEC_JUMP is not set
|
# CONFIG_KEXEC_JUMP is not set
|
||||||
CONFIG_PHYSICAL_START=0x1000000
|
CONFIG_PHYSICAL_START=0x1000000
|
||||||
# CONFIG_RELOCATABLE is not set
|
CONFIG_RELOCATABLE=y
|
||||||
CONFIG_PHYSICAL_ALIGN=0x200000
|
CONFIG_X86_NEED_RELOCS=y
|
||||||
|
CONFIG_PHYSICAL_ALIGN=0x1000000
|
||||||
CONFIG_HOTPLUG_CPU=y
|
CONFIG_HOTPLUG_CPU=y
|
||||||
# CONFIG_COMPAT_VDSO is not set
|
# CONFIG_COMPAT_VDSO is not set
|
||||||
# CONFIG_CMDLINE_BOOL is not set
|
# CONFIG_CMDLINE_BOOL is not set
|
||||||
|
@ -363,7 +385,6 @@ CONFIG_ACPI_THERMAL=y
|
||||||
CONFIG_ACPI_BLACKLIST_YEAR=0
|
CONFIG_ACPI_BLACKLIST_YEAR=0
|
||||||
# CONFIG_ACPI_DEBUG is not set
|
# CONFIG_ACPI_DEBUG is not set
|
||||||
# CONFIG_ACPI_PCI_SLOT is not set
|
# CONFIG_ACPI_PCI_SLOT is not set
|
||||||
CONFIG_ACPI_SYSTEM=y
|
|
||||||
CONFIG_X86_PM_TIMER=y
|
CONFIG_X86_PM_TIMER=y
|
||||||
CONFIG_ACPI_CONTAINER=y
|
CONFIG_ACPI_CONTAINER=y
|
||||||
# CONFIG_ACPI_SBS is not set
|
# CONFIG_ACPI_SBS is not set
|
||||||
|
@ -425,6 +446,7 @@ CONFIG_PCI_BIOS=y
|
||||||
CONFIG_PCI_DIRECT=y
|
CONFIG_PCI_DIRECT=y
|
||||||
CONFIG_PCI_MMCONFIG=y
|
CONFIG_PCI_MMCONFIG=y
|
||||||
CONFIG_PCI_DOMAINS=y
|
CONFIG_PCI_DOMAINS=y
|
||||||
|
# CONFIG_DMAR is not set
|
||||||
CONFIG_PCIEPORTBUS=y
|
CONFIG_PCIEPORTBUS=y
|
||||||
# CONFIG_HOTPLUG_PCI_PCIE is not set
|
# CONFIG_HOTPLUG_PCI_PCIE is not set
|
||||||
CONFIG_PCIEAER=y
|
CONFIG_PCIEAER=y
|
||||||
|
@ -435,6 +457,7 @@ CONFIG_PCI_MSI=y
|
||||||
# CONFIG_PCI_DEBUG is not set
|
# CONFIG_PCI_DEBUG is not set
|
||||||
# CONFIG_PCI_STUB is not set
|
# CONFIG_PCI_STUB is not set
|
||||||
CONFIG_HT_IRQ=y
|
CONFIG_HT_IRQ=y
|
||||||
|
# CONFIG_PCI_IOV is not set
|
||||||
CONFIG_ISA_DMA_API=y
|
CONFIG_ISA_DMA_API=y
|
||||||
# CONFIG_ISA is not set
|
# CONFIG_ISA is not set
|
||||||
# CONFIG_MCA is not set
|
# CONFIG_MCA is not set
|
||||||
|
@ -481,7 +504,6 @@ CONFIG_NET=y
|
||||||
#
|
#
|
||||||
# Networking options
|
# Networking options
|
||||||
#
|
#
|
||||||
CONFIG_COMPAT_NET_DEV_OPS=y
|
|
||||||
CONFIG_PACKET=y
|
CONFIG_PACKET=y
|
||||||
CONFIG_PACKET_MMAP=y
|
CONFIG_PACKET_MMAP=y
|
||||||
CONFIG_UNIX=y
|
CONFIG_UNIX=y
|
||||||
|
@ -639,6 +661,7 @@ CONFIG_LLC=y
|
||||||
# CONFIG_LAPB is not set
|
# CONFIG_LAPB is not set
|
||||||
# CONFIG_ECONET is not set
|
# CONFIG_ECONET is not set
|
||||||
# CONFIG_WAN_ROUTER is not set
|
# CONFIG_WAN_ROUTER is not set
|
||||||
|
# CONFIG_PHONET is not set
|
||||||
CONFIG_NET_SCHED=y
|
CONFIG_NET_SCHED=y
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -696,6 +719,7 @@ CONFIG_NET_SCH_FIFO=y
|
||||||
#
|
#
|
||||||
# CONFIG_NET_PKTGEN is not set
|
# CONFIG_NET_PKTGEN is not set
|
||||||
# CONFIG_NET_TCPPROBE is not set
|
# CONFIG_NET_TCPPROBE is not set
|
||||||
|
# CONFIG_NET_DROP_MONITOR is not set
|
||||||
CONFIG_HAMRADIO=y
|
CONFIG_HAMRADIO=y
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -706,12 +730,10 @@ CONFIG_HAMRADIO=y
|
||||||
# CONFIG_IRDA is not set
|
# CONFIG_IRDA is not set
|
||||||
# CONFIG_BT is not set
|
# CONFIG_BT is not set
|
||||||
# CONFIG_AF_RXRPC is not set
|
# CONFIG_AF_RXRPC is not set
|
||||||
# CONFIG_PHONET is not set
|
|
||||||
CONFIG_FIB_RULES=y
|
CONFIG_FIB_RULES=y
|
||||||
CONFIG_WIRELESS=y
|
CONFIG_WIRELESS=y
|
||||||
CONFIG_CFG80211=y
|
CONFIG_CFG80211=y
|
||||||
# CONFIG_CFG80211_REG_DEBUG is not set
|
# CONFIG_CFG80211_REG_DEBUG is not set
|
||||||
CONFIG_NL80211=y
|
|
||||||
CONFIG_WIRELESS_OLD_REGULATORY=y
|
CONFIG_WIRELESS_OLD_REGULATORY=y
|
||||||
CONFIG_WIRELESS_EXT=y
|
CONFIG_WIRELESS_EXT=y
|
||||||
CONFIG_WIRELESS_EXT_SYSFS=y
|
CONFIG_WIRELESS_EXT_SYSFS=y
|
||||||
|
@ -789,6 +811,7 @@ CONFIG_MISC_DEVICES=y
|
||||||
# CONFIG_ICS932S401 is not set
|
# CONFIG_ICS932S401 is not set
|
||||||
# CONFIG_ENCLOSURE_SERVICES is not set
|
# CONFIG_ENCLOSURE_SERVICES is not set
|
||||||
# CONFIG_HP_ILO is not set
|
# CONFIG_HP_ILO is not set
|
||||||
|
# CONFIG_ISL29003 is not set
|
||||||
# CONFIG_C2PORT is not set
|
# CONFIG_C2PORT is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -842,6 +865,7 @@ CONFIG_SCSI_SPI_ATTRS=y
|
||||||
# CONFIG_SCSI_LOWLEVEL is not set
|
# CONFIG_SCSI_LOWLEVEL is not set
|
||||||
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
|
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
|
||||||
# CONFIG_SCSI_DH is not set
|
# CONFIG_SCSI_DH is not set
|
||||||
|
# CONFIG_SCSI_OSD_INITIATOR is not set
|
||||||
CONFIG_ATA=y
|
CONFIG_ATA=y
|
||||||
# CONFIG_ATA_NONSTANDARD is not set
|
# CONFIG_ATA_NONSTANDARD is not set
|
||||||
CONFIG_ATA_ACPI=y
|
CONFIG_ATA_ACPI=y
|
||||||
|
@ -940,6 +964,7 @@ CONFIG_DM_ZERO=y
|
||||||
CONFIG_MACINTOSH_DRIVERS=y
|
CONFIG_MACINTOSH_DRIVERS=y
|
||||||
CONFIG_MAC_EMUMOUSEBTN=y
|
CONFIG_MAC_EMUMOUSEBTN=y
|
||||||
CONFIG_NETDEVICES=y
|
CONFIG_NETDEVICES=y
|
||||||
|
CONFIG_COMPAT_NET_DEV_OPS=y
|
||||||
# CONFIG_IFB is not set
|
# CONFIG_IFB is not set
|
||||||
# CONFIG_DUMMY is not set
|
# CONFIG_DUMMY is not set
|
||||||
# CONFIG_BONDING is not set
|
# CONFIG_BONDING is not set
|
||||||
|
@ -977,6 +1002,8 @@ CONFIG_MII=y
|
||||||
CONFIG_NET_VENDOR_3COM=y
|
CONFIG_NET_VENDOR_3COM=y
|
||||||
# CONFIG_VORTEX is not set
|
# CONFIG_VORTEX is not set
|
||||||
# CONFIG_TYPHOON is not set
|
# CONFIG_TYPHOON is not set
|
||||||
|
# CONFIG_ETHOC is not set
|
||||||
|
# CONFIG_DNET is not set
|
||||||
CONFIG_NET_TULIP=y
|
CONFIG_NET_TULIP=y
|
||||||
# CONFIG_DE2104X is not set
|
# CONFIG_DE2104X is not set
|
||||||
# CONFIG_TULIP is not set
|
# CONFIG_TULIP is not set
|
||||||
|
@ -1026,6 +1053,7 @@ CONFIG_E1000=y
|
||||||
CONFIG_E1000E=y
|
CONFIG_E1000E=y
|
||||||
# CONFIG_IP1000 is not set
|
# CONFIG_IP1000 is not set
|
||||||
# CONFIG_IGB is not set
|
# CONFIG_IGB is not set
|
||||||
|
# CONFIG_IGBVF is not set
|
||||||
# CONFIG_NS83820 is not set
|
# CONFIG_NS83820 is not set
|
||||||
# CONFIG_HAMACHI is not set
|
# CONFIG_HAMACHI is not set
|
||||||
# CONFIG_YELLOWFIN is not set
|
# CONFIG_YELLOWFIN is not set
|
||||||
|
@ -1040,6 +1068,7 @@ CONFIG_BNX2=y
|
||||||
# CONFIG_QLA3XXX is not set
|
# CONFIG_QLA3XXX is not set
|
||||||
# CONFIG_ATL1 is not set
|
# CONFIG_ATL1 is not set
|
||||||
# CONFIG_ATL1E is not set
|
# CONFIG_ATL1E is not set
|
||||||
|
# CONFIG_ATL1C is not set
|
||||||
# CONFIG_JME is not set
|
# CONFIG_JME is not set
|
||||||
CONFIG_NETDEV_10000=y
|
CONFIG_NETDEV_10000=y
|
||||||
# CONFIG_CHELSIO_T1 is not set
|
# CONFIG_CHELSIO_T1 is not set
|
||||||
|
@ -1049,6 +1078,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
|
||||||
# CONFIG_IXGBE is not set
|
# CONFIG_IXGBE is not set
|
||||||
# CONFIG_IXGB is not set
|
# CONFIG_IXGB is not set
|
||||||
# CONFIG_S2IO is not set
|
# CONFIG_S2IO is not set
|
||||||
|
# CONFIG_VXGE is not set
|
||||||
# CONFIG_MYRI10GE is not set
|
# CONFIG_MYRI10GE is not set
|
||||||
# CONFIG_NETXEN_NIC is not set
|
# CONFIG_NETXEN_NIC is not set
|
||||||
# CONFIG_NIU is not set
|
# CONFIG_NIU is not set
|
||||||
|
@ -1058,6 +1088,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
|
||||||
# CONFIG_BNX2X is not set
|
# CONFIG_BNX2X is not set
|
||||||
# CONFIG_QLGE is not set
|
# CONFIG_QLGE is not set
|
||||||
# CONFIG_SFC is not set
|
# CONFIG_SFC is not set
|
||||||
|
# CONFIG_BE2NET is not set
|
||||||
CONFIG_TR=y
|
CONFIG_TR=y
|
||||||
# CONFIG_IBMOL is not set
|
# CONFIG_IBMOL is not set
|
||||||
# CONFIG_IBMLS is not set
|
# CONFIG_IBMLS is not set
|
||||||
|
@ -1073,8 +1104,8 @@ CONFIG_WLAN_80211=y
|
||||||
# CONFIG_LIBERTAS is not set
|
# CONFIG_LIBERTAS is not set
|
||||||
# CONFIG_LIBERTAS_THINFIRM is not set
|
# CONFIG_LIBERTAS_THINFIRM is not set
|
||||||
# CONFIG_AIRO is not set
|
# CONFIG_AIRO is not set
|
||||||
# CONFIG_HERMES is not set
|
|
||||||
# CONFIG_ATMEL is not set
|
# CONFIG_ATMEL is not set
|
||||||
|
# CONFIG_AT76C50X_USB is not set
|
||||||
# CONFIG_AIRO_CS is not set
|
# CONFIG_AIRO_CS is not set
|
||||||
# CONFIG_PCMCIA_WL3501 is not set
|
# CONFIG_PCMCIA_WL3501 is not set
|
||||||
# CONFIG_PRISM54 is not set
|
# CONFIG_PRISM54 is not set
|
||||||
|
@ -1084,21 +1115,21 @@ CONFIG_WLAN_80211=y
|
||||||
# CONFIG_RTL8187 is not set
|
# CONFIG_RTL8187 is not set
|
||||||
# CONFIG_ADM8211 is not set
|
# CONFIG_ADM8211 is not set
|
||||||
# CONFIG_MAC80211_HWSIM is not set
|
# CONFIG_MAC80211_HWSIM is not set
|
||||||
|
# CONFIG_MWL8K is not set
|
||||||
# CONFIG_P54_COMMON is not set
|
# CONFIG_P54_COMMON is not set
|
||||||
CONFIG_ATH5K=y
|
CONFIG_ATH5K=y
|
||||||
# CONFIG_ATH5K_DEBUG is not set
|
# CONFIG_ATH5K_DEBUG is not set
|
||||||
# CONFIG_ATH9K is not set
|
# CONFIG_ATH9K is not set
|
||||||
|
# CONFIG_AR9170_USB is not set
|
||||||
# CONFIG_IPW2100 is not set
|
# CONFIG_IPW2100 is not set
|
||||||
# CONFIG_IPW2200 is not set
|
# CONFIG_IPW2200 is not set
|
||||||
# CONFIG_IWLCORE is not set
|
# CONFIG_IWLWIFI is not set
|
||||||
# CONFIG_IWLWIFI_LEDS is not set
|
|
||||||
# CONFIG_IWLAGN is not set
|
|
||||||
# CONFIG_IWL3945 is not set
|
|
||||||
# CONFIG_HOSTAP is not set
|
# CONFIG_HOSTAP is not set
|
||||||
# CONFIG_B43 is not set
|
# CONFIG_B43 is not set
|
||||||
# CONFIG_B43LEGACY is not set
|
# CONFIG_B43LEGACY is not set
|
||||||
# CONFIG_ZD1211RW is not set
|
# CONFIG_ZD1211RW is not set
|
||||||
# CONFIG_RT2X00 is not set
|
# CONFIG_RT2X00 is not set
|
||||||
|
# CONFIG_HERMES is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Enable WiMAX (Networking options) to see the WiMAX drivers
|
# Enable WiMAX (Networking options) to see the WiMAX drivers
|
||||||
|
@ -1209,6 +1240,8 @@ CONFIG_INPUT_TABLET=y
|
||||||
# CONFIG_TABLET_USB_KBTAB is not set
|
# CONFIG_TABLET_USB_KBTAB is not set
|
||||||
# CONFIG_TABLET_USB_WACOM is not set
|
# CONFIG_TABLET_USB_WACOM is not set
|
||||||
CONFIG_INPUT_TOUCHSCREEN=y
|
CONFIG_INPUT_TOUCHSCREEN=y
|
||||||
|
# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
|
||||||
|
# CONFIG_TOUCHSCREEN_AD7879 is not set
|
||||||
# CONFIG_TOUCHSCREEN_FUJITSU is not set
|
# CONFIG_TOUCHSCREEN_FUJITSU is not set
|
||||||
# CONFIG_TOUCHSCREEN_GUNZE is not set
|
# CONFIG_TOUCHSCREEN_GUNZE is not set
|
||||||
# CONFIG_TOUCHSCREEN_ELO is not set
|
# CONFIG_TOUCHSCREEN_ELO is not set
|
||||||
|
@ -1303,6 +1336,7 @@ CONFIG_UNIX98_PTYS=y
|
||||||
# CONFIG_LEGACY_PTYS is not set
|
# CONFIG_LEGACY_PTYS is not set
|
||||||
# CONFIG_IPMI_HANDLER is not set
|
# CONFIG_IPMI_HANDLER is not set
|
||||||
CONFIG_HW_RANDOM=y
|
CONFIG_HW_RANDOM=y
|
||||||
|
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
|
||||||
CONFIG_HW_RANDOM_INTEL=y
|
CONFIG_HW_RANDOM_INTEL=y
|
||||||
CONFIG_HW_RANDOM_AMD=y
|
CONFIG_HW_RANDOM_AMD=y
|
||||||
CONFIG_HW_RANDOM_GEODE=y
|
CONFIG_HW_RANDOM_GEODE=y
|
||||||
|
@ -1390,7 +1424,6 @@ CONFIG_I2C_I801=y
|
||||||
# CONFIG_SENSORS_PCF8574 is not set
|
# CONFIG_SENSORS_PCF8574 is not set
|
||||||
# CONFIG_PCF8575 is not set
|
# CONFIG_PCF8575 is not set
|
||||||
# CONFIG_SENSORS_PCA9539 is not set
|
# CONFIG_SENSORS_PCA9539 is not set
|
||||||
# CONFIG_SENSORS_PCF8591 is not set
|
|
||||||
# CONFIG_SENSORS_MAX6875 is not set
|
# CONFIG_SENSORS_MAX6875 is not set
|
||||||
# CONFIG_SENSORS_TSL2550 is not set
|
# CONFIG_SENSORS_TSL2550 is not set
|
||||||
# CONFIG_I2C_DEBUG_CORE is not set
|
# CONFIG_I2C_DEBUG_CORE is not set
|
||||||
|
@ -1424,6 +1457,7 @@ CONFIG_HWMON=y
|
||||||
# CONFIG_SENSORS_ADT7475 is not set
|
# CONFIG_SENSORS_ADT7475 is not set
|
||||||
# CONFIG_SENSORS_K8TEMP is not set
|
# CONFIG_SENSORS_K8TEMP is not set
|
||||||
# CONFIG_SENSORS_ASB100 is not set
|
# CONFIG_SENSORS_ASB100 is not set
|
||||||
|
# CONFIG_SENSORS_ATK0110 is not set
|
||||||
# CONFIG_SENSORS_ATXP1 is not set
|
# CONFIG_SENSORS_ATXP1 is not set
|
||||||
# CONFIG_SENSORS_DS1621 is not set
|
# CONFIG_SENSORS_DS1621 is not set
|
||||||
# CONFIG_SENSORS_I5K_AMB is not set
|
# CONFIG_SENSORS_I5K_AMB is not set
|
||||||
|
@ -1433,6 +1467,7 @@ CONFIG_HWMON=y
|
||||||
# CONFIG_SENSORS_FSCHER is not set
|
# CONFIG_SENSORS_FSCHER is not set
|
||||||
# CONFIG_SENSORS_FSCPOS is not set
|
# CONFIG_SENSORS_FSCPOS is not set
|
||||||
# CONFIG_SENSORS_FSCHMD is not set
|
# CONFIG_SENSORS_FSCHMD is not set
|
||||||
|
# CONFIG_SENSORS_G760A is not set
|
||||||
# CONFIG_SENSORS_GL518SM is not set
|
# CONFIG_SENSORS_GL518SM is not set
|
||||||
# CONFIG_SENSORS_GL520SM is not set
|
# CONFIG_SENSORS_GL520SM is not set
|
||||||
# CONFIG_SENSORS_CORETEMP is not set
|
# CONFIG_SENSORS_CORETEMP is not set
|
||||||
|
@ -1448,11 +1483,14 @@ CONFIG_HWMON=y
|
||||||
# CONFIG_SENSORS_LM90 is not set
|
# CONFIG_SENSORS_LM90 is not set
|
||||||
# CONFIG_SENSORS_LM92 is not set
|
# CONFIG_SENSORS_LM92 is not set
|
||||||
# CONFIG_SENSORS_LM93 is not set
|
# CONFIG_SENSORS_LM93 is not set
|
||||||
|
# CONFIG_SENSORS_LTC4215 is not set
|
||||||
# CONFIG_SENSORS_LTC4245 is not set
|
# CONFIG_SENSORS_LTC4245 is not set
|
||||||
|
# CONFIG_SENSORS_LM95241 is not set
|
||||||
# CONFIG_SENSORS_MAX1619 is not set
|
# CONFIG_SENSORS_MAX1619 is not set
|
||||||
# CONFIG_SENSORS_MAX6650 is not set
|
# CONFIG_SENSORS_MAX6650 is not set
|
||||||
# CONFIG_SENSORS_PC87360 is not set
|
# CONFIG_SENSORS_PC87360 is not set
|
||||||
# CONFIG_SENSORS_PC87427 is not set
|
# CONFIG_SENSORS_PC87427 is not set
|
||||||
|
# CONFIG_SENSORS_PCF8591 is not set
|
||||||
# CONFIG_SENSORS_SIS5595 is not set
|
# CONFIG_SENSORS_SIS5595 is not set
|
||||||
# CONFIG_SENSORS_DME1737 is not set
|
# CONFIG_SENSORS_DME1737 is not set
|
||||||
# CONFIG_SENSORS_SMSC47M1 is not set
|
# CONFIG_SENSORS_SMSC47M1 is not set
|
||||||
|
@ -1643,7 +1681,6 @@ CONFIG_FB_EFI=y
|
||||||
# CONFIG_FB_3DFX is not set
|
# CONFIG_FB_3DFX is not set
|
||||||
# CONFIG_FB_VOODOO1 is not set
|
# CONFIG_FB_VOODOO1 is not set
|
||||||
# CONFIG_FB_VT8623 is not set
|
# CONFIG_FB_VT8623 is not set
|
||||||
# CONFIG_FB_CYBLA is not set
|
|
||||||
# CONFIG_FB_TRIDENT is not set
|
# CONFIG_FB_TRIDENT is not set
|
||||||
# CONFIG_FB_ARK is not set
|
# CONFIG_FB_ARK is not set
|
||||||
# CONFIG_FB_PM3 is not set
|
# CONFIG_FB_PM3 is not set
|
||||||
|
@ -1652,6 +1689,7 @@ CONFIG_FB_EFI=y
|
||||||
# CONFIG_FB_VIRTUAL is not set
|
# CONFIG_FB_VIRTUAL is not set
|
||||||
# CONFIG_FB_METRONOME is not set
|
# CONFIG_FB_METRONOME is not set
|
||||||
# CONFIG_FB_MB862XX is not set
|
# CONFIG_FB_MB862XX is not set
|
||||||
|
# CONFIG_FB_BROADSHEET is not set
|
||||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||||
# CONFIG_LCD_CLASS_DEVICE is not set
|
# CONFIG_LCD_CLASS_DEVICE is not set
|
||||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||||
|
@ -1738,6 +1776,8 @@ CONFIG_SND_PCI=y
|
||||||
# CONFIG_SND_INDIGO is not set
|
# CONFIG_SND_INDIGO is not set
|
||||||
# CONFIG_SND_INDIGOIO is not set
|
# CONFIG_SND_INDIGOIO is not set
|
||||||
# CONFIG_SND_INDIGODJ is not set
|
# CONFIG_SND_INDIGODJ is not set
|
||||||
|
# CONFIG_SND_INDIGOIOX is not set
|
||||||
|
# CONFIG_SND_INDIGODJX is not set
|
||||||
# CONFIG_SND_EMU10K1 is not set
|
# CONFIG_SND_EMU10K1 is not set
|
||||||
# CONFIG_SND_EMU10K1X is not set
|
# CONFIG_SND_EMU10K1X is not set
|
||||||
# CONFIG_SND_ENS1370 is not set
|
# CONFIG_SND_ENS1370 is not set
|
||||||
|
@ -1811,15 +1851,17 @@ CONFIG_USB_HIDDEV=y
|
||||||
#
|
#
|
||||||
# Special HID drivers
|
# Special HID drivers
|
||||||
#
|
#
|
||||||
CONFIG_HID_COMPAT=y
|
|
||||||
CONFIG_HID_A4TECH=y
|
CONFIG_HID_A4TECH=y
|
||||||
CONFIG_HID_APPLE=y
|
CONFIG_HID_APPLE=y
|
||||||
CONFIG_HID_BELKIN=y
|
CONFIG_HID_BELKIN=y
|
||||||
CONFIG_HID_CHERRY=y
|
CONFIG_HID_CHERRY=y
|
||||||
CONFIG_HID_CHICONY=y
|
CONFIG_HID_CHICONY=y
|
||||||
CONFIG_HID_CYPRESS=y
|
CONFIG_HID_CYPRESS=y
|
||||||
|
# CONFIG_DRAGONRISE_FF is not set
|
||||||
CONFIG_HID_EZKEY=y
|
CONFIG_HID_EZKEY=y
|
||||||
|
CONFIG_HID_KYE=y
|
||||||
CONFIG_HID_GYRATION=y
|
CONFIG_HID_GYRATION=y
|
||||||
|
CONFIG_HID_KENSINGTON=y
|
||||||
CONFIG_HID_LOGITECH=y
|
CONFIG_HID_LOGITECH=y
|
||||||
CONFIG_LOGITECH_FF=y
|
CONFIG_LOGITECH_FF=y
|
||||||
# CONFIG_LOGIRUMBLEPAD2_FF is not set
|
# CONFIG_LOGIRUMBLEPAD2_FF is not set
|
||||||
|
@ -1885,11 +1927,11 @@ CONFIG_USB_PRINTER=y
|
||||||
# CONFIG_USB_TMC is not set
|
# CONFIG_USB_TMC is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
|
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
|
||||||
#
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# see USB_STORAGE Help for more information
|
# also be needed; see USB_STORAGE Help for more info
|
||||||
#
|
#
|
||||||
CONFIG_USB_STORAGE=y
|
CONFIG_USB_STORAGE=y
|
||||||
# CONFIG_USB_STORAGE_DEBUG is not set
|
# CONFIG_USB_STORAGE_DEBUG is not set
|
||||||
|
@ -1931,7 +1973,6 @@ CONFIG_USB_LIBUSUAL=y
|
||||||
# CONFIG_USB_LED is not set
|
# CONFIG_USB_LED is not set
|
||||||
# CONFIG_USB_CYPRESS_CY7C63 is not set
|
# CONFIG_USB_CYPRESS_CY7C63 is not set
|
||||||
# CONFIG_USB_CYTHERM is not set
|
# CONFIG_USB_CYTHERM is not set
|
||||||
# CONFIG_USB_PHIDGET is not set
|
|
||||||
# CONFIG_USB_IDMOUSE is not set
|
# CONFIG_USB_IDMOUSE is not set
|
||||||
# CONFIG_USB_FTDI_ELAN is not set
|
# CONFIG_USB_FTDI_ELAN is not set
|
||||||
# CONFIG_USB_APPLEDISPLAY is not set
|
# CONFIG_USB_APPLEDISPLAY is not set
|
||||||
|
@ -1947,6 +1988,7 @@ CONFIG_USB_LIBUSUAL=y
|
||||||
#
|
#
|
||||||
# OTG and related infrastructure
|
# OTG and related infrastructure
|
||||||
#
|
#
|
||||||
|
# CONFIG_NOP_USB_XCEIV is not set
|
||||||
# CONFIG_UWB is not set
|
# CONFIG_UWB is not set
|
||||||
# CONFIG_MMC is not set
|
# CONFIG_MMC is not set
|
||||||
# CONFIG_MEMSTICK is not set
|
# CONFIG_MEMSTICK is not set
|
||||||
|
@ -1958,8 +2000,10 @@ CONFIG_LEDS_CLASS=y
|
||||||
#
|
#
|
||||||
# CONFIG_LEDS_ALIX2 is not set
|
# CONFIG_LEDS_ALIX2 is not set
|
||||||
# CONFIG_LEDS_PCA9532 is not set
|
# CONFIG_LEDS_PCA9532 is not set
|
||||||
|
# CONFIG_LEDS_LP5521 is not set
|
||||||
# CONFIG_LEDS_CLEVO_MAIL is not set
|
# CONFIG_LEDS_CLEVO_MAIL is not set
|
||||||
# CONFIG_LEDS_PCA955X is not set
|
# CONFIG_LEDS_PCA955X is not set
|
||||||
|
# CONFIG_LEDS_BD2802 is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# LED Triggers
|
# LED Triggers
|
||||||
|
@ -1969,6 +2013,10 @@ CONFIG_LEDS_TRIGGERS=y
|
||||||
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
|
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
|
||||||
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
|
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
|
||||||
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
|
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# iptables trigger is under Netfilter config (LED target)
|
||||||
|
#
|
||||||
# CONFIG_ACCESSIBILITY is not set
|
# CONFIG_ACCESSIBILITY is not set
|
||||||
# CONFIG_INFINIBAND is not set
|
# CONFIG_INFINIBAND is not set
|
||||||
CONFIG_EDAC=y
|
CONFIG_EDAC=y
|
||||||
|
@ -2037,6 +2085,7 @@ CONFIG_DMADEVICES=y
|
||||||
# DMA Devices
|
# DMA Devices
|
||||||
#
|
#
|
||||||
# CONFIG_INTEL_IOATDMA is not set
|
# CONFIG_INTEL_IOATDMA is not set
|
||||||
|
# CONFIG_AUXDISPLAY is not set
|
||||||
# CONFIG_UIO is not set
|
# CONFIG_UIO is not set
|
||||||
# CONFIG_STAGING is not set
|
# CONFIG_STAGING is not set
|
||||||
CONFIG_X86_PLATFORM_DEVICES=y
|
CONFIG_X86_PLATFORM_DEVICES=y
|
||||||
|
@ -2071,6 +2120,7 @@ CONFIG_DMIID=y
|
||||||
#
|
#
|
||||||
# CONFIG_EXT2_FS is not set
|
# CONFIG_EXT2_FS is not set
|
||||||
CONFIG_EXT3_FS=y
|
CONFIG_EXT3_FS=y
|
||||||
|
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
|
||||||
CONFIG_EXT3_FS_XATTR=y
|
CONFIG_EXT3_FS_XATTR=y
|
||||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||||
CONFIG_EXT3_FS_SECURITY=y
|
CONFIG_EXT3_FS_SECURITY=y
|
||||||
|
@ -2100,6 +2150,11 @@ CONFIG_AUTOFS4_FS=y
|
||||||
# CONFIG_FUSE_FS is not set
|
# CONFIG_FUSE_FS is not set
|
||||||
CONFIG_GENERIC_ACL=y
|
CONFIG_GENERIC_ACL=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# Caches
|
||||||
|
#
|
||||||
|
# CONFIG_FSCACHE is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# CD-ROM/DVD Filesystems
|
# CD-ROM/DVD Filesystems
|
||||||
#
|
#
|
||||||
|
@ -2151,6 +2206,7 @@ CONFIG_MISC_FILESYSTEMS=y
|
||||||
# CONFIG_ROMFS_FS is not set
|
# CONFIG_ROMFS_FS is not set
|
||||||
# CONFIG_SYSV_FS is not set
|
# CONFIG_SYSV_FS is not set
|
||||||
# CONFIG_UFS_FS is not set
|
# CONFIG_UFS_FS is not set
|
||||||
|
# CONFIG_NILFS2_FS is not set
|
||||||
CONFIG_NETWORK_FILESYSTEMS=y
|
CONFIG_NETWORK_FILESYSTEMS=y
|
||||||
CONFIG_NFS_FS=y
|
CONFIG_NFS_FS=y
|
||||||
CONFIG_NFS_V3=y
|
CONFIG_NFS_V3=y
|
||||||
|
@ -2164,7 +2220,6 @@ CONFIG_NFS_ACL_SUPPORT=y
|
||||||
CONFIG_NFS_COMMON=y
|
CONFIG_NFS_COMMON=y
|
||||||
CONFIG_SUNRPC=y
|
CONFIG_SUNRPC=y
|
||||||
CONFIG_SUNRPC_GSS=y
|
CONFIG_SUNRPC_GSS=y
|
||||||
# CONFIG_SUNRPC_REGISTER_V4 is not set
|
|
||||||
CONFIG_RPCSEC_GSS_KRB5=y
|
CONFIG_RPCSEC_GSS_KRB5=y
|
||||||
# CONFIG_RPCSEC_GSS_SPKM3 is not set
|
# CONFIG_RPCSEC_GSS_SPKM3 is not set
|
||||||
# CONFIG_SMB_FS is not set
|
# CONFIG_SMB_FS is not set
|
||||||
|
@ -2251,6 +2306,7 @@ CONFIG_DEBUG_FS=y
|
||||||
CONFIG_DEBUG_KERNEL=y
|
CONFIG_DEBUG_KERNEL=y
|
||||||
# CONFIG_DEBUG_SHIRQ is not set
|
# CONFIG_DEBUG_SHIRQ is not set
|
||||||
# CONFIG_DETECT_SOFTLOCKUP is not set
|
# CONFIG_DETECT_SOFTLOCKUP is not set
|
||||||
|
# CONFIG_DETECT_HUNG_TASK is not set
|
||||||
# CONFIG_SCHED_DEBUG is not set
|
# CONFIG_SCHED_DEBUG is not set
|
||||||
CONFIG_SCHEDSTATS=y
|
CONFIG_SCHEDSTATS=y
|
||||||
CONFIG_TIMER_STATS=y
|
CONFIG_TIMER_STATS=y
|
||||||
|
@ -2266,6 +2322,7 @@ CONFIG_TIMER_STATS=y
|
||||||
# CONFIG_LOCK_STAT is not set
|
# CONFIG_LOCK_STAT is not set
|
||||||
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
|
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
|
||||||
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
|
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
|
||||||
|
CONFIG_STACKTRACE=y
|
||||||
# CONFIG_DEBUG_KOBJECT is not set
|
# CONFIG_DEBUG_KOBJECT is not set
|
||||||
# CONFIG_DEBUG_HIGHMEM is not set
|
# CONFIG_DEBUG_HIGHMEM is not set
|
||||||
CONFIG_DEBUG_BUGVERBOSE=y
|
CONFIG_DEBUG_BUGVERBOSE=y
|
||||||
|
@ -2289,13 +2346,19 @@ CONFIG_FRAME_POINTER=y
|
||||||
# CONFIG_FAULT_INJECTION is not set
|
# CONFIG_FAULT_INJECTION is not set
|
||||||
# CONFIG_LATENCYTOP is not set
|
# CONFIG_LATENCYTOP is not set
|
||||||
CONFIG_SYSCTL_SYSCALL_CHECK=y
|
CONFIG_SYSCTL_SYSCALL_CHECK=y
|
||||||
|
# CONFIG_DEBUG_PAGEALLOC is not set
|
||||||
CONFIG_USER_STACKTRACE_SUPPORT=y
|
CONFIG_USER_STACKTRACE_SUPPORT=y
|
||||||
|
CONFIG_NOP_TRACER=y
|
||||||
CONFIG_HAVE_FUNCTION_TRACER=y
|
CONFIG_HAVE_FUNCTION_TRACER=y
|
||||||
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
|
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
|
||||||
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
|
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
|
||||||
CONFIG_HAVE_DYNAMIC_FTRACE=y
|
CONFIG_HAVE_DYNAMIC_FTRACE=y
|
||||||
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
|
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
|
||||||
CONFIG_HAVE_HW_BRANCH_TRACER=y
|
CONFIG_HAVE_HW_BRANCH_TRACER=y
|
||||||
|
CONFIG_HAVE_FTRACE_SYSCALLS=y
|
||||||
|
CONFIG_RING_BUFFER=y
|
||||||
|
CONFIG_TRACING=y
|
||||||
|
CONFIG_TRACING_SUPPORT=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Tracers
|
# Tracers
|
||||||
|
@ -2305,13 +2368,21 @@ CONFIG_HAVE_HW_BRANCH_TRACER=y
|
||||||
# CONFIG_SYSPROF_TRACER is not set
|
# CONFIG_SYSPROF_TRACER is not set
|
||||||
# CONFIG_SCHED_TRACER is not set
|
# CONFIG_SCHED_TRACER is not set
|
||||||
# CONFIG_CONTEXT_SWITCH_TRACER is not set
|
# CONFIG_CONTEXT_SWITCH_TRACER is not set
|
||||||
|
# CONFIG_EVENT_TRACER is not set
|
||||||
|
# CONFIG_FTRACE_SYSCALLS is not set
|
||||||
# CONFIG_BOOT_TRACER is not set
|
# CONFIG_BOOT_TRACER is not set
|
||||||
# CONFIG_TRACE_BRANCH_PROFILING is not set
|
# CONFIG_TRACE_BRANCH_PROFILING is not set
|
||||||
# CONFIG_POWER_TRACER is not set
|
# CONFIG_POWER_TRACER is not set
|
||||||
# CONFIG_STACK_TRACER is not set
|
# CONFIG_STACK_TRACER is not set
|
||||||
# CONFIG_HW_BRANCH_TRACER is not set
|
# CONFIG_HW_BRANCH_TRACER is not set
|
||||||
|
# CONFIG_KMEMTRACE is not set
|
||||||
|
# CONFIG_WORKQUEUE_TRACER is not set
|
||||||
|
CONFIG_BLK_DEV_IO_TRACE=y
|
||||||
|
# CONFIG_FTRACE_STARTUP_TEST is not set
|
||||||
|
# CONFIG_MMIOTRACE is not set
|
||||||
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
|
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
|
||||||
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
|
# CONFIG_DYNAMIC_DEBUG is not set
|
||||||
|
# CONFIG_DMA_API_DEBUG is not set
|
||||||
# CONFIG_SAMPLES is not set
|
# CONFIG_SAMPLES is not set
|
||||||
CONFIG_HAVE_ARCH_KGDB=y
|
CONFIG_HAVE_ARCH_KGDB=y
|
||||||
# CONFIG_KGDB is not set
|
# CONFIG_KGDB is not set
|
||||||
|
@ -2321,7 +2392,6 @@ CONFIG_EARLY_PRINTK=y
|
||||||
CONFIG_EARLY_PRINTK_DBGP=y
|
CONFIG_EARLY_PRINTK_DBGP=y
|
||||||
CONFIG_DEBUG_STACKOVERFLOW=y
|
CONFIG_DEBUG_STACKOVERFLOW=y
|
||||||
CONFIG_DEBUG_STACK_USAGE=y
|
CONFIG_DEBUG_STACK_USAGE=y
|
||||||
# CONFIG_DEBUG_PAGEALLOC is not set
|
|
||||||
# CONFIG_DEBUG_PER_CPU_MAPS is not set
|
# CONFIG_DEBUG_PER_CPU_MAPS is not set
|
||||||
# CONFIG_X86_PTDUMP is not set
|
# CONFIG_X86_PTDUMP is not set
|
||||||
CONFIG_DEBUG_RODATA=y
|
CONFIG_DEBUG_RODATA=y
|
||||||
|
@ -2329,7 +2399,7 @@ CONFIG_DEBUG_RODATA=y
|
||||||
CONFIG_DEBUG_NX_TEST=m
|
CONFIG_DEBUG_NX_TEST=m
|
||||||
# CONFIG_4KSTACKS is not set
|
# CONFIG_4KSTACKS is not set
|
||||||
CONFIG_DOUBLEFAULT=y
|
CONFIG_DOUBLEFAULT=y
|
||||||
# CONFIG_MMIOTRACE is not set
|
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
|
||||||
CONFIG_IO_DELAY_TYPE_0X80=0
|
CONFIG_IO_DELAY_TYPE_0X80=0
|
||||||
CONFIG_IO_DELAY_TYPE_0XED=1
|
CONFIG_IO_DELAY_TYPE_0XED=1
|
||||||
CONFIG_IO_DELAY_TYPE_UDELAY=2
|
CONFIG_IO_DELAY_TYPE_UDELAY=2
|
||||||
|
@ -2365,6 +2435,8 @@ CONFIG_SECURITY_SELINUX_AVC_STATS=y
|
||||||
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
|
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
|
||||||
# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
|
# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
|
||||||
# CONFIG_SECURITY_SMACK is not set
|
# CONFIG_SECURITY_SMACK is not set
|
||||||
|
# CONFIG_SECURITY_TOMOYO is not set
|
||||||
|
# CONFIG_IMA is not set
|
||||||
CONFIG_CRYPTO=y
|
CONFIG_CRYPTO=y
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -2380,10 +2452,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
|
||||||
CONFIG_CRYPTO_HASH=y
|
CONFIG_CRYPTO_HASH=y
|
||||||
CONFIG_CRYPTO_HASH2=y
|
CONFIG_CRYPTO_HASH2=y
|
||||||
CONFIG_CRYPTO_RNG2=y
|
CONFIG_CRYPTO_RNG2=y
|
||||||
|
CONFIG_CRYPTO_PCOMP=y
|
||||||
CONFIG_CRYPTO_MANAGER=y
|
CONFIG_CRYPTO_MANAGER=y
|
||||||
CONFIG_CRYPTO_MANAGER2=y
|
CONFIG_CRYPTO_MANAGER2=y
|
||||||
# CONFIG_CRYPTO_GF128MUL is not set
|
# CONFIG_CRYPTO_GF128MUL is not set
|
||||||
# CONFIG_CRYPTO_NULL is not set
|
# CONFIG_CRYPTO_NULL is not set
|
||||||
|
CONFIG_CRYPTO_WORKQUEUE=y
|
||||||
# CONFIG_CRYPTO_CRYPTD is not set
|
# CONFIG_CRYPTO_CRYPTD is not set
|
||||||
CONFIG_CRYPTO_AUTHENC=y
|
CONFIG_CRYPTO_AUTHENC=y
|
||||||
# CONFIG_CRYPTO_TEST is not set
|
# CONFIG_CRYPTO_TEST is not set
|
||||||
|
@ -2456,6 +2530,7 @@ CONFIG_CRYPTO_DES=y
|
||||||
# Compression
|
# Compression
|
||||||
#
|
#
|
||||||
# CONFIG_CRYPTO_DEFLATE is not set
|
# CONFIG_CRYPTO_DEFLATE is not set
|
||||||
|
# CONFIG_CRYPTO_ZLIB is not set
|
||||||
# CONFIG_CRYPTO_LZO is not set
|
# CONFIG_CRYPTO_LZO is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -2467,11 +2542,13 @@ CONFIG_CRYPTO_HW=y
|
||||||
# CONFIG_CRYPTO_DEV_GEODE is not set
|
# CONFIG_CRYPTO_DEV_GEODE is not set
|
||||||
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
|
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
|
||||||
CONFIG_HAVE_KVM=y
|
CONFIG_HAVE_KVM=y
|
||||||
|
CONFIG_HAVE_KVM_IRQCHIP=y
|
||||||
CONFIG_VIRTUALIZATION=y
|
CONFIG_VIRTUALIZATION=y
|
||||||
# CONFIG_KVM is not set
|
# CONFIG_KVM is not set
|
||||||
# CONFIG_LGUEST is not set
|
# CONFIG_LGUEST is not set
|
||||||
# CONFIG_VIRTIO_PCI is not set
|
# CONFIG_VIRTIO_PCI is not set
|
||||||
# CONFIG_VIRTIO_BALLOON is not set
|
# CONFIG_VIRTIO_BALLOON is not set
|
||||||
|
CONFIG_BINARY_PRINTF=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Library routines
|
# Library routines
|
||||||
|
@ -2489,7 +2566,10 @@ CONFIG_CRC32=y
|
||||||
# CONFIG_LIBCRC32C is not set
|
# CONFIG_LIBCRC32C is not set
|
||||||
CONFIG_AUDIT_GENERIC=y
|
CONFIG_AUDIT_GENERIC=y
|
||||||
CONFIG_ZLIB_INFLATE=y
|
CONFIG_ZLIB_INFLATE=y
|
||||||
CONFIG_PLIST=y
|
CONFIG_DECOMPRESS_GZIP=y
|
||||||
|
CONFIG_DECOMPRESS_BZIP2=y
|
||||||
|
CONFIG_DECOMPRESS_LZMA=y
|
||||||
CONFIG_HAS_IOMEM=y
|
CONFIG_HAS_IOMEM=y
|
||||||
CONFIG_HAS_IOPORT=y
|
CONFIG_HAS_IOPORT=y
|
||||||
CONFIG_HAS_DMA=y
|
CONFIG_HAS_DMA=y
|
||||||
|
CONFIG_NLATTR=y
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#
|
#
|
||||||
# Automatically generated make config: don't edit
|
# Automatically generated make config: don't edit
|
||||||
# Linux kernel version: 2.6.29-rc4
|
# Linux kernel version: 2.6.30-rc2
|
||||||
# Tue Feb 24 15:44:16 2009
|
# Mon May 11 16:22:00 2009
|
||||||
#
|
#
|
||||||
CONFIG_64BIT=y
|
CONFIG_64BIT=y
|
||||||
# CONFIG_X86_32 is not set
|
# CONFIG_X86_32 is not set
|
||||||
CONFIG_X86_64=y
|
CONFIG_X86_64=y
|
||||||
CONFIG_X86=y
|
CONFIG_X86=y
|
||||||
|
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
|
||||||
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
|
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
|
||||||
CONFIG_GENERIC_TIME=y
|
CONFIG_GENERIC_TIME=y
|
||||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||||
|
@ -34,6 +35,7 @@ CONFIG_ARCH_HAS_CPU_RELAX=y
|
||||||
CONFIG_ARCH_HAS_DEFAULT_IDLE=y
|
CONFIG_ARCH_HAS_DEFAULT_IDLE=y
|
||||||
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
|
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
|
||||||
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
|
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
|
||||||
|
CONFIG_HAVE_DYNAMIC_PER_CPU_AREA=y
|
||||||
CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y
|
CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y
|
||||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||||
|
@ -41,14 +43,14 @@ CONFIG_ZONE_DMA32=y
|
||||||
CONFIG_ARCH_POPULATES_NODE_MAP=y
|
CONFIG_ARCH_POPULATES_NODE_MAP=y
|
||||||
CONFIG_AUDIT_ARCH=y
|
CONFIG_AUDIT_ARCH=y
|
||||||
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
|
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
|
||||||
|
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
|
||||||
CONFIG_GENERIC_HARDIRQS=y
|
CONFIG_GENERIC_HARDIRQS=y
|
||||||
|
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
|
||||||
CONFIG_GENERIC_IRQ_PROBE=y
|
CONFIG_GENERIC_IRQ_PROBE=y
|
||||||
CONFIG_GENERIC_PENDING_IRQ=y
|
CONFIG_GENERIC_PENDING_IRQ=y
|
||||||
CONFIG_X86_SMP=y
|
|
||||||
CONFIG_USE_GENERIC_SMP_HELPERS=y
|
CONFIG_USE_GENERIC_SMP_HELPERS=y
|
||||||
CONFIG_X86_64_SMP=y
|
CONFIG_X86_64_SMP=y
|
||||||
CONFIG_X86_HT=y
|
CONFIG_X86_HT=y
|
||||||
CONFIG_X86_BIOS_REBOOT=y
|
|
||||||
CONFIG_X86_TRAMPOLINE=y
|
CONFIG_X86_TRAMPOLINE=y
|
||||||
# CONFIG_KTIME_SCALAR is not set
|
# CONFIG_KTIME_SCALAR is not set
|
||||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||||
|
@ -61,10 +63,17 @@ CONFIG_LOCK_KERNEL=y
|
||||||
CONFIG_INIT_ENV_ARG_LIMIT=32
|
CONFIG_INIT_ENV_ARG_LIMIT=32
|
||||||
CONFIG_LOCALVERSION=""
|
CONFIG_LOCALVERSION=""
|
||||||
# CONFIG_LOCALVERSION_AUTO is not set
|
# CONFIG_LOCALVERSION_AUTO is not set
|
||||||
|
CONFIG_HAVE_KERNEL_GZIP=y
|
||||||
|
CONFIG_HAVE_KERNEL_BZIP2=y
|
||||||
|
CONFIG_HAVE_KERNEL_LZMA=y
|
||||||
|
CONFIG_KERNEL_GZIP=y
|
||||||
|
# CONFIG_KERNEL_BZIP2 is not set
|
||||||
|
# CONFIG_KERNEL_LZMA is not set
|
||||||
CONFIG_SWAP=y
|
CONFIG_SWAP=y
|
||||||
CONFIG_SYSVIPC=y
|
CONFIG_SYSVIPC=y
|
||||||
CONFIG_SYSVIPC_SYSCTL=y
|
CONFIG_SYSVIPC_SYSCTL=y
|
||||||
CONFIG_POSIX_MQUEUE=y
|
CONFIG_POSIX_MQUEUE=y
|
||||||
|
CONFIG_POSIX_MQUEUE_SYSCTL=y
|
||||||
CONFIG_BSD_PROCESS_ACCT=y
|
CONFIG_BSD_PROCESS_ACCT=y
|
||||||
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
|
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
|
||||||
CONFIG_TASKSTATS=y
|
CONFIG_TASKSTATS=y
|
||||||
|
@ -114,23 +123,26 @@ CONFIG_PID_NS=y
|
||||||
CONFIG_NET_NS=y
|
CONFIG_NET_NS=y
|
||||||
CONFIG_BLK_DEV_INITRD=y
|
CONFIG_BLK_DEV_INITRD=y
|
||||||
CONFIG_INITRAMFS_SOURCE=""
|
CONFIG_INITRAMFS_SOURCE=""
|
||||||
|
CONFIG_RD_GZIP=y
|
||||||
|
CONFIG_RD_BZIP2=y
|
||||||
|
CONFIG_RD_LZMA=y
|
||||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||||
CONFIG_SYSCTL=y
|
CONFIG_SYSCTL=y
|
||||||
|
CONFIG_ANON_INODES=y
|
||||||
# CONFIG_EMBEDDED is not set
|
# CONFIG_EMBEDDED is not set
|
||||||
CONFIG_UID16=y
|
CONFIG_UID16=y
|
||||||
CONFIG_SYSCTL_SYSCALL=y
|
CONFIG_SYSCTL_SYSCALL=y
|
||||||
CONFIG_KALLSYMS=y
|
CONFIG_KALLSYMS=y
|
||||||
CONFIG_KALLSYMS_ALL=y
|
CONFIG_KALLSYMS_ALL=y
|
||||||
CONFIG_KALLSYMS_EXTRA_PASS=y
|
CONFIG_KALLSYMS_EXTRA_PASS=y
|
||||||
|
# CONFIG_STRIP_ASM_SYMS is not set
|
||||||
CONFIG_HOTPLUG=y
|
CONFIG_HOTPLUG=y
|
||||||
CONFIG_PRINTK=y
|
CONFIG_PRINTK=y
|
||||||
CONFIG_BUG=y
|
CONFIG_BUG=y
|
||||||
CONFIG_ELF_CORE=y
|
CONFIG_ELF_CORE=y
|
||||||
CONFIG_PCSPKR_PLATFORM=y
|
CONFIG_PCSPKR_PLATFORM=y
|
||||||
# CONFIG_COMPAT_BRK is not set
|
|
||||||
CONFIG_BASE_FULL=y
|
CONFIG_BASE_FULL=y
|
||||||
CONFIG_FUTEX=y
|
CONFIG_FUTEX=y
|
||||||
CONFIG_ANON_INODES=y
|
|
||||||
CONFIG_EPOLL=y
|
CONFIG_EPOLL=y
|
||||||
CONFIG_SIGNALFD=y
|
CONFIG_SIGNALFD=y
|
||||||
CONFIG_TIMERFD=y
|
CONFIG_TIMERFD=y
|
||||||
|
@ -140,6 +152,7 @@ CONFIG_AIO=y
|
||||||
CONFIG_VM_EVENT_COUNTERS=y
|
CONFIG_VM_EVENT_COUNTERS=y
|
||||||
CONFIG_PCI_QUIRKS=y
|
CONFIG_PCI_QUIRKS=y
|
||||||
CONFIG_SLUB_DEBUG=y
|
CONFIG_SLUB_DEBUG=y
|
||||||
|
# CONFIG_COMPAT_BRK is not set
|
||||||
# CONFIG_SLAB is not set
|
# CONFIG_SLAB is not set
|
||||||
CONFIG_SLUB=y
|
CONFIG_SLUB=y
|
||||||
# CONFIG_SLOB is not set
|
# CONFIG_SLOB is not set
|
||||||
|
@ -155,6 +168,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
|
||||||
CONFIG_HAVE_KPROBES=y
|
CONFIG_HAVE_KPROBES=y
|
||||||
CONFIG_HAVE_KRETPROBES=y
|
CONFIG_HAVE_KRETPROBES=y
|
||||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||||
|
CONFIG_HAVE_DMA_API_DEBUG=y
|
||||||
|
# CONFIG_SLOW_WORK is not set
|
||||||
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
|
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
|
||||||
CONFIG_SLABINFO=y
|
CONFIG_SLABINFO=y
|
||||||
CONFIG_RT_MUTEXES=y
|
CONFIG_RT_MUTEXES=y
|
||||||
|
@ -167,7 +182,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
|
||||||
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||||
CONFIG_STOP_MACHINE=y
|
CONFIG_STOP_MACHINE=y
|
||||||
CONFIG_BLOCK=y
|
CONFIG_BLOCK=y
|
||||||
CONFIG_BLK_DEV_IO_TRACE=y
|
|
||||||
CONFIG_BLK_DEV_BSG=y
|
CONFIG_BLK_DEV_BSG=y
|
||||||
# CONFIG_BLK_DEV_INTEGRITY is not set
|
# CONFIG_BLK_DEV_INTEGRITY is not set
|
||||||
CONFIG_BLOCK_COMPAT=y
|
CONFIG_BLOCK_COMPAT=y
|
||||||
|
@ -195,12 +209,10 @@ CONFIG_HIGH_RES_TIMERS=y
|
||||||
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
||||||
CONFIG_SMP=y
|
CONFIG_SMP=y
|
||||||
CONFIG_SPARSE_IRQ=y
|
CONFIG_SPARSE_IRQ=y
|
||||||
# CONFIG_NUMA_MIGRATE_IRQ_DESC is not set
|
|
||||||
CONFIG_X86_FIND_SMP_CONFIG=y
|
|
||||||
CONFIG_X86_MPPARSE=y
|
CONFIG_X86_MPPARSE=y
|
||||||
# CONFIG_X86_ELAN is not set
|
CONFIG_X86_EXTENDED_PLATFORM=y
|
||||||
# CONFIG_X86_GENERICARCH is not set
|
|
||||||
# CONFIG_X86_VSMP is not set
|
# CONFIG_X86_VSMP is not set
|
||||||
|
# CONFIG_X86_UV is not set
|
||||||
CONFIG_SCHED_OMIT_FRAME_POINTER=y
|
CONFIG_SCHED_OMIT_FRAME_POINTER=y
|
||||||
# CONFIG_PARAVIRT_GUEST is not set
|
# CONFIG_PARAVIRT_GUEST is not set
|
||||||
# CONFIG_MEMTEST is not set
|
# CONFIG_MEMTEST is not set
|
||||||
|
@ -230,10 +242,10 @@ CONFIG_SCHED_OMIT_FRAME_POINTER=y
|
||||||
# CONFIG_MCORE2 is not set
|
# CONFIG_MCORE2 is not set
|
||||||
CONFIG_GENERIC_CPU=y
|
CONFIG_GENERIC_CPU=y
|
||||||
CONFIG_X86_CPU=y
|
CONFIG_X86_CPU=y
|
||||||
CONFIG_X86_L1_CACHE_BYTES=128
|
CONFIG_X86_L1_CACHE_BYTES=64
|
||||||
CONFIG_X86_INTERNODE_CACHE_BYTES=128
|
CONFIG_X86_INTERNODE_CACHE_BYTES=64
|
||||||
CONFIG_X86_CMPXCHG=y
|
CONFIG_X86_CMPXCHG=y
|
||||||
CONFIG_X86_L1_CACHE_SHIFT=7
|
CONFIG_X86_L1_CACHE_SHIFT=6
|
||||||
CONFIG_X86_WP_WORKS_OK=y
|
CONFIG_X86_WP_WORKS_OK=y
|
||||||
CONFIG_X86_TSC=y
|
CONFIG_X86_TSC=y
|
||||||
CONFIG_X86_CMPXCHG64=y
|
CONFIG_X86_CMPXCHG64=y
|
||||||
|
@ -242,7 +254,7 @@ CONFIG_X86_MINIMUM_CPU_FAMILY=64
|
||||||
CONFIG_X86_DEBUGCTLMSR=y
|
CONFIG_X86_DEBUGCTLMSR=y
|
||||||
CONFIG_CPU_SUP_INTEL=y
|
CONFIG_CPU_SUP_INTEL=y
|
||||||
CONFIG_CPU_SUP_AMD=y
|
CONFIG_CPU_SUP_AMD=y
|
||||||
CONFIG_CPU_SUP_CENTAUR_64=y
|
CONFIG_CPU_SUP_CENTAUR=y
|
||||||
CONFIG_X86_DS=y
|
CONFIG_X86_DS=y
|
||||||
CONFIG_X86_PTRACE_BTS=y
|
CONFIG_X86_PTRACE_BTS=y
|
||||||
CONFIG_HPET_TIMER=y
|
CONFIG_HPET_TIMER=y
|
||||||
|
@ -269,6 +281,7 @@ CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
|
||||||
CONFIG_X86_MCE=y
|
CONFIG_X86_MCE=y
|
||||||
CONFIG_X86_MCE_INTEL=y
|
CONFIG_X86_MCE_INTEL=y
|
||||||
CONFIG_X86_MCE_AMD=y
|
CONFIG_X86_MCE_AMD=y
|
||||||
|
CONFIG_X86_MCE_THRESHOLD=y
|
||||||
# CONFIG_I8K is not set
|
# CONFIG_I8K is not set
|
||||||
CONFIG_MICROCODE=y
|
CONFIG_MICROCODE=y
|
||||||
CONFIG_MICROCODE_INTEL=y
|
CONFIG_MICROCODE_INTEL=y
|
||||||
|
@ -276,6 +289,7 @@ CONFIG_MICROCODE_AMD=y
|
||||||
CONFIG_MICROCODE_OLD_INTERFACE=y
|
CONFIG_MICROCODE_OLD_INTERFACE=y
|
||||||
CONFIG_X86_MSR=y
|
CONFIG_X86_MSR=y
|
||||||
CONFIG_X86_CPUID=y
|
CONFIG_X86_CPUID=y
|
||||||
|
# CONFIG_X86_CPU_DEBUG is not set
|
||||||
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
|
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
|
||||||
CONFIG_DIRECT_GBPAGES=y
|
CONFIG_DIRECT_GBPAGES=y
|
||||||
CONFIG_NUMA=y
|
CONFIG_NUMA=y
|
||||||
|
@ -309,6 +323,8 @@ CONFIG_ZONE_DMA_FLAG=1
|
||||||
CONFIG_BOUNCE=y
|
CONFIG_BOUNCE=y
|
||||||
CONFIG_VIRT_TO_BUS=y
|
CONFIG_VIRT_TO_BUS=y
|
||||||
CONFIG_UNEVICTABLE_LRU=y
|
CONFIG_UNEVICTABLE_LRU=y
|
||||||
|
CONFIG_HAVE_MLOCK=y
|
||||||
|
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
|
||||||
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
|
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
|
||||||
CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
|
CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
|
||||||
CONFIG_X86_RESERVE_LOW_64K=y
|
CONFIG_X86_RESERVE_LOW_64K=y
|
||||||
|
@ -317,6 +333,7 @@ CONFIG_MTRR=y
|
||||||
CONFIG_X86_PAT=y
|
CONFIG_X86_PAT=y
|
||||||
CONFIG_EFI=y
|
CONFIG_EFI=y
|
||||||
CONFIG_SECCOMP=y
|
CONFIG_SECCOMP=y
|
||||||
|
# CONFIG_CC_STACKPROTECTOR is not set
|
||||||
# CONFIG_HZ_100 is not set
|
# CONFIG_HZ_100 is not set
|
||||||
# CONFIG_HZ_250 is not set
|
# CONFIG_HZ_250 is not set
|
||||||
# CONFIG_HZ_300 is not set
|
# CONFIG_HZ_300 is not set
|
||||||
|
@ -325,9 +342,10 @@ CONFIG_HZ=1000
|
||||||
CONFIG_SCHED_HRTICK=y
|
CONFIG_SCHED_HRTICK=y
|
||||||
CONFIG_KEXEC=y
|
CONFIG_KEXEC=y
|
||||||
CONFIG_CRASH_DUMP=y
|
CONFIG_CRASH_DUMP=y
|
||||||
|
# CONFIG_KEXEC_JUMP is not set
|
||||||
CONFIG_PHYSICAL_START=0x1000000
|
CONFIG_PHYSICAL_START=0x1000000
|
||||||
# CONFIG_RELOCATABLE is not set
|
CONFIG_RELOCATABLE=y
|
||||||
CONFIG_PHYSICAL_ALIGN=0x200000
|
CONFIG_PHYSICAL_ALIGN=0x1000000
|
||||||
CONFIG_HOTPLUG_CPU=y
|
CONFIG_HOTPLUG_CPU=y
|
||||||
# CONFIG_COMPAT_VDSO is not set
|
# CONFIG_COMPAT_VDSO is not set
|
||||||
# CONFIG_CMDLINE_BOOL is not set
|
# CONFIG_CMDLINE_BOOL is not set
|
||||||
|
@ -370,7 +388,6 @@ CONFIG_ACPI_NUMA=y
|
||||||
CONFIG_ACPI_BLACKLIST_YEAR=0
|
CONFIG_ACPI_BLACKLIST_YEAR=0
|
||||||
# CONFIG_ACPI_DEBUG is not set
|
# CONFIG_ACPI_DEBUG is not set
|
||||||
# CONFIG_ACPI_PCI_SLOT is not set
|
# CONFIG_ACPI_PCI_SLOT is not set
|
||||||
CONFIG_ACPI_SYSTEM=y
|
|
||||||
CONFIG_X86_PM_TIMER=y
|
CONFIG_X86_PM_TIMER=y
|
||||||
CONFIG_ACPI_CONTAINER=y
|
CONFIG_ACPI_CONTAINER=y
|
||||||
# CONFIG_ACPI_SBS is not set
|
# CONFIG_ACPI_SBS is not set
|
||||||
|
@ -436,6 +453,7 @@ CONFIG_PCI_MSI=y
|
||||||
# CONFIG_PCI_DEBUG is not set
|
# CONFIG_PCI_DEBUG is not set
|
||||||
# CONFIG_PCI_STUB is not set
|
# CONFIG_PCI_STUB is not set
|
||||||
CONFIG_HT_IRQ=y
|
CONFIG_HT_IRQ=y
|
||||||
|
# CONFIG_PCI_IOV is not set
|
||||||
CONFIG_ISA_DMA_API=y
|
CONFIG_ISA_DMA_API=y
|
||||||
CONFIG_K8_NB=y
|
CONFIG_K8_NB=y
|
||||||
CONFIG_PCCARD=y
|
CONFIG_PCCARD=y
|
||||||
|
@ -481,7 +499,6 @@ CONFIG_NET=y
|
||||||
#
|
#
|
||||||
# Networking options
|
# Networking options
|
||||||
#
|
#
|
||||||
CONFIG_COMPAT_NET_DEV_OPS=y
|
|
||||||
CONFIG_PACKET=y
|
CONFIG_PACKET=y
|
||||||
CONFIG_PACKET_MMAP=y
|
CONFIG_PACKET_MMAP=y
|
||||||
CONFIG_UNIX=y
|
CONFIG_UNIX=y
|
||||||
|
@ -639,6 +656,7 @@ CONFIG_LLC=y
|
||||||
# CONFIG_LAPB is not set
|
# CONFIG_LAPB is not set
|
||||||
# CONFIG_ECONET is not set
|
# CONFIG_ECONET is not set
|
||||||
# CONFIG_WAN_ROUTER is not set
|
# CONFIG_WAN_ROUTER is not set
|
||||||
|
# CONFIG_PHONET is not set
|
||||||
CONFIG_NET_SCHED=y
|
CONFIG_NET_SCHED=y
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -696,6 +714,7 @@ CONFIG_NET_SCH_FIFO=y
|
||||||
#
|
#
|
||||||
# CONFIG_NET_PKTGEN is not set
|
# CONFIG_NET_PKTGEN is not set
|
||||||
# CONFIG_NET_TCPPROBE is not set
|
# CONFIG_NET_TCPPROBE is not set
|
||||||
|
# CONFIG_NET_DROP_MONITOR is not set
|
||||||
CONFIG_HAMRADIO=y
|
CONFIG_HAMRADIO=y
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -706,12 +725,10 @@ CONFIG_HAMRADIO=y
|
||||||
# CONFIG_IRDA is not set
|
# CONFIG_IRDA is not set
|
||||||
# CONFIG_BT is not set
|
# CONFIG_BT is not set
|
||||||
# CONFIG_AF_RXRPC is not set
|
# CONFIG_AF_RXRPC is not set
|
||||||
# CONFIG_PHONET is not set
|
|
||||||
CONFIG_FIB_RULES=y
|
CONFIG_FIB_RULES=y
|
||||||
CONFIG_WIRELESS=y
|
CONFIG_WIRELESS=y
|
||||||
CONFIG_CFG80211=y
|
CONFIG_CFG80211=y
|
||||||
# CONFIG_CFG80211_REG_DEBUG is not set
|
# CONFIG_CFG80211_REG_DEBUG is not set
|
||||||
CONFIG_NL80211=y
|
|
||||||
CONFIG_WIRELESS_OLD_REGULATORY=y
|
CONFIG_WIRELESS_OLD_REGULATORY=y
|
||||||
CONFIG_WIRELESS_EXT=y
|
CONFIG_WIRELESS_EXT=y
|
||||||
CONFIG_WIRELESS_EXT_SYSFS=y
|
CONFIG_WIRELESS_EXT_SYSFS=y
|
||||||
|
@ -788,9 +805,8 @@ CONFIG_MISC_DEVICES=y
|
||||||
# CONFIG_TIFM_CORE is not set
|
# CONFIG_TIFM_CORE is not set
|
||||||
# CONFIG_ICS932S401 is not set
|
# CONFIG_ICS932S401 is not set
|
||||||
# CONFIG_ENCLOSURE_SERVICES is not set
|
# CONFIG_ENCLOSURE_SERVICES is not set
|
||||||
# CONFIG_SGI_XP is not set
|
|
||||||
# CONFIG_HP_ILO is not set
|
# CONFIG_HP_ILO is not set
|
||||||
# CONFIG_SGI_GRU is not set
|
# CONFIG_ISL29003 is not set
|
||||||
# CONFIG_C2PORT is not set
|
# CONFIG_C2PORT is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -844,6 +860,7 @@ CONFIG_SCSI_SPI_ATTRS=y
|
||||||
# CONFIG_SCSI_LOWLEVEL is not set
|
# CONFIG_SCSI_LOWLEVEL is not set
|
||||||
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
|
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
|
||||||
# CONFIG_SCSI_DH is not set
|
# CONFIG_SCSI_DH is not set
|
||||||
|
# CONFIG_SCSI_OSD_INITIATOR is not set
|
||||||
CONFIG_ATA=y
|
CONFIG_ATA=y
|
||||||
# CONFIG_ATA_NONSTANDARD is not set
|
# CONFIG_ATA_NONSTANDARD is not set
|
||||||
CONFIG_ATA_ACPI=y
|
CONFIG_ATA_ACPI=y
|
||||||
|
@ -940,6 +957,7 @@ CONFIG_DM_ZERO=y
|
||||||
CONFIG_MACINTOSH_DRIVERS=y
|
CONFIG_MACINTOSH_DRIVERS=y
|
||||||
CONFIG_MAC_EMUMOUSEBTN=y
|
CONFIG_MAC_EMUMOUSEBTN=y
|
||||||
CONFIG_NETDEVICES=y
|
CONFIG_NETDEVICES=y
|
||||||
|
CONFIG_COMPAT_NET_DEV_OPS=y
|
||||||
# CONFIG_IFB is not set
|
# CONFIG_IFB is not set
|
||||||
# CONFIG_DUMMY is not set
|
# CONFIG_DUMMY is not set
|
||||||
# CONFIG_BONDING is not set
|
# CONFIG_BONDING is not set
|
||||||
|
@ -977,6 +995,8 @@ CONFIG_MII=y
|
||||||
CONFIG_NET_VENDOR_3COM=y
|
CONFIG_NET_VENDOR_3COM=y
|
||||||
# CONFIG_VORTEX is not set
|
# CONFIG_VORTEX is not set
|
||||||
# CONFIG_TYPHOON is not set
|
# CONFIG_TYPHOON is not set
|
||||||
|
# CONFIG_ETHOC is not set
|
||||||
|
# CONFIG_DNET is not set
|
||||||
CONFIG_NET_TULIP=y
|
CONFIG_NET_TULIP=y
|
||||||
# CONFIG_DE2104X is not set
|
# CONFIG_DE2104X is not set
|
||||||
# CONFIG_TULIP is not set
|
# CONFIG_TULIP is not set
|
||||||
|
@ -1026,6 +1046,7 @@ CONFIG_E1000=y
|
||||||
# CONFIG_E1000E is not set
|
# CONFIG_E1000E is not set
|
||||||
# CONFIG_IP1000 is not set
|
# CONFIG_IP1000 is not set
|
||||||
# CONFIG_IGB is not set
|
# CONFIG_IGB is not set
|
||||||
|
# CONFIG_IGBVF is not set
|
||||||
# CONFIG_NS83820 is not set
|
# CONFIG_NS83820 is not set
|
||||||
# CONFIG_HAMACHI is not set
|
# CONFIG_HAMACHI is not set
|
||||||
# CONFIG_YELLOWFIN is not set
|
# CONFIG_YELLOWFIN is not set
|
||||||
|
@ -1040,6 +1061,7 @@ CONFIG_TIGON3=y
|
||||||
# CONFIG_QLA3XXX is not set
|
# CONFIG_QLA3XXX is not set
|
||||||
# CONFIG_ATL1 is not set
|
# CONFIG_ATL1 is not set
|
||||||
# CONFIG_ATL1E is not set
|
# CONFIG_ATL1E is not set
|
||||||
|
# CONFIG_ATL1C is not set
|
||||||
# CONFIG_JME is not set
|
# CONFIG_JME is not set
|
||||||
CONFIG_NETDEV_10000=y
|
CONFIG_NETDEV_10000=y
|
||||||
# CONFIG_CHELSIO_T1 is not set
|
# CONFIG_CHELSIO_T1 is not set
|
||||||
|
@ -1049,6 +1071,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
|
||||||
# CONFIG_IXGBE is not set
|
# CONFIG_IXGBE is not set
|
||||||
# CONFIG_IXGB is not set
|
# CONFIG_IXGB is not set
|
||||||
# CONFIG_S2IO is not set
|
# CONFIG_S2IO is not set
|
||||||
|
# CONFIG_VXGE is not set
|
||||||
# CONFIG_MYRI10GE is not set
|
# CONFIG_MYRI10GE is not set
|
||||||
# CONFIG_NETXEN_NIC is not set
|
# CONFIG_NETXEN_NIC is not set
|
||||||
# CONFIG_NIU is not set
|
# CONFIG_NIU is not set
|
||||||
|
@ -1058,6 +1081,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
|
||||||
# CONFIG_BNX2X is not set
|
# CONFIG_BNX2X is not set
|
||||||
# CONFIG_QLGE is not set
|
# CONFIG_QLGE is not set
|
||||||
# CONFIG_SFC is not set
|
# CONFIG_SFC is not set
|
||||||
|
# CONFIG_BE2NET is not set
|
||||||
CONFIG_TR=y
|
CONFIG_TR=y
|
||||||
# CONFIG_IBMOL is not set
|
# CONFIG_IBMOL is not set
|
||||||
# CONFIG_3C359 is not set
|
# CONFIG_3C359 is not set
|
||||||
|
@ -1072,8 +1096,8 @@ CONFIG_WLAN_80211=y
|
||||||
# CONFIG_LIBERTAS is not set
|
# CONFIG_LIBERTAS is not set
|
||||||
# CONFIG_LIBERTAS_THINFIRM is not set
|
# CONFIG_LIBERTAS_THINFIRM is not set
|
||||||
# CONFIG_AIRO is not set
|
# CONFIG_AIRO is not set
|
||||||
# CONFIG_HERMES is not set
|
|
||||||
# CONFIG_ATMEL is not set
|
# CONFIG_ATMEL is not set
|
||||||
|
# CONFIG_AT76C50X_USB is not set
|
||||||
# CONFIG_AIRO_CS is not set
|
# CONFIG_AIRO_CS is not set
|
||||||
# CONFIG_PCMCIA_WL3501 is not set
|
# CONFIG_PCMCIA_WL3501 is not set
|
||||||
# CONFIG_PRISM54 is not set
|
# CONFIG_PRISM54 is not set
|
||||||
|
@ -1083,21 +1107,21 @@ CONFIG_WLAN_80211=y
|
||||||
# CONFIG_RTL8187 is not set
|
# CONFIG_RTL8187 is not set
|
||||||
# CONFIG_ADM8211 is not set
|
# CONFIG_ADM8211 is not set
|
||||||
# CONFIG_MAC80211_HWSIM is not set
|
# CONFIG_MAC80211_HWSIM is not set
|
||||||
|
# CONFIG_MWL8K is not set
|
||||||
# CONFIG_P54_COMMON is not set
|
# CONFIG_P54_COMMON is not set
|
||||||
CONFIG_ATH5K=y
|
CONFIG_ATH5K=y
|
||||||
# CONFIG_ATH5K_DEBUG is not set
|
# CONFIG_ATH5K_DEBUG is not set
|
||||||
# CONFIG_ATH9K is not set
|
# CONFIG_ATH9K is not set
|
||||||
|
# CONFIG_AR9170_USB is not set
|
||||||
# CONFIG_IPW2100 is not set
|
# CONFIG_IPW2100 is not set
|
||||||
# CONFIG_IPW2200 is not set
|
# CONFIG_IPW2200 is not set
|
||||||
# CONFIG_IWLCORE is not set
|
# CONFIG_IWLWIFI is not set
|
||||||
# CONFIG_IWLWIFI_LEDS is not set
|
|
||||||
# CONFIG_IWLAGN is not set
|
|
||||||
# CONFIG_IWL3945 is not set
|
|
||||||
# CONFIG_HOSTAP is not set
|
# CONFIG_HOSTAP is not set
|
||||||
# CONFIG_B43 is not set
|
# CONFIG_B43 is not set
|
||||||
# CONFIG_B43LEGACY is not set
|
# CONFIG_B43LEGACY is not set
|
||||||
# CONFIG_ZD1211RW is not set
|
# CONFIG_ZD1211RW is not set
|
||||||
# CONFIG_RT2X00 is not set
|
# CONFIG_RT2X00 is not set
|
||||||
|
# CONFIG_HERMES is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Enable WiMAX (Networking options) to see the WiMAX drivers
|
# Enable WiMAX (Networking options) to see the WiMAX drivers
|
||||||
|
@ -1208,6 +1232,8 @@ CONFIG_INPUT_TABLET=y
|
||||||
# CONFIG_TABLET_USB_KBTAB is not set
|
# CONFIG_TABLET_USB_KBTAB is not set
|
||||||
# CONFIG_TABLET_USB_WACOM is not set
|
# CONFIG_TABLET_USB_WACOM is not set
|
||||||
CONFIG_INPUT_TOUCHSCREEN=y
|
CONFIG_INPUT_TOUCHSCREEN=y
|
||||||
|
# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
|
||||||
|
# CONFIG_TOUCHSCREEN_AD7879 is not set
|
||||||
# CONFIG_TOUCHSCREEN_FUJITSU is not set
|
# CONFIG_TOUCHSCREEN_FUJITSU is not set
|
||||||
# CONFIG_TOUCHSCREEN_GUNZE is not set
|
# CONFIG_TOUCHSCREEN_GUNZE is not set
|
||||||
# CONFIG_TOUCHSCREEN_ELO is not set
|
# CONFIG_TOUCHSCREEN_ELO is not set
|
||||||
|
@ -1301,6 +1327,7 @@ CONFIG_UNIX98_PTYS=y
|
||||||
# CONFIG_LEGACY_PTYS is not set
|
# CONFIG_LEGACY_PTYS is not set
|
||||||
# CONFIG_IPMI_HANDLER is not set
|
# CONFIG_IPMI_HANDLER is not set
|
||||||
CONFIG_HW_RANDOM=y
|
CONFIG_HW_RANDOM=y
|
||||||
|
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
|
||||||
# CONFIG_HW_RANDOM_INTEL is not set
|
# CONFIG_HW_RANDOM_INTEL is not set
|
||||||
# CONFIG_HW_RANDOM_AMD is not set
|
# CONFIG_HW_RANDOM_AMD is not set
|
||||||
CONFIG_NVRAM=y
|
CONFIG_NVRAM=y
|
||||||
|
@ -1382,7 +1409,6 @@ CONFIG_I2C_I801=y
|
||||||
# CONFIG_SENSORS_PCF8574 is not set
|
# CONFIG_SENSORS_PCF8574 is not set
|
||||||
# CONFIG_PCF8575 is not set
|
# CONFIG_PCF8575 is not set
|
||||||
# CONFIG_SENSORS_PCA9539 is not set
|
# CONFIG_SENSORS_PCA9539 is not set
|
||||||
# CONFIG_SENSORS_PCF8591 is not set
|
|
||||||
# CONFIG_SENSORS_MAX6875 is not set
|
# CONFIG_SENSORS_MAX6875 is not set
|
||||||
# CONFIG_SENSORS_TSL2550 is not set
|
# CONFIG_SENSORS_TSL2550 is not set
|
||||||
# CONFIG_I2C_DEBUG_CORE is not set
|
# CONFIG_I2C_DEBUG_CORE is not set
|
||||||
|
@ -1416,6 +1442,7 @@ CONFIG_HWMON=y
|
||||||
# CONFIG_SENSORS_ADT7475 is not set
|
# CONFIG_SENSORS_ADT7475 is not set
|
||||||
# CONFIG_SENSORS_K8TEMP is not set
|
# CONFIG_SENSORS_K8TEMP is not set
|
||||||
# CONFIG_SENSORS_ASB100 is not set
|
# CONFIG_SENSORS_ASB100 is not set
|
||||||
|
# CONFIG_SENSORS_ATK0110 is not set
|
||||||
# CONFIG_SENSORS_ATXP1 is not set
|
# CONFIG_SENSORS_ATXP1 is not set
|
||||||
# CONFIG_SENSORS_DS1621 is not set
|
# CONFIG_SENSORS_DS1621 is not set
|
||||||
# CONFIG_SENSORS_I5K_AMB is not set
|
# CONFIG_SENSORS_I5K_AMB is not set
|
||||||
|
@ -1425,6 +1452,7 @@ CONFIG_HWMON=y
|
||||||
# CONFIG_SENSORS_FSCHER is not set
|
# CONFIG_SENSORS_FSCHER is not set
|
||||||
# CONFIG_SENSORS_FSCPOS is not set
|
# CONFIG_SENSORS_FSCPOS is not set
|
||||||
# CONFIG_SENSORS_FSCHMD is not set
|
# CONFIG_SENSORS_FSCHMD is not set
|
||||||
|
# CONFIG_SENSORS_G760A is not set
|
||||||
# CONFIG_SENSORS_GL518SM is not set
|
# CONFIG_SENSORS_GL518SM is not set
|
||||||
# CONFIG_SENSORS_GL520SM is not set
|
# CONFIG_SENSORS_GL520SM is not set
|
||||||
# CONFIG_SENSORS_CORETEMP is not set
|
# CONFIG_SENSORS_CORETEMP is not set
|
||||||
|
@ -1440,11 +1468,14 @@ CONFIG_HWMON=y
|
||||||
# CONFIG_SENSORS_LM90 is not set
|
# CONFIG_SENSORS_LM90 is not set
|
||||||
# CONFIG_SENSORS_LM92 is not set
|
# CONFIG_SENSORS_LM92 is not set
|
||||||
# CONFIG_SENSORS_LM93 is not set
|
# CONFIG_SENSORS_LM93 is not set
|
||||||
|
# CONFIG_SENSORS_LTC4215 is not set
|
||||||
# CONFIG_SENSORS_LTC4245 is not set
|
# CONFIG_SENSORS_LTC4245 is not set
|
||||||
|
# CONFIG_SENSORS_LM95241 is not set
|
||||||
# CONFIG_SENSORS_MAX1619 is not set
|
# CONFIG_SENSORS_MAX1619 is not set
|
||||||
# CONFIG_SENSORS_MAX6650 is not set
|
# CONFIG_SENSORS_MAX6650 is not set
|
||||||
# CONFIG_SENSORS_PC87360 is not set
|
# CONFIG_SENSORS_PC87360 is not set
|
||||||
# CONFIG_SENSORS_PC87427 is not set
|
# CONFIG_SENSORS_PC87427 is not set
|
||||||
|
# CONFIG_SENSORS_PCF8591 is not set
|
||||||
# CONFIG_SENSORS_SIS5595 is not set
|
# CONFIG_SENSORS_SIS5595 is not set
|
||||||
# CONFIG_SENSORS_DME1737 is not set
|
# CONFIG_SENSORS_DME1737 is not set
|
||||||
# CONFIG_SENSORS_SMSC47M1 is not set
|
# CONFIG_SENSORS_SMSC47M1 is not set
|
||||||
|
@ -1635,6 +1666,7 @@ CONFIG_FB_EFI=y
|
||||||
# CONFIG_FB_VIRTUAL is not set
|
# CONFIG_FB_VIRTUAL is not set
|
||||||
# CONFIG_FB_METRONOME is not set
|
# CONFIG_FB_METRONOME is not set
|
||||||
# CONFIG_FB_MB862XX is not set
|
# CONFIG_FB_MB862XX is not set
|
||||||
|
# CONFIG_FB_BROADSHEET is not set
|
||||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||||
# CONFIG_LCD_CLASS_DEVICE is not set
|
# CONFIG_LCD_CLASS_DEVICE is not set
|
||||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||||
|
@ -1720,6 +1752,8 @@ CONFIG_SND_PCI=y
|
||||||
# CONFIG_SND_INDIGO is not set
|
# CONFIG_SND_INDIGO is not set
|
||||||
# CONFIG_SND_INDIGOIO is not set
|
# CONFIG_SND_INDIGOIO is not set
|
||||||
# CONFIG_SND_INDIGODJ is not set
|
# CONFIG_SND_INDIGODJ is not set
|
||||||
|
# CONFIG_SND_INDIGOIOX is not set
|
||||||
|
# CONFIG_SND_INDIGODJX is not set
|
||||||
# CONFIG_SND_EMU10K1 is not set
|
# CONFIG_SND_EMU10K1 is not set
|
||||||
# CONFIG_SND_EMU10K1X is not set
|
# CONFIG_SND_EMU10K1X is not set
|
||||||
# CONFIG_SND_ENS1370 is not set
|
# CONFIG_SND_ENS1370 is not set
|
||||||
|
@ -1792,15 +1826,17 @@ CONFIG_USB_HIDDEV=y
|
||||||
#
|
#
|
||||||
# Special HID drivers
|
# Special HID drivers
|
||||||
#
|
#
|
||||||
CONFIG_HID_COMPAT=y
|
|
||||||
CONFIG_HID_A4TECH=y
|
CONFIG_HID_A4TECH=y
|
||||||
CONFIG_HID_APPLE=y
|
CONFIG_HID_APPLE=y
|
||||||
CONFIG_HID_BELKIN=y
|
CONFIG_HID_BELKIN=y
|
||||||
CONFIG_HID_CHERRY=y
|
CONFIG_HID_CHERRY=y
|
||||||
CONFIG_HID_CHICONY=y
|
CONFIG_HID_CHICONY=y
|
||||||
CONFIG_HID_CYPRESS=y
|
CONFIG_HID_CYPRESS=y
|
||||||
|
# CONFIG_DRAGONRISE_FF is not set
|
||||||
CONFIG_HID_EZKEY=y
|
CONFIG_HID_EZKEY=y
|
||||||
|
CONFIG_HID_KYE=y
|
||||||
CONFIG_HID_GYRATION=y
|
CONFIG_HID_GYRATION=y
|
||||||
|
CONFIG_HID_KENSINGTON=y
|
||||||
CONFIG_HID_LOGITECH=y
|
CONFIG_HID_LOGITECH=y
|
||||||
CONFIG_LOGITECH_FF=y
|
CONFIG_LOGITECH_FF=y
|
||||||
# CONFIG_LOGIRUMBLEPAD2_FF is not set
|
# CONFIG_LOGIRUMBLEPAD2_FF is not set
|
||||||
|
@ -1866,11 +1902,11 @@ CONFIG_USB_PRINTER=y
|
||||||
# CONFIG_USB_TMC is not set
|
# CONFIG_USB_TMC is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
|
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
|
||||||
#
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# see USB_STORAGE Help for more information
|
# also be needed; see USB_STORAGE Help for more info
|
||||||
#
|
#
|
||||||
CONFIG_USB_STORAGE=y
|
CONFIG_USB_STORAGE=y
|
||||||
# CONFIG_USB_STORAGE_DEBUG is not set
|
# CONFIG_USB_STORAGE_DEBUG is not set
|
||||||
|
@ -1912,7 +1948,6 @@ CONFIG_USB_LIBUSUAL=y
|
||||||
# CONFIG_USB_LED is not set
|
# CONFIG_USB_LED is not set
|
||||||
# CONFIG_USB_CYPRESS_CY7C63 is not set
|
# CONFIG_USB_CYPRESS_CY7C63 is not set
|
||||||
# CONFIG_USB_CYTHERM is not set
|
# CONFIG_USB_CYTHERM is not set
|
||||||
# CONFIG_USB_PHIDGET is not set
|
|
||||||
# CONFIG_USB_IDMOUSE is not set
|
# CONFIG_USB_IDMOUSE is not set
|
||||||
# CONFIG_USB_FTDI_ELAN is not set
|
# CONFIG_USB_FTDI_ELAN is not set
|
||||||
# CONFIG_USB_APPLEDISPLAY is not set
|
# CONFIG_USB_APPLEDISPLAY is not set
|
||||||
|
@ -1928,6 +1963,7 @@ CONFIG_USB_LIBUSUAL=y
|
||||||
#
|
#
|
||||||
# OTG and related infrastructure
|
# OTG and related infrastructure
|
||||||
#
|
#
|
||||||
|
# CONFIG_NOP_USB_XCEIV is not set
|
||||||
# CONFIG_UWB is not set
|
# CONFIG_UWB is not set
|
||||||
# CONFIG_MMC is not set
|
# CONFIG_MMC is not set
|
||||||
# CONFIG_MEMSTICK is not set
|
# CONFIG_MEMSTICK is not set
|
||||||
|
@ -1939,8 +1975,10 @@ CONFIG_LEDS_CLASS=y
|
||||||
#
|
#
|
||||||
# CONFIG_LEDS_ALIX2 is not set
|
# CONFIG_LEDS_ALIX2 is not set
|
||||||
# CONFIG_LEDS_PCA9532 is not set
|
# CONFIG_LEDS_PCA9532 is not set
|
||||||
|
# CONFIG_LEDS_LP5521 is not set
|
||||||
# CONFIG_LEDS_CLEVO_MAIL is not set
|
# CONFIG_LEDS_CLEVO_MAIL is not set
|
||||||
# CONFIG_LEDS_PCA955X is not set
|
# CONFIG_LEDS_PCA955X is not set
|
||||||
|
# CONFIG_LEDS_BD2802 is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# LED Triggers
|
# LED Triggers
|
||||||
|
@ -1950,6 +1988,10 @@ CONFIG_LEDS_TRIGGERS=y
|
||||||
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
|
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
|
||||||
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
|
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
|
||||||
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
|
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# iptables trigger is under Netfilter config (LED target)
|
||||||
|
#
|
||||||
# CONFIG_ACCESSIBILITY is not set
|
# CONFIG_ACCESSIBILITY is not set
|
||||||
# CONFIG_INFINIBAND is not set
|
# CONFIG_INFINIBAND is not set
|
||||||
CONFIG_EDAC=y
|
CONFIG_EDAC=y
|
||||||
|
@ -2018,6 +2060,7 @@ CONFIG_DMADEVICES=y
|
||||||
# DMA Devices
|
# DMA Devices
|
||||||
#
|
#
|
||||||
# CONFIG_INTEL_IOATDMA is not set
|
# CONFIG_INTEL_IOATDMA is not set
|
||||||
|
# CONFIG_AUXDISPLAY is not set
|
||||||
# CONFIG_UIO is not set
|
# CONFIG_UIO is not set
|
||||||
# CONFIG_STAGING is not set
|
# CONFIG_STAGING is not set
|
||||||
CONFIG_X86_PLATFORM_DEVICES=y
|
CONFIG_X86_PLATFORM_DEVICES=y
|
||||||
|
@ -2051,6 +2094,7 @@ CONFIG_DMIID=y
|
||||||
#
|
#
|
||||||
# CONFIG_EXT2_FS is not set
|
# CONFIG_EXT2_FS is not set
|
||||||
CONFIG_EXT3_FS=y
|
CONFIG_EXT3_FS=y
|
||||||
|
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
|
||||||
CONFIG_EXT3_FS_XATTR=y
|
CONFIG_EXT3_FS_XATTR=y
|
||||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||||
CONFIG_EXT3_FS_SECURITY=y
|
CONFIG_EXT3_FS_SECURITY=y
|
||||||
|
@ -2081,6 +2125,11 @@ CONFIG_AUTOFS4_FS=y
|
||||||
# CONFIG_FUSE_FS is not set
|
# CONFIG_FUSE_FS is not set
|
||||||
CONFIG_GENERIC_ACL=y
|
CONFIG_GENERIC_ACL=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# Caches
|
||||||
|
#
|
||||||
|
# CONFIG_FSCACHE is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# CD-ROM/DVD Filesystems
|
# CD-ROM/DVD Filesystems
|
||||||
#
|
#
|
||||||
|
@ -2132,6 +2181,7 @@ CONFIG_MISC_FILESYSTEMS=y
|
||||||
# CONFIG_ROMFS_FS is not set
|
# CONFIG_ROMFS_FS is not set
|
||||||
# CONFIG_SYSV_FS is not set
|
# CONFIG_SYSV_FS is not set
|
||||||
# CONFIG_UFS_FS is not set
|
# CONFIG_UFS_FS is not set
|
||||||
|
# CONFIG_NILFS2_FS is not set
|
||||||
CONFIG_NETWORK_FILESYSTEMS=y
|
CONFIG_NETWORK_FILESYSTEMS=y
|
||||||
CONFIG_NFS_FS=y
|
CONFIG_NFS_FS=y
|
||||||
CONFIG_NFS_V3=y
|
CONFIG_NFS_V3=y
|
||||||
|
@ -2145,7 +2195,6 @@ CONFIG_NFS_ACL_SUPPORT=y
|
||||||
CONFIG_NFS_COMMON=y
|
CONFIG_NFS_COMMON=y
|
||||||
CONFIG_SUNRPC=y
|
CONFIG_SUNRPC=y
|
||||||
CONFIG_SUNRPC_GSS=y
|
CONFIG_SUNRPC_GSS=y
|
||||||
# CONFIG_SUNRPC_REGISTER_V4 is not set
|
|
||||||
CONFIG_RPCSEC_GSS_KRB5=y
|
CONFIG_RPCSEC_GSS_KRB5=y
|
||||||
# CONFIG_RPCSEC_GSS_SPKM3 is not set
|
# CONFIG_RPCSEC_GSS_SPKM3 is not set
|
||||||
# CONFIG_SMB_FS is not set
|
# CONFIG_SMB_FS is not set
|
||||||
|
@ -2232,6 +2281,7 @@ CONFIG_DEBUG_FS=y
|
||||||
CONFIG_DEBUG_KERNEL=y
|
CONFIG_DEBUG_KERNEL=y
|
||||||
# CONFIG_DEBUG_SHIRQ is not set
|
# CONFIG_DEBUG_SHIRQ is not set
|
||||||
# CONFIG_DETECT_SOFTLOCKUP is not set
|
# CONFIG_DETECT_SOFTLOCKUP is not set
|
||||||
|
# CONFIG_DETECT_HUNG_TASK is not set
|
||||||
# CONFIG_SCHED_DEBUG is not set
|
# CONFIG_SCHED_DEBUG is not set
|
||||||
CONFIG_SCHEDSTATS=y
|
CONFIG_SCHEDSTATS=y
|
||||||
CONFIG_TIMER_STATS=y
|
CONFIG_TIMER_STATS=y
|
||||||
|
@ -2247,6 +2297,7 @@ CONFIG_TIMER_STATS=y
|
||||||
# CONFIG_LOCK_STAT is not set
|
# CONFIG_LOCK_STAT is not set
|
||||||
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
|
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
|
||||||
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
|
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
|
||||||
|
CONFIG_STACKTRACE=y
|
||||||
# CONFIG_DEBUG_KOBJECT is not set
|
# CONFIG_DEBUG_KOBJECT is not set
|
||||||
CONFIG_DEBUG_BUGVERBOSE=y
|
CONFIG_DEBUG_BUGVERBOSE=y
|
||||||
# CONFIG_DEBUG_INFO is not set
|
# CONFIG_DEBUG_INFO is not set
|
||||||
|
@ -2269,13 +2320,19 @@ CONFIG_FRAME_POINTER=y
|
||||||
# CONFIG_FAULT_INJECTION is not set
|
# CONFIG_FAULT_INJECTION is not set
|
||||||
# CONFIG_LATENCYTOP is not set
|
# CONFIG_LATENCYTOP is not set
|
||||||
CONFIG_SYSCTL_SYSCALL_CHECK=y
|
CONFIG_SYSCTL_SYSCALL_CHECK=y
|
||||||
|
# CONFIG_DEBUG_PAGEALLOC is not set
|
||||||
CONFIG_USER_STACKTRACE_SUPPORT=y
|
CONFIG_USER_STACKTRACE_SUPPORT=y
|
||||||
|
CONFIG_NOP_TRACER=y
|
||||||
CONFIG_HAVE_FUNCTION_TRACER=y
|
CONFIG_HAVE_FUNCTION_TRACER=y
|
||||||
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
|
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
|
||||||
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
|
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
|
||||||
CONFIG_HAVE_DYNAMIC_FTRACE=y
|
CONFIG_HAVE_DYNAMIC_FTRACE=y
|
||||||
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
|
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
|
||||||
CONFIG_HAVE_HW_BRANCH_TRACER=y
|
CONFIG_HAVE_HW_BRANCH_TRACER=y
|
||||||
|
CONFIG_HAVE_FTRACE_SYSCALLS=y
|
||||||
|
CONFIG_RING_BUFFER=y
|
||||||
|
CONFIG_TRACING=y
|
||||||
|
CONFIG_TRACING_SUPPORT=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Tracers
|
# Tracers
|
||||||
|
@ -2285,13 +2342,21 @@ CONFIG_HAVE_HW_BRANCH_TRACER=y
|
||||||
# CONFIG_SYSPROF_TRACER is not set
|
# CONFIG_SYSPROF_TRACER is not set
|
||||||
# CONFIG_SCHED_TRACER is not set
|
# CONFIG_SCHED_TRACER is not set
|
||||||
# CONFIG_CONTEXT_SWITCH_TRACER is not set
|
# CONFIG_CONTEXT_SWITCH_TRACER is not set
|
||||||
|
# CONFIG_EVENT_TRACER is not set
|
||||||
|
# CONFIG_FTRACE_SYSCALLS is not set
|
||||||
# CONFIG_BOOT_TRACER is not set
|
# CONFIG_BOOT_TRACER is not set
|
||||||
# CONFIG_TRACE_BRANCH_PROFILING is not set
|
# CONFIG_TRACE_BRANCH_PROFILING is not set
|
||||||
# CONFIG_POWER_TRACER is not set
|
# CONFIG_POWER_TRACER is not set
|
||||||
# CONFIG_STACK_TRACER is not set
|
# CONFIG_STACK_TRACER is not set
|
||||||
# CONFIG_HW_BRANCH_TRACER is not set
|
# CONFIG_HW_BRANCH_TRACER is not set
|
||||||
|
# CONFIG_KMEMTRACE is not set
|
||||||
|
# CONFIG_WORKQUEUE_TRACER is not set
|
||||||
|
CONFIG_BLK_DEV_IO_TRACE=y
|
||||||
|
# CONFIG_FTRACE_STARTUP_TEST is not set
|
||||||
|
# CONFIG_MMIOTRACE is not set
|
||||||
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
|
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
|
||||||
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
|
# CONFIG_DYNAMIC_DEBUG is not set
|
||||||
|
# CONFIG_DMA_API_DEBUG is not set
|
||||||
# CONFIG_SAMPLES is not set
|
# CONFIG_SAMPLES is not set
|
||||||
CONFIG_HAVE_ARCH_KGDB=y
|
CONFIG_HAVE_ARCH_KGDB=y
|
||||||
# CONFIG_KGDB is not set
|
# CONFIG_KGDB is not set
|
||||||
|
@ -2301,14 +2366,13 @@ CONFIG_EARLY_PRINTK=y
|
||||||
CONFIG_EARLY_PRINTK_DBGP=y
|
CONFIG_EARLY_PRINTK_DBGP=y
|
||||||
CONFIG_DEBUG_STACKOVERFLOW=y
|
CONFIG_DEBUG_STACKOVERFLOW=y
|
||||||
CONFIG_DEBUG_STACK_USAGE=y
|
CONFIG_DEBUG_STACK_USAGE=y
|
||||||
# CONFIG_DEBUG_PAGEALLOC is not set
|
|
||||||
# CONFIG_DEBUG_PER_CPU_MAPS is not set
|
# CONFIG_DEBUG_PER_CPU_MAPS is not set
|
||||||
# CONFIG_X86_PTDUMP is not set
|
# CONFIG_X86_PTDUMP is not set
|
||||||
CONFIG_DEBUG_RODATA=y
|
CONFIG_DEBUG_RODATA=y
|
||||||
# CONFIG_DEBUG_RODATA_TEST is not set
|
# CONFIG_DEBUG_RODATA_TEST is not set
|
||||||
CONFIG_DEBUG_NX_TEST=m
|
CONFIG_DEBUG_NX_TEST=m
|
||||||
# CONFIG_IOMMU_DEBUG is not set
|
# CONFIG_IOMMU_DEBUG is not set
|
||||||
# CONFIG_MMIOTRACE is not set
|
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
|
||||||
CONFIG_IO_DELAY_TYPE_0X80=0
|
CONFIG_IO_DELAY_TYPE_0X80=0
|
||||||
CONFIG_IO_DELAY_TYPE_0XED=1
|
CONFIG_IO_DELAY_TYPE_0XED=1
|
||||||
CONFIG_IO_DELAY_TYPE_UDELAY=2
|
CONFIG_IO_DELAY_TYPE_UDELAY=2
|
||||||
|
@ -2344,6 +2408,8 @@ CONFIG_SECURITY_SELINUX_AVC_STATS=y
|
||||||
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
|
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
|
||||||
# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
|
# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
|
||||||
# CONFIG_SECURITY_SMACK is not set
|
# CONFIG_SECURITY_SMACK is not set
|
||||||
|
# CONFIG_SECURITY_TOMOYO is not set
|
||||||
|
# CONFIG_IMA is not set
|
||||||
CONFIG_CRYPTO=y
|
CONFIG_CRYPTO=y
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -2359,10 +2425,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
|
||||||
CONFIG_CRYPTO_HASH=y
|
CONFIG_CRYPTO_HASH=y
|
||||||
CONFIG_CRYPTO_HASH2=y
|
CONFIG_CRYPTO_HASH2=y
|
||||||
CONFIG_CRYPTO_RNG2=y
|
CONFIG_CRYPTO_RNG2=y
|
||||||
|
CONFIG_CRYPTO_PCOMP=y
|
||||||
CONFIG_CRYPTO_MANAGER=y
|
CONFIG_CRYPTO_MANAGER=y
|
||||||
CONFIG_CRYPTO_MANAGER2=y
|
CONFIG_CRYPTO_MANAGER2=y
|
||||||
# CONFIG_CRYPTO_GF128MUL is not set
|
# CONFIG_CRYPTO_GF128MUL is not set
|
||||||
# CONFIG_CRYPTO_NULL is not set
|
# CONFIG_CRYPTO_NULL is not set
|
||||||
|
CONFIG_CRYPTO_WORKQUEUE=y
|
||||||
# CONFIG_CRYPTO_CRYPTD is not set
|
# CONFIG_CRYPTO_CRYPTD is not set
|
||||||
CONFIG_CRYPTO_AUTHENC=y
|
CONFIG_CRYPTO_AUTHENC=y
|
||||||
# CONFIG_CRYPTO_TEST is not set
|
# CONFIG_CRYPTO_TEST is not set
|
||||||
|
@ -2414,6 +2482,7 @@ CONFIG_CRYPTO_SHA1=y
|
||||||
#
|
#
|
||||||
CONFIG_CRYPTO_AES=y
|
CONFIG_CRYPTO_AES=y
|
||||||
# CONFIG_CRYPTO_AES_X86_64 is not set
|
# CONFIG_CRYPTO_AES_X86_64 is not set
|
||||||
|
# CONFIG_CRYPTO_AES_NI_INTEL is not set
|
||||||
# CONFIG_CRYPTO_ANUBIS is not set
|
# CONFIG_CRYPTO_ANUBIS is not set
|
||||||
CONFIG_CRYPTO_ARC4=y
|
CONFIG_CRYPTO_ARC4=y
|
||||||
# CONFIG_CRYPTO_BLOWFISH is not set
|
# CONFIG_CRYPTO_BLOWFISH is not set
|
||||||
|
@ -2435,6 +2504,7 @@ CONFIG_CRYPTO_DES=y
|
||||||
# Compression
|
# Compression
|
||||||
#
|
#
|
||||||
# CONFIG_CRYPTO_DEFLATE is not set
|
# CONFIG_CRYPTO_DEFLATE is not set
|
||||||
|
# CONFIG_CRYPTO_ZLIB is not set
|
||||||
# CONFIG_CRYPTO_LZO is not set
|
# CONFIG_CRYPTO_LZO is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -2444,10 +2514,12 @@ CONFIG_CRYPTO_DES=y
|
||||||
CONFIG_CRYPTO_HW=y
|
CONFIG_CRYPTO_HW=y
|
||||||
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
|
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
|
||||||
CONFIG_HAVE_KVM=y
|
CONFIG_HAVE_KVM=y
|
||||||
|
CONFIG_HAVE_KVM_IRQCHIP=y
|
||||||
CONFIG_VIRTUALIZATION=y
|
CONFIG_VIRTUALIZATION=y
|
||||||
# CONFIG_KVM is not set
|
# CONFIG_KVM is not set
|
||||||
# CONFIG_VIRTIO_PCI is not set
|
# CONFIG_VIRTIO_PCI is not set
|
||||||
# CONFIG_VIRTIO_BALLOON is not set
|
# CONFIG_VIRTIO_BALLOON is not set
|
||||||
|
CONFIG_BINARY_PRINTF=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Library routines
|
# Library routines
|
||||||
|
@ -2464,7 +2536,10 @@ CONFIG_CRC32=y
|
||||||
# CONFIG_CRC7 is not set
|
# CONFIG_CRC7 is not set
|
||||||
# CONFIG_LIBCRC32C is not set
|
# CONFIG_LIBCRC32C is not set
|
||||||
CONFIG_ZLIB_INFLATE=y
|
CONFIG_ZLIB_INFLATE=y
|
||||||
CONFIG_PLIST=y
|
CONFIG_DECOMPRESS_GZIP=y
|
||||||
|
CONFIG_DECOMPRESS_BZIP2=y
|
||||||
|
CONFIG_DECOMPRESS_LZMA=y
|
||||||
CONFIG_HAS_IOMEM=y
|
CONFIG_HAS_IOMEM=y
|
||||||
CONFIG_HAS_IOPORT=y
|
CONFIG_HAS_IOPORT=y
|
||||||
CONFIG_HAS_DMA=y
|
CONFIG_HAS_DMA=y
|
||||||
|
CONFIG_NLATTR=y
|
||||||
|
|
|
@ -825,9 +825,11 @@ ia32_sys_call_table:
|
||||||
.quad compat_sys_signalfd4
|
.quad compat_sys_signalfd4
|
||||||
.quad sys_eventfd2
|
.quad sys_eventfd2
|
||||||
.quad sys_epoll_create1
|
.quad sys_epoll_create1
|
||||||
.quad sys_dup3 /* 330 */
|
.quad sys_dup3 /* 330 */
|
||||||
.quad sys_pipe2
|
.quad sys_pipe2
|
||||||
.quad sys_inotify_init1
|
.quad sys_inotify_init1
|
||||||
.quad compat_sys_preadv
|
.quad compat_sys_preadv
|
||||||
.quad compat_sys_pwritev
|
.quad compat_sys_pwritev
|
||||||
|
.quad compat_sys_rt_tgsigqueueinfo /* 335 */
|
||||||
|
.quad sys_perf_counter_open
|
||||||
ia32_syscall_end:
|
ia32_syscall_end:
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/stddef.h>
|
#include <linux/stddef.h>
|
||||||
|
#include <linux/stringify.h>
|
||||||
#include <asm/asm.h>
|
#include <asm/asm.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -74,6 +75,22 @@ static inline void alternatives_smp_switch(int smp) {}
|
||||||
|
|
||||||
const unsigned char *const *find_nop_table(void);
|
const unsigned char *const *find_nop_table(void);
|
||||||
|
|
||||||
|
/* alternative assembly primitive: */
|
||||||
|
#define ALTERNATIVE(oldinstr, newinstr, feature) \
|
||||||
|
\
|
||||||
|
"661:\n\t" oldinstr "\n662:\n" \
|
||||||
|
".section .altinstructions,\"a\"\n" \
|
||||||
|
_ASM_ALIGN "\n" \
|
||||||
|
_ASM_PTR "661b\n" /* label */ \
|
||||||
|
_ASM_PTR "663f\n" /* new instruction */ \
|
||||||
|
" .byte " __stringify(feature) "\n" /* feature bit */ \
|
||||||
|
" .byte 662b-661b\n" /* sourcelen */ \
|
||||||
|
" .byte 664f-663f\n" /* replacementlen */ \
|
||||||
|
".previous\n" \
|
||||||
|
".section .altinstr_replacement, \"ax\"\n" \
|
||||||
|
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
|
||||||
|
".previous"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Alternative instructions for different CPU types or capabilities.
|
* Alternative instructions for different CPU types or capabilities.
|
||||||
*
|
*
|
||||||
|
@ -87,18 +104,7 @@ const unsigned char *const *find_nop_table(void);
|
||||||
* without volatile and memory clobber.
|
* without volatile and memory clobber.
|
||||||
*/
|
*/
|
||||||
#define alternative(oldinstr, newinstr, feature) \
|
#define alternative(oldinstr, newinstr, feature) \
|
||||||
asm volatile ("661:\n\t" oldinstr "\n662:\n" \
|
asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) : : : "memory")
|
||||||
".section .altinstructions,\"a\"\n" \
|
|
||||||
_ASM_ALIGN "\n" \
|
|
||||||
_ASM_PTR "661b\n" /* label */ \
|
|
||||||
_ASM_PTR "663f\n" /* new instruction */ \
|
|
||||||
" .byte %c0\n" /* feature bit */ \
|
|
||||||
" .byte 662b-661b\n" /* sourcelen */ \
|
|
||||||
" .byte 664f-663f\n" /* replacementlen */ \
|
|
||||||
".previous\n" \
|
|
||||||
".section .altinstr_replacement,\"ax\"\n" \
|
|
||||||
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
|
|
||||||
".previous" :: "i" (feature) : "memory")
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Alternative inline assembly with input.
|
* Alternative inline assembly with input.
|
||||||
|
@ -109,35 +115,16 @@ const unsigned char *const *find_nop_table(void);
|
||||||
* Best is to use constraints that are fixed size (like (%1) ... "r")
|
* Best is to use constraints that are fixed size (like (%1) ... "r")
|
||||||
* If you use variable sized constraints like "m" or "g" in the
|
* If you use variable sized constraints like "m" or "g" in the
|
||||||
* replacement make sure to pad to the worst case length.
|
* replacement make sure to pad to the worst case length.
|
||||||
|
* Leaving an unused argument 0 to keep API compatibility.
|
||||||
*/
|
*/
|
||||||
#define alternative_input(oldinstr, newinstr, feature, input...) \
|
#define alternative_input(oldinstr, newinstr, feature, input...) \
|
||||||
asm volatile ("661:\n\t" oldinstr "\n662:\n" \
|
asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) \
|
||||||
".section .altinstructions,\"a\"\n" \
|
: : "i" (0), ## input)
|
||||||
_ASM_ALIGN "\n" \
|
|
||||||
_ASM_PTR "661b\n" /* label */ \
|
|
||||||
_ASM_PTR "663f\n" /* new instruction */ \
|
|
||||||
" .byte %c0\n" /* feature bit */ \
|
|
||||||
" .byte 662b-661b\n" /* sourcelen */ \
|
|
||||||
" .byte 664f-663f\n" /* replacementlen */ \
|
|
||||||
".previous\n" \
|
|
||||||
".section .altinstr_replacement,\"ax\"\n" \
|
|
||||||
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
|
|
||||||
".previous" :: "i" (feature), ##input)
|
|
||||||
|
|
||||||
/* Like alternative_input, but with a single output argument */
|
/* Like alternative_input, but with a single output argument */
|
||||||
#define alternative_io(oldinstr, newinstr, feature, output, input...) \
|
#define alternative_io(oldinstr, newinstr, feature, output, input...) \
|
||||||
asm volatile ("661:\n\t" oldinstr "\n662:\n" \
|
asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) \
|
||||||
".section .altinstructions,\"a\"\n" \
|
: output : "i" (0), ## input)
|
||||||
_ASM_ALIGN "\n" \
|
|
||||||
_ASM_PTR "661b\n" /* label */ \
|
|
||||||
_ASM_PTR "663f\n" /* new instruction */ \
|
|
||||||
" .byte %c[feat]\n" /* feature bit */ \
|
|
||||||
" .byte 662b-661b\n" /* sourcelen */ \
|
|
||||||
" .byte 664f-663f\n" /* replacementlen */ \
|
|
||||||
".previous\n" \
|
|
||||||
".section .altinstr_replacement,\"ax\"\n" \
|
|
||||||
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
|
|
||||||
".previous" : output : [feat] "i" (feature), ##input)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* use this macro(s) if you need more than one output parameter
|
* use this macro(s) if you need more than one output parameter
|
||||||
|
|
|
@ -27,6 +27,8 @@ extern int amd_iommu_init(void);
|
||||||
extern int amd_iommu_init_dma_ops(void);
|
extern int amd_iommu_init_dma_ops(void);
|
||||||
extern void amd_iommu_detect(void);
|
extern void amd_iommu_detect(void);
|
||||||
extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
|
extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
|
||||||
|
extern void amd_iommu_flush_all_domains(void);
|
||||||
|
extern void amd_iommu_flush_all_devices(void);
|
||||||
#else
|
#else
|
||||||
static inline int amd_iommu_init(void) { return -ENODEV; }
|
static inline int amd_iommu_init(void) { return -ENODEV; }
|
||||||
static inline void amd_iommu_detect(void) { }
|
static inline void amd_iommu_detect(void) { }
|
||||||
|
|
|
@ -194,6 +194,27 @@
|
||||||
#define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */
|
#define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */
|
||||||
#define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops
|
#define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops
|
||||||
domain for an IOMMU */
|
domain for an IOMMU */
|
||||||
|
extern bool amd_iommu_dump;
|
||||||
|
#define DUMP_printk(format, arg...) \
|
||||||
|
do { \
|
||||||
|
if (amd_iommu_dump) \
|
||||||
|
printk(KERN_INFO "AMD IOMMU: " format, ## arg); \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make iterating over all IOMMUs easier
|
||||||
|
*/
|
||||||
|
#define for_each_iommu(iommu) \
|
||||||
|
list_for_each_entry((iommu), &amd_iommu_list, list)
|
||||||
|
#define for_each_iommu_safe(iommu, next) \
|
||||||
|
list_for_each_entry_safe((iommu), (next), &amd_iommu_list, list)
|
||||||
|
|
||||||
|
#define APERTURE_RANGE_SHIFT 27 /* 128 MB */
|
||||||
|
#define APERTURE_RANGE_SIZE (1ULL << APERTURE_RANGE_SHIFT)
|
||||||
|
#define APERTURE_RANGE_PAGES (APERTURE_RANGE_SIZE >> PAGE_SHIFT)
|
||||||
|
#define APERTURE_MAX_RANGES 32 /* allows 4GB of DMA address space */
|
||||||
|
#define APERTURE_RANGE_INDEX(a) ((a) >> APERTURE_RANGE_SHIFT)
|
||||||
|
#define APERTURE_PAGE_INDEX(a) (((a) >> 21) & 0x3fULL)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This structure contains generic data for IOMMU protection domains
|
* This structure contains generic data for IOMMU protection domains
|
||||||
|
@ -209,6 +230,26 @@ struct protection_domain {
|
||||||
void *priv; /* private data */
|
void *priv; /* private data */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For dynamic growth the aperture size is split into ranges of 128MB of
|
||||||
|
* DMA address space each. This struct represents one such range.
|
||||||
|
*/
|
||||||
|
struct aperture_range {
|
||||||
|
|
||||||
|
/* address allocation bitmap */
|
||||||
|
unsigned long *bitmap;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Array of PTE pages for the aperture. In this array we save all the
|
||||||
|
* leaf pages of the domain page table used for the aperture. This way
|
||||||
|
* we don't need to walk the page table to find a specific PTE. We can
|
||||||
|
* just calculate its address in constant time.
|
||||||
|
*/
|
||||||
|
u64 *pte_pages[64];
|
||||||
|
|
||||||
|
unsigned long offset;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Data container for a dma_ops specific protection domain
|
* Data container for a dma_ops specific protection domain
|
||||||
*/
|
*/
|
||||||
|
@ -222,18 +263,10 @@ struct dma_ops_domain {
|
||||||
unsigned long aperture_size;
|
unsigned long aperture_size;
|
||||||
|
|
||||||
/* address we start to search for free addresses */
|
/* address we start to search for free addresses */
|
||||||
unsigned long next_bit;
|
unsigned long next_address;
|
||||||
|
|
||||||
/* address allocation bitmap */
|
/* address space relevant data */
|
||||||
unsigned long *bitmap;
|
struct aperture_range *aperture[APERTURE_MAX_RANGES];
|
||||||
|
|
||||||
/*
|
|
||||||
* Array of PTE pages for the aperture. In this array we save all the
|
|
||||||
* leaf pages of the domain page table used for the aperture. This way
|
|
||||||
* we don't need to walk the page table to find a specific PTE. We can
|
|
||||||
* just calculate its address in constant time.
|
|
||||||
*/
|
|
||||||
u64 **pte_pages;
|
|
||||||
|
|
||||||
/* This will be set to true when TLB needs to be flushed */
|
/* This will be set to true when TLB needs to be flushed */
|
||||||
bool need_flush;
|
bool need_flush;
|
||||||
|
|
|
@ -107,8 +107,7 @@ extern u32 native_safe_apic_wait_icr_idle(void);
|
||||||
extern void native_apic_icr_write(u32 low, u32 id);
|
extern void native_apic_icr_write(u32 low, u32 id);
|
||||||
extern u64 native_apic_icr_read(void);
|
extern u64 native_apic_icr_read(void);
|
||||||
|
|
||||||
#define EIM_8BIT_APIC_ID 0
|
extern int x2apic_mode;
|
||||||
#define EIM_32BIT_APIC_ID 1
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_X2APIC
|
#ifdef CONFIG_X86_X2APIC
|
||||||
/*
|
/*
|
||||||
|
@ -166,10 +165,9 @@ static inline u64 native_x2apic_icr_read(void)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int x2apic, x2apic_phys;
|
extern int x2apic_phys;
|
||||||
extern void check_x2apic(void);
|
extern void check_x2apic(void);
|
||||||
extern void enable_x2apic(void);
|
extern void enable_x2apic(void);
|
||||||
extern void enable_IR_x2apic(void);
|
|
||||||
extern void x2apic_icr_write(u32 low, u32 id);
|
extern void x2apic_icr_write(u32 low, u32 id);
|
||||||
static inline int x2apic_enabled(void)
|
static inline int x2apic_enabled(void)
|
||||||
{
|
{
|
||||||
|
@ -183,6 +181,8 @@ static inline int x2apic_enabled(void)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define x2apic_supported() (cpu_has_x2apic)
|
||||||
#else
|
#else
|
||||||
static inline void check_x2apic(void)
|
static inline void check_x2apic(void)
|
||||||
{
|
{
|
||||||
|
@ -190,28 +190,20 @@ static inline void check_x2apic(void)
|
||||||
static inline void enable_x2apic(void)
|
static inline void enable_x2apic(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
static inline void enable_IR_x2apic(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
static inline int x2apic_enabled(void)
|
static inline int x2apic_enabled(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define x2apic 0
|
#define x2apic_preenabled 0
|
||||||
|
#define x2apic_supported() 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern void enable_IR_x2apic(void);
|
||||||
|
|
||||||
extern int get_physical_broadcast(void);
|
extern int get_physical_broadcast(void);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_X2APIC
|
extern void apic_disable(void);
|
||||||
static inline void ack_x2APIC_irq(void)
|
|
||||||
{
|
|
||||||
/* Docs say use 0 for future compatibility */
|
|
||||||
native_apic_msr_write(APIC_EOI, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int lapic_get_maxlvt(void);
|
extern int lapic_get_maxlvt(void);
|
||||||
extern void clear_local_APIC(void);
|
extern void clear_local_APIC(void);
|
||||||
extern void connect_bsp_APIC(void);
|
extern void connect_bsp_APIC(void);
|
||||||
|
@ -252,7 +244,7 @@ static inline void lapic_shutdown(void) { }
|
||||||
#define local_apic_timer_c2_ok 1
|
#define local_apic_timer_c2_ok 1
|
||||||
static inline void init_apic_mappings(void) { }
|
static inline void init_apic_mappings(void) { }
|
||||||
static inline void disable_local_APIC(void) { }
|
static inline void disable_local_APIC(void) { }
|
||||||
|
static inline void apic_disable(void) { }
|
||||||
#endif /* !CONFIG_X86_LOCAL_APIC */
|
#endif /* !CONFIG_X86_LOCAL_APIC */
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
|
@ -410,7 +402,7 @@ static inline unsigned default_get_apic_id(unsigned long x)
|
||||||
{
|
{
|
||||||
unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
|
unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
|
||||||
|
|
||||||
if (APIC_XAPIC(ver))
|
if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID))
|
||||||
return (x >> 24) & 0xFF;
|
return (x >> 24) & 0xFF;
|
||||||
else
|
else
|
||||||
return (x >> 24) & 0x0F;
|
return (x >> 24) & 0x0F;
|
||||||
|
@ -478,6 +470,9 @@ static inline unsigned int read_apic_id(void)
|
||||||
extern void default_setup_apic_routing(void);
|
extern void default_setup_apic_routing(void);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
|
|
||||||
|
extern struct apic apic_default;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the logical destination ID.
|
* Set up the logical destination ID.
|
||||||
*
|
*
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
# define APIC_INTEGRATED(x) (1)
|
# define APIC_INTEGRATED(x) (1)
|
||||||
#endif
|
#endif
|
||||||
#define APIC_XAPIC(x) ((x) >= 0x14)
|
#define APIC_XAPIC(x) ((x) >= 0x14)
|
||||||
|
#define APIC_EXT_SPACE(x) ((x) & 0x80000000)
|
||||||
#define APIC_TASKPRI 0x80
|
#define APIC_TASKPRI 0x80
|
||||||
#define APIC_TPRI_MASK 0xFFu
|
#define APIC_TPRI_MASK 0xFFu
|
||||||
#define APIC_ARBPRI 0x90
|
#define APIC_ARBPRI 0x90
|
||||||
|
@ -116,7 +117,9 @@
|
||||||
#define APIC_TDR_DIV_32 0x8
|
#define APIC_TDR_DIV_32 0x8
|
||||||
#define APIC_TDR_DIV_64 0x9
|
#define APIC_TDR_DIV_64 0x9
|
||||||
#define APIC_TDR_DIV_128 0xA
|
#define APIC_TDR_DIV_128 0xA
|
||||||
#define APIC_EILVT0 0x500
|
#define APIC_EFEAT 0x400
|
||||||
|
#define APIC_ECTRL 0x410
|
||||||
|
#define APIC_EILVTn(n) (0x500 + 0x10 * n)
|
||||||
#define APIC_EILVT_NR_AMD_K8 1 /* # of extended interrupts */
|
#define APIC_EILVT_NR_AMD_K8 1 /* # of extended interrupts */
|
||||||
#define APIC_EILVT_NR_AMD_10H 4
|
#define APIC_EILVT_NR_AMD_10H 4
|
||||||
#define APIC_EILVT_LVTOFF(x) (((x) >> 4) & 0xF)
|
#define APIC_EILVT_LVTOFF(x) (((x) >> 4) & 0xF)
|
||||||
|
@ -125,9 +128,6 @@
|
||||||
#define APIC_EILVT_MSG_NMI 0x4
|
#define APIC_EILVT_MSG_NMI 0x4
|
||||||
#define APIC_EILVT_MSG_EXT 0x7
|
#define APIC_EILVT_MSG_EXT 0x7
|
||||||
#define APIC_EILVT_MASKED (1 << 16)
|
#define APIC_EILVT_MASKED (1 << 16)
|
||||||
#define APIC_EILVT1 0x510
|
|
||||||
#define APIC_EILVT2 0x520
|
|
||||||
#define APIC_EILVT3 0x530
|
|
||||||
|
|
||||||
#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
|
#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
|
||||||
#define APIC_BASE_MSR 0x800
|
#define APIC_BASE_MSR 0x800
|
||||||
|
|
|
@ -247,5 +247,241 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
|
||||||
#define smp_mb__before_atomic_inc() barrier()
|
#define smp_mb__before_atomic_inc() barrier()
|
||||||
#define smp_mb__after_atomic_inc() barrier()
|
#define smp_mb__after_atomic_inc() barrier()
|
||||||
|
|
||||||
|
/* An 64bit atomic type */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned long long counter;
|
||||||
|
} atomic64_t;
|
||||||
|
|
||||||
|
#define ATOMIC64_INIT(val) { (val) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_read - read atomic64 variable
|
||||||
|
* @v: pointer of type atomic64_t
|
||||||
|
*
|
||||||
|
* Atomically reads the value of @v.
|
||||||
|
* Doesn't imply a read memory barrier.
|
||||||
|
*/
|
||||||
|
#define __atomic64_read(ptr) ((ptr)->counter)
|
||||||
|
|
||||||
|
static inline unsigned long long
|
||||||
|
cmpxchg8b(unsigned long long *ptr, unsigned long long old, unsigned long long new)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
|
||||||
|
LOCK_PREFIX "cmpxchg8b (%[ptr])\n"
|
||||||
|
|
||||||
|
: "=A" (old)
|
||||||
|
|
||||||
|
: [ptr] "D" (ptr),
|
||||||
|
"A" (old),
|
||||||
|
"b" (ll_low(new)),
|
||||||
|
"c" (ll_high(new))
|
||||||
|
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long long
|
||||||
|
atomic64_cmpxchg(atomic64_t *ptr, unsigned long long old_val,
|
||||||
|
unsigned long long new_val)
|
||||||
|
{
|
||||||
|
return cmpxchg8b(&ptr->counter, old_val, new_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_xchg - xchg atomic64 variable
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
* @new_val: value to assign
|
||||||
|
* @old_val: old value that was there
|
||||||
|
*
|
||||||
|
* Atomically xchgs the value of @ptr to @new_val and returns
|
||||||
|
* the old value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline unsigned long long
|
||||||
|
atomic64_xchg(atomic64_t *ptr, unsigned long long new_val)
|
||||||
|
{
|
||||||
|
unsigned long long old_val;
|
||||||
|
|
||||||
|
do {
|
||||||
|
old_val = atomic_read(ptr);
|
||||||
|
} while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val);
|
||||||
|
|
||||||
|
return old_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_set - set atomic64 variable
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
* @new_val: value to assign
|
||||||
|
*
|
||||||
|
* Atomically sets the value of @ptr to @new_val.
|
||||||
|
*/
|
||||||
|
static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val)
|
||||||
|
{
|
||||||
|
atomic64_xchg(ptr, new_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_read - read atomic64 variable
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
*
|
||||||
|
* Atomically reads the value of @ptr and returns it.
|
||||||
|
*/
|
||||||
|
static inline unsigned long long atomic64_read(atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
unsigned long long curr_val;
|
||||||
|
|
||||||
|
do {
|
||||||
|
curr_val = __atomic64_read(ptr);
|
||||||
|
} while (atomic64_cmpxchg(ptr, curr_val, curr_val) != curr_val);
|
||||||
|
|
||||||
|
return curr_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_add_return - add and return
|
||||||
|
* @delta: integer value to add
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
*
|
||||||
|
* Atomically adds @delta to @ptr and returns @delta + *@ptr
|
||||||
|
*/
|
||||||
|
static inline unsigned long long
|
||||||
|
atomic64_add_return(unsigned long long delta, atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
unsigned long long old_val, new_val;
|
||||||
|
|
||||||
|
do {
|
||||||
|
old_val = atomic_read(ptr);
|
||||||
|
new_val = old_val + delta;
|
||||||
|
|
||||||
|
} while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val);
|
||||||
|
|
||||||
|
return new_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long atomic64_sub_return(unsigned long long delta, atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
return atomic64_add_return(-delta, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long atomic64_inc_return(atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
return atomic64_add_return(1, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long atomic64_dec_return(atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
return atomic64_sub_return(1, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_add - add integer to atomic64 variable
|
||||||
|
* @delta: integer value to add
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
*
|
||||||
|
* Atomically adds @delta to @ptr.
|
||||||
|
*/
|
||||||
|
static inline void atomic64_add(unsigned long long delta, atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
atomic64_add_return(delta, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_sub - subtract the atomic64 variable
|
||||||
|
* @delta: integer value to subtract
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
*
|
||||||
|
* Atomically subtracts @delta from @ptr.
|
||||||
|
*/
|
||||||
|
static inline void atomic64_sub(unsigned long long delta, atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
atomic64_add(-delta, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_sub_and_test - subtract value from variable and test result
|
||||||
|
* @delta: integer value to subtract
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
*
|
||||||
|
* Atomically subtracts @delta from @ptr and returns
|
||||||
|
* true if the result is zero, or false for all
|
||||||
|
* other cases.
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
atomic64_sub_and_test(unsigned long long delta, atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
unsigned long long old_val = atomic64_sub_return(delta, ptr);
|
||||||
|
|
||||||
|
return old_val == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_inc - increment atomic64 variable
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
*
|
||||||
|
* Atomically increments @ptr by 1.
|
||||||
|
*/
|
||||||
|
static inline void atomic64_inc(atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
atomic64_add(1, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_dec - decrement atomic64 variable
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
*
|
||||||
|
* Atomically decrements @ptr by 1.
|
||||||
|
*/
|
||||||
|
static inline void atomic64_dec(atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
atomic64_sub(1, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_dec_and_test - decrement and test
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
*
|
||||||
|
* Atomically decrements @ptr by 1 and
|
||||||
|
* returns true if the result is 0, or false for all other
|
||||||
|
* cases.
|
||||||
|
*/
|
||||||
|
static inline int atomic64_dec_and_test(atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
return atomic64_sub_and_test(1, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_inc_and_test - increment and test
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
*
|
||||||
|
* Atomically increments @ptr by 1
|
||||||
|
* and returns true if the result is zero, or false for all
|
||||||
|
* other cases.
|
||||||
|
*/
|
||||||
|
static inline int atomic64_inc_and_test(atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
return atomic64_sub_and_test(-1, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic64_add_negative - add and test if negative
|
||||||
|
* @delta: integer value to add
|
||||||
|
* @ptr: pointer to type atomic64_t
|
||||||
|
*
|
||||||
|
* Atomically adds @delta to @ptr and returns true
|
||||||
|
* if the result is negative, or false when
|
||||||
|
* result is greater than or equal to zero.
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
atomic64_add_negative(unsigned long long delta, atomic64_t *ptr)
|
||||||
|
{
|
||||||
|
long long old_val = atomic64_add_return(delta, ptr);
|
||||||
|
|
||||||
|
return old_val < 0;
|
||||||
|
}
|
||||||
|
|
||||||
#include <asm-generic/atomic.h>
|
#include <asm-generic/atomic.h>
|
||||||
#endif /* _ASM_X86_ATOMIC_32_H */
|
#endif /* _ASM_X86_ATOMIC_32_H */
|
||||||
|
|
|
@ -8,11 +8,26 @@
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
#include <asm/page_types.h>
|
||||||
|
|
||||||
/* Physical address where kernel should be loaded. */
|
/* Physical address where kernel should be loaded. */
|
||||||
#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
|
#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
|
||||||
+ (CONFIG_PHYSICAL_ALIGN - 1)) \
|
+ (CONFIG_PHYSICAL_ALIGN - 1)) \
|
||||||
& ~(CONFIG_PHYSICAL_ALIGN - 1))
|
& ~(CONFIG_PHYSICAL_ALIGN - 1))
|
||||||
|
|
||||||
|
/* Minimum kernel alignment, as a power of two */
|
||||||
|
#ifdef CONFIG_x86_64
|
||||||
|
#define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT
|
||||||
|
#else
|
||||||
|
#define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT+1)
|
||||||
|
#endif
|
||||||
|
#define MIN_KERNEL_ALIGN (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2)
|
||||||
|
|
||||||
|
#if (CONFIG_PHYSICAL_ALIGN & (CONFIG_PHYSICAL_ALIGN-1)) || \
|
||||||
|
(CONFIG_PHYSICAL_ALIGN < (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2))
|
||||||
|
#error "Invalid value for CONFIG_PHYSICAL_ALIGN"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_KERNEL_BZIP2
|
#ifdef CONFIG_KERNEL_BZIP2
|
||||||
#define BOOT_HEAP_SIZE 0x400000
|
#define BOOT_HEAP_SIZE 0x400000
|
||||||
#else /* !CONFIG_KERNEL_BZIP2 */
|
#else /* !CONFIG_KERNEL_BZIP2 */
|
||||||
|
|
|
@ -50,7 +50,8 @@ struct setup_header {
|
||||||
__u32 ramdisk_size;
|
__u32 ramdisk_size;
|
||||||
__u32 bootsect_kludge;
|
__u32 bootsect_kludge;
|
||||||
__u16 heap_end_ptr;
|
__u16 heap_end_ptr;
|
||||||
__u16 _pad1;
|
__u8 ext_loader_ver;
|
||||||
|
__u8 ext_loader_type;
|
||||||
__u32 cmd_line_ptr;
|
__u32 cmd_line_ptr;
|
||||||
__u32 initrd_addr_max;
|
__u32 initrd_addr_max;
|
||||||
__u32 kernel_alignment;
|
__u32 kernel_alignment;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue