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
Kirill Smelkov
linux
Commits
57bd45fd
Commit
57bd45fd
authored
Apr 13, 2002
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ppc64: EEH updates and FWNMI handler from Todd Inglett
parent
b8dd4c32
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
258 additions
and
163 deletions
+258
-163
arch/ppc64/config.in
arch/ppc64/config.in
+0
-1
arch/ppc64/kernel/Makefile
arch/ppc64/kernel/Makefile
+1
-2
arch/ppc64/kernel/chrp_setup.c
arch/ppc64/kernel/chrp_setup.c
+22
-0
arch/ppc64/kernel/eeh.c
arch/ppc64/kernel/eeh.c
+64
-33
arch/ppc64/kernel/entry.S
arch/ppc64/kernel/entry.S
+1
-1
arch/ppc64/kernel/head.S
arch/ppc64/kernel/head.S
+19
-1
arch/ppc64/kernel/pSeries_pci.c
arch/ppc64/kernel/pSeries_pci.c
+72
-74
arch/ppc64/kernel/pci.c
arch/ppc64/kernel/pci.c
+16
-20
arch/ppc64/kernel/ppc_asm.h
arch/ppc64/kernel/ppc_asm.h
+1
-1
arch/ppc64/kernel/ppc_ksyms.c
arch/ppc64/kernel/ppc_ksyms.c
+2
-8
arch/ppc64/kernel/traps.c
arch/ppc64/kernel/traps.c
+54
-2
arch/ppc64/mm/init.c
arch/ppc64/mm/init.c
+0
-2
include/asm-ppc64/eeh.h
include/asm-ppc64/eeh.h
+5
-3
include/asm-ppc64/io.h
include/asm-ppc64/io.h
+1
-15
No files found.
arch/ppc64/config.in
View file @
57bd45fd
...
@@ -24,7 +24,6 @@ if [ "$CONFIG_SMP" = "y" ]; then
...
@@ -24,7 +24,6 @@ if [ "$CONFIG_SMP" = "y" ]; then
bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS
bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS
if [ "$CONFIG_PPC_PSERIES" = "y" ]; then
if [ "$CONFIG_PPC_PSERIES" = "y" ]; then
bool ' Hardware multithreading' CONFIG_HMT
bool ' Hardware multithreading' CONFIG_HMT
bool ' PCI Enhanced Error Handling' CONFIG_PPC_EEH
fi
fi
fi
fi
define_bool CONFIG_PREEMPT n
define_bool CONFIG_PREEMPT n
...
...
arch/ppc64/kernel/Makefile
View file @
57bd45fd
...
@@ -30,13 +30,12 @@ obj-y := ppc_ksyms.o setup.o entry.o traps.o irq.o idle.o \
...
@@ -30,13 +30,12 @@ obj-y := ppc_ksyms.o setup.o entry.o traps.o irq.o idle.o \
rtc.o init_task.o pSeries_htab.o
rtc.o init_task.o pSeries_htab.o
obj-$(CONFIG_PCI)
+=
pci.o pci_dn.o pci_dma.o
obj-$(CONFIG_PCI)
+=
pci.o pci_dn.o pci_dma.o
obj-$(CONFIG_PPC_EEH)
+=
eeh.o
ifeq
($(CONFIG_PPC_ISERIES),y)
ifeq
($(CONFIG_PPC_ISERIES),y)
obj-$(CONFIG_PCI)
+=
iSeries_pci.o iSeries_pci_reset.o iSeries_IoMmTable.o iSeries_irq.o iSeries_VpdInfo.o XmPciLpEvent.o
obj-$(CONFIG_PCI)
+=
iSeries_pci.o iSeries_pci_reset.o iSeries_IoMmTable.o iSeries_irq.o iSeries_VpdInfo.o XmPciLpEvent.o
endif
endif
ifeq
($(CONFIG_PPC_PSERIES),y)
ifeq
($(CONFIG_PPC_PSERIES),y)
obj-$(CONFIG_PCI)
+=
pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o
obj-$(CONFIG_PCI)
+=
pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o
eeh.o
obj-y
+=
rtasd.o nvram.o
obj-y
+=
rtasd.o nvram.o
endif
endif
...
...
arch/ppc64/kernel/chrp_setup.c
View file @
57bd45fd
...
@@ -90,6 +90,9 @@ extern void iSeries_pcibios_fixup(void);
...
@@ -90,6 +90,9 @@ extern void iSeries_pcibios_fixup(void);
extern
void
pSeries_get_rtc_time
(
struct
rtc_time
*
rtc_time
);
extern
void
pSeries_get_rtc_time
(
struct
rtc_time
*
rtc_time
);
extern
int
pSeries_set_rtc_time
(
struct
rtc_time
*
rtc_time
);
extern
int
pSeries_set_rtc_time
(
struct
rtc_time
*
rtc_time
);
void
pSeries_calibrate_decr
(
void
);
void
pSeries_calibrate_decr
(
void
);
static
void
fwnmi_init
(
void
);
extern
void
SystemReset_FWNMI
(
void
),
MachineCheck_FWNMI
(
void
);
/* from head.S */
int
fwnmi_active
;
/* TRUE if an FWNMI handler is present */
kdev_t
boot_dev
;
kdev_t
boot_dev
;
unsigned
long
virtPython0Facilities
=
0
;
// python0 facility area (memory mapped io) (64-bit format) VIRTUAL address.
unsigned
long
virtPython0Facilities
=
0
;
// python0 facility area (memory mapped io) (64-bit format) VIRTUAL address.
...
@@ -152,6 +155,8 @@ chrp_setup_arch(void)
...
@@ -152,6 +155,8 @@ chrp_setup_arch(void)
printk
(
"Boot arguments: %s
\n
"
,
cmd_line
);
printk
(
"Boot arguments: %s
\n
"
,
cmd_line
);
fwnmi_init
();
/* Find and initialize PCI host bridges */
/* Find and initialize PCI host bridges */
/* iSeries needs to be done much later. */
/* iSeries needs to be done much later. */
#ifndef CONFIG_PPC_ISERIES
#ifndef CONFIG_PPC_ISERIES
...
@@ -189,6 +194,23 @@ chrp_init2(void)
...
@@ -189,6 +194,23 @@ chrp_init2(void)
ppc_md
.
progress
(
UTS_RELEASE
,
0x7777
);
ppc_md
.
progress
(
UTS_RELEASE
,
0x7777
);
}
}
/* Initialize firmware assisted non-maskable interrupts if
* the firmware supports this feature.
*
*/
static
void
__init
fwnmi_init
(
void
)
{
long
ret
;
int
ibm_nmi_register
=
rtas_token
(
"ibm,nmi-register"
);
if
(
ibm_nmi_register
==
RTAS_UNKNOWN_SERVICE
)
return
;
ret
=
rtas_call
(
ibm_nmi_register
,
2
,
1
,
NULL
,
__pa
((
unsigned
long
)
SystemReset_FWNMI
),
__pa
((
unsigned
long
)
MachineCheck_FWNMI
));
if
(
ret
==
0
)
fwnmi_active
=
1
;
}
/* Early initialization. Relocation is on but do not reference unbolted pages */
/* Early initialization. Relocation is on but do not reference unbolted pages */
void
__init
pSeries_init_early
(
void
)
void
__init
pSeries_init_early
(
void
)
...
...
arch/ppc64/kernel/eeh.c
View file @
57bd45fd
...
@@ -36,7 +36,6 @@
...
@@ -36,7 +36,6 @@
#define BUID_LO(buid) ((buid) & 0xffffffff)
#define BUID_LO(buid) ((buid) & 0xffffffff)
#define CONFIG_ADDR(busno, devfn) (((((busno) & 0xff) << 8) | ((devfn) & 0xf8)) << 8)
#define CONFIG_ADDR(busno, devfn) (((((busno) & 0xff) << 8) | ((devfn) & 0xf8)) << 8)
unsigned
long
eeh_total_mmio_reads
;
unsigned
long
eeh_total_mmio_ffs
;
unsigned
long
eeh_total_mmio_ffs
;
unsigned
long
eeh_false_positives
;
unsigned
long
eeh_false_positives
;
/* RTAS tokens */
/* RTAS tokens */
...
@@ -44,11 +43,11 @@ static int ibm_set_eeh_option;
...
@@ -44,11 +43,11 @@ static int ibm_set_eeh_option;
static
int
ibm_set_slot_reset
;
static
int
ibm_set_slot_reset
;
static
int
ibm_read_slot_reset_state
;
static
int
ibm_read_slot_reset_state
;
static
int
eeh_implemented
;
int
eeh_implemented
;
#define EEH_MAX_OPTS 4096
#define EEH_MAX_OPTS 4096
static
char
*
eeh_opts
;
static
char
*
eeh_opts
;
static
int
eeh_opts_last
;
static
int
eeh_opts_last
;
static
int
eeh_check_opts_config
(
struct
pci_dev
*
dev
);
static
int
eeh_check_opts_config
(
struct
pci_dev
*
dev
,
int
default_state
);
unsigned
long
eeh_token
(
unsigned
long
phb
,
unsigned
long
bus
,
unsigned
long
devfn
,
unsigned
long
offset
)
unsigned
long
eeh_token
(
unsigned
long
phb
,
unsigned
long
bus
,
unsigned
long
devfn
,
unsigned
long
offset
)
...
@@ -86,33 +85,58 @@ unsigned long eeh_check_failure(void *token, unsigned long val)
...
@@ -86,33 +85,58 @@ unsigned long eeh_check_failure(void *token, unsigned long val)
panic
(
"EEH: checking token %p phb index of %ld is greater than max of %d
\n
"
,
token
,
phbidx
,
global_phb_number
-
1
);
panic
(
"EEH: checking token %p phb index of %ld is greater than max of %d
\n
"
,
token
,
phbidx
,
global_phb_number
-
1
);
}
}
phb
=
phbtab
[
phbidx
];
phb
=
phbtab
[
phbidx
];
eeh_false_positives
++
;
ret
=
rtas_call
(
ibm_read_slot_reset_state
,
3
,
3
,
rets
,
ret
=
rtas_call
(
ibm_read_slot_reset_state
,
3
,
3
,
rets
,
config_addr
,
BUID_HI
(
phb
->
buid
),
BUID_LO
(
phb
->
buid
));
config_addr
,
BUID_HI
(
phb
->
buid
),
BUID_LO
(
phb
->
buid
));
if
(
ret
==
0
&&
rets
[
1
]
==
1
&&
rets
[
2
]
!=
0
)
{
if
(
ret
==
0
&&
rets
[
1
]
==
1
&&
rets
[
0
]
>=
2
)
{
struct
pci_dev
*
dev
;
struct
pci_dev
*
dev
;
int
bus
=
((
unsigned
long
)
token
>>
40
)
&
0xffff
;
/* include PHB# in bus */
int
bus
=
((
unsigned
long
)
token
>>
40
)
&
0xffff
;
/* include PHB# in bus */
int
devfn
=
(
config_addr
>>
8
)
&
0xff
;
int
devfn
=
(
config_addr
>>
8
)
&
0xff
;
dev
=
pci_find_slot
(
bus
,
devfn
);
dev
=
pci_find_slot
(
bus
,
devfn
);
if
(
dev
)
if
(
dev
)
{
udbg_printf
(
"EEH: MMIO failure (%ld) on device:
\n
%s %s
\n
"
,
rets
[
0
],
dev
->
slot_name
,
dev
->
name
);
printk
(
"EEH: MMIO failure (%ld) on device:
\n
%s %s
\n
"
,
rets
[
0
],
dev
->
slot_name
,
dev
->
name
);
PPCDBG_ENTER_DEBUGGER
();
panic
(
"EEH: MMIO failure (%ld) on device:
\n
%s %s
\n
"
,
panic
(
"EEH: MMIO failure (%ld) on device:
\n
%s %s
\n
"
,
rets
[
2
],
dev
->
slot_name
,
dev
->
name
);
rets
[
0
],
dev
->
slot_name
,
dev
->
name
);
else
}
else
{
panic
(
"EEH: MMIO failure (%ld) on device buid %lx, config_addr %lx
\n
"
,
rets
[
2
],
phb
->
buid
,
config_addr
);
udbg_printf
(
"EEH: MMIO failure (%ld) on device buid %lx, config_addr %lx
\n
"
,
rets
[
0
],
phb
->
buid
,
config_addr
);
printk
(
"EEH: MMIO failure (%ld) on device buid %lx, config_addr %lx
\n
"
,
rets
[
0
],
phb
->
buid
,
config_addr
);
PPCDBG_ENTER_DEBUGGER
();
panic
(
"EEH: MMIO failure (%ld) on device buid %lx, config_addr %lx
\n
"
,
rets
[
0
],
phb
->
buid
,
config_addr
);
}
}
}
eeh_false_positives
++
;
return
val
;
/* good case */
return
val
;
/* good case */
}
}
void
eeh_init
(
void
)
{
void
eeh_init
(
void
)
{
extern
char
cmd_line
[];
/* Very early cmd line parse. Cheap, but works. */
char
*
eeh_force_off
=
strstr
(
cmd_line
,
"eeh-force-off"
);
char
*
eeh_force_on
=
strstr
(
cmd_line
,
"eeh-force-on"
);
ibm_set_eeh_option
=
rtas_token
(
"ibm,set-eeh-option"
);
ibm_set_eeh_option
=
rtas_token
(
"ibm,set-eeh-option"
);
ibm_set_slot_reset
=
rtas_token
(
"ibm,set-slot-reset"
);
ibm_set_slot_reset
=
rtas_token
(
"ibm,set-slot-reset"
);
ibm_read_slot_reset_state
=
rtas_token
(
"ibm,read-slot-reset-state"
);
ibm_read_slot_reset_state
=
rtas_token
(
"ibm,read-slot-reset-state"
);
if
(
ibm_set_eeh_option
!=
RTAS_UNKNOWN_SERVICE
)
{
if
(
ibm_set_eeh_option
!=
RTAS_UNKNOWN_SERVICE
&&
_machine
==
_MACH_pSeriesLP
)
printk
(
"PCI Enhanced I/O Error Handling Enabled
\n
"
);
eeh_implemented
=
1
;
eeh_implemented
=
1
;
if
(
eeh_force_off
>
eeh_force_on
)
{
/* User is forcing EEH off. Be noisy if it is implemented. */
if
(
eeh_implemented
)
printk
(
"EEH: WARNING: PCI Enhanced I/O Error Handling is user disabled
\n
"
);
eeh_implemented
=
0
;
return
;
}
}
if
(
eeh_force_on
>
eeh_force_off
)
eeh_implemented
=
1
;
/* User is forcing it on. */
if
(
eeh_implemented
)
printk
(
"EEH: PCI Enhanced I/O Error Handling Enabled
\n
"
);
}
}
...
@@ -124,27 +148,35 @@ int is_eeh_configured(struct pci_dev *dev)
...
@@ -124,27 +148,35 @@ int is_eeh_configured(struct pci_dev *dev)
struct
device_node
*
dn
=
pci_device_to_OF_node
(
dev
);
struct
device_node
*
dn
=
pci_device_to_OF_node
(
dev
);
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
dev
);
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
dev
);
unsigned
long
ret
,
rets
[
2
];
unsigned
long
ret
,
rets
[
2
];
int
eeh_capable
;
int
default_state
=
1
;
/* default enable EEH if we can. */
if
(
dn
==
NULL
||
phb
==
NULL
||
phb
->
buid
==
0
||
!
eeh_implemented
)
if
(
dn
==
NULL
||
phb
==
NULL
||
!
eeh_implemented
)
return
0
;
return
0
;
/* Hack: turn off eeh for display class devices.
/* Hack: turn off eeh for display class devices
by default
.
* This fixes matrox accel framebuffer.
* This fixes matrox accel framebuffer.
*/
*/
if
((
dev
->
class
>>
16
)
==
PCI_BASE_CLASS_DISPLAY
)
if
((
dev
->
class
>>
16
)
==
PCI_BASE_CLASS_DISPLAY
)
return
0
;
default_state
=
0
;
if
(
!
eeh_check_opts_config
(
dev
))
/* Ignore known PHBs and EADs bridges */
if
(
dev
->
vendor
==
PCI_VENDOR_ID_IBM
&&
(
dev
->
device
==
0x0102
||
dev
->
device
==
0x008b
))
default_state
=
0
;
if
(
!
eeh_check_opts_config
(
dev
,
default_state
))
{
if
(
default_state
)
printk
(
"EEH: %s %s user requested to run without EEH.
\n
"
,
dev
->
slot_name
,
dev
->
name
);
return
0
;
return
0
;
}
ret
=
rtas_call
(
ibm_read_slot_reset_state
,
3
,
3
,
rets
,
ret
=
rtas_call
(
ibm_read_slot_reset_state
,
3
,
3
,
rets
,
CONFIG_ADDR
(
dn
->
busno
,
dn
->
devfn
),
CONFIG_ADDR
(
dn
->
busno
,
dn
->
devfn
),
BUID_HI
(
phb
->
buid
),
BUID_LO
(
phb
->
buid
));
BUID_HI
(
phb
->
buid
),
BUID_LO
(
phb
->
buid
));
if
(
ret
==
0
&&
rets
[
1
]
==
1
)
{
eeh_capable
=
(
ret
==
0
&&
rets
[
1
]
==
1
);
printk
(
"EEH: %s %s is EEH capable.
\n
"
,
dev
->
slot_name
,
dev
->
name
);
printk
(
"EEH: %s %s is%s EEH capable.
\n
"
,
dev
->
slot_name
,
dev
->
name
,
eeh_capable
?
""
:
" not"
);
return
1
;
return
eeh_capable
;
}
return
0
;
}
}
int
eeh_set_option
(
struct
pci_dev
*
dev
,
int
option
)
int
eeh_set_option
(
struct
pci_dev
*
dev
,
int
option
)
...
@@ -166,41 +198,41 @@ static int eeh_proc_falsepositive_read(char *page, char **start, off_t off,
...
@@ -166,41 +198,41 @@ static int eeh_proc_falsepositive_read(char *page, char **start, off_t off,
{
{
int
len
;
int
len
;
len
=
sprintf
(
page
,
"eeh_false_positives=%ld
\n
"
len
=
sprintf
(
page
,
"eeh_false_positives=%ld
\n
"
"eeh_total_mmio_ffs=%ld
\n
"
"eeh_total_mmio_ffs=%ld
\n
"
,
"eeh_total_mmio_reads=%ld
\n
"
,
eeh_false_positives
,
eeh_total_mmio_ffs
);
eeh_false_positives
,
eeh_total_mmio_ffs
,
eeh_total_mmio_reads
);
return
len
;
return
len
;
}
}
/* Implementation of /proc/ppc64/eeh
/* Implementation of /proc/ppc64/eeh
* For now it is one file showing false positives.
* For now it is one file showing false positives.
*/
*/
void
eeh_init_proc
(
struct
proc_dir_entry
*
top
)
static
int
__init
eeh_init_proc
(
void
)
{
{
struct
proc_dir_entry
*
ent
=
create_proc_entry
(
"
eeh"
,
S_IRUGO
,
top
);
struct
proc_dir_entry
*
ent
=
create_proc_entry
(
"
ppc64/eeh"
,
S_IRUGO
,
0
);
if
(
ent
)
{
if
(
ent
)
{
ent
->
nlink
=
1
;
ent
->
nlink
=
1
;
ent
->
data
=
NULL
;
ent
->
data
=
NULL
;
ent
->
read_proc
=
(
void
*
)
eeh_proc_falsepositive_read
;
ent
->
read_proc
=
(
void
*
)
eeh_proc_falsepositive_read
;
}
}
return
0
;
}
}
/*
/*
* Test if "dev" should be configured on or off.
* Test if "dev" should be configured on or off.
* This processes the options literally from
right to lef
t.
* This processes the options literally from
left to righ
t.
* This lets the user specify stupid combinations of options,
* This lets the user specify stupid combinations of options,
* but at least the result should be very predictable.
* but at least the result should be very predictable.
*/
*/
static
int
eeh_check_opts_config
(
struct
pci_dev
*
dev
)
static
int
eeh_check_opts_config
(
struct
pci_dev
*
dev
,
int
default_state
)
{
{
struct
device_node
*
dn
=
pci_device_to_OF_node
(
dev
);
struct
device_node
*
dn
=
pci_device_to_OF_node
(
dev
);
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
dev
);
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
dev
);
char
devname
[
32
],
classname
[
32
],
phbname
[
32
];
char
devname
[
32
],
classname
[
32
],
phbname
[
32
];
char
*
strs
[
8
],
*
s
;
char
*
strs
[
8
],
*
s
;
int
nstrs
,
i
;
int
nstrs
,
i
;
int
ret
=
0
;
int
ret
=
default_state
;
if
(
dn
==
NULL
||
phb
==
NULL
||
phb
->
buid
==
0
||
!
eeh_implemented
)
if
(
dn
==
NULL
||
phb
==
NULL
)
return
0
;
return
0
;
/* Build list of strings to match */
/* Build list of strings to match */
nstrs
=
0
;
nstrs
=
0
;
...
@@ -221,7 +253,7 @@ static int eeh_check_opts_config(struct pci_dev *dev)
...
@@ -221,7 +253,7 @@ static int eeh_check_opts_config(struct pci_dev *dev)
for
(
s
=
eeh_opts
;
s
&&
(
s
<
(
eeh_opts
+
eeh_opts_last
));
s
+=
strlen
(
s
)
+
1
)
{
for
(
s
=
eeh_opts
;
s
&&
(
s
<
(
eeh_opts
+
eeh_opts_last
));
s
+=
strlen
(
s
)
+
1
)
{
for
(
i
=
0
;
i
<
nstrs
;
i
++
)
{
for
(
i
=
0
;
i
<
nstrs
;
i
++
)
{
if
(
strcasecmp
(
strs
[
i
],
s
+
1
)
==
0
)
{
if
(
strcasecmp
(
strs
[
i
],
s
+
1
)
==
0
)
{
ret
=
(
strs
[
0
]
==
'+'
)
?
1
:
0
;
ret
=
(
strs
[
i
][
0
]
==
'+'
)
?
1
:
0
;
}
}
}
}
}
}
...
@@ -234,7 +266,7 @@ static int eeh_check_opts_config(struct pci_dev *dev)
...
@@ -234,7 +266,7 @@ static int eeh_check_opts_config(struct pci_dev *dev)
* eeh-off=loc1,loc2,loc3...
* eeh-off=loc1,loc2,loc3...
*
*
* and this option can be repeated so
* and this option can be repeated so
* eeh-off=loc1,loc2 eeh=loc3
* eeh-off=loc1,loc2 eeh
-off
=loc3
* is the same as eeh-off=loc1,loc2,loc3
* is the same as eeh-off=loc1,loc2,loc3
*
*
* loc is an IBM location code that can be found in a manual or
* loc is an IBM location code that can be found in a manual or
...
@@ -285,7 +317,6 @@ static int __init eeh_parm(char *str, int state)
...
@@ -285,7 +317,6 @@ static int __init eeh_parm(char *str, int state)
curend
=
cur
+
strlen
(
cur
);
curend
=
cur
+
strlen
(
cur
);
if
(
*
cur
)
{
if
(
*
cur
)
{
int
curlen
=
curend
-
cur
;
int
curlen
=
curend
-
cur
;
char
*
sym
=
eeh_opts
+
eeh_opts_last
;
if
(
eeh_opts_last
+
curlen
>
EEH_MAX_OPTS
-
2
)
{
if
(
eeh_opts_last
+
curlen
>
EEH_MAX_OPTS
-
2
)
{
printk
(
"EEH: sorry...too many eeh cmd line options
\n
"
);
printk
(
"EEH: sorry...too many eeh cmd line options
\n
"
);
return
1
;
return
1
;
...
@@ -308,6 +339,6 @@ static int __init eehon_parm(char *str)
...
@@ -308,6 +339,6 @@ static int __init eehon_parm(char *str)
return
eeh_parm
(
str
,
1
);
return
eeh_parm
(
str
,
1
);
}
}
__initcall
(
eeh_init_proc
);
__setup
(
"eeh-off"
,
eehoff_parm
);
__setup
(
"eeh-off"
,
eehoff_parm
);
__setup
(
"eeh-on"
,
eehon_parm
);
__setup
(
"eeh-on"
,
eehon_parm
);
arch/ppc64/kernel/entry.S
View file @
57bd45fd
/*
/*
*
arch
/
ppc
/
kernel
/
entry
.
S
*
arch
/
ppc
64
/
kernel
/
entry
.
S
*
*
*
PowerPC
version
*
PowerPC
version
*
Copyright
(
C
)
1995
-
1996
Gary
Thomas
(
gdt
@
linuxppc
.
org
)
*
Copyright
(
C
)
1995
-
1996
Gary
Thomas
(
gdt
@
linuxppc
.
org
)
...
...
arch/ppc64/kernel/head.S
View file @
57bd45fd
...
@@ -490,6 +490,24 @@ maskable_exception_exit:
...
@@ -490,6 +490,24 @@ maskable_exception_exit:
mfspr
r20
,
SPRG2
mfspr
r20
,
SPRG2
rfid
rfid
/*
*
Data
area
reserved
for
FWNMI
option
.
*/
.
=
0x7000
.
globl
fwnmi_data_area
fwnmi_data_area
:
/*
*
Vectors
for
the
FWNMI
option
.
Share
common
code
.
*/
.
=
0x8000
.
globl
SystemReset_FWNMI
SystemReset_FWNMI
:
//
EXCEPTION_PROLOG_PSERIES
(0
x100
,
SystemReset_common
)
.
globl
MachineCheck_FWNMI
MachineCheck_FWNMI
:
//
EXCEPTION_PROLOG_PSERIES
(0
x200
,
MachineCheck_common
)
/***
Common
interrupt
handlers
***/
/***
Common
interrupt
handlers
***/
STD_EXCEPTION_COMMON
(
0x100
,
SystemReset
,
.
SystemResetException
)
STD_EXCEPTION_COMMON
(
0x100
,
SystemReset
,
.
SystemResetException
)
...
@@ -1285,7 +1303,7 @@ _STATIC(__after_prom_start)
...
@@ -1285,7 +1303,7 @@ _STATIC(__after_prom_start)
/
*
this
includes
the
code
being
*/
/
*
this
includes
the
code
being
*/
/
*
executed
here
.
*/
/
*
executed
here
.
*/
li
r0
,
4
f
@
l
/*
Jump
to
the
copy
of
this
code
*/
LOADADDR
(
r0
,
4
f
)
/*
Jump
to
the
copy
of
this
code
*/
mtctr
r0
/*
that
we
just
made
*/
mtctr
r0
/*
that
we
just
made
*/
bctr
bctr
...
...
arch/ppc64/kernel/pSeries_pci.c
View file @
57bd45fd
...
@@ -41,9 +41,7 @@
...
@@ -41,9 +41,7 @@
#include <asm/ppcdebug.h>
#include <asm/ppcdebug.h>
#include <asm/naca.h>
#include <asm/naca.h>
#include <asm/pci_dma.h>
#include <asm/pci_dma.h>
#ifdef CONFIG_PPC_EEH
#include <asm/eeh.h>
#include <asm/eeh.h>
#endif
#include "xics.h"
#include "xics.h"
#include "open_pic.h"
#include "open_pic.h"
...
@@ -256,9 +254,8 @@ find_and_init_phbs(void)
...
@@ -256,9 +254,8 @@ find_and_init_phbs(void)
write_pci_config
=
rtas_token
(
"write-pci-config"
);
write_pci_config
=
rtas_token
(
"write-pci-config"
);
ibm_read_pci_config
=
rtas_token
(
"ibm,read-pci-config"
);
ibm_read_pci_config
=
rtas_token
(
"ibm,read-pci-config"
);
ibm_write_pci_config
=
rtas_token
(
"ibm,write-pci-config"
);
ibm_write_pci_config
=
rtas_token
(
"ibm,write-pci-config"
);
#ifdef CONFIG_PPC_EEH
eeh_init
();
eeh_init
();
#endif
if
(
naca
->
interrupt_controller
==
IC_OPEN_PIC
)
{
if
(
naca
->
interrupt_controller
==
IC_OPEN_PIC
)
{
opprop
=
(
unsigned
int
*
)
get_property
(
find_path_device
(
"/"
),
opprop
=
(
unsigned
int
*
)
get_property
(
find_path_device
(
"/"
),
...
@@ -358,24 +355,24 @@ find_and_init_phbs(void)
...
@@ -358,24 +355,24 @@ find_and_init_phbs(void)
res
=
&
phb
->
io_resource
;
res
=
&
phb
->
io_resource
;
res
->
name
=
Pci_Node
->
full_name
;
res
->
name
=
Pci_Node
->
full_name
;
res
->
flags
=
IORESOURCE_IO
;
res
->
flags
=
IORESOURCE_IO
;
#ifdef CONFIG_PPC_EEH
if
(
is_eeh_implemented
())
{
if
(
!
isa_io_base
&&
has_isa
)
{
if
(
!
isa_io_base
&&
has_isa
)
{
/* map a page for ISA ports. Not EEH protected. */
/* map a page for ISA ports. Not EEH protected. */
isa_io_base
=
(
unsigned
long
)
__ioremap
(
phb
->
io_base_phys
,
PAGE_SIZE
,
_PAGE_NO_CACHE
);
isa_io_base
=
(
unsigned
long
)
__ioremap
(
phb
->
io_base_phys
,
PAGE_SIZE
,
_PAGE_NO_CACHE
);
}
}
res
->
start
=
phb
->
io_base_virt
=
eeh_token
(
index
,
0
,
0
,
0
);
res
->
start
=
phb
->
io_base_virt
=
eeh_token
(
index
,
0
,
0
,
0
);
res
->
end
=
eeh_token
(
index
,
0xff
,
0xff
,
0xffffffff
);
res
->
end
=
eeh_token
(
index
,
0xff
,
0xff
,
0xffffffff
);
#else
}
else
{
phb
->
io_base_virt
=
ioremap
(
phb
->
io_base_phys
,
range
.
size
);
phb
->
io_base_virt
=
ioremap
(
phb
->
io_base_phys
,
range
.
size
);
if
(
!
pci_io_base
)
{
if
(
!
pci_io_base
)
{
pci_io_base
=
(
unsigned
long
)
phb
->
io_base_virt
;
pci_io_base
=
(
unsigned
long
)
phb
->
io_base_virt
;
if
(
has_isa
)
if
(
has_isa
)
isa_io_base
=
pci_io_base
;
isa_io_base
=
pci_io_base
;
}
res
->
start
=
((((
unsigned
long
)
range
.
child_addr
.
a_mid
)
<<
32
)
|
(
range
.
child_addr
.
a_lo
));
res
->
start
+=
(
unsigned
long
)
phb
->
io_base_virt
;
res
->
end
=
res
->
start
+
range
.
size
-
1
;
}
}
res
->
start
=
((((
unsigned
long
)
range
.
child_addr
.
a_mid
)
<<
32
)
|
(
range
.
child_addr
.
a_lo
));
res
->
start
+=
(
unsigned
long
)
phb
->
io_base_virt
;
res
->
end
=
res
->
start
+
range
.
size
-
1
;
#endif
res
->
parent
=
NULL
;
res
->
parent
=
NULL
;
res
->
sibling
=
NULL
;
res
->
sibling
=
NULL
;
res
->
child
=
NULL
;
res
->
child
=
NULL
;
...
@@ -399,13 +396,13 @@ find_and_init_phbs(void)
...
@@ -399,13 +396,13 @@ find_and_init_phbs(void)
++
memno
;
++
memno
;
res
->
name
=
Pci_Node
->
full_name
;
res
->
name
=
Pci_Node
->
full_name
;
res
->
flags
=
IORESOURCE_MEM
;
res
->
flags
=
IORESOURCE_MEM
;
#ifdef CONFIG_PPC_EEH
if
(
is_eeh_implemented
())
{
res
->
start
=
eeh_token
(
index
,
0
,
0
,
0
);
res
->
start
=
eeh_token
(
index
,
0
,
0
,
0
);
res
->
end
=
eeh_token
(
index
,
0xff
,
0xff
,
0xffffffff
);
res
->
end
=
eeh_token
(
index
,
0xff
,
0xff
,
0xffffffff
);
#else
}
else
{
res
->
start
=
range
.
parent_addr
;
res
->
start
=
range
.
parent_addr
;
res
->
end
=
range
.
parent_addr
+
range
.
size
-
1
;
res
->
end
=
range
.
parent_addr
+
range
.
size
-
1
;
#endif
}
res
->
parent
=
NULL
;
res
->
parent
=
NULL
;
res
->
sibling
=
NULL
;
res
->
sibling
=
NULL
;
res
->
child
=
NULL
;
res
->
child
=
NULL
;
...
@@ -566,14 +563,11 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
...
@@ -566,14 +563,11 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
phb
->
ops
=
&
rtas_pci_ops
;
phb
->
ops
=
&
rtas_pci_ops
;
buid_vals
=
(
int
*
)
get_property
(
dev
,
"ibm,fw-phb-id"
,
&
len
);
buid_vals
=
(
int
*
)
get_property
(
dev
,
"ibm,fw-phb-id"
,
&
len
);
if
(
buid_vals
==
NULL
||
len
<
2
*
sizeof
(
int
))
{
if
(
buid_vals
==
NULL
)
{
phb
->
buid
=
0
;
phb
->
buid
=
0
;
}
else
{
}
/* Big bus system. These systems start new bus numbers under
else
{
* each phb. Until pci domains are standard, we depend on a
* patch which makes bus numbers ints and we shift the phb
* number into the upper bits.
*/
struct
pci_bus
check
;
struct
pci_bus
check
;
if
(
sizeof
(
check
.
number
)
==
1
||
sizeof
(
check
.
primary
)
==
1
||
if
(
sizeof
(
check
.
number
)
==
1
||
sizeof
(
check
.
primary
)
==
1
||
sizeof
(
check
.
secondary
)
==
1
||
sizeof
(
check
.
subordinate
)
==
1
)
{
sizeof
(
check
.
secondary
)
==
1
||
sizeof
(
check
.
subordinate
)
==
1
)
{
...
@@ -583,9 +577,14 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
...
@@ -583,9 +577,14 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
panic
(
"pSeries_pci: this system has large bus numbers and the kernel was not
\n
"
panic
(
"pSeries_pci: this system has large bus numbers and the kernel was not
\n
"
"built with the patch that fixes include/linux/pci.h struct pci_bus so
\n
"
"built with the patch that fixes include/linux/pci.h struct pci_bus so
\n
"
"number, primary, secondary and subordinate are ints.
\n
"
);
"number, primary, secondary and subordinate are ints.
\n
"
);
}
}
phb
->
buid
=
(((
unsigned
long
)
buid_vals
[
0
])
<<
32UL
)
|
(((
unsigned
long
)
buid_vals
[
1
])
&
0xffffffff
);
if
(
len
<
2
*
sizeof
(
int
))
phb
->
buid
=
(
unsigned
long
)
buid_vals
[
0
];
// Support for new OF that only has 1 integer for buid.
else
phb
->
buid
=
(((
unsigned
long
)
buid_vals
[
0
])
<<
32UL
)
|
(((
unsigned
long
)
buid_vals
[
1
])
&
0xffffffff
);
phb
->
first_busno
+=
(
phb
->
global_number
<<
8
);
phb
->
first_busno
+=
(
phb
->
global_number
<<
8
);
phb
->
last_busno
+=
(
phb
->
global_number
<<
8
);
phb
->
last_busno
+=
(
phb
->
global_number
<<
8
);
}
}
...
@@ -601,7 +600,6 @@ fixup_resources(struct pci_dev *dev)
...
@@ -601,7 +600,6 @@ fixup_resources(struct pci_dev *dev)
{
{
int
i
;
int
i
;
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
dev
);
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
dev
);
#ifdef CONFIG_PPC_EEH
struct
device_node
*
dn
;
struct
device_node
*
dn
;
unsigned
long
eeh_disable_bit
;
unsigned
long
eeh_disable_bit
;
...
@@ -620,19 +618,19 @@ fixup_resources(struct pci_dev *dev)
...
@@ -620,19 +618,19 @@ fixup_resources(struct pci_dev *dev)
}
}
}
}
if
(
is_eeh_configured
(
dev
))
{
if
(
is_eeh_implemented
())
{
eeh_disable_bit
=
0
;
if
(
is_eeh_configured
(
dev
))
{
printk
(
"PCI: eeh configured for %s %s
\n
"
,
dev
->
slot_name
,
dev
->
name
);
eeh_disable_bit
=
0
;
if
(
eeh_set_option
(
dev
,
EEH_ENABLE
)
!=
0
)
{
if
(
eeh_set_option
(
dev
,
EEH_ENABLE
)
!=
0
)
{
printk
(
"PCI: failed to enable eeh for %s %s
\n
"
,
dev
->
slot_name
,
dev
->
name
);
printk
(
"PCI: failed to enable EEH for %s %s
\n
"
,
dev
->
slot_name
,
dev
->
name
);
eeh_disable_bit
=
EEH_TOKEN_DISABLED
;
}
}
else
{
/* Assume device is by default EEH_DISABLE'd */
printk
(
"PCI: eeh NOT configured for %s %s
\n
"
,
dev
->
slot_name
,
dev
->
name
);
eeh_disable_bit
=
EEH_TOKEN_DISABLED
;
eeh_disable_bit
=
EEH_TOKEN_DISABLED
;
}
}
}
else
{
/* Assume device is by default EEH_DISABLE'd */
printk
(
"PCI: eeh NOT configured for %s %s
\n
"
,
dev
->
slot_name
,
dev
->
name
);
eeh_disable_bit
=
EEH_TOKEN_DISABLED
;
}
}
#endif
PPCDBG
(
PPCDBG_PHBINIT
,
"fixup_resources:
\n
"
);
PPCDBG
(
PPCDBG_PHBINIT
,
"fixup_resources:
\n
"
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
phb = 0x%016LX
\n
"
,
phb
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
phb = 0x%016LX
\n
"
,
phb
);
...
@@ -657,19 +655,19 @@ fixup_resources(struct pci_dev *dev)
...
@@ -657,19 +655,19 @@ fixup_resources(struct pci_dev *dev)
}
}
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_IO
)
{
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_IO
)
{
#ifdef CONFIG_PPC_EEH
if
(
is_eeh_implemented
())
{
unsigned
int
busno
=
dev
->
bus
?
dev
->
bus
->
number
:
0
;
unsigned
int
busno
=
dev
->
bus
?
dev
->
bus
->
number
:
0
;
unsigned
long
size
=
dev
->
resource
[
i
].
end
-
dev
->
resource
[
i
].
start
;
unsigned
long
size
=
dev
->
resource
[
i
].
end
-
dev
->
resource
[
i
].
start
;
unsigned
long
addr
=
(
unsigned
long
)
__ioremap
(
dev
->
resource
[
i
].
start
+
phb
->
io_base_phys
,
size
,
_PAGE_NO_CACHE
);
unsigned
long
addr
=
(
unsigned
long
)
__ioremap
(
dev
->
resource
[
i
].
start
+
phb
->
io_base_phys
,
size
,
_PAGE_NO_CACHE
);
if
(
!
addr
)
if
(
!
addr
)
panic
(
"fixup_resources: ioremap failed!
\n
"
);
panic
(
"fixup_resources: ioremap failed!
\n
"
);
dev
->
resource
[
i
].
start
=
eeh_token
(
phb
->
global_number
,
busno
,
dev
->
devfn
,
addr
)
|
eeh_disable_bit
;
dev
->
resource
[
i
].
start
=
eeh_token
(
phb
->
global_number
,
busno
,
dev
->
devfn
,
addr
)
|
eeh_disable_bit
;
dev
->
resource
[
i
].
end
=
dev
->
resource
[
i
].
start
+
size
;
dev
->
resource
[
i
].
end
=
dev
->
resource
[
i
].
start
+
size
;
#else
}
else
{
unsigned
long
offset
=
(
unsigned
long
)
phb
->
io_base_virt
;
unsigned
long
offset
=
(
unsigned
long
)
phb
->
io_base_virt
;
dev
->
resource
[
i
].
start
+=
offset
;
dev
->
resource
[
i
].
start
+=
offset
;
dev
->
resource
[
i
].
end
+=
offset
;
dev
->
resource
[
i
].
end
+=
offset
;
#endif
}
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t\t
-> now [%lx .. %lx]
\n
"
,
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t\t
-> now [%lx .. %lx]
\n
"
,
dev
->
resource
[
i
].
start
,
dev
->
resource
[
i
].
end
);
dev
->
resource
[
i
].
start
,
dev
->
resource
[
i
].
end
);
}
else
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_MEM
)
{
}
else
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_MEM
)
{
...
@@ -677,18 +675,18 @@ fixup_resources(struct pci_dev *dev)
...
@@ -677,18 +675,18 @@ fixup_resources(struct pci_dev *dev)
/* Bogus. Probably an unused bridge. */
/* Bogus. Probably an unused bridge. */
dev
->
resource
[
i
].
end
=
0
;
dev
->
resource
[
i
].
end
=
0
;
}
else
{
}
else
{
#ifdef CONFIG_PPC_EEH
if
(
is_eeh_implemented
())
{
unsigned
int
busno
=
dev
->
bus
?
dev
->
bus
->
number
:
0
;
unsigned
int
busno
=
dev
->
bus
?
dev
->
bus
->
number
:
0
;
unsigned
long
size
=
dev
->
resource
[
i
].
end
-
dev
->
resource
[
i
].
start
;
unsigned
long
size
=
dev
->
resource
[
i
].
end
-
dev
->
resource
[
i
].
start
;
unsigned
long
addr
=
(
unsigned
long
)
__ioremap
(
dev
->
resource
[
i
].
start
+
phb
->
pci_mem_offset
,
size
,
_PAGE_NO_CACHE
);
unsigned
long
addr
=
(
unsigned
long
)
__ioremap
(
dev
->
resource
[
i
].
start
+
phb
->
pci_mem_offset
,
size
,
_PAGE_NO_CACHE
);
if
(
!
addr
)
if
(
!
addr
)
panic
(
"fixup_resources: ioremap failed!
\n
"
);
panic
(
"fixup_resources: ioremap failed!
\n
"
);
dev
->
resource
[
i
].
start
=
eeh_token
(
phb
->
global_number
,
busno
,
dev
->
devfn
,
addr
)
|
eeh_disable_bit
;
dev
->
resource
[
i
].
start
=
eeh_token
(
phb
->
global_number
,
busno
,
dev
->
devfn
,
addr
)
|
eeh_disable_bit
;
dev
->
resource
[
i
].
end
=
dev
->
resource
[
i
].
start
+
size
;
dev
->
resource
[
i
].
end
=
dev
->
resource
[
i
].
start
+
size
;
#else
}
else
{
dev
->
resource
[
i
].
start
+=
phb
->
pci_mem_offset
;
dev
->
resource
[
i
].
start
+=
phb
->
pci_mem_offset
;
dev
->
resource
[
i
].
end
+=
phb
->
pci_mem_offset
;
dev
->
resource
[
i
].
end
+=
phb
->
pci_mem_offset
;
#endif
}
}
}
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t\t
-> now [%lx..%lx]
\n
"
,
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t\t
-> now [%lx..%lx]
\n
"
,
dev
->
resource
[
i
].
start
,
dev
->
resource
[
i
].
end
);
dev
->
resource
[
i
].
start
,
dev
->
resource
[
i
].
end
);
...
...
arch/ppc64/kernel/pci.c
View file @
57bd45fd
...
@@ -33,9 +33,7 @@
...
@@ -33,9 +33,7 @@
#include <asm/naca.h>
#include <asm/naca.h>
#include <asm/pci_dma.h>
#include <asm/pci_dma.h>
#include <asm/machdep.h>
#include <asm/machdep.h>
#ifdef CONFIG_PPC_EEH
#include <asm/eeh.h>
#include <asm/eeh.h>
#endif
#include "pci.h"
#include "pci.h"
...
@@ -61,8 +59,7 @@ void fixup_resources(struct pci_dev* dev);
...
@@ -61,8 +59,7 @@ void fixup_resources(struct pci_dev* dev);
void
iSeries_pcibios_init
(
void
);
void
iSeries_pcibios_init
(
void
);
void
pSeries_pcibios_init
(
void
);
void
pSeries_pcibios_init
(
void
);
int
pci_assign_all_busses
=
0
;
int
pci_assign_all_busses
=
0
;
struct
pci_controller
*
hose_head
;
struct
pci_controller
*
hose_head
;
struct
pci_controller
**
hose_tail
=
&
hose_head
;
struct
pci_controller
**
hose_tail
=
&
hose_head
;
...
@@ -514,7 +511,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
...
@@ -514,7 +511,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
{
{
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
bus
);
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
bus
);
struct
resource
*
res
;
struct
resource
*
res
;
unsigned
long
io_offset
;
int
i
;
int
i
;
#ifndef CONFIG_PPC_ISERIES
#ifndef CONFIG_PPC_ISERIES
...
@@ -546,23 +542,23 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
...
@@ -546,23 +542,23 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
/* Transparent resource -- don't try to "fix" it. */
/* Transparent resource -- don't try to "fix" it. */
continue
;
continue
;
}
}
#ifdef CONFIG_PPC_EEH
if
(
is_eeh_implemented
())
{
if
(
res
->
flags
&
(
IORESOURCE_IO
|
IORESOURCE_MEM
))
{
if
(
res
->
flags
&
(
IORESOURCE_IO
|
IORESOURCE_MEM
))
{
res
->
start
=
eeh_token
(
phb
->
global_number
,
bus
->
number
,
0
,
0
);
res
->
start
=
eeh_token
(
phb
->
global_number
,
bus
->
number
,
0
,
0
);
res
->
end
=
eeh_token
(
phb
->
global_number
,
bus
->
number
,
0xff
,
0xffffffff
);
res
->
end
=
eeh_token
(
phb
->
global_number
,
bus
->
number
,
0xff
,
0xffffffff
);
}
}
#else
}
else
{
if
(
res
->
flags
&
IORESOURCE_IO
)
{
if
(
res
->
flags
&
IORESOURCE_IO
)
{
res
->
start
+=
(
unsigned
long
)
phb
->
io_base_virt
;
res
->
start
+=
(
unsigned
long
)
phb
->
io_base_virt
;
res
->
end
+=
(
unsigned
long
)
phb
->
io_base_virt
;
res
->
end
+=
(
unsigned
long
)
phb
->
io_base_virt
;
}
else
if
(
phb
->
pci_mem_offset
}
else
if
(
phb
->
pci_mem_offset
&&
(
res
->
flags
&
IORESOURCE_MEM
))
{
&&
(
res
->
flags
&
IORESOURCE_MEM
))
{
if
(
res
->
start
<
phb
->
pci_mem_offset
)
{
if
(
res
->
start
<
phb
->
pci_mem_offset
)
{
res
->
start
+=
phb
->
pci_mem_offset
;
res
->
start
+=
phb
->
pci_mem_offset
;
res
->
end
+=
phb
->
pci_mem_offset
;
res
->
end
+=
phb
->
pci_mem_offset
;
}
}
}
}
}
#endif
}
}
}
}
#endif
#endif
...
...
arch/ppc64/kernel/ppc_asm.h
View file @
57bd45fd
/*
/*
* arch/ppc/kernel/ppc_asm.h
* arch/ppc
64
/kernel/ppc_asm.h
*
*
* Definitions used by various bits of low-level assembly code on PowerPC.
* Definitions used by various bits of low-level assembly code on PowerPC.
*
*
...
...
arch/ppc64/kernel/ppc_ksyms.c
View file @
57bd45fd
...
@@ -191,13 +191,11 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio);
...
@@ -191,13 +191,11 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio);
EXPORT_SYMBOL
(
iSeries_Read_Word
);
EXPORT_SYMBOL
(
iSeries_Read_Word
);
EXPORT_SYMBOL
(
iSeries_Read_Byte
);
EXPORT_SYMBOL
(
iSeries_Read_Byte
);
EXPORT_SYMBOL
(
iSeries_Write_Byte
);
EXPORT_SYMBOL
(
iSeries_Write_Byte
);
#endif
/* CONFIG_PPC_ISERIES */
#endif
/* CONFIG_PPC_ISERIES */
#if
def CONFIG_PPC_EEH
#if
ndef CONFIG_PPC_ISERIES
EXPORT_SYMBOL
(
eeh_check_failure
);
EXPORT_SYMBOL
(
eeh_check_failure
);
EXPORT_SYMBOL
(
eeh_total_mmio_ffs
);
EXPORT_SYMBOL
(
eeh_total_mmio_ffs
);
EXPORT_SYMBOL
(
eeh_total_mmio_reads
);
#endif
/* CONFIG_PPC_ISERIES */
#endif
/* CONFIG_PPC_EEH */
#endif
/* CONFIG_PCI */
#endif
/* CONFIG_PCI */
EXPORT_SYMBOL
(
iSeries_veth_dev
);
EXPORT_SYMBOL
(
iSeries_veth_dev
);
...
@@ -241,10 +239,6 @@ EXPORT_SYMBOL(machine_is_compatible);
...
@@ -241,10 +239,6 @@ EXPORT_SYMBOL(machine_is_compatible);
EXPORT_SYMBOL
(
find_all_nodes
);
EXPORT_SYMBOL
(
find_all_nodes
);
EXPORT_SYMBOL
(
get_property
);
EXPORT_SYMBOL
(
get_property
);
#ifdef CONFIG_NVRAM
EXPORT_SYMBOL
(
nvram_read_byte
);
EXPORT_SYMBOL
(
nvram_write_byte
);
#endif
/* CONFIG_NVRAM */
EXPORT_SYMBOL_NOVERS
(
__ashrdi3
);
EXPORT_SYMBOL_NOVERS
(
__ashrdi3
);
EXPORT_SYMBOL_NOVERS
(
__ashldi3
);
EXPORT_SYMBOL_NOVERS
(
__ashldi3
);
...
...
arch/ppc64/kernel/traps.c
View file @
57bd45fd
...
@@ -40,6 +40,9 @@
...
@@ -40,6 +40,9 @@
extern
int
fix_alignment
(
struct
pt_regs
*
);
extern
int
fix_alignment
(
struct
pt_regs
*
);
extern
void
bad_page_fault
(
struct
pt_regs
*
,
unsigned
long
);
extern
void
bad_page_fault
(
struct
pt_regs
*
,
unsigned
long
);
/* This is true if we are using the firmware NMI handler (typically LPAR) */
extern
int
fwnmi_active
;
#ifdef CONFIG_XMON
#ifdef CONFIG_XMON
extern
void
xmon
(
struct
pt_regs
*
regs
);
extern
void
xmon
(
struct
pt_regs
*
regs
);
extern
int
xmon_bpt
(
struct
pt_regs
*
regs
);
extern
int
xmon_bpt
(
struct
pt_regs
*
regs
);
...
@@ -91,13 +94,55 @@ _exception(int signr, struct pt_regs *regs)
...
@@ -91,13 +94,55 @@ _exception(int signr, struct pt_regs *regs)
force_sig
(
signr
,
current
);
force_sig
(
signr
,
current
);
}
}
/* Get the error information for errors coming through the
* FWNMI vectors. The pt_regs' r3 will be updated to reflect
* the actual r3 if possible, and a ptr to the error log entry
* will be returned if found.
*/
static
struct
rtas_error_log
*
FWNMI_get_errinfo
(
struct
pt_regs
*
regs
)
{
unsigned
long
errdata
=
regs
->
gpr
[
3
];
struct
rtas_error_log
*
errhdr
=
NULL
;
unsigned
long
*
savep
;
if
((
errdata
>=
0x7000
&&
errdata
<
0x7fff0
)
||
(
errdata
>=
rtas
.
base
&&
errdata
<
rtas
.
base
+
rtas
.
size
-
16
))
{
savep
=
__va
(
errdata
);
regs
->
gpr
[
3
]
=
savep
[
0
];
/* restore original r3 */
errhdr
=
(
struct
rtas_error_log
*
)(
savep
+
1
);
}
else
{
printk
(
"FWNMI: corrupt r3
\n
"
);
}
return
errhdr
;
}
/* Call this when done with the data returned by FWNMI_get_errinfo.
* It will release the saved data area for other CPUs in the
* partition to receive FWNMI errors.
*/
static
void
FWNMI_release_errinfo
(
void
)
{
unsigned
long
ret
=
rtas_call
(
rtas_token
(
"ibm,nmi-interlock"
),
0
,
1
,
NULL
);
if
(
ret
!=
0
)
printk
(
"FWNMI: nmi-interlock failed: %ld
\n
"
,
ret
);
}
void
void
SystemResetException
(
struct
pt_regs
*
regs
)
SystemResetException
(
struct
pt_regs
*
regs
)
{
{
udbg_printf
(
"System Reset in kernel mode.
\n
"
);
char
*
msg
=
"System Reset in kernel mode.
\n
"
;
printk
(
"System Reset in kernel mode.
\n
"
);
udbg_printf
(
msg
);
printk
(
msg
);
if
(
fwnmi_active
)
{
unsigned
long
*
r3
=
__va
(
regs
->
gpr
[
3
]);
/* for FWNMI debug */
struct
rtas_error_log
*
errlog
;
msg
=
"FWNMI is active with save area at %016lx
\n
"
;
udbg_printf
(
msg
,
r3
);
printk
(
msg
,
r3
);
errlog
=
FWNMI_get_errinfo
(
regs
);
}
#if defined(CONFIG_XMON)
#if defined(CONFIG_XMON)
xmon
(
regs
);
xmon
(
regs
);
udbg_printf
(
"leaving xmon...
\n
"
);
#else
#else
for
(;;);
for
(;;);
#endif
#endif
...
@@ -106,6 +151,13 @@ SystemResetException(struct pt_regs *regs)
...
@@ -106,6 +151,13 @@ SystemResetException(struct pt_regs *regs)
void
void
MachineCheckException
(
struct
pt_regs
*
regs
)
MachineCheckException
(
struct
pt_regs
*
regs
)
{
{
if
(
fwnmi_active
)
{
struct
rtas_error_log
*
errhdr
=
FWNMI_get_errinfo
(
regs
);
if
(
errhdr
)
{
/* ToDo: attempt to recover from some errors here */
}
FWNMI_release_errinfo
();
}
if
(
!
user_mode
(
regs
)
)
if
(
!
user_mode
(
regs
)
)
{
{
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
...
...
arch/ppc64/mm/init.c
View file @
57bd45fd
...
@@ -155,13 +155,11 @@ ioremap(unsigned long addr, unsigned long size)
...
@@ -155,13 +155,11 @@ ioremap(unsigned long addr, unsigned long size)
#ifdef CONFIG_PPC_ISERIES
#ifdef CONFIG_PPC_ISERIES
return
(
void
*
)
addr
;
return
(
void
*
)
addr
;
#else
#else
#ifdef CONFIG_PPC_EEH
if
(
mem_init_done
&&
(
addr
>>
60UL
))
{
if
(
mem_init_done
&&
(
addr
>>
60UL
))
{
if
(
IS_EEH_TOKEN_DISABLED
(
addr
))
if
(
IS_EEH_TOKEN_DISABLED
(
addr
))
return
IO_TOKEN_TO_ADDR
(
addr
);
return
IO_TOKEN_TO_ADDR
(
addr
);
return
(
void
*
)
addr
;
/* already mapped address or EEH token. */
return
(
void
*
)
addr
;
/* already mapped address or EEH token. */
}
}
#endif
return
__ioremap
(
addr
,
size
,
_PAGE_NO_CACHE
);
return
__ioremap
(
addr
,
size
,
_PAGE_NO_CACHE
);
#endif
#endif
}
}
...
...
include/asm-ppc64/eeh.h
View file @
57bd45fd
...
@@ -37,11 +37,13 @@ struct pci_dev;
...
@@ -37,11 +37,13 @@ struct pci_dev;
#define EEH_STATE_OVERRIDE 1
/* IOA does not require eeh traps */
#define EEH_STATE_OVERRIDE 1
/* IOA does not require eeh traps */
#define EEH_STATE_FAILURE 16
/* */
#define EEH_STATE_FAILURE 16
/* */
/* This is for profiling only and should be removed */
/* This is for profiling only */
extern
unsigned
long
eeh_total_mmio_reads
;
extern
unsigned
long
eeh_total_mmio_ffs
;
extern
unsigned
long
eeh_total_mmio_ffs
;
extern
int
eeh_implemented
;
void
eeh_init
(
void
);
void
eeh_init
(
void
);
static
inline
int
is_eeh_implemented
(
void
)
{
return
eeh_implemented
;
}
int
eeh_get_state
(
unsigned
long
ea
);
int
eeh_get_state
(
unsigned
long
ea
);
unsigned
long
eeh_check_failure
(
void
*
token
,
unsigned
long
val
);
unsigned
long
eeh_check_failure
(
void
*
token
,
unsigned
long
val
);
...
@@ -83,7 +85,7 @@ extern void *memset(void *,int, unsigned long);
...
@@ -83,7 +85,7 @@ extern void *memset(void *,int, unsigned long);
*/
*/
/* #define EEH_POSSIBLE_ERROR(addr, vaddr, val) ((vaddr) != (addr) && ~(val) == 0 && !IS_EEH_TOKEN_DISABLED(addr)) */
/* #define EEH_POSSIBLE_ERROR(addr, vaddr, val) ((vaddr) != (addr) && ~(val) == 0 && !IS_EEH_TOKEN_DISABLED(addr)) */
/* This version is rearranged to collect some profiling data */
/* This version is rearranged to collect some profiling data */
#define EEH_POSSIBLE_ERROR(addr, vaddr, val) (
++eeh_total_mmio_reads, (~(val) == 0 && (++eeh_total_mmio_ffs, (vaddr) != (addr) && !IS_EEH_TOKEN_DISABLED(addr)
)))
#define EEH_POSSIBLE_ERROR(addr, vaddr, val) (
~(val) == 0 && (++eeh_total_mmio_ffs, (vaddr) != (addr) && !IS_EEH_TOKEN_DISABLED(addr
)))
/*
/*
* MMIO read/write operations with EEH support.
* MMIO read/write operations with EEH support.
...
...
include/asm-ppc64/io.h
View file @
57bd45fd
...
@@ -51,7 +51,6 @@ extern int have_print;
...
@@ -51,7 +51,6 @@ extern int have_print;
#define outl(data,addr) writel(data,((unsigned long)(addr)))
#define outl(data,addr) writel(data,((unsigned long)(addr)))
#else
#else
#define IS_MAPPED_VADDR(port) ((unsigned long)(port) >> 60UL)
#define IS_MAPPED_VADDR(port) ((unsigned long)(port) >> 60UL)
#ifdef CONFIG_PPC_EEH
#define readb(addr) eeh_readb((void*)(addr))
#define readb(addr) eeh_readb((void*)(addr))
#define readw(addr) eeh_readw((void*)(addr))
#define readw(addr) eeh_readw((void*)(addr))
#define readl(addr) eeh_readl((void*)(addr))
#define readl(addr) eeh_readl((void*)(addr))
...
@@ -61,17 +60,6 @@ extern int have_print;
...
@@ -61,17 +60,6 @@ extern int have_print;
#define memset_io(a,b,c) eeh_memset((void *)(a),(b),(c))
#define memset_io(a,b,c) eeh_memset((void *)(a),(b),(c))
#define memcpy_fromio(a,b,c) eeh_memcpy_fromio((a),(void *)(b),(c))
#define memcpy_fromio(a,b,c) eeh_memcpy_fromio((a),(void *)(b),(c))
#define memcpy_toio(a,b,c) eeh_memcpy_toio((void *)(a),(b),(c))
#define memcpy_toio(a,b,c) eeh_memcpy_toio((void *)(a),(b),(c))
#else
#define readb(addr) in_8((volatile u8 *)(addr))
#define writeb(b,addr) out_8((volatile u8 *)(addr), (b))
#define readw(addr) in_le16((volatile u16 *)(addr))
#define readl(addr) in_le32((volatile u32 *)(addr))
#define writew(b,addr) out_le16((volatile u16 *)(addr),(b))
#define writel(b,addr) out_le32((volatile u32 *)(addr),(b))
#define memset_io(a,b,c) memset((void *)(a),(b),(c))
#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
#endif
#define inb(port) _inb((unsigned long)port)
#define inb(port) _inb((unsigned long)port)
#define outb(val, port) _outb(val, (unsigned long)port)
#define outb(val, port) _outb(val, (unsigned long)port)
#define inw(port) _inw((unsigned long)port)
#define inw(port) _inw((unsigned long)port)
...
@@ -259,11 +247,9 @@ extern inline void out_be32(volatile unsigned *addr, int val)
...
@@ -259,11 +247,9 @@ extern inline void out_be32(volatile unsigned *addr, int val)
__asm__
__volatile__
(
"stw%U0%X0 %1,%0"
:
"=m"
(
*
addr
)
:
"r"
(
val
));
__asm__
__volatile__
(
"stw%U0%X0 %1,%0"
:
"=m"
(
*
addr
)
:
"r"
(
val
));
}
}
#if
def CONFIG_PPC_EEH
#if
ndef CONFIG_PPC_ISERIES
#include <asm/eeh.h>
#include <asm/eeh.h>
#endif
#ifndef CONFIG_PPC_ISERIES
static
inline
u8
_inb
(
unsigned
long
port
)
{
static
inline
u8
_inb
(
unsigned
long
port
)
{
if
(
IS_MAPPED_VADDR
(
port
))
if
(
IS_MAPPED_VADDR
(
port
))
return
readb
((
void
*
)
port
);
return
readb
((
void
*
)
port
);
...
...
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