Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
374046d5
Commit
374046d5
authored
Jun 15, 2003
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge davem@nuts.ninka.net:/home/davem/src/BK/net-2.5
into kernel.bkbits.net:/home/davem/net-2.5
parents
06b4a180
4fb416f4
Changes
39
Show whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
183 additions
and
2270 deletions
+183
-2270
arch/x86_64/Makefile
arch/x86_64/Makefile
+0
-1
arch/x86_64/ia32/vsyscall.S
arch/x86_64/ia32/vsyscall.S
+1
-1
arch/x86_64/kernel/Makefile
arch/x86_64/kernel/Makefile
+3
-1
arch/x86_64/kernel/aperture.c
arch/x86_64/kernel/aperture.c
+0
-2
arch/x86_64/kernel/apic.c
arch/x86_64/kernel/apic.c
+14
-20
arch/x86_64/kernel/bluesmoke.c
arch/x86_64/kernel/bluesmoke.c
+1
-2
arch/x86_64/kernel/cpuid.c
arch/x86_64/kernel/cpuid.c
+0
-178
arch/x86_64/kernel/ldt.c
arch/x86_64/kernel/ldt.c
+1
-2
arch/x86_64/kernel/msr.c
arch/x86_64/kernel/msr.c
+12
-12
arch/x86_64/kernel/nmi.c
arch/x86_64/kernel/nmi.c
+19
-25
arch/x86_64/kernel/pci-gart.c
arch/x86_64/kernel/pci-gart.c
+23
-11
arch/x86_64/kernel/pci-nommu.c
arch/x86_64/kernel/pci-nommu.c
+1
-2
arch/x86_64/kernel/process.c
arch/x86_64/kernel/process.c
+0
-2
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/setup.c
+1
-1
arch/x86_64/kernel/signal.c
arch/x86_64/kernel/signal.c
+0
-2
arch/x86_64/kernel/smpboot.c
arch/x86_64/kernel/smpboot.c
+1
-11
arch/x86_64/kernel/time.c
arch/x86_64/kernel/time.c
+1
-3
arch/x86_64/kernel/traps.c
arch/x86_64/kernel/traps.c
+1
-8
arch/x86_64/kernel/wakeup.S
arch/x86_64/kernel/wakeup.S
+0
-306
arch/x86_64/lib/delay.c
arch/x86_64/lib/delay.c
+0
-2
arch/x86_64/mm/init.c
arch/x86_64/mm/init.c
+42
-1
arch/x86_64/pci/Makefile
arch/x86_64/pci/Makefile
+22
-1
arch/x86_64/pci/acpi.c
arch/x86_64/pci/acpi.c
+0
-27
arch/x86_64/pci/changelog
arch/x86_64/pci/changelog
+0
-1
arch/x86_64/pci/common.c
arch/x86_64/pci/common.c
+0
-212
arch/x86_64/pci/direct.c
arch/x86_64/pci/direct.c
+0
-281
arch/x86_64/pci/fixup.c
arch/x86_64/pci/fixup.c
+0
-48
arch/x86_64/pci/irq.c
arch/x86_64/pci/irq.c
+0
-639
arch/x86_64/pci/legacy.c
arch/x86_64/pci/legacy.c
+0
-68
arch/x86_64/pci/pci.h
arch/x86_64/pci/pci.h
+0
-75
arch/x86_64/pci/x86-64.c
arch/x86_64/pci/x86-64.c
+0
-299
drivers/char/rtc.c
drivers/char/rtc.c
+5
-4
include/asm-x86_64/fixmap.h
include/asm-x86_64/fixmap.h
+5
-0
include/asm-x86_64/io.h
include/asm-x86_64/io.h
+1
-1
include/asm-x86_64/mmzone.h
include/asm-x86_64/mmzone.h
+0
-14
include/asm-x86_64/page.h
include/asm-x86_64/page.h
+2
-0
include/asm-x86_64/pci.h
include/asm-x86_64/pci.h
+0
-1
include/asm-x86_64/pgtable.h
include/asm-x86_64/pgtable.h
+7
-4
include/asm-x86_64/proto.h
include/asm-x86_64/proto.h
+20
-2
No files found.
arch/x86_64/Makefile
View file @
374046d5
...
...
@@ -42,7 +42,6 @@ CFLAGS += -mno-red-zone
CFLAGS
+=
-mcmodel
=
kernel
CFLAGS
+=
-pipe
# this makes reading assembly source easier, but produces worse code
# disable for production kernel
CFLAGS
+=
-fno-reorder-blocks
# should lower this a lot and see how much .text is saves
CFLAGS
+=
-finline-limit
=
2000
...
...
arch/x86_64/ia32/vsyscall.S
View file @
374046d5
...
...
@@ -35,7 +35,7 @@ __kernel_sigreturn:
.
section
.
text
.
rtsigreturn
,
"ax"
.
balign
32
.
globl
__kernel_rt_sigreturn
,
"ax"
.
globl
__kernel_rt_sigreturn
.
type
__kernel_rt_sigreturn
,
@
function
__kernel_rt_sigreturn
:
.
LSTART_rt_sigreturn
:
...
...
arch/x86_64/kernel/Makefile
View file @
374046d5
...
...
@@ -24,6 +24,8 @@ obj-$(CONFIG_MODULES) += module.o
$(obj)/bootflag.c
:
@
ln
-sf
../../i386/kernel/bootflag.c
$(obj)
/bootflag.c
$(obj)/cpuid.c
:
@
ln
-sf
../../i386/kernel/cpuid.c
$(obj)
/cpuid.c
clean-files
+=
bootflag.c
clean-files
+=
bootflag.c
cpuid.c
arch/x86_64/kernel/aperture.c
View file @
374046d5
...
...
@@ -25,8 +25,6 @@
int
fallback_aper_order
__initdata
=
1
;
/* 64MB */
int
fallback_aper_force
__initdata
=
0
;
extern
int
no_iommu
,
force_mmu
;
/* This code runs before the PCI subsystem is initialized, so just
access the northbridge directly. */
...
...
arch/x86_64/kernel/apic.c
View file @
374046d5
...
...
@@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
#include <linux/sysdev.h>
#include <asm/atomic.h>
#include <asm/smp.h>
...
...
@@ -464,13 +465,11 @@ static struct {
unsigned
int
apic_thmr
;
}
apic_pm_state
;
static
int
lapic_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
static
int
lapic_suspend
(
struct
sys_device
*
dev
,
u32
state
)
{
unsigned
int
l
,
h
;
unsigned
long
flags
;
if
(
level
!=
SUSPEND_POWER_DOWN
)
return
0
;
if
(
!
apic_pm_state
.
active
)
return
0
;
...
...
@@ -497,13 +496,11 @@ static int lapic_suspend(struct device *dev, u32 state, u32 level)
return
0
;
}
static
int
lapic_resume
(
struct
device
*
dev
,
u32
level
)
static
int
lapic_resume
(
struct
sys_device
*
dev
)
{
unsigned
int
l
,
h
;
unsigned
long
flags
;
if
(
level
!=
RESUME_POWER_ON
)
return
0
;
if
(
!
apic_pm_state
.
active
)
return
0
;
...
...
@@ -537,38 +534,35 @@ static int lapic_resume(struct device *dev, u32 level)
return
0
;
}
static
struct
device_driver
lapic_driver
=
{
.
name
=
"lapic"
,
.
bus
=
&
system_bus_type
,
static
struct
sysdev_class
lapic_sysclass
=
{
set_kset_name
(
"lapic"
),
.
resume
=
lapic_resume
,
.
suspend
=
lapic_suspend
,
};
/* not static, needed by child devices */
struct
sys_device
device_lapic
=
{
.
name
=
"lapic"
,
static
struct
sys_device
device_lapic
=
{
.
id
=
0
,
.
dev
=
{
.
name
=
"lapic"
,
.
driver
=
&
lapic_driver
,
},
.
cls
=
&
lapic_sysclass
,
};
EXPORT_SYMBOL
(
device_lapic
);
static
void
__init
apic_pm_activate
(
void
)
{
apic_pm_state
.
active
=
1
;
}
static
int
__init
init_lapic_
device
fs
(
void
)
static
int
__init
init_lapic_
sys
fs
(
void
)
{
int
error
;
if
(
!
cpu_has_apic
)
return
0
;
/* XXX: remove suspend/resume procs if !apic_pm_state.active? */
driver_register
(
&
lapic_driver
);
return
sys_device_register
(
&
device_lapic
);
error
=
sysdev_class_register
(
&
lapic_sysclass
);
if
(
!
error
)
error
=
sys_device_register
(
&
device_lapic
);
return
error
;
}
device_initcall
(
init_lapic_
device
fs
);
device_initcall
(
init_lapic_
sys
fs
);
#else
/* CONFIG_PM */
...
...
arch/x86_64/kernel/bluesmoke.c
View file @
374046d5
...
...
@@ -303,7 +303,7 @@ static void k8_machine_check(struct pt_regs * regs, long error_code)
wrmsrl
(
MSR_IA32_MCG_STATUS
,
0
);
if
(
regs
&&
(
status
&
(
1
<<
1
)))
printk
(
KERN_EMERG
"MCE at
EIP %lx E
SP %lx
\n
"
,
regs
->
rip
,
regs
->
rsp
);
printk
(
KERN_EMERG
"MCE at
RIP %lx R
SP %lx
\n
"
,
regs
->
rip
,
regs
->
rsp
);
others:
generic_machine_check
(
regs
,
error_code
);
...
...
@@ -352,7 +352,6 @@ static void __init k8_mcheck_init(struct cpuinfo_x86 *c)
{
u64
cap
;
int
i
;
struct
pci_dev
*
nb
;
if
(
!
test_bit
(
X86_FEATURE_MCE
,
&
c
->
x86_capability
)
||
!
test_bit
(
X86_FEATURE_MCA
,
&
c
->
x86_capability
))
...
...
arch/x86_64/kernel/cpuid.c
deleted
100644 → 0
View file @
06b4a180
#ident "$Id: cpuid.c,v 1.4 2001/10/24 23:58:53 ak Exp $"
/* ----------------------------------------------------------------------- *
*
* Copyright 2000 H. Peter Anvin - 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 as published by
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
* USA; either version 2 of the License, or (at your option) any later
* version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/*
* cpuid.c
*
* x86 CPUID access device
*
* This device is accessed by lseek() to the appropriate CPUID level
* and then read in chunks of 16 bytes. A larger size means multiple
* reads of consecutive levels.
*
* This driver uses /dev/cpu/%d/cpuid where %d is the minor number, and on
* an SMP box will direct the access to CPU %d.
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/smp.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#ifdef CONFIG_SMP
struct
cpuid_command
{
int
cpu
;
u32
reg
;
u32
*
data
;
};
static
void
cpuid_smp_cpuid
(
void
*
cmd_block
)
{
struct
cpuid_command
*
cmd
=
(
struct
cpuid_command
*
)
cmd_block
;
if
(
cmd
->
cpu
==
smp_processor_id
()
)
cpuid
(
cmd
->
reg
,
&
cmd
->
data
[
0
],
&
cmd
->
data
[
1
],
&
cmd
->
data
[
2
],
&
cmd
->
data
[
3
]);
}
static
inline
void
do_cpuid
(
int
cpu
,
u32
reg
,
u32
*
data
)
{
struct
cpuid_command
cmd
;
preempt_disable
();
if
(
cpu
==
smp_processor_id
()
)
{
cpuid
(
reg
,
&
data
[
0
],
&
data
[
1
],
&
data
[
2
],
&
data
[
3
]);
}
else
{
cmd
.
cpu
=
cpu
;
cmd
.
reg
=
reg
;
cmd
.
data
=
data
;
smp_call_function
(
cpuid_smp_cpuid
,
&
cmd
,
1
,
1
);
}
preempt_enable
();
}
#else
/* ! CONFIG_SMP */
static
inline
void
do_cpuid
(
int
cpu
,
u32
reg
,
u32
*
data
)
{
cpuid
(
reg
,
&
data
[
0
],
&
data
[
1
],
&
data
[
2
],
&
data
[
3
]);
}
#endif
/* ! CONFIG_SMP */
static
loff_t
cpuid_seek
(
struct
file
*
file
,
loff_t
offset
,
int
orig
)
{
loff_t
ret
;
lock_kernel
();
switch
(
orig
)
{
case
0
:
file
->
f_pos
=
offset
;
ret
=
file
->
f_pos
;
break
;
case
1
:
file
->
f_pos
+=
offset
;
ret
=
file
->
f_pos
;
break
;
default:
ret
=
-
EINVAL
;
}
unlock_kernel
();
return
ret
;
}
static
ssize_t
cpuid_read
(
struct
file
*
file
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
u32
*
tmp
=
(
u32
*
)
buf
;
u32
data
[
4
];
size_t
rv
;
u32
reg
=
*
ppos
;
int
cpu
=
minor
(
file
->
f_dentry
->
d_inode
->
i_rdev
);
if
(
count
%
16
)
return
-
EINVAL
;
/* Invalid chunk size */
for
(
rv
=
0
;
count
;
count
-=
16
)
{
do_cpuid
(
cpu
,
reg
,
data
);
if
(
copy_to_user
(
tmp
,
&
data
,
16
)
)
return
-
EFAULT
;
tmp
+=
4
;
*
ppos
=
reg
++
;
}
return
((
char
*
)
tmp
)
-
buf
;
}
static
int
cpuid_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
int
cpu
=
minor
(
file
->
f_dentry
->
d_inode
->
i_rdev
);
struct
cpuinfo_x86
*
c
=
&
(
cpu_data
)[
cpu
];
if
(
!
(
cpu_online_map
&
(
1UL
<<
cpu
))
)
return
-
ENXIO
;
/* No such CPU */
if
(
c
->
cpuid_level
<
0
)
return
-
EIO
;
/* CPUID not supported */
return
0
;
}
/*
* File operations we support
*/
static
struct
file_operations
cpuid_fops
=
{
.
owner
=
THIS_MODULE
,
.
llseek
=
cpuid_seek
,
.
read
=
cpuid_read
,
.
open
=
cpuid_open
,
};
int
__init
cpuid_init
(
void
)
{
if
(
register_chrdev
(
CPUID_MAJOR
,
"cpu/cpuid"
,
&
cpuid_fops
))
{
printk
(
KERN_ERR
"cpuid: unable to get major %d for cpuid
\n
"
,
CPUID_MAJOR
);
return
-
EBUSY
;
}
return
0
;
}
void
__exit
cpuid_exit
(
void
)
{
unregister_chrdev
(
CPUID_MAJOR
,
"cpu/cpuid"
);
}
module_init
(
cpuid_init
);
module_exit
(
cpuid_exit
)
MODULE_AUTHOR
(
"H. Peter Anvin <hpa@zytor.com>"
);
MODULE_DESCRIPTION
(
"x86 generic CPUID driver"
);
MODULE_LICENSE
(
"GPL"
);
arch/x86_64/kernel/ldt.c
View file @
374046d5
...
...
@@ -21,8 +21,7 @@
#include <asm/system.h>
#include <asm/ldt.h>
#include <asm/desc.h>
extern
void
load_gs_index
(
unsigned
gs
);
#include <asm/proto.h>
#ifdef CONFIG_SMP
/* avoids "defined but not used" warnig */
static
void
flush_ldt
(
void
*
null
)
...
...
arch/x86_64/kernel/msr.c
View file @
374046d5
#ident "$Id
: msr.c,v 1.6 2001/10/24 23:58:53 ak Exp
$"
#ident "$Id$"
/* ----------------------------------------------------------------------- *
*
* Copyright 2000 H. Peter Anvin - All Rights Reserved
...
...
@@ -22,9 +22,6 @@
*
* This driver uses /dev/cpu/%d/msr where %d is the minor number, and on
* an SMP box will direct the access to CPU %d.
RED-PEN: need to get power management for S3 restore
*/
#include <linux/module.h>
...
...
@@ -44,7 +41,6 @@ RED-PEN: need to get power management for S3 restore
#include <asm/msr.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/cpufeature.h>
/* Note: "err" is handled in a funny way below. Otherwise one version
of gcc or another breaks. */
...
...
@@ -119,12 +115,11 @@ static void msr_smp_rdmsr(void *cmd_block)
static
inline
int
do_wrmsr
(
int
cpu
,
u32
reg
,
u32
eax
,
u32
edx
)
{
struct
msr_command
cmd
;
int
ret
;
preempt_disable
();
if
(
cpu
==
smp_processor_id
()
)
{
int
ret
=
wrmsr_eio
(
reg
,
eax
,
edx
);
preempt_enable
();
return
ret
;
ret
=
wrmsr_eio
(
reg
,
eax
,
edx
);
}
else
{
cmd
.
cpu
=
cpu
;
cmd
.
reg
=
reg
;
...
...
@@ -132,17 +127,20 @@ static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
cmd
.
data
[
1
]
=
edx
;
smp_call_function
(
msr_smp_wrmsr
,
&
cmd
,
1
,
1
);
preempt_enable
();
return
cmd
.
err
;
ret
=
cmd
.
err
;
}
preempt_enable
();
return
ret
;
}
static
inline
int
do_rdmsr
(
int
cpu
,
u32
reg
,
u32
*
eax
,
u32
*
edx
)
{
struct
msr_command
cmd
;
int
ret
;
preempt_disable
();
if
(
cpu
==
smp_processor_id
()
)
{
ret
urn
rdmsr_eio
(
reg
,
eax
,
edx
);
ret
=
rdmsr_eio
(
reg
,
eax
,
edx
);
}
else
{
cmd
.
cpu
=
cpu
;
cmd
.
reg
=
reg
;
...
...
@@ -152,8 +150,10 @@ static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx)
*
eax
=
cmd
.
data
[
0
];
*
edx
=
cmd
.
data
[
1
];
ret
urn
cmd
.
err
;
ret
=
cmd
.
err
;
}
preempt_enable
();
return
ret
;
}
#else
/* ! CONFIG_SMP */
...
...
arch/x86_64/kernel/nmi.c
View file @
374046d5
...
...
@@ -22,6 +22,7 @@
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/sysdev.h>
#include <asm/smp.h>
#include <asm/mtrr.h>
...
...
@@ -152,50 +153,45 @@ void enable_lapic_nmi_watchdog(void)
#include <linux/device.h>
static
int
lapic_nmi_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
{
if
(
level
!=
SUSPEND_POWER_DOWN
)
return
0
;
static
int
lapic_nmi_suspend
(
struct
sys_device
*
dev
,
u32
state
)
{
disable_lapic_nmi_watchdog
();
return
0
;
}
}
static
int
lapic_nmi_resume
(
struct
device
*
dev
,
u32
level
)
{
if
(
level
!=
RESUME_POWER_ON
)
return
0
;
static
int
lapic_nmi_resume
(
struct
sys_device
*
dev
)
{
#if 0
enable_lapic_nmi_watchdog();
#endif
return
0
;
}
}
static
struct
device_driver
lapic_nmi_driver
=
{
.
name
=
"lapic_nmi"
,
.
bus
=
&
system_bus_type
,
static
struct
sysdev_class
nmi_sysclass
=
{
set_kset_name
(
"lapic_nmi"
),
.
resume
=
lapic_nmi_resume
,
.
suspend
=
lapic_nmi_suspend
,
};
static
struct
sys_device
device_lapic_nmi
=
{
.
name
=
"lapic_nmi"
,
.
id
=
0
,
.
dev
=
{
.
name
=
"lapic_nmi"
,
.
driver
=
&
lapic_nmi_driver
,
.
parent
=
&
device_lapic
.
dev
,
},
.
cls
=
&
nmi_sysclass
,
};
static
int
__init
init_lapic_nmi_
device
fs
(
void
)
static
int
__init
init_lapic_nmi_
sys
fs
(
void
)
{
int
error
;
if
(
nmi_active
==
0
)
return
0
;
driver_register
(
&
lapic_nmi_driver
);
return
sys_device_register
(
&
device_lapic_nmi
);
error
=
sysdev_class_register
(
&
nmi_sysclass
);
if
(
!
error
)
error
=
sys_device_register
(
&
device_lapic_nmi
);
return
error
;
}
/* must come after the local APIC's device_initcall() */
late_initcall
(
init_lapic_nmi_
device
fs
);
late_initcall
(
init_lapic_nmi_
sys
fs
);
#endif
/* CONFIG_PM */
...
...
@@ -332,13 +328,11 @@ asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
{
int
cpu
=
safe_smp_processor_id
();
init_tss
[
cpu
].
ist
[
NMI_STACK
]
-=
2048
;
/* this shouldn't be needed. */
nmi_enter
();
add_pda
(
__nmi_count
,
1
);
if
(
!
nmi_callback
(
regs
,
cpu
))
default_do_nmi
(
regs
);
nmi_exit
();
init_tss
[
cpu
].
ist
[
NMI_STACK
]
+=
2048
;
}
void
set_nmi_callback
(
nmi_callback_t
callback
)
...
...
arch/x86_64/kernel/pci-gart.c
View file @
374046d5
...
...
@@ -38,6 +38,8 @@ possible future tuning:
#include <asm/pgtable.h>
#include <asm/proto.h>
#include <asm/cacheflush.h>
#include <asm/kdebug.h>
#include <asm/proto.h>
unsigned
long
iommu_bus_base
;
/* GART remapping area (physical) */
static
unsigned
long
iommu_size
;
/* size of remapping area bytes */
...
...
@@ -53,9 +55,6 @@ int force_mmu = 1;
int
force_mmu
=
0
;
#endif
extern
int
fallback_aper_order
;
extern
int
fallback_aper_force
;
/* Allocation bitmap for the remapping area */
static
spinlock_t
iommu_bitmap_lock
=
SPIN_LOCK_UNLOCKED
;
static
unsigned
long
*
iommu_gart_bitmap
;
/* guarded by iommu_bitmap_lock */
...
...
@@ -135,10 +134,19 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
void
*
memory
;
int
gfp
=
GFP_ATOMIC
;
int
i
;
unsigned
long
iommu_page
;
int
flush
=
0
;
unsigned
long
iommu_page
;
unsigned
long
dma_mask
;
if
(
hwdev
==
NULL
||
hwdev
->
dma_mask
<
0xffffffff
||
no_iommu
)
if
(
hwdev
==
NULL
)
{
gfp
|=
GFP_DMA
;
dma_mask
=
0xffffffff
;
}
else
{
dma_mask
=
hwdev
->
consistent_dma_mask
;
}
if
(
dma_mask
==
0
)
dma_mask
=
0xffffffff
;
if
(
dma_mask
<
0xffffffff
||
no_iommu
)
gfp
|=
GFP_DMA
;
/*
...
...
@@ -151,7 +159,7 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
return
NULL
;
}
else
{
int
high
=
0
,
mmu
;
if
(((
unsigned
long
)
virt_to_bus
(
memory
)
+
size
)
>
0xffffffffUL
)
if
(((
unsigned
long
)
virt_to_bus
(
memory
)
+
size
)
>
dma_mask
)
high
=
1
;
mmu
=
1
;
if
(
force_mmu
&&
!
(
gfp
&
GFP_DMA
))
...
...
@@ -222,7 +230,6 @@ void pci_free_consistent(struct pci_dev *hwdev, size_t size,
static
void
**
iommu_leak_tab
;
static
int
leak_trace
;
int
iommu_leak_pages
=
20
;
extern
unsigned
long
printk_address
(
unsigned
long
);
void
dump_leak
(
void
)
{
int
i
;
...
...
@@ -459,7 +466,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
extern
int
agp_amdk8_init
(
void
);
void
__init
pci_iommu_init
(
void
)
int
__init
pci_iommu_init
(
void
)
{
struct
agp_kern_info
info
;
unsigned
long
aper_size
;
...
...
@@ -468,6 +475,7 @@ void __init pci_iommu_init(void)
#ifndef CONFIG_AGP_AMD_8151
no_agp
=
1
;
#else
/* Makefile puts PCI initialization via subsys_initcall first. */
/* Add other K8 AGP bridge drivers here */
no_agp
=
no_agp
||
(
agp_amdk8_init
()
<
0
)
||
...
...
@@ -477,7 +485,7 @@ void __init pci_iommu_init(void)
if
(
no_iommu
||
(
!
force_mmu
&&
end_pfn
<
0xffffffff
>>
PAGE_SHIFT
))
{
printk
(
KERN_INFO
"PCI-DMA: Disabling IOMMU.
\n
"
);
no_iommu
=
1
;
return
;
return
-
1
;
}
if
(
no_agp
)
{
...
...
@@ -489,7 +497,7 @@ void __init pci_iommu_init(void)
if
(
err
<
0
)
{
printk
(
KERN_INFO
"PCI-DMA: Disabling IOMMU.
\n
"
);
no_iommu
=
1
;
return
;
return
-
1
;
}
}
...
...
@@ -540,8 +548,13 @@ void __init pci_iommu_init(void)
clear_kernel_mapping
((
unsigned
long
)
__va
(
iommu_bus_base
),
iommu_size
);
flush_gart
();
return
0
;
}
/* Must execute after PCI subsystem */
fs_initcall
(
pci_iommu_init
);
/* iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]]
size set size of iommu (in bytes)
noagp don't initialize the AGP driver and use full aperture.
...
...
@@ -589,4 +602,3 @@ __init int iommu_setup(char *opt)
}
return
1
;
}
arch/x86_64/kernel/pci-nommu.c
View file @
374046d5
...
...
@@ -2,13 +2,12 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <asm/proto.h>
/*
* Dummy IO MMU functions
*/
extern
unsigned
long
end_pfn
;
void
*
pci_alloc_consistent
(
struct
pci_dev
*
hwdev
,
size_t
size
,
dma_addr_t
*
dma_handle
)
{
...
...
arch/x86_64/kernel/process.c
View file @
374046d5
...
...
@@ -200,8 +200,6 @@ void show_regs(struct pt_regs *regs)
show_trace
(
&
regs
->
rsp
);
}
extern
void
load_gs_index
(
unsigned
);
/*
* Free current thread data structures etc..
*/
...
...
arch/x86_64/kernel/setup.c
View file @
374046d5
...
...
@@ -585,7 +585,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
void
__init
print_cpu_info
(
struct
cpuinfo_x86
*
c
)
{
if
(
c
->
x86_model_id
[
0
])
printk
(
"
AMD
%s"
,
c
->
x86_model_id
);
printk
(
"%s"
,
c
->
x86_model_id
);
if
(
c
->
x86_mask
||
c
->
cpuid_level
>=
0
)
printk
(
" stepping %02x
\n
"
,
c
->
x86_mask
);
...
...
arch/x86_64/kernel/signal.c
View file @
374046d5
...
...
@@ -475,8 +475,6 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 thread_info_
do_signal
(
regs
,
oldset
);
}
extern
int
exception_trace
;
void
signal_fault
(
struct
pt_regs
*
regs
,
void
*
frame
,
char
*
where
)
{
struct
task_struct
*
me
=
current
;
...
...
arch/x86_64/kernel/smpboot.c
View file @
374046d5
...
...
@@ -51,8 +51,7 @@
#include <asm/desc.h>
#include <asm/kdebug.h>
#include <asm/tlbflush.h>
extern
int
disable_apic
;
#include <asm/proto.h>
/* Bitmask of currently online CPUs */
unsigned
long
cpu_online_map
=
1
;
...
...
@@ -67,8 +66,6 @@ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
/* Set when the idlers are all forked */
int
smp_threads_ready
;
extern
void
time_init_smp
(
void
);
/*
* Trampoline 80x86 program as an array.
*/
...
...
@@ -128,7 +125,6 @@ static void __init synchronize_tsc_bp (void)
long
long
delta
;
long
one_usec
;
int
buggy
=
0
;
extern
unsigned
cpu_khz
;
printk
(
KERN_INFO
"checking TSC synchronization across %u CPUs: "
,
num_booting_cpus
());
...
...
@@ -242,8 +238,6 @@ static void __init synchronize_tsc_ap (void)
}
#undef NR_LOOPS
extern
void
calibrate_delay
(
void
);
static
atomic_t
init_deasserted
;
void
__init
smp_callin
(
void
)
...
...
@@ -337,8 +331,6 @@ void __init smp_callin(void)
int
cpucount
;
extern
int
cpu_idle
(
void
);
/*
* Activate a secondary processor.
*/
...
...
@@ -560,8 +552,6 @@ static int __init wakeup_secondary_via_INIT(int phys_apicid, unsigned int start_
return
(
send_status
|
accept_status
);
}
extern
unsigned
long
cpu_initialized
;
static
void
__init
do_boot_cpu
(
int
apicid
)
{
struct
task_struct
*
idle
;
...
...
arch/x86_64/kernel/time.c
View file @
374046d5
...
...
@@ -27,6 +27,7 @@
#include <asm/pgtable.h>
#include <asm/vsyscall.h>
#include <asm/timex.h>
#include <asm/proto.h>
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/apic.h>
#endif
...
...
@@ -38,9 +39,6 @@ extern int using_apic_timer;
spinlock_t
rtc_lock
=
SPIN_LOCK_UNLOCKED
;
spinlock_t
i8253_lock
=
SPIN_LOCK_UNLOCKED
;
extern
int
using_apic_timer
;
extern
void
smp_local_timer_interrupt
(
struct
pt_regs
*
regs
);
#undef HPET_HACK_ENABLE_DANGEROUS
...
...
arch/x86_64/kernel/traps.c
View file @
374046d5
...
...
@@ -41,13 +41,10 @@
#include <asm/smp.h>
#include <asm/pgalloc.h>
#include <asm/pda.h>
#include <asm/proto.h>
#include <linux/irq.h>
asmlinkage
int
system_call
(
void
);
asmlinkage
int
kernel_syscall
(
void
);
extern
void
ia32_syscall
(
void
);
extern
struct
gate_struct
idt_table
[
256
];
asmlinkage
void
divide_error
(
void
);
...
...
@@ -73,8 +70,6 @@ asmlinkage void machine_check(void);
asmlinkage
void
spurious_interrupt_bug
(
void
);
asmlinkage
void
call_debug
(
void
);
extern
int
exception_trace
;
struct
notifier_block
*
die_chain
;
static
inline
void
conditional_sti
(
struct
pt_regs
*
regs
)
...
...
@@ -457,8 +452,6 @@ DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
DO_ERROR_INFO
(
17
,
SIGBUS
,
"alignment check"
,
alignment_check
,
BUS_ADRALN
,
get_cr2
())
DO_ERROR
(
18
,
SIGSEGV
,
"reserved"
,
reserved
)
extern
void
dump_pagetable
(
unsigned
long
);
asmlinkage
void
do_general_protection
(
struct
pt_regs
*
regs
,
long
error_code
)
{
conditional_sti
(
regs
);
...
...
arch/x86_64/kernel/wakeup.S
deleted
100644 → 0
View file @
06b4a180
/*
*
ACPI
S3
entry
/
exit
handling
.
*
*
Notes
:
*
Relies
on
kernel
being
loaded
below
4
GB
.
*
Needs
restore_low_mappings
called
before
.
*
*
Copyright
2003
by
Andi
Kleen
,
SuSE
Labs
.
*
*
Long
mode
entry
loosely
based
on
example
code
in
chapter
14
of
the
x86
-
64
system
*
programmer
's manual.
*
*
Notebook
:
FIXME
need
to
interface
with
suspend
.
c
properly
.
do_magic
.
check
i386
.
rename
to
suspend64
.
S
Need
to
fix
vgacon
,
mtrr
,
bluesmoke
to
do
resume
Interrupts
should
be
off
until
the
io
-
apic
code
has
reinited
the
APIC
.
Need
support
for
that
in
the
pm
frame
work
or
a
special
hack
?
SMP
support
is
non
existent
.
Need
to
somehow
restart
the
other
CPUs
again
.
If
CPU
hotplug
was
working
it
could
be
used
.
Save
/
Restore
needs
to
run
on
the
same
CPU
.
Should
check
magic
like
i386
code
suspend
code
copies
something
.
check
what
it
is
.
*/
#include <linux/linkage.h>
#include <asm/msr.h>
#include <asm/segment.h>
#include <asm/page.h>
#define O(x) (x-acpi_wakeup)
.
text
.
code16
ENTRY
(
acpi_wakeup
)
/
*
16
bit
real
mode
entered
from
ACPI
BIOS
*/
/
*
The
machine
is
just
through
BIOS
setup
after
power
down
and
everything
set
up
by
Linux
needs
to
be
restored
.
*/
/
*
The
code
here
needs
to
be
position
independent
or
manually
relocated
,
because
it
is
copied
to
a
<
1
MB
page
for
real
mode
execution
*/
/
*
A20
enabled
(
according
to
ACPI
spec
)
*/
/
*
cs
=
acpi_wakeup
>>
4
; eip = acpi_wakeup & 0xF */
movw
%
cs
,%
ax
movw
%
ax
,%
ds
/*
make
%
ds
point
to
acpi_wakeup
*/
movw
%
ax
,%
ss
movw
$O
(
wakeup_stack
),%
sp
/*
setup
stack
*/
pushl
$
0
popfl
/*
clear
EFLAGS
*/
lgdt
%
ds
:
O
(
pGDT
)
/*
load
kernel
GDT
*/
movl
$
0x1
,%
eax
/*
enable
protected
mode
*/
movl
%
eax
,%
cr0
movl
%
ds
:
O
(
wakeup_page_table
),%
edi
ljmpl
$
__KERNEL16_CS
,
$
0
/*
->
s3_prot16
(
filled
in
earlier
by
caller
)
*/
/
*
patched
by
s3_restore_state
below
*/
pGDT
:
.
short
0
.
quad
0
.
align
4
.
globl
wakeup_page_table
wakeup_page_table
:
.
long
0
.
align
8
wakeup_stack
:
.
fill
128
,
1
,
0
.
globl
acpi_wakeup_end
acpi_wakeup_end
:
/
*
end
of
real
mode
trampoline
*/
/
*
pointed
to
by
__KERNEL16_CS
:
0
*/
.
code16
ENTRY
(
s3_prot16
)
/
*
Now
in
16
bit
protected
mode
,
still
no
paging
,
stack
/
data
segments
invalid
*/
/
*
Prepare
everything
for
64
bit
paging
,
but
still
keep
it
turned
off
*/
movl
%
cr4
,%
eax
bts
$
5
,%
eax
/*
set
PAE
bit
*/
movl
%
eax
,%
cr4
movl
%
edi
,%
cr3
/*
load
kernel
page
table
*/
movl
$
0x80000001
,%
eax
cpuid
/*
no
execute
supported
?
*/
movl
%
edx
,%
esi
movl
$MSR_EFER
,%
ecx
rdmsr
bts
$
8
,%
eax
/*
long
mode
*/
bt
$
20
,%
esi
/*
NX
supported
?
*/
jnc
1
f
bt
$
_EFER_NX
,%
eax
1
:
wrmsr
/*
set
temporary
efer
-
real
one
is
restored
a
bit
later
*/
movl
%
cr0
,%
eax
bts
$
31
,%
eax
/*
paging
*/
movl
%
eax
,%
cr0
/
*
running
in
identity
mapping
now
*/
/
*
go
to
64
bit
code
segment
*/
ljmpl
$
__KERNEL_CS
,
$s3_restore_state
-
__START_KERNEL_map
.
code64
.
macro
SAVEMSR
msr
,
target
movl
$\
msr
,%
ecx
rdmsr
shlq
$
32
,%
rdx
orq
%
rax
,%
rdx
movq
%
rdx
,
\
target
(%
rip
)
.
endm
.
macro
RESTMSR
msr
,
src
movl
$\
msr
,%
ecx
movq
\
src
(%
rip
),%
rax
movq
%
rax
,%
rdx
shrq
$
32
,%
rdx
wrmsr
.
endm
.
macro
SAVECTL
reg
movq
%
\
reg
,%
rax
movq
%
rax
,
saved_
\
reg
(%
rip
)
.
endm
.
macro
RESTCTL
reg
movq
saved_
\
reg
(%
rip
),%
rax
movq
%
rax
,%
\
reg
.
endm
/
*
Running
in
identity
mapping
,
long
mode
*/
s3_restore_state_low
:
movq
$s3_restore_state
,%
rax
jmpq
*%
rax
/
*
Running
in
real
kernel
mapping
now
*/
s3_restore_state
:
xorl
%
eax
,%
eax
movl
%
eax
,%
ds
movq
saved_rsp
(%
rip
),%
rsp
movw
saved_ss
(%
rip
),%
ss
movw
saved_fs
(%
rip
),%
fs
movw
saved_gs
(%
rip
),%
gs
movw
saved_es
(%
rip
),%
es
movw
saved_ds
(%
rip
),%
ds
lidt
saved_idt
ltr
saved_tr
lldt
saved_ldt
/
*
gdt
is
already
loaded
*/
RESTCTL
cr0
RESTCTL
cr4
/
*
cr3
is
already
loaded
*/
RESTMSR
MSR_EFER
,
saved_efer
RESTMSR
MSR_LSTAR
,
saved_lstar
RESTMSR
MSR_CSTAR
,
saved_cstar
RESTMSR
MSR_FS_BASE
,
saved_fs_base
RESTMSR
MSR_GS_BASE
,
saved_gs_base
RESTMSR
MSR_KERNEL_GS_BASE
,
saved_kernel_gs_base
RESTMSR
MSR_SYSCALL_MASK
,
saved_syscall_mask
fxrstor
fpustate
(%
rip
)
RESTCTL
dr0
RESTCTL
dr1
RESTCTL
dr2
RESTCTL
dr3
RESTCTL
dr6
RESTCTL
dr7
movq
saved_rflags
(%
rip
),%
rax
pushq
%
rax
popfq
movq
saved_rbp
(%
rip
),%
rbp
movq
saved_rbx
(%
rip
),%
rbx
movq
saved_r12
(%
rip
),%
r12
movq
saved_r13
(%
rip
),%
r13
movq
saved_r14
(%
rip
),%
r14
movq
saved_r15
(%
rip
),%
r15
ret
ENTRY
(
acpi_prepare_wakeup
)
sgdt
saved_gdt
/
*
copy
gdt
descr
and
page
table
to
low
level
wakeup
code
so
that
it
can
reload
them
early
.
*/
movq
acpi_wakeup_address
(%
rip
),%
rax
movw
saved_gdt
+
8
(%
rip
),%
cx
movw
%
cx
,
O
(
pGDT
)+
8
(%
rax
)
movq
saved_gdt
(%
rip
),%
rcx
movq
%
rcx
,
O
(
pGDT
)(%
rax
)
movq
%
cr3
,%
rdi
movl
%
edi
,
O
(
wakeup_page_table
)(%
rax
)
ret
/
*
Save
CPU
state
.
*/
/
*
Everything
saved
here
needs
to
be
restored
above
.
*/
ENTRY
(
do_suspend_lowlevel
)
testl
%
edi
,%
edi
jnz
s3_restore_state
SAVECTL
cr0
SAVECTL
cr4
SAVECTL
cr3
str
saved_tr
sidt
saved_idt
sgdt
saved_gdt
sldt
saved_ldt
SAVEMSR
MSR_EFER
,
saved_efer
SAVEMSR
MSR_LSTAR
,
saved_lstar
SAVEMSR
MSR_CSTAR
,
saved_cstar
SAVEMSR
MSR_FS_BASE
,
saved_fs_base
SAVEMSR
MSR_GS_BASE
,
saved_gs_base
SAVEMSR
MSR_KERNEL_GS_BASE
,
saved_kernel_gs_base
SAVEMSR
MSR_SYSCALL_MASK
,
saved_syscall_mask
movw
%
ds
,
saved_ds
(%
rip
)
movw
%
es
,
saved_es
(%
rip
)
movw
%
fs
,
saved_fs
(%
rip
)
movw
%
gs
,
saved_gs
(%
rip
)
movw
%
ss
,
saved_ss
(%
rip
)
movq
%
rsp
,
saved_rsp
(%
rip
)
pushfq
popq
%
rax
movq
%
rax
,
saved_rflags
(%
rip
)
SAVECTL
dr0
SAVECTL
dr1
SAVECTL
dr2
SAVECTL
dr3
SAVECTL
dr6
SAVECTL
dr7
fxsave
fpustate
(%
rip
)
/
*
finally
save
callee
saved
registers
*/
movq
%
rbp
,
saved_rbp
(%
rip
)
movq
%
rbx
,
saved_rbx
(%
rip
)
movq
%
r12
,
saved_r12
(%
rip
)
movq
%
r13
,
saved_r13
(%
rip
)
movq
%
r14
,
saved_r14
(%
rip
)
movq
%
r15
,
saved_r15
(%
rip
)
movq
$
3
,%
rdi
call
acpi_enter_sleep_state
ret
/*
should
not
happen
*/
.
data
.
align
8
saved_efer
:
.
quad
0
saved_lstar
:
.
quad
0
saved_cstar
:
.
quad
0
saved_cr4
:
.
quad
0
saved_cr3
:
.
quad
0
saved_cr0
:
.
quad
0
saved_rbp
:
.
quad
0
saved_rbx
:
.
quad
0
saved_rsp
:
.
quad
0
saved_r12
:
.
quad
0
saved_r13
:
.
quad
0
saved_r14
:
.
quad
0
saved_r15
:
.
quad
0
saved_rflags
:
.
quad
0
saved_gs_base
:
.
quad
0
saved_fs_base
:
.
quad
0
saved_kernel_gs_base
:
.
quad
0
saved_syscall_mask
:
.
quad
0
saved_dr0
:
.
quad
0
saved_dr1
:
.
quad
0
saved_dr2
:
.
quad
0
saved_dr3
:
.
quad
0
saved_dr6
:
.
quad
0
saved_dr7
:
.
quad
0
saved_ds
:
.
short
0
saved_fs
:
.
short
0
saved_gs
:
.
short
0
saved_es
:
.
short
0
saved_ss
:
.
short
0
saved_idt
:
.
short
0
.
quad
0
saved_ldt
:
.
short
0
saved_gdt
:
.
short
0
.
quad
0
saved_tr
:
.
short
0
.
align
16
fpustate
:
.
fill
512
,
1
,
0
arch/x86_64/lib/delay.c
View file @
374046d5
...
...
@@ -21,7 +21,6 @@ int x86_udelay_tsc = 0; /* Delay via TSC */
void
__delay
(
unsigned
long
loops
)
{
#ifndef CONFIG_SIMNOW
unsigned
long
bclock
,
now
;
rdtscl
(
bclock
);
...
...
@@ -31,7 +30,6 @@ void __delay(unsigned long loops)
rdtscl
(
now
);
}
while
((
now
-
bclock
)
<
loops
);
#endif
}
inline
void
__const_udelay
(
unsigned
long
xloops
)
...
...
arch/x86_64/mm/init.c
View file @
374046d5
...
...
@@ -24,6 +24,7 @@
#endif
#include <linux/pagemap.h>
#include <linux/bootmem.h>
#include <linux/proc_fs.h>
#include <asm/processor.h>
#include <asm/system.h>
...
...
@@ -41,6 +42,8 @@
#define Dprintk(x...)
extern
char
_stext
;
DEFINE_PER_CPU
(
struct
mmu_gather
,
mmu_gathers
);
/*
...
...
@@ -393,6 +396,9 @@ static inline int page_is_ram (unsigned long pagenr)
return
0
;
}
static
struct
kcore_list
kcore_mem
,
kcore_vmalloc
,
kcore_kernel
,
kcore_modules
,
kcore_vsyscall
;
void
__init
mem_init
(
void
)
{
int
codesize
,
reservedpages
,
datasize
,
initsize
;
...
...
@@ -434,6 +440,15 @@ void __init mem_init(void)
datasize
=
(
unsigned
long
)
&
_edata
-
(
unsigned
long
)
&
_etext
;
initsize
=
(
unsigned
long
)
&
__init_end
-
(
unsigned
long
)
&
__init_begin
;
/* Register memory areas for /proc/kcore */
kclist_add
(
&
kcore_mem
,
__va
(
0
),
max_low_pfn
<<
PAGE_SHIFT
);
kclist_add
(
&
kcore_vmalloc
,
(
void
*
)
VMALLOC_START
,
VMALLOC_END
-
VMALLOC_START
);
kclist_add
(
&
kcore_kernel
,
&
_stext
,
&
_end
-
&
_stext
);
kclist_add
(
&
kcore_modules
,
(
void
*
)
MODULES_VADDR
,
MODULES_LEN
);
kclist_add
(
&
kcore_vsyscall
,
(
void
*
)
VSYSCALL_START
,
VSYSCALL_END
-
VSYSCALL_START
);
printk
(
"Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)
\n
"
,
(
unsigned
long
)
nr_free_pages
()
<<
(
PAGE_SHIFT
-
10
),
end_pfn
<<
(
PAGE_SHIFT
-
10
),
...
...
@@ -462,7 +477,7 @@ void free_initmem(void)
ClearPageReserved
(
virt_to_page
(
addr
));
set_page_count
(
virt_to_page
(
addr
),
1
);
#ifdef CONFIG_INIT_DEBUG
memset
(
addr
&
~
(
PAGE_SIZE
-
1
),
0xcc
,
PAGE_SIZE
);
memset
(
(
void
*
)(
addr
&
~
(
PAGE_SIZE
-
1
)
),
0xcc
,
PAGE_SIZE
);
#endif
free_page
(
addr
);
totalram_pages
++
;
...
...
@@ -497,3 +512,29 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
reserve_bootmem
(
phys
,
len
);
#endif
}
int
kern_addr_valid
(
unsigned
long
addr
)
{
unsigned
long
above
=
((
long
)
addr
)
>>
__VIRTUAL_MASK_SHIFT
;
if
(
above
!=
0
&&
above
!=
-
1UL
)
return
0
;
pml4_t
*
pml4
=
pml4_offset_k
(
addr
);
if
(
pml4_none
(
*
pml4
))
return
0
;
pgd_t
*
pgd
=
pgd_offset_k
(
addr
);
if
(
pgd_none
(
*
pgd
))
return
0
;
pmd_t
*
pmd
=
pmd_offset
(
pgd
,
addr
);
if
(
pmd_none
(
*
pmd
))
return
0
;
if
(
pmd_large
(
*
pmd
))
return
pfn_valid
(
pmd_pfn
(
*
pmd
));
pte_t
*
pte
=
pte_offset_kernel
(
pmd
,
addr
);
if
(
pte_none
(
*
pte
))
return
0
;
return
pfn_valid
(
pte_pfn
(
*
pte
));
}
arch/x86_64/pci/Makefile
View file @
374046d5
#
# Makefile for X86_64 specific PCI routines
#
obj-y
:=
x86-64.o
# Reuse the i386 PCI subsystem using symlinks
#
obj-y
:=
i386.o
obj-$(CONFIG_PCI_DIRECT)
+=
direct.o
obj-y
+=
fixup.o
obj-$(CONFIG_ACPI_PCI)
+=
acpi.o
obj-y
+=
legacy.o irq.o common.o
$(obj)/direct.c
:
$(obj)/pci.h
@
ln
-sf
../../i386/pci/direct.c
$(obj)
/direct.c
$(obj)/legacy.c
:
$(obj)/pci.h
@
ln
-sf
../../i386/pci/legacy.c
$(obj)
/legacy.c
$(obj)/common.c
:
$(obj)/pci.h
@
ln
-sf
../../i386/pci/common.c
$(obj)
/common.c
$(obj)/acpi.c
:
$(obj)/pci.h
@
ln
-sf
../../i386/pci/acpi.c
$(obj)
/acpi.c
$(obj)/pci.h
:
@
ln
-sf
../../i386/pci/pci.h
$(obj)
/pci.h
$(obj)/irq.c
:
$(obj)/pci.h
@
ln
-sf
../../i386/pci/irq.c
$(obj)
/irq.c
$(obj)/fixup.c
:
$(obj)/pci.h
@
ln
-sf
../../i386/pci/fixup.c
$(obj)
/fixup.c
$(obj)/i386.c
:
$(obj)/pci.h
@
ln
-sf
../../i386/pci/i386.c
$(obj)
/i386.c
clean-files
+=
i386.c legacy.c fixup.c acpi.c irq.c pci.h common.c direct.c
arch/x86_64/pci/acpi.c
deleted
100644 → 0
View file @
06b4a180
#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/init.h>
#include "pci.h"
static
int
__init
pci_acpi_init
(
void
)
{
if
(
pcibios_scanned
)
return
0
;
if
(
!
(
pci_probe
&
PCI_NO_ACPI_ROUTING
))
{
if
(
!
acpi_pci_irq_init
())
{
printk
(
KERN_INFO
"PCI: Using ACPI for IRQ routing
\n
"
);
printk
(
KERN_INFO
"PCI: if you experience problems, try using option 'pci=noacpi'
\n
"
);
pcibios_scanned
++
;
pcibios_enable_irq
=
acpi_pci_irq_enable
;
}
else
printk
(
KERN_WARNING
"PCI: Invalid ACPI-PCI IRQ routing table
\n
"
);
/* still scan manually in case ACPI forgot some bus */
pcibios_fixup_peer_bridges
();
}
return
0
;
}
subsys_initcall
(
pci_acpi_init
);
arch/x86_64/pci/changelog
deleted
100644 → 0
View file @
06b4a180
See arch/i386/pci/changelog for early changelog.
arch/x86_64/pci/common.c
deleted
100644 → 0
View file @
06b4a180
/*
* Low-Level PCI Support for PC
*
* (c) 1999--2000 Martin Mares <mj@ucw.cz>
Note: on x86-64 there is no PCI BIOS so there is no way to sort in the
same order as 32bit Linux. This could cause grief for dualbooting because
devices may wander. May want to use ACPI for sorting eventually.
*/
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <asm/segment.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/cache.h>
#include "pci.h"
unsigned
int
pci_probe
=
PCI_PROBE_CONF1
|
PCI_PROBE_CONF2
;
int
pcibios_last_bus
=
0xff
;
/* XXX */
struct
pci_bus
*
pci_root_bus
=
NULL
;
struct
pci_ops
*
pci_root_ops
=
NULL
;
int
(
*
pci_config_read
)(
int
seg
,
int
bus
,
int
dev
,
int
fn
,
int
reg
,
int
len
,
u32
*
value
)
=
NULL
;
int
(
*
pci_config_write
)(
int
seg
,
int
bus
,
int
dev
,
int
fn
,
int
reg
,
int
len
,
u32
value
)
=
NULL
;
/*
* legacy, numa, and acpi all want to call pcibios_scan_root
* from their initcalls. This flag prevents that.
*/
int
pcibios_scanned
;
/*
* This interrupt-safe spinlock protects all accesses to PCI
* configuration space.
*/
spinlock_t
pci_config_lock
=
SPIN_LOCK_UNLOCKED
;
/*
* Several buggy motherboards address only 16 devices and mirror
* them to next 16 IDs. We try to detect this `feature' on all
* primary buses (those containing host bridges as they are
* expected to be unique) and remove the ghost devices.
*/
static
void
__devinit
pcibios_fixup_ghosts
(
struct
pci_bus
*
b
)
{
struct
list_head
*
ln
,
*
mn
;
struct
pci_dev
*
d
,
*
e
;
int
mirror
=
PCI_DEVFN
(
16
,
0
);
int
seen_host_bridge
=
0
;
int
i
;
DBG
(
"PCI: Scanning for ghost devices on bus %d
\n
"
,
b
->
number
);
for
(
ln
=
b
->
devices
.
next
;
ln
!=
&
b
->
devices
;
ln
=
ln
->
next
)
{
d
=
pci_dev_b
(
ln
);
if
((
d
->
class
>>
8
)
==
PCI_CLASS_BRIDGE_HOST
)
seen_host_bridge
++
;
for
(
mn
=
ln
->
next
;
mn
!=
&
b
->
devices
;
mn
=
mn
->
next
)
{
e
=
pci_dev_b
(
mn
);
if
(
e
->
devfn
!=
d
->
devfn
+
mirror
||
e
->
vendor
!=
d
->
vendor
||
e
->
device
!=
d
->
device
||
e
->
class
!=
d
->
class
)
continue
;
for
(
i
=
0
;
i
<
PCI_NUM_RESOURCES
;
i
++
)
if
(
e
->
resource
[
i
].
start
!=
d
->
resource
[
i
].
start
||
e
->
resource
[
i
].
end
!=
d
->
resource
[
i
].
end
||
e
->
resource
[
i
].
flags
!=
d
->
resource
[
i
].
flags
)
continue
;
break
;
}
if
(
mn
==
&
b
->
devices
)
return
;
}
if
(
!
seen_host_bridge
)
return
;
printk
(
KERN_WARNING
"PCI: Ignoring ghost devices on bus %02x
\n
"
,
b
->
number
);
ln
=
&
b
->
devices
;
while
(
ln
->
next
!=
&
b
->
devices
)
{
d
=
pci_dev_b
(
ln
->
next
);
if
(
d
->
devfn
>=
mirror
)
{
list_del
(
&
d
->
global_list
);
list_del
(
&
d
->
bus_list
);
kfree
(
d
);
}
else
ln
=
ln
->
next
;
}
}
struct
pbus_set_ranges_data
;
void
__devinit
pcibios_fixup_pbus_ranges
(
struct
pci_bus
*
bus
,
struct
pbus_set_ranges_data
*
ranges
)
{
}
/*
* Called after each bus is probed, but before its children
* are examined.
*/
void
__devinit
pcibios_fixup_bus
(
struct
pci_bus
*
b
)
{
pcibios_fixup_ghosts
(
b
);
pci_read_bridge_bases
(
b
);
}
struct
pci_bus
*
__devinit
pcibios_scan_root
(
int
busnum
)
{
struct
list_head
*
list
;
struct
pci_bus
*
bus
;
list_for_each
(
list
,
&
pci_root_buses
)
{
bus
=
pci_bus_b
(
list
);
if
(
bus
->
number
==
busnum
)
{
/* Already scanned */
return
bus
;
}
}
printk
(
"PCI: Probing PCI hardware (bus %02x)
\n
"
,
busnum
);
return
pci_scan_bus
(
busnum
,
pci_root_ops
,
NULL
);
}
extern
u8
pci_cache_line_size
;
static
int
__init
pcibios_init
(
void
)
{
if
(
!
pci_root_ops
)
{
printk
(
"PCI: System does not support PCI
\n
"
);
return
0
;
}
pci_cache_line_size
=
boot_cpu_data
.
x86_clflush_size
>>
2
;
pcibios_resource_survey
();
#ifdef CONFIG_GART_IOMMU
pci_iommu_init
();
#endif
/* may eventually need to do ACPI sort here. */
return
0
;
}
subsys_initcall
(
pcibios_init
);
char
*
__devinit
pcibios_setup
(
char
*
str
)
{
if
(
!
strcmp
(
str
,
"off"
))
{
pci_probe
=
0
;
return
NULL
;
}
#ifdef CONFIG_PCI_DIRECT
else
if
(
!
strcmp
(
str
,
"conf1"
))
{
pci_probe
=
PCI_PROBE_CONF1
|
PCI_NO_CHECKS
;
return
NULL
;
}
else
if
(
!
strcmp
(
str
,
"conf2"
))
{
pci_probe
=
PCI_PROBE_CONF2
|
PCI_NO_CHECKS
;
return
NULL
;
}
#endif
#ifdef CONFIG_ACPI_PCI
else
if
(
!
strcmp
(
str
,
"noacpi"
))
{
pci_probe
|=
PCI_NO_ACPI_ROUTING
;
return
NULL
;
}
#endif
else
if
(
!
strcmp
(
str
,
"rom"
))
{
pci_probe
|=
PCI_ASSIGN_ROMS
;
return
NULL
;
}
else
if
(
!
strcmp
(
str
,
"assign-busses"
))
{
pci_probe
|=
PCI_ASSIGN_ALL_BUSSES
;
return
NULL
;
}
else
if
(
!
strcmp
(
str
,
"usepirqmask"
))
{
pci_probe
|=
PCI_USE_PIRQ_MASK
;
return
NULL
;
}
else
if
(
!
strncmp
(
str
,
"irqmask="
,
8
))
{
pcibios_irq_mask
=
simple_strtol
(
str
+
8
,
NULL
,
0
);
return
NULL
;
}
else
if
(
!
strncmp
(
str
,
"lastbus="
,
8
))
{
pcibios_last_bus
=
simple_strtol
(
str
+
8
,
NULL
,
0
);
return
NULL
;
}
return
str
;
}
unsigned
int
pcibios_assign_all_busses
(
void
)
{
return
(
pci_probe
&
PCI_ASSIGN_ALL_BUSSES
)
?
1
:
0
;
}
int
pcibios_enable_device
(
struct
pci_dev
*
dev
,
int
mask
)
{
int
err
;
if
((
err
=
pcibios_enable_resources
(
dev
,
mask
))
<
0
)
return
err
;
return
pcibios_enable_irq
(
dev
);
}
arch/x86_64/pci/direct.c
deleted
100644 → 0
View file @
06b4a180
/*
* direct.c - Low-level direct PCI config space access
*/
#include <linux/pci.h>
#include <linux/init.h>
#include "pci.h"
/*
* Functions for accessing PCI configuration space with type 1 accesses
*/
#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
static
int
__pci_conf1_read
(
int
seg
,
int
bus
,
int
dev
,
int
fn
,
int
reg
,
int
len
,
u32
*
value
)
{
unsigned
long
flags
;
if
(
!
value
||
(
bus
>
255
)
||
(
dev
>
31
)
||
(
fn
>
7
)
||
(
reg
>
255
))
return
-
EINVAL
;
spin_lock_irqsave
(
&
pci_config_lock
,
flags
);
outl
(
PCI_CONF1_ADDRESS
(
bus
,
dev
,
fn
,
reg
),
0xCF8
);
switch
(
len
)
{
case
1
:
*
value
=
inb
(
0xCFC
+
(
reg
&
3
));
break
;
case
2
:
*
value
=
inw
(
0xCFC
+
(
reg
&
2
));
break
;
case
4
:
*
value
=
inl
(
0xCFC
);
break
;
}
spin_unlock_irqrestore
(
&
pci_config_lock
,
flags
);
return
0
;
}
static
int
__pci_conf1_write
(
int
seg
,
int
bus
,
int
dev
,
int
fn
,
int
reg
,
int
len
,
u32
value
)
{
unsigned
long
flags
;
if
((
bus
>
255
)
||
(
dev
>
31
)
||
(
fn
>
7
)
||
(
reg
>
255
))
return
-
EINVAL
;
spin_lock_irqsave
(
&
pci_config_lock
,
flags
);
outl
(
PCI_CONF1_ADDRESS
(
bus
,
dev
,
fn
,
reg
),
0xCF8
);
switch
(
len
)
{
case
1
:
outb
((
u8
)
value
,
0xCFC
+
(
reg
&
3
));
break
;
case
2
:
outw
((
u16
)
value
,
0xCFC
+
(
reg
&
2
));
break
;
case
4
:
outl
((
u32
)
value
,
0xCFC
);
break
;
}
spin_unlock_irqrestore
(
&
pci_config_lock
,
flags
);
return
0
;
}
#undef PCI_CONF1_ADDRESS
static
int
pci_conf1_read
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
*
value
)
{
return
__pci_conf1_read
(
0
,
bus
->
number
,
PCI_SLOT
(
devfn
),
PCI_FUNC
(
devfn
),
where
,
size
,
value
);
}
static
int
pci_conf1_write
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
value
)
{
return
__pci_conf1_write
(
0
,
bus
->
number
,
PCI_SLOT
(
devfn
),
PCI_FUNC
(
devfn
),
where
,
size
,
value
);
}
static
struct
pci_ops
pci_direct_conf1
=
{
.
read
=
pci_conf1_read
,
.
write
=
pci_conf1_write
,
};
/*
* Functions for accessing PCI configuration space with type 2 accesses
*/
#define PCI_CONF2_ADDRESS(dev, reg) (u16)(0xC000 | (dev << 8) | reg)
static
int
__pci_conf2_read
(
int
seg
,
int
bus
,
int
dev
,
int
fn
,
int
reg
,
int
len
,
u32
*
value
)
{
unsigned
long
flags
;
if
(
!
value
||
(
bus
>
255
)
||
(
dev
>
31
)
||
(
fn
>
7
)
||
(
reg
>
255
))
return
-
EINVAL
;
if
(
dev
&
0x10
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
spin_lock_irqsave
(
&
pci_config_lock
,
flags
);
outb
((
u8
)(
0xF0
|
(
fn
<<
1
)),
0xCF8
);
outb
((
u8
)
bus
,
0xCFA
);
switch
(
len
)
{
case
1
:
*
value
=
inb
(
PCI_CONF2_ADDRESS
(
dev
,
reg
));
break
;
case
2
:
*
value
=
inw
(
PCI_CONF2_ADDRESS
(
dev
,
reg
));
break
;
case
4
:
*
value
=
inl
(
PCI_CONF2_ADDRESS
(
dev
,
reg
));
break
;
}
outb
(
0
,
0xCF8
);
spin_unlock_irqrestore
(
&
pci_config_lock
,
flags
);
return
0
;
}
static
int
__pci_conf2_write
(
int
seg
,
int
bus
,
int
dev
,
int
fn
,
int
reg
,
int
len
,
u32
value
)
{
unsigned
long
flags
;
if
((
bus
>
255
)
||
(
dev
>
31
)
||
(
fn
>
7
)
||
(
reg
>
255
))
return
-
EINVAL
;
if
(
dev
&
0x10
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
spin_lock_irqsave
(
&
pci_config_lock
,
flags
);
outb
((
u8
)(
0xF0
|
(
fn
<<
1
)),
0xCF8
);
outb
((
u8
)
bus
,
0xCFA
);
switch
(
len
)
{
case
1
:
outb
((
u8
)
value
,
PCI_CONF2_ADDRESS
(
dev
,
reg
));
break
;
case
2
:
outw
((
u16
)
value
,
PCI_CONF2_ADDRESS
(
dev
,
reg
));
break
;
case
4
:
outl
((
u32
)
value
,
PCI_CONF2_ADDRESS
(
dev
,
reg
));
break
;
}
outb
(
0
,
0xCF8
);
spin_unlock_irqrestore
(
&
pci_config_lock
,
flags
);
return
0
;
}
#undef PCI_CONF2_ADDRESS
static
int
pci_conf2_read
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
*
value
)
{
return
__pci_conf2_read
(
0
,
bus
->
number
,
PCI_SLOT
(
devfn
),
PCI_FUNC
(
devfn
),
where
,
size
,
value
);
}
static
int
pci_conf2_write
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
value
)
{
return
__pci_conf2_write
(
0
,
bus
->
number
,
PCI_SLOT
(
devfn
),
PCI_FUNC
(
devfn
),
where
,
size
,
value
);
}
static
struct
pci_ops
pci_direct_conf2
=
{
.
read
=
pci_conf2_read
,
.
write
=
pci_conf2_write
,
};
/*
* Before we decide to use direct hardware access mechanisms, we try to do some
* trivial checks to ensure it at least _seems_ to be working -- we just test
* whether bus 00 contains a host bridge (this is similar to checking
* techniques used in XFree86, but ours should be more reliable since we
* attempt to make use of direct access hints provided by the PCI BIOS).
*
* This should be close to trivial, but it isn't, because there are buggy
* chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
*/
static
int
__devinit
pci_sanity_check
(
struct
pci_ops
*
o
)
{
u32
x
=
0
;
int
retval
=
0
;
struct
pci_bus
*
bus
;
/* Fake bus and device */
struct
pci_dev
*
dev
;
if
(
pci_probe
&
PCI_NO_CHECKS
)
return
1
;
bus
=
kmalloc
(
sizeof
(
*
bus
),
GFP_ATOMIC
);
dev
=
kmalloc
(
sizeof
(
*
dev
),
GFP_ATOMIC
);
if
(
!
bus
||
!
dev
)
{
printk
(
KERN_ERR
"Out of memory in %s
\n
"
,
__FUNCTION__
);
goto
exit
;
}
bus
->
number
=
0
;
dev
->
bus
=
bus
;
for
(
dev
->
devfn
=
0
;
dev
->
devfn
<
0x100
;
dev
->
devfn
++
)
if
((
!
o
->
read
(
bus
,
dev
->
devfn
,
PCI_CLASS_DEVICE
,
2
,
&
x
)
&&
(
x
==
PCI_CLASS_BRIDGE_HOST
||
x
==
PCI_CLASS_DISPLAY_VGA
))
||
(
!
o
->
read
(
bus
,
dev
->
devfn
,
PCI_VENDOR_ID
,
2
,
&
x
)
&&
(
x
==
PCI_VENDOR_ID_INTEL
||
x
==
PCI_VENDOR_ID_COMPAQ
)))
{
retval
=
1
;
goto
exit
;
}
DBG
(
"PCI: Sanity check failed
\n
"
);
exit:
kfree
(
dev
);
kfree
(
bus
);
return
retval
;
}
static
int
__init
pci_direct_init
(
void
)
{
unsigned
int
tmp
;
unsigned
long
flags
;
local_irq_save
(
flags
);
/*
* Check if configuration type 1 works.
*/
if
(
pci_probe
&
PCI_PROBE_CONF1
)
{
outb
(
0x01
,
0xCFB
);
tmp
=
inl
(
0xCF8
);
outl
(
0x80000000
,
0xCF8
);
if
(
inl
(
0xCF8
)
==
0x80000000
&&
pci_sanity_check
(
&
pci_direct_conf1
))
{
outl
(
tmp
,
0xCF8
);
local_irq_restore
(
flags
);
printk
(
KERN_INFO
"PCI: Using configuration type 1
\n
"
);
if
(
!
request_region
(
0xCF8
,
8
,
"PCI conf1"
))
pci_root_ops
=
NULL
;
else
pci_root_ops
=
&
pci_direct_conf1
;
return
0
;
}
outl
(
tmp
,
0xCF8
);
}
/*
* Check if configuration type 2 works.
*/
if
(
pci_probe
&
PCI_PROBE_CONF2
)
{
outb
(
0x00
,
0xCFB
);
outb
(
0x00
,
0xCF8
);
outb
(
0x00
,
0xCFA
);
if
(
inb
(
0xCF8
)
==
0x00
&&
inb
(
0xCFA
)
==
0x00
&&
pci_sanity_check
(
&
pci_direct_conf2
))
{
local_irq_restore
(
flags
);
printk
(
KERN_INFO
"PCI: Using configuration type 2
\n
"
);
if
(
!
request_region
(
0xCF8
,
4
,
"PCI conf2"
))
pci_root_ops
=
NULL
;
else
pci_root_ops
=
&
pci_direct_conf2
;
return
0
;
}
}
local_irq_restore
(
flags
);
return
0
;
}
arch_initcall
(
pci_direct_init
);
arch/x86_64/pci/fixup.c
deleted
100644 → 0
View file @
06b4a180
/*
* Exceptions for specific devices. Usually work-arounds for fatal design flaws.
*
Short list on x86-64........so far.
*/
#include <linux/pci.h>
#include <linux/init.h>
#include "pci.h"
static
void
__devinit
pci_fixup_ncr53c810
(
struct
pci_dev
*
d
)
{
/*
* NCR 53C810 returns class code 0 (at least on some systems).
* Fix class to be PCI_CLASS_STORAGE_SCSI
*/
if
(
!
d
->
class
)
{
printk
(
KERN_WARNING
"PCI: fixing NCR 53C810 class code for %s
\n
"
,
d
->
slot_name
);
d
->
class
=
PCI_CLASS_STORAGE_SCSI
<<
8
;
}
}
static
void
__devinit
pci_fixup_ide_bases
(
struct
pci_dev
*
d
)
{
int
i
;
/*
* PCI IDE controllers use non-standard I/O port decoding, respect it.
*/
if
((
d
->
class
>>
8
)
!=
PCI_CLASS_STORAGE_IDE
)
return
;
DBG
(
"PCI: IDE base address fixup for %s
\n
"
,
d
->
slot_name
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
struct
resource
*
r
=
&
d
->
resource
[
i
];
if
((
r
->
start
&
~
0x80
)
==
0x374
)
{
r
->
start
|=
2
;
r
->
end
=
r
->
start
;
}
}
}
struct
pci_fixup
pcibios_fixups
[]
=
{
{
PCI_FIXUP_HEADER
,
PCI_ANY_ID
,
PCI_ANY_ID
,
pci_fixup_ide_bases
},
{
PCI_FIXUP_HEADER
,
PCI_VENDOR_ID_NCR
,
PCI_DEVICE_ID_NCR_53C810
,
pci_fixup_ncr53c810
},
{
0
}
};
arch/x86_64/pci/irq.c
deleted
100644 → 0
View file @
06b4a180
/*
* Low-Level PCI Support for PC -- Routing of Interrupts
*
* (c) 1999--2000 Martin Mares <mj@ucw.cz>
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/io_apic.h>
#include "pci.h"
#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
#define PIRQ_VERSION 0x0100
int
broken_hp_bios_irq9
;
static
struct
irq_routing_table
*
pirq_table
;
/*
* Never use: 0, 1, 2 (timer, keyboard, and cascade)
* Avoid using: 13, 14 and 15 (FP error and IDE).
* Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse)
*/
unsigned
int
pcibios_irq_mask
=
0xfff8
;
static
int
pirq_penalty
[
16
]
=
{
1000000
,
1000000
,
1000000
,
1000
,
1000
,
0
,
1000
,
1000
,
0
,
0
,
0
,
0
,
1000
,
100000
,
100000
,
100000
};
struct
irq_router
{
char
*
name
;
u16
vendor
,
device
;
int
(
*
get
)(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
);
int
(
*
set
)(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
,
int
new
);
};
int
(
*
pcibios_enable_irq
)(
struct
pci_dev
*
dev
)
=
NULL
;
/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
static
struct
irq_routing_table
*
__init
pirq_find_routing_table
(
void
)
{
u8
*
addr
;
struct
irq_routing_table
*
rt
;
int
i
;
u8
sum
;
for
(
addr
=
(
u8
*
)
__va
(
0xf0000
);
addr
<
(
u8
*
)
__va
(
0x100000
);
addr
+=
16
)
{
rt
=
(
struct
irq_routing_table
*
)
addr
;
if
(
rt
->
signature
!=
PIRQ_SIGNATURE
||
rt
->
version
!=
PIRQ_VERSION
||
rt
->
size
%
16
||
rt
->
size
<
sizeof
(
struct
irq_routing_table
))
continue
;
sum
=
0
;
for
(
i
=
0
;
i
<
rt
->
size
;
i
++
)
sum
+=
addr
[
i
];
if
(
!
sum
)
{
DBG
(
"PCI: Interrupt Routing Table found at 0x%p
\n
"
,
rt
);
return
rt
;
}
}
return
NULL
;
}
/*
* If we have a IRQ routing table, use it to search for peer host
* bridges. It's a gross hack, but since there are no other known
* ways how to get a list of buses, we have to go this way.
*/
static
void
__init
pirq_peer_trick
(
void
)
{
struct
irq_routing_table
*
rt
=
pirq_table
;
u8
busmap
[
256
];
int
i
;
struct
irq_info
*
e
;
memset
(
busmap
,
0
,
sizeof
(
busmap
));
for
(
i
=
0
;
i
<
(
rt
->
size
-
sizeof
(
struct
irq_routing_table
))
/
sizeof
(
struct
irq_info
);
i
++
)
{
e
=
&
rt
->
slots
[
i
];
#ifdef DEBUG
{
int
j
;
DBG
(
"%02x:%02x slot=%02x"
,
e
->
bus
,
e
->
devfn
/
8
,
e
->
slot
);
for
(
j
=
0
;
j
<
4
;
j
++
)
DBG
(
" %d:%02x/%04x"
,
j
,
e
->
irq
[
j
].
link
,
e
->
irq
[
j
].
bitmap
);
DBG
(
"
\n
"
);
}
#endif
busmap
[
e
->
bus
]
=
1
;
}
for
(
i
=
1
;
i
<
256
;
i
++
)
/*
* It might be a secondary bus, but in this case its parent is already
* known (ascending bus order) and therefore pci_scan_bus returns immediately.
*/
if
(
busmap
[
i
]
&&
pci_scan_bus
(
i
,
pci_root_bus
->
ops
,
NULL
))
printk
(
KERN_INFO
"PCI: Discovered primary peer bus %02x [IRQ]
\n
"
,
i
);
//pcibios_last_bus = -1;
}
/*
* Code for querying and setting of IRQ routes on various interrupt routers.
*/
void
eisa_set_level_irq
(
unsigned
int
irq
)
{
unsigned
char
mask
=
1
<<
(
irq
&
7
);
unsigned
int
port
=
0x4d0
+
(
irq
>>
3
);
unsigned
char
val
=
inb
(
port
);
if
(
!
(
val
&
mask
))
{
DBG
(
" -> edge"
);
outb
(
val
|
mask
,
port
);
}
}
/*
* Common IRQ routing practice: nybbles in config space,
* offset by some magic constant.
*/
static
unsigned
int
read_config_nybble
(
struct
pci_dev
*
router
,
unsigned
offset
,
unsigned
nr
)
{
u8
x
;
unsigned
reg
=
offset
+
(
nr
>>
1
);
pci_read_config_byte
(
router
,
reg
,
&
x
);
return
(
nr
&
1
)
?
(
x
>>
4
)
:
(
x
&
0xf
);
}
static
void
write_config_nybble
(
struct
pci_dev
*
router
,
unsigned
offset
,
unsigned
nr
,
unsigned
int
val
)
{
u8
x
;
unsigned
reg
=
offset
+
(
nr
>>
1
);
pci_read_config_byte
(
router
,
reg
,
&
x
);
x
=
(
nr
&
1
)
?
((
x
&
0x0f
)
|
(
val
<<
4
))
:
((
x
&
0xf0
)
|
val
);
pci_write_config_byte
(
router
,
reg
,
x
);
}
#if 0 /* enable when pci ids ae known */
/*
* The VIA pirq rules are nibble-based, like ALI,
* but without the ugly irq number munging.
*/
static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
return read_config_nybble(router, 0x55, pirq);
}
static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
{
write_config_nybble(router, 0x55, pirq, irq);
return 1;
}
/*
* PIRQ routing for SiS 85C503 router used in several SiS chipsets
* According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997)
* the related registers work as follows:
*
* general: one byte per re-routable IRQ,
* bit 7 IRQ mapping enabled (0) or disabled (1)
* bits [6:4] reserved
* bits [3:0] IRQ to map to
* allowed: 3-7, 9-12, 14-15
* reserved: 0, 1, 2, 8, 13
*
* individual registers in device config space:
*
* 0x41/0x42/0x43/0x44: PCI INT A/B/C/D - bits as in general case
*
* 0x61: IDEIRQ: bits as in general case - but:
* bits [6:5] must be written 01
* bit 4 channel-select primary (0), secondary (1)
*
* 0x62: USBIRQ: bits as in general case - but:
* bit 4 OHCI function disabled (0), enabled (1)
*
* 0x6a: ACPI/SCI IRQ - bits as in general case
*
* 0x7e: Data Acq. Module IRQ - bits as in general case
*
* Apparently there are systems implementing PCI routing table using both
* link values 0x01-0x04 and 0x41-0x44 for PCI INTA..D, but register offsets
* like 0x62 as link values for USBIRQ e.g. So there is no simple
* "register = offset + pirq" relation.
* Currently we support PCI INTA..D and USBIRQ and try our best to handle
* both link mappings.
* IDE/ACPI/DAQ mapping is currently unsupported (left untouched as set by BIOS).
*/
static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
u8 x;
int reg = pirq;
switch(pirq) {
case 0x01:
case 0x02:
case 0x03:
case 0x04:
reg += 0x40;
case 0x41:
case 0x42:
case 0x43:
case 0x44:
case 0x62:
pci_read_config_byte(router, reg, &x);
if (reg != 0x62)
break;
if (!(x & 0x40))
return 0;
break;
case 0x61:
case 0x6a:
case 0x7e:
printk(KERN_INFO "SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n");
return 0;
default:
printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
return 0;
}
return (x & 0x80) ? 0 : (x & 0x0f);
}
static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
{
u8 x;
int reg = pirq;
switch(pirq) {
case 0x01:
case 0x02:
case 0x03:
case 0x04:
reg += 0x40;
case 0x41:
case 0x42:
case 0x43:
case 0x44:
case 0x62:
x = (irq&0x0f) ? (irq&0x0f) : 0x80;
if (reg != 0x62)
break;
/* always mark OHCI enabled, as nothing else knows about this */
x |= 0x40;
break;
case 0x61:
case 0x6a:
case 0x7e:
printk(KERN_INFO "advanced SiS pirq mapping not yet implemented\n");
return 0;
default:
printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
return 0;
}
pci_write_config_byte(router, reg, x);
return 1;
}
#endif
/* Support for AMD756 PCI IRQ Routing
* Jhon H. Caicedo <jhcaiced@osso.org.co>
* Jun/21/2001 0.2.0 Release, fixed to use "nybble" functions... (jhcaiced)
* Jun/19/2001 Alpha Release 0.1.0 (jhcaiced)
* The AMD756 pirq rules are nibble-based
* offset 0x56 0-3 PIRQA 4-7 PIRQB
* offset 0x57 0-3 PIRQC 4-7 PIRQD
*/
static
int
pirq_amd756_get
(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
)
{
u8
irq
;
irq
=
0
;
if
(
pirq
<=
4
)
{
irq
=
read_config_nybble
(
router
,
0x56
,
pirq
-
1
);
}
printk
(
KERN_INFO
"AMD756: dev %04x:%04x, router pirq : %d get irq : %2d
\n
"
,
dev
->
vendor
,
dev
->
device
,
pirq
,
irq
);
return
irq
;
}
static
int
pirq_amd756_set
(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
,
int
irq
)
{
printk
(
KERN_INFO
"AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d
\n
"
,
dev
->
vendor
,
dev
->
device
,
pirq
,
irq
);
if
(
pirq
<=
4
)
{
write_config_nybble
(
router
,
0x56
,
pirq
-
1
,
irq
);
}
return
1
;
}
static
struct
irq_router
pirq_routers
[]
=
{
#if 0 /* all these do not exist on Hammer currently, but keep one example
for each. All these vendors have announced K8 chipsets, so we'll
eventually need a router for them. Luckily they tend to use the
same ones, so with luck just enabling the existing ones will work
when you know the final PCI ids. */
{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
{ "SIS", PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, pirq_sis_get, pirq_sis_set },
#endif
{
"AMD756 VIPER"
,
PCI_VENDOR_ID_AMD
,
PCI_DEVICE_ID_AMD_VIPER_740B
,
pirq_amd756_get
,
pirq_amd756_set
},
{
"default"
,
0
,
0
,
NULL
,
NULL
}
};
static
struct
irq_router
*
pirq_router
;
static
struct
pci_dev
*
pirq_router_dev
;
static
void
__init
pirq_find_router
(
void
)
{
struct
irq_routing_table
*
rt
=
pirq_table
;
struct
irq_router
*
r
;
DBG
(
"PCI: Attempting to find IRQ router for %04x:%04x
\n
"
,
rt
->
rtr_vendor
,
rt
->
rtr_device
);
/* fall back to default router if nothing else found */
pirq_router
=
&
pirq_routers
[
ARRAY_SIZE
(
pirq_routers
)
-
1
];
pirq_router_dev
=
pci_find_slot
(
rt
->
rtr_bus
,
rt
->
rtr_devfn
);
if
(
!
pirq_router_dev
)
{
DBG
(
"PCI: Interrupt router not found at %02x:%02x
\n
"
,
rt
->
rtr_bus
,
rt
->
rtr_devfn
);
return
;
}
for
(
r
=
pirq_routers
;
r
->
vendor
;
r
++
)
{
/* Exact match against router table entry? Use it! */
if
(
r
->
vendor
==
rt
->
rtr_vendor
&&
r
->
device
==
rt
->
rtr_device
)
{
pirq_router
=
r
;
break
;
}
/* Match against router device entry? Use it as a fallback */
if
(
r
->
vendor
==
pirq_router_dev
->
vendor
&&
r
->
device
==
pirq_router_dev
->
device
)
{
pirq_router
=
r
;
}
}
printk
(
KERN_INFO
"PCI: Using IRQ router %s [%04x/%04x] at %s
\n
"
,
pirq_router
->
name
,
pirq_router_dev
->
vendor
,
pirq_router_dev
->
device
,
pirq_router_dev
->
slot_name
);
}
static
struct
irq_info
*
pirq_get_info
(
struct
pci_dev
*
dev
)
{
struct
irq_routing_table
*
rt
=
pirq_table
;
int
entries
=
(
rt
->
size
-
sizeof
(
struct
irq_routing_table
))
/
sizeof
(
struct
irq_info
);
struct
irq_info
*
info
;
for
(
info
=
rt
->
slots
;
entries
--
;
info
++
)
if
(
info
->
bus
==
dev
->
bus
->
number
&&
PCI_SLOT
(
info
->
devfn
)
==
PCI_SLOT
(
dev
->
devfn
))
return
info
;
return
NULL
;
}
static
irqreturn_t
pcibios_test_irq_handler
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
return
IRQ_NONE
;
}
static
int
pcibios_lookup_irq
(
struct
pci_dev
*
dev
,
int
assign
)
{
u8
pin
;
struct
irq_info
*
info
;
int
i
,
pirq
,
newirq
;
int
irq
=
0
;
u32
mask
;
struct
irq_router
*
r
=
pirq_router
;
struct
pci_dev
*
dev2
=
NULL
;
char
*
msg
=
NULL
;
/* Find IRQ pin */
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_PIN
,
&
pin
);
if
(
!
pin
)
{
DBG
(
" -> no interrupt pin
\n
"
);
return
0
;
}
pin
=
pin
-
1
;
/* Find IRQ routing entry */
if
(
!
pirq_table
)
return
0
;
DBG
(
"IRQ for %s:%d"
,
dev
->
slot_name
,
pin
);
info
=
pirq_get_info
(
dev
);
if
(
!
info
)
{
DBG
(
" -> not found in routing table
\n
"
);
return
0
;
}
pirq
=
info
->
irq
[
pin
].
link
;
mask
=
info
->
irq
[
pin
].
bitmap
;
if
(
!
pirq
)
{
DBG
(
" -> not routed
\n
"
);
return
0
;
}
DBG
(
" -> PIRQ %02x, mask %04x, excl %04x"
,
pirq
,
mask
,
pirq_table
->
exclusive_irqs
);
mask
&=
pcibios_irq_mask
;
/* Work around broken HP Pavilion Notebooks which assign USB to
IRQ 9 even though it is actually wired to IRQ 11 */
if
(
broken_hp_bios_irq9
&&
pirq
==
0x59
&&
dev
->
irq
==
9
)
{
dev
->
irq
=
11
;
pci_write_config_byte
(
dev
,
PCI_INTERRUPT_LINE
,
11
);
r
->
set
(
pirq_router_dev
,
dev
,
pirq
,
11
);
}
/*
* Find the best IRQ to assign: use the one
* reported by the device if possible.
*/
newirq
=
dev
->
irq
;
if
(
!
((
1
<<
newirq
)
&
mask
))
{
if
(
pci_probe
&
PCI_USE_PIRQ_MASK
)
newirq
=
0
;
else
printk
(
KERN_WARNING
"PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask
\n
"
,
newirq
,
dev
->
slot_name
);
}
if
(
!
newirq
&&
assign
)
{
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(
!
(
mask
&
(
1
<<
i
)))
continue
;
if
(
pirq_penalty
[
i
]
<
pirq_penalty
[
newirq
]
&&
!
request_irq
(
i
,
pcibios_test_irq_handler
,
SA_SHIRQ
,
"pci-test"
,
dev
))
{
free_irq
(
i
,
dev
);
newirq
=
i
;
}
}
}
DBG
(
" -> newirq=%d"
,
newirq
);
/* Check if it is hardcoded */
if
((
pirq
&
0xf0
)
==
0xf0
)
{
irq
=
pirq
&
0xf
;
DBG
(
" -> hardcoded IRQ %d
\n
"
,
irq
);
msg
=
"Hardcoded"
;
}
else
if
(
r
->
get
&&
(
irq
=
r
->
get
(
pirq_router_dev
,
dev
,
pirq
))
&&
\
((
!
(
pci_probe
&
PCI_USE_PIRQ_MASK
))
||
((
1
<<
irq
)
&
mask
))
)
{
DBG
(
" -> got IRQ %d
\n
"
,
irq
);
msg
=
"Found"
;
}
else
if
(
newirq
&&
r
->
set
&&
(
dev
->
class
>>
8
)
!=
PCI_CLASS_DISPLAY_VGA
)
{
DBG
(
" -> assigning IRQ %d"
,
newirq
);
if
(
r
->
set
(
pirq_router_dev
,
dev
,
pirq
,
newirq
))
{
eisa_set_level_irq
(
newirq
);
DBG
(
" ... OK
\n
"
);
msg
=
"Assigned"
;
irq
=
newirq
;
}
}
if
(
!
irq
)
{
DBG
(
" ... failed
\n
"
);
if
(
newirq
&&
mask
==
(
1
<<
newirq
))
{
msg
=
"Guessed"
;
irq
=
newirq
;
}
else
return
0
;
}
printk
(
KERN_INFO
"PCI: %s IRQ %d for device %s
\n
"
,
msg
,
irq
,
dev
->
slot_name
);
/* Update IRQ for all devices with the same pirq value */
while
((
dev2
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
dev2
))
!=
NULL
)
{
pci_read_config_byte
(
dev2
,
PCI_INTERRUPT_PIN
,
&
pin
);
if
(
!
pin
)
continue
;
pin
--
;
info
=
pirq_get_info
(
dev2
);
if
(
!
info
)
continue
;
if
(
info
->
irq
[
pin
].
link
==
pirq
)
{
/* We refuse to override the dev->irq information. Give a warning! */
if
(
dev2
->
irq
&&
dev2
->
irq
!=
irq
&&
\
(
!
(
pci_probe
&
PCI_USE_PIRQ_MASK
)
||
\
((
1
<<
dev2
->
irq
)
&
mask
))
)
{
printk
(
KERN_INFO
"IRQ routing conflict for %s, have irq %d, want irq %d
\n
"
,
dev2
->
slot_name
,
dev2
->
irq
,
irq
);
continue
;
}
dev2
->
irq
=
irq
;
pirq_penalty
[
irq
]
++
;
if
(
dev
!=
dev2
)
printk
(
KERN_INFO
"PCI: Sharing IRQ %d with %s
\n
"
,
irq
,
dev2
->
slot_name
);
}
}
return
1
;
}
void
__init
pcibios_fixup_irqs
(
void
)
{
struct
pci_dev
*
dev
=
NULL
;
u8
pin
;
DBG
(
"PCI: IRQ fixup
\n
"
);
while
((
dev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
dev
))
!=
NULL
)
{
/*
* If the BIOS has set an out of range IRQ number, just ignore it.
* Also keep track of which IRQ's are already in use.
*/
if
(
dev
->
irq
>=
16
)
{
DBG
(
"%s: ignoring bogus IRQ %d
\n
"
,
dev
->
slot_name
,
dev
->
irq
);
dev
->
irq
=
0
;
}
/* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */
if
(
pirq_penalty
[
dev
->
irq
]
>=
100
&&
pirq_penalty
[
dev
->
irq
]
<
100000
)
pirq_penalty
[
dev
->
irq
]
=
0
;
pirq_penalty
[
dev
->
irq
]
++
;
}
dev
=
NULL
;
while
((
dev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
dev
))
!=
NULL
)
{
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_PIN
,
&
pin
);
#ifdef CONFIG_X86_IO_APIC
/*
* Recalculate IRQ numbers if we use the I/O APIC.
*/
if
(
io_apic_assign_pci_irqs
)
{
int
irq
;
if
(
pin
)
{
pin
--
;
/* interrupt pins are numbered starting from 1 */
irq
=
IO_APIC_get_PCI_irq_vector
(
dev
->
bus
->
number
,
PCI_SLOT
(
dev
->
devfn
),
pin
);
/*
* Busses behind bridges are typically not listed in the MP-table.
* In this case we have to look up the IRQ based on the parent bus,
* parent slot, and pin number. The SMP code detects such bridged
* busses itself so we should get into this branch reliably.
*/
if
(
irq
<
0
&&
dev
->
bus
->
parent
)
{
/* go back to the bridge */
struct
pci_dev
*
bridge
=
dev
->
bus
->
self
;
pin
=
(
pin
+
PCI_SLOT
(
dev
->
devfn
))
%
4
;
irq
=
IO_APIC_get_PCI_irq_vector
(
bridge
->
bus
->
number
,
PCI_SLOT
(
bridge
->
devfn
),
pin
);
if
(
irq
>=
0
)
printk
(
KERN_WARNING
"PCI: using PPB(B%d,I%d,P%d) to get irq %d
\n
"
,
bridge
->
bus
->
number
,
PCI_SLOT
(
bridge
->
devfn
),
pin
,
irq
);
}
if
(
irq
>=
0
)
{
printk
(
KERN_INFO
"PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d
\n
"
,
dev
->
bus
->
number
,
PCI_SLOT
(
dev
->
devfn
),
pin
,
irq
);
dev
->
irq
=
irq
;
}
}
}
#endif
/*
* Still no IRQ? Try to lookup one...
*/
if
(
pin
&&
!
dev
->
irq
)
pcibios_lookup_irq
(
dev
,
0
);
}
}
static
int
__init
pcibios_irq_init
(
void
)
{
DBG
(
"PCI: IRQ init
\n
"
);
if
(
pcibios_enable_irq
)
return
0
;
pirq_table
=
pirq_find_routing_table
();
if
(
pirq_table
)
{
pirq_peer_trick
();
pirq_find_router
();
if
(
pirq_table
->
exclusive_irqs
)
{
int
i
;
for
(
i
=
0
;
i
<
16
;
i
++
)
if
(
!
(
pirq_table
->
exclusive_irqs
&
(
1
<<
i
)))
pirq_penalty
[
i
]
+=
100
;
}
/* If we're using the I/O APIC, avoid using the PCI IRQ routing table */
if
(
io_apic_assign_pci_irqs
)
pirq_table
=
NULL
;
}
pcibios_enable_irq
=
pirq_enable_irq
;
pcibios_fixup_irqs
();
return
0
;
}
subsys_initcall
(
pcibios_irq_init
);
void
pcibios_penalize_isa_irq
(
int
irq
)
{
/*
* If any ISAPnP device reports an IRQ in its list of possible
* IRQ's, we try to avoid assigning it to PCI devices.
*/
pirq_penalty
[
irq
]
+=
100
;
}
int
pirq_enable_irq
(
struct
pci_dev
*
dev
)
{
u8
pin
;
extern
int
interrupt_line_quirk
;
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_PIN
,
&
pin
);
if
(
pin
&&
!
pcibios_lookup_irq
(
dev
,
1
)
&&
!
dev
->
irq
)
{
/* With IDE legacy devices the IRQ lookup failure is not a problem.. */
if
(
dev
->
class
>>
8
==
PCI_CLASS_STORAGE_IDE
&&
!
(
dev
->
class
&
0x5
))
return
0
;
printk
(
KERN_WARNING
"PCI: No IRQ known for interrupt pin %c of device %s.
\n
"
,
'A'
+
pin
-
1
,
dev
->
slot_name
);
}
/* VIA bridges use interrupt line for apic/pci steering across
the V-Link */
else
if
(
interrupt_line_quirk
)
pci_write_config_byte
(
dev
,
PCI_INTERRUPT_LINE
,
dev
->
irq
);
return
0
;
}
arch/x86_64/pci/legacy.c
deleted
100644 → 0
View file @
06b4a180
/*
* legacy.c - traditional, old school PCI bus probing
*/
#include <linux/init.h>
#include <linux/pci.h>
#include "pci.h"
/*
* Discover remaining PCI buses in case there are peer host bridges.
* We use the number of last PCI bus provided by the PCI BIOS.
*/
void
__devinit
pcibios_fixup_peer_bridges
(
void
)
{
int
n
;
struct
pci_bus
*
bus
;
struct
pci_dev
*
dev
;
u16
l
;
if
(
pcibios_last_bus
<=
0
||
pcibios_last_bus
>=
0xff
)
return
;
DBG
(
"PCI: Peer bridge fixup
\n
"
);
bus
=
kmalloc
(
sizeof
(
*
bus
),
GFP_ATOMIC
);
dev
=
kmalloc
(
sizeof
(
*
dev
),
GFP_ATOMIC
);
if
(
!
bus
||
!
dev
)
{
printk
(
KERN_ERR
"Out of memory in %s
\n
"
,
__FUNCTION__
);
goto
exit
;
}
for
(
n
=
0
;
n
<=
pcibios_last_bus
;
n
++
)
{
if
(
pci_bus_exists
(
&
pci_root_buses
,
n
))
continue
;
bus
->
number
=
n
;
bus
->
ops
=
pci_root_ops
;
dev
->
bus
=
bus
;
for
(
dev
->
devfn
=
0
;
dev
->
devfn
<
256
;
dev
->
devfn
+=
8
)
if
(
!
pci_read_config_word
(
dev
,
PCI_VENDOR_ID
,
&
l
)
&&
l
!=
0x0000
&&
l
!=
0xffff
)
{
DBG
(
"Found device at %02x:%02x [%04x]
\n
"
,
n
,
dev
->
devfn
,
l
);
printk
(
KERN_INFO
"PCI: Discovered peer bus %02x
\n
"
,
n
);
pci_scan_bus
(
n
,
pci_root_ops
,
NULL
);
break
;
}
}
exit:
kfree
(
dev
);
kfree
(
bus
);
}
static
int
__init
pci_legacy_init
(
void
)
{
if
(
!
pci_root_ops
)
{
printk
(
"PCI: System does not support PCI
\n
"
);
return
0
;
}
if
(
pcibios_scanned
++
)
return
0
;
printk
(
"PCI: Probing PCI hardware
\n
"
);
pci_root_bus
=
pcibios_scan_root
(
0
);
pcibios_fixup_peer_bridges
();
return
0
;
}
subsys_initcall
(
pci_legacy_init
);
arch/x86_64/pci/pci.h
deleted
100644 → 0
View file @
06b4a180
/*
* Low-Level PCI Access for x86-64 machines.
*
* (c) 1999 Martin Mares <mj@ucw.cz>
*/
#undef DEBUG
#ifdef DEBUG
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
#define PCI_PROBE_BIOS 0x0001
#define PCI_PROBE_CONF1 0x0002
#define PCI_PROBE_CONF2 0x0004
#define PCI_NO_SORT 0x0100
#define PCI_BIOS_SORT 0x0200
#define PCI_NO_CHECKS 0x0400
#define PCI_USE_PIRQ_MASK 0x0800
#define PCI_ASSIGN_ROMS 0x1000
#define PCI_BIOS_IRQ_SCAN 0x2000
#define PCI_ASSIGN_ALL_BUSSES 0x4000
#define PCI_NO_ACPI_ROUTING 0x8000
extern
unsigned
int
pci_probe
;
extern
unsigned
int
pcibios_max_latency
;
void
pcibios_resource_survey
(
void
);
int
pcibios_enable_resources
(
struct
pci_dev
*
,
int
);
/* pci-pc.c */
extern
int
pcibios_last_bus
;
extern
struct
pci_bus
*
pci_root_bus
;
extern
struct
pci_ops
*
pci_root_ops
;
/* pci-irq.c */
struct
irq_info
{
u8
bus
,
devfn
;
/* Bus, device and function */
struct
{
u8
link
;
/* IRQ line ID, chipset dependent, 0=not routed */
u16
bitmap
;
/* Available IRQs */
}
__attribute__
((
packed
))
irq
[
4
];
u8
slot
;
/* Slot number, 0=onboard */
u8
rfu
;
}
__attribute__
((
packed
));
struct
irq_routing_table
{
u32
signature
;
/* PIRQ_SIGNATURE should be here */
u16
version
;
/* PIRQ_VERSION */
u16
size
;
/* Table size in bytes */
u8
rtr_bus
,
rtr_devfn
;
/* Where the interrupt router lies */
u16
exclusive_irqs
;
/* IRQs devoted exclusively to PCI usage */
u16
rtr_vendor
,
rtr_device
;
/* Vendor and device ID of interrupt router */
u32
miniport_data
;
/* Crap */
u8
rfu
[
11
];
u8
checksum
;
/* Modulo 256 checksum must give zero */
struct
irq_info
slots
[
0
];
}
__attribute__
((
packed
));
extern
unsigned
int
pcibios_irq_mask
;
extern
int
pcibios_scanned
;
extern
spinlock_t
pci_config_lock
;
int
pirq_enable_irq
(
struct
pci_dev
*
dev
);
extern
int
(
*
pcibios_enable_irq
)(
struct
pci_dev
*
dev
);
/* legacy.c */
extern
void
pcibios_fixup_peer_bridges
(
void
);
arch/x86_64/pci/x86-64.c
deleted
100644 → 0
View file @
06b4a180
/*
* Low-Level PCI Access for x86-64 machines
*
* Copyright 1993, 1994 Drew Eckhardt
* Visionary Computing
* (Unix and Linux consulting and custom programming)
* Drew@Colorado.EDU
* +1 (303) 786-7975
*
* Drew's work was sponsored by:
* iX Multiuser Multitasking Magazine
* Hannover, Germany
* hm@ix.de
*
* Copyright 1997--2000 Martin Mares <mj@ucw.cz>
*
* For more information, please consult the following manuals (look at
* http://www.pcisig.com/ for how to get them):
*
* PCI BIOS Specification
* PCI Local Bus Specification
* PCI to PCI Bridge Specification
* PCI System Design Guide
*
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include "pci.h"
/*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
* addresses to be allocated in the 0x000-0x0ff region
* modulo 0x400.
*
* Why? Because some silly external IO cards only decode
* the low 10 bits of the IO address. The 0x00-0xff region
* is reserved for motherboard devices that decode all 16
* bits, so it's ok to allocate at, say, 0x2800-0x28ff,
* but we want to try to avoid allocating at 0x2900-0x2bff
* which might have be mirrored at 0x0100-0x03ff..
*/
void
pcibios_align_resource
(
void
*
data
,
struct
resource
*
res
,
unsigned
long
size
,
unsigned
long
align
)
{
if
(
res
->
flags
&
IORESOURCE_IO
)
{
unsigned
long
start
=
res
->
start
;
if
(
start
&
0x300
)
{
start
=
(
start
+
0x3ff
)
&
~
0x3ff
;
res
->
start
=
start
;
}
}
}
/*
* Handle resources of PCI devices. If the world were perfect, we could
* just allocate all the resource regions and do nothing more. It isn't.
* On the other hand, we cannot just re-allocate all devices, as it would
* require us to know lots of host bridge internals. So we attempt to
* keep as much of the original configuration as possible, but tweak it
* when it's found to be wrong.
*
* Known BIOS problems we have to work around:
* - I/O or memory regions not configured
* - regions configured, but not enabled in the command register
* - bogus I/O addresses above 64K used
* - expansion ROMs left enabled (this may sound harmless, but given
* the fact the PCI specs explicitly allow address decoders to be
* shared between expansion ROMs and other resource regions, it's
* at least dangerous)
*
* Our solution:
* (1) Allocate resources for all buses behind PCI-to-PCI bridges.
* This gives us fixed barriers on where we can allocate.
* (2) Allocate resources for all enabled devices. If there is
* a collision, just mark the resource as unallocated. Also
* disable expansion ROMs during this step.
* (3) Try to allocate resources for disabled devices. If the
* resources were assigned correctly, everything goes well,
* if they weren't, they won't disturb allocation of other
* resources.
* (4) Assign new addresses to resources which were either
* not configured at all or misconfigured. If explicitly
* requested by the user, configure expansion ROM address
* as well.
*/
static
void
__init
pcibios_allocate_bus_resources
(
struct
list_head
*
bus_list
)
{
struct
list_head
*
ln
;
struct
pci_bus
*
bus
;
struct
pci_dev
*
dev
;
int
idx
;
struct
resource
*
r
,
*
pr
;
/* Depth-First Search on bus tree */
for
(
ln
=
bus_list
->
next
;
ln
!=
bus_list
;
ln
=
ln
->
next
)
{
bus
=
pci_bus_b
(
ln
);
if
((
dev
=
bus
->
self
))
{
for
(
idx
=
PCI_BRIDGE_RESOURCES
;
idx
<
PCI_NUM_RESOURCES
;
idx
++
)
{
r
=
&
dev
->
resource
[
idx
];
if
(
!
r
->
start
)
continue
;
pr
=
pci_find_parent_resource
(
dev
,
r
);
if
(
!
pr
||
request_resource
(
pr
,
r
)
<
0
)
printk
(
KERN_ERR
"PCI: Cannot allocate resource region %d of bridge %s
\n
"
,
idx
,
dev
->
slot_name
);
}
}
pcibios_allocate_bus_resources
(
&
bus
->
children
);
}
}
static
void
__init
pcibios_allocate_resources
(
int
pass
)
{
struct
pci_dev
*
dev
=
NULL
;
int
idx
,
disabled
;
u16
command
;
struct
resource
*
r
,
*
pr
;
while
((
dev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
dev
))
!=
NULL
)
{
pci_read_config_word
(
dev
,
PCI_COMMAND
,
&
command
);
for
(
idx
=
0
;
idx
<
6
;
idx
++
)
{
r
=
&
dev
->
resource
[
idx
];
if
(
r
->
parent
)
/* Already allocated */
continue
;
if
(
!
r
->
start
)
/* Address not assigned at all */
continue
;
if
(
r
->
flags
&
IORESOURCE_IO
)
disabled
=
!
(
command
&
PCI_COMMAND_IO
);
else
disabled
=
!
(
command
&
PCI_COMMAND_MEMORY
);
if
(
pass
==
disabled
)
{
DBG
(
"PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)
\n
"
,
r
->
start
,
r
->
end
,
r
->
flags
,
disabled
,
pass
);
pr
=
pci_find_parent_resource
(
dev
,
r
);
if
(
!
pr
||
request_resource
(
pr
,
r
)
<
0
)
{
printk
(
KERN_ERR
"PCI: Cannot allocate resource region %d of device %s
\n
"
,
idx
,
dev
->
slot_name
);
/* We'll assign a new address later */
r
->
end
-=
r
->
start
;
r
->
start
=
0
;
}
}
}
if
(
!
pass
)
{
r
=
&
dev
->
resource
[
PCI_ROM_RESOURCE
];
if
(
r
->
flags
&
PCI_ROM_ADDRESS_ENABLE
)
{
/* Turn the ROM off, leave the resource region, but keep it unregistered. */
u32
reg
;
DBG
(
"PCI: Switching off ROM of %s
\n
"
,
dev
->
slot_name
);
r
->
flags
&=
~
PCI_ROM_ADDRESS_ENABLE
;
pci_read_config_dword
(
dev
,
dev
->
rom_base_reg
,
&
reg
);
pci_write_config_dword
(
dev
,
dev
->
rom_base_reg
,
reg
&
~
PCI_ROM_ADDRESS_ENABLE
);
}
}
}
}
static
void
__init
pcibios_assign_resources
(
void
)
{
struct
pci_dev
*
dev
=
NULL
;
int
idx
;
struct
resource
*
r
;
while
((
dev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
dev
))
!=
NULL
)
{
int
class
=
dev
->
class
>>
8
;
/* Don't touch classless devices and host bridges */
if
(
!
class
||
class
==
PCI_CLASS_BRIDGE_HOST
)
continue
;
for
(
idx
=
0
;
idx
<
6
;
idx
++
)
{
r
=
&
dev
->
resource
[
idx
];
/*
* Don't touch IDE controllers and I/O ports of video cards!
*/
if
((
class
==
PCI_CLASS_STORAGE_IDE
&&
idx
<
4
)
||
(
class
==
PCI_CLASS_DISPLAY_VGA
&&
(
r
->
flags
&
IORESOURCE_IO
)))
continue
;
/*
* We shall assign a new address to this resource, either because
* the BIOS forgot to do so or because we have decided the old
* address was unusable for some reason.
*/
if
(
!
r
->
start
&&
r
->
end
)
pci_assign_resource
(
dev
,
idx
);
}
if
(
pci_probe
&
PCI_ASSIGN_ROMS
)
{
r
=
&
dev
->
resource
[
PCI_ROM_RESOURCE
];
r
->
end
-=
r
->
start
;
r
->
start
=
0
;
if
(
r
->
end
)
pci_assign_resource
(
dev
,
PCI_ROM_RESOURCE
);
}
}
}
void
__init
pcibios_resource_survey
(
void
)
{
DBG
(
"PCI: Allocating resources
\n
"
);
pcibios_allocate_bus_resources
(
&
pci_root_buses
);
pcibios_allocate_resources
(
0
);
pcibios_allocate_resources
(
1
);
pcibios_assign_resources
();
}
int
pcibios_enable_resources
(
struct
pci_dev
*
dev
,
int
mask
)
{
u16
cmd
,
old_cmd
;
int
idx
;
struct
resource
*
r
;
pci_read_config_word
(
dev
,
PCI_COMMAND
,
&
cmd
);
old_cmd
=
cmd
;
for
(
idx
=
0
;
idx
<
6
;
idx
++
)
{
if
(
!
(
mask
&
(
1
<<
idx
)))
continue
;
r
=
&
dev
->
resource
[
idx
];
if
(
!
r
->
start
&&
r
->
end
)
{
printk
(
KERN_ERR
"PCI: Device %s not available because of resource collisions
\n
"
,
dev
->
slot_name
);
return
-
EINVAL
;
}
if
(
r
->
flags
&
IORESOURCE_IO
)
cmd
|=
PCI_COMMAND_IO
;
if
(
r
->
flags
&
IORESOURCE_MEM
)
cmd
|=
PCI_COMMAND_MEMORY
;
}
if
(
dev
->
resource
[
PCI_ROM_RESOURCE
].
start
)
cmd
|=
PCI_COMMAND_MEMORY
;
if
(
cmd
!=
old_cmd
)
{
printk
(
"PCI: Enabling device %s (%04x -> %04x)
\n
"
,
dev
->
slot_name
,
old_cmd
,
cmd
);
pci_write_config_word
(
dev
,
PCI_COMMAND
,
cmd
);
}
return
0
;
}
/*
* If we set up a device for bus mastering, we need to check the latency
* timer as certain crappy BIOSes forget to set it properly.
*/
unsigned
int
pcibios_max_latency
=
255
;
void
pcibios_set_master
(
struct
pci_dev
*
dev
)
{
u8
lat
;
pci_read_config_byte
(
dev
,
PCI_LATENCY_TIMER
,
&
lat
);
if
(
lat
<
16
)
lat
=
(
64
<=
pcibios_max_latency
)
?
64
:
pcibios_max_latency
;
else
if
(
lat
>
pcibios_max_latency
)
lat
=
pcibios_max_latency
;
else
return
;
printk
(
"PCI: Setting latency timer of device %s to %d
\n
"
,
dev
->
slot_name
,
lat
);
pci_write_config_byte
(
dev
,
PCI_LATENCY_TIMER
,
lat
);
}
int
pci_mmap_page_range
(
struct
pci_dev
*
dev
,
struct
vm_area_struct
*
vma
,
enum
pci_mmap_state
mmap_state
,
int
write_combine
)
{
unsigned
long
prot
;
/* I/O space cannot be accessed via normal processor loads and
* stores on this platform.
*/
if
(
mmap_state
==
pci_mmap_io
)
return
-
EINVAL
;
/* Leave vm_pgoff as-is, the PCI space address is the physical
* address on this platform.
*/
vma
->
vm_flags
|=
(
VM_SHM
|
VM_LOCKED
|
VM_IO
);
prot
=
pgprot_val
(
vma
->
vm_page_prot
);
if
(
boot_cpu_data
.
x86
>
3
)
prot
|=
_PAGE_PCD
|
_PAGE_PWT
;
vma
->
vm_page_prot
=
__pgprot
(
prot
);
/* Write-combine setting is ignored, it is changed via the mtrr
* interfaces on this platform.
*/
if
(
remap_page_range
(
vma
,
vma
->
vm_start
,
vma
->
vm_pgoff
<<
PAGE_SHIFT
,
vma
->
vm_end
-
vma
->
vm_start
,
vma
->
vm_page_prot
))
return
-
EAGAIN
;
return
0
;
}
drivers/char/rtc.c
View file @
374046d5
...
...
@@ -279,7 +279,7 @@ static ssize_t rtc_read(struct file *file, char *buf,
if
(
rtc_has_irq
==
0
)
return
-
EIO
;
if
(
count
<
sizeof
(
unsigned
long
))
if
(
count
<
sizeof
(
unsigned
))
return
-
EINVAL
;
add_wait_queue
(
&
rtc_wait
,
&
wait
);
...
...
@@ -310,9 +310,10 @@ static ssize_t rtc_read(struct file *file, char *buf,
schedule
();
}
while
(
1
);
retval
=
put_user
(
data
,
(
unsigned
long
*
)
buf
);
if
(
!
retval
)
retval
=
sizeof
(
unsigned
long
);
if
(
count
<
sizeof
(
unsigned
long
))
retval
=
put_user
(
data
,
(
unsigned
int
*
)
buf
)
?:
sizeof
(
int
);
else
retval
=
put_user
(
data
,
(
unsigned
long
*
)
buf
)
?:
sizeof
(
long
);
out:
current
->
state
=
TASK_RUNNING
;
remove_wait_queue
(
&
rtc_wait
,
&
wait
);
...
...
include/asm-x86_64/fixmap.h
View file @
374046d5
...
...
@@ -16,6 +16,7 @@
#include <asm/apicdef.h>
#include <asm/page.h>
#include <asm/vsyscall.h>
#include <asm/vsyscall32.h>
/*
* Here we define all the compile-time 'special' virtual
...
...
@@ -62,6 +63,10 @@ extern void __set_fixmap (enum fixed_addresses idx,
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
/* Only covers 32bit vsyscalls currently. Need another set for 64bit. */
#define FIXADDR_USER_START ((unsigned long)VSYSCALL32_VSYSCALL)
#define FIXADDR_USER_END (FIXADDR_USER_START + PAGE_SIZE)
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
extern
void
__this_fixmap_does_not_exist
(
void
);
...
...
include/asm-x86_64/io.h
View file @
374046d5
...
...
@@ -105,7 +105,7 @@ __OUTS(l)
#define IO_SPACE_LIMIT 0xffff
#if
def __KERNEL
__
#if
defined(__KERNEL__) && __x86_64
__
#include <linux/vmalloc.h>
...
...
include/asm-x86_64/mmzone.h
View file @
374046d5
...
...
@@ -23,7 +23,6 @@ extern int maxnode;
extern
struct
pglist_data
*
node_data
[];
/* kern_addr_valid below hardcodes the same algorithm*/
static
inline
__attribute__
((
pure
))
int
phys_to_nid
(
unsigned
long
addr
)
{
int
nid
;
...
...
@@ -46,19 +45,6 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr)
#define local_mapnr(kvaddr) \
( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) )
#define kern_addr_valid(kvaddr) ({ \
int ok = 0; \
unsigned long index = __pa(kvaddr) >> memnode_shift; \
if (index <= NODEMAPSIZE) { \
unsigned nodeid = memnodemap[index]; \
unsigned long pfn = __pa(kvaddr) >> PAGE_SHIFT; \
unsigned long start_pfn = node_start_pfn(nodeid); \
ok = (nodeid != 0xff) && \
(pfn >= start_pfn) && \
(pfn < start_pfn + node_size(nodeid)); \
} \
ok; \
})
/* AK: this currently doesn't deal with invalid addresses. We'll see
if the 2.5 kernel doesn't pass them
...
...
include/asm-x86_64/page.h
View file @
374046d5
...
...
@@ -76,6 +76,8 @@ extern unsigned long vm_force_exec32;
#define __PAGE_OFFSET 0x0000010000000000
/* 1 << 40 */
#define __PHYSICAL_MASK_SHIFT 40
#define __PHYSICAL_MASK ((1UL << __PHYSICAL_MASK_SHIFT) - 1)
#define __VIRTUAL_MASK_SHIFT 48
#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
#define KERNEL_TEXT_SIZE (40UL*1024*1024)
#define KERNEL_TEXT_START 0xffffffff80000000UL
...
...
include/asm-x86_64/pci.h
View file @
374046d5
...
...
@@ -45,7 +45,6 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
struct
pci_dev
;
extern
int
iommu_setup
(
char
*
opt
);
extern
void
pci_iommu_init
(
void
);
/* Allocate and map kernel buffer using consistent mode DMA for a device.
* hwdev should be valid struct pci_dev pointer for PCI devices,
...
...
include/asm-x86_64/pgtable.h
View file @
374046d5
...
...
@@ -339,7 +339,7 @@ static inline pgd_t *current_pgd_offset_k(unsigned long address)
#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
#define pmd_bad(x) ((pmd_val(x) & (~PTE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE )
#define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot)))
#define pmd_pfn(x) ((pmd_val(x) >> PAGE_SHIFT) & __PHYSICAL_MASK)
#define pte_to_pgoff(pte) ((pte_val(pte) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT)
#define pgoff_to_pte(off) ((pte_t) { ((off) << PAGE_SHIFT) | _PAGE_FILE })
...
...
@@ -392,9 +392,7 @@ typedef pte_t *pte_addr_t;
#endif
/* !__ASSEMBLY__ */
#ifndef CONFIG_DISCONTIGMEM
#define kern_addr_valid(addr) (1)
#endif
extern
int
kern_addr_valid
(
unsigned
long
addr
);
#define io_remap_page_range remap_page_range
...
...
@@ -403,4 +401,9 @@ typedef pte_t *pte_addr_t;
#define pgtable_cache_init() do { } while (0)
#define check_pgt_cache() do { } while (0)
/* fs/proc/kcore.c */
#define kc_vaddr_to_offset(v) ((v) & __VIRTUAL_MASK)
#define kc_offset_to_vaddr(o) \
(((o) & (1UL << (__VIRTUAL_MASK_SHIFT-1))) ? ((o) | (~__VIRTUAL_MASK)) : (o))
#endif
/* _X86_64_PGTABLE_H */
include/asm-x86_64/proto.h
View file @
374046d5
...
...
@@ -16,7 +16,12 @@ extern void mcheck_init(struct cpuinfo_x86 *c);
extern
void
init_memory_mapping
(
void
);
extern
void
system_call
(
void
);
extern
int
kernel_syscall
(
void
);
extern
void
syscall_init
(
void
);
extern
void
ia32_syscall
(
void
);
extern
void
ia32_cstar_target
(
void
);
extern
void
calibrate_delay
(
void
);
extern
void
cpu_idle
(
void
);
extern
void
sys_ni_syscall
(
void
);
...
...
@@ -24,6 +29,8 @@ extern void config_acpi_tables(void);
extern
void
ia32_syscall
(
void
);
extern
void
iommu_hole_init
(
void
);
extern
void
time_init_smp
(
void
);
extern
void
do_softirq_thunk
(
void
);
extern
int
numa_setup
(
char
*
opt
);
...
...
@@ -39,8 +46,12 @@ extern unsigned long numa_free_all_bootmem(void);
extern
void
reserve_bootmem_generic
(
unsigned
long
phys
,
unsigned
len
);
extern
void
free_bootmem_generic
(
unsigned
long
phys
,
unsigned
len
);
extern
void
load_gs_index
(
unsigned
gs
);
extern
unsigned
long
end_pfn_map
;
extern
unsigned
long
cpu_initialized
;
extern
void
show_stack
(
unsigned
long
*
rsp
);
extern
void
show_trace
(
unsigned
long
*
rsp
);
extern
void
show_registers
(
struct
pt_regs
*
regs
);
...
...
@@ -66,9 +77,16 @@ extern unsigned long max_mapnr;
extern
unsigned
long
end_pfn
;
extern
unsigned
long
table_start
,
table_end
;
extern
void
syscall_init
(
void
);
extern
int
exception_trace
;
extern
int
no_iommu
,
force_mmu
;
extern
int
using_apic_timer
;
extern
int
disable_apic
;
extern
unsigned
cpu_khz
;
struct
pt_regs
;
extern
int
fallback_aper_order
;
extern
int
fallback_aper_force
;
extern
void
smp_local_timer_interrupt
(
struct
pt_regs
*
regs
);
long
do_arch_prctl
(
struct
task_struct
*
task
,
int
code
,
unsigned
long
addr
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment