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
e54c378a
Commit
e54c378a
authored
Dec 08, 2002
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ppc64: EEH cleanup from Todd Inglett
parent
84f2d288
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
322 additions
and
312 deletions
+322
-312
arch/ppc64/kernel/chrp_setup.c
arch/ppc64/kernel/chrp_setup.c
+4
-3
arch/ppc64/kernel/eeh.c
arch/ppc64/kernel/eeh.c
+153
-100
arch/ppc64/kernel/htab.c
arch/ppc64/kernel/htab.c
+1
-1
arch/ppc64/kernel/pSeries_pci.c
arch/ppc64/kernel/pSeries_pci.c
+16
-67
arch/ppc64/kernel/pci.c
arch/ppc64/kernel/pci.c
+46
-16
arch/ppc64/kernel/pci.h
arch/ppc64/kernel/pci.h
+1
-0
arch/ppc64/mm/init.c
arch/ppc64/mm/init.c
+4
-6
include/asm-ppc64/eeh.h
include/asm-ppc64/eeh.h
+61
-45
include/asm-ppc64/io.h
include/asm-ppc64/io.h
+27
-73
include/asm-ppc64/page.h
include/asm-ppc64/page.h
+2
-0
include/asm-ppc64/prom.h
include/asm-ppc64/prom.h
+7
-1
No files found.
arch/ppc64/kernel/chrp_setup.c
View file @
e54c378a
...
@@ -141,11 +141,12 @@ chrp_setup_arch(void)
...
@@ -141,11 +141,12 @@ chrp_setup_arch(void)
fwnmi_init
();
fwnmi_init
();
#ifndef CONFIG_PPC_ISERIES
/* 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
eeh_init
();
find_and_init_phbs
();
find_and_init_phbs
();
#endif
#endif
/* Find the Open PIC if present */
/* Find the Open PIC if present */
root
=
find_path_device
(
"/"
);
root
=
find_path_device
(
"/"
);
...
...
arch/ppc64/kernel/eeh.c
View file @
e54c378a
This diff is collapsed.
Click to expand it.
arch/ppc64/kernel/htab.c
View file @
e54c378a
...
@@ -393,7 +393,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
...
@@ -393,7 +393,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
mm
=
&
init_mm
;
mm
=
&
init_mm
;
vsid
=
get_kernel_vsid
(
ea
);
vsid
=
get_kernel_vsid
(
ea
);
break
;
break
;
case
IO_UNMAPPED
_REGION_ID
:
case
EEH
_REGION_ID
:
/*
/*
* Should only be hit if there is an access to MMIO space
* Should only be hit if there is an access to MMIO space
* which is protected by EEH.
* which is protected by EEH.
...
...
arch/ppc64/kernel/pSeries_pci.c
View file @
e54c378a
...
@@ -39,7 +39,6 @@
...
@@ -39,7 +39,6 @@
#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>
#include <asm/eeh.h>
#include "xics.h"
#include "xics.h"
#include "open_pic.h"
#include "open_pic.h"
...
@@ -250,8 +249,6 @@ find_and_init_phbs(void)
...
@@ -250,8 +249,6 @@ find_and_init_phbs(void)
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"
);
eeh_init
();
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
(
"/"
),
"platform-open-pic"
,
NULL
);
"platform-open-pic"
,
NULL
);
...
@@ -350,24 +347,16 @@ find_and_init_phbs(void)
...
@@ -350,24 +347,16 @@ 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
;
if
(
is_eeh_implemented
())
{
phb
->
io_base_virt
=
__ioremap
(
phb
->
io_base_phys
,
range
.
size
,
_PAGE_NO_CACHE
);
if
(
!
isa_io_base
&&
has_isa
)
{
printk
(
"back
\n
"
);
/* map a page for ISA ports. Not EEH protected. */
if
(
!
pci_io_base
)
{
isa_io_base
=
(
unsigned
long
)
__ioremap
(
phb
->
io_base_phys
,
PAGE_SIZE
,
_PAGE_NO_CACHE
);
pci_io_base
=
(
unsigned
long
)
phb
->
io_base_virt
;
}
if
(
has_isa
)
res
->
start
=
phb
->
io_base_virt
=
eeh_token
(
index
,
0
,
0
,
0
);
isa_io_base
=
pci_io_base
;
res
->
end
=
eeh_token
(
index
,
0xff
,
0xff
,
0xffffffff
);
}
else
{
phb
->
io_base_virt
=
ioremap
(
phb
->
io_base_phys
,
range
.
size
);
if
(
!
pci_io_base
)
{
pci_io_base
=
(
unsigned
long
)
phb
->
io_base_virt
;
if
(
has_isa
)
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
-
pci_io_base
;
res
->
end
=
res
->
start
+
range
.
size
-
1
;
res
->
parent
=
NULL
;
res
->
parent
=
NULL
;
res
->
sibling
=
NULL
;
res
->
sibling
=
NULL
;
res
->
child
=
NULL
;
res
->
child
=
NULL
;
...
@@ -391,13 +380,8 @@ find_and_init_phbs(void)
...
@@ -391,13 +380,8 @@ 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
;
if
(
is_eeh_implemented
())
{
res
->
start
=
range
.
parent_addr
;
res
->
start
=
eeh_token
(
index
,
0
,
0
,
0
);
res
->
end
=
range
.
parent_addr
+
range
.
size
-
1
;
res
->
end
=
eeh_token
(
index
,
0xff
,
0xff
,
0xffffffff
);
}
else
{
res
->
start
=
range
.
parent_addr
;
res
->
end
=
range
.
parent_addr
+
range
.
size
-
1
;
}
res
->
parent
=
NULL
;
res
->
parent
=
NULL
;
res
->
sibling
=
NULL
;
res
->
sibling
=
NULL
;
res
->
child
=
NULL
;
res
->
child
=
NULL
;
...
@@ -574,7 +558,6 @@ fixup_resources(struct pci_dev *dev)
...
@@ -574,7 +558,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
);
struct
device_node
*
dn
;
struct
device_node
*
dn
;
unsigned
long
eeh_disable_bit
;
/* Add IBM loc code (slot) as a prefix to the device names for service */
/* Add IBM loc code (slot) as a prefix to the device names for service */
dn
=
pci_device_to_OF_node
(
dev
);
dn
=
pci_device_to_OF_node
(
dev
);
...
@@ -591,20 +574,6 @@ fixup_resources(struct pci_dev *dev)
...
@@ -591,20 +574,6 @@ fixup_resources(struct pci_dev *dev)
}
}
}
}
if
(
is_eeh_implemented
())
{
if
(
is_eeh_configured
(
dev
))
{
eeh_disable_bit
=
0
;
if
(
eeh_set_option
(
dev
,
EEH_ENABLE
)
!=
0
)
{
printk
(
"PCI: failed to enable EEH for %s %s
\n
"
,
dev
->
slot_name
,
dev
->
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
->
dev
.
name
);
eeh_disable_bit
=
EEH_TOKEN_DISABLED
;
}
}
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
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
phb->pci_io_offset = 0x%016LX
\n
"
,
phb
->
pci_io_offset
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
phb->pci_io_offset = 0x%016LX
\n
"
,
phb
->
pci_io_offset
);
...
@@ -633,19 +602,9 @@ fixup_resources(struct pci_dev *dev)
...
@@ -633,19 +602,9 @@ fixup_resources(struct pci_dev *dev)
}
}
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_IO
)
{
if
(
dev
->
resource
[
i
].
flags
&
IORESOURCE_IO
)
{
if
(
is_eeh_implemented
())
{
unsigned
long
offset
=
(
unsigned
long
)
phb
->
io_base_virt
-
pci_io_base
;
unsigned
int
busno
=
dev
->
bus
?
dev
->
bus
->
number
:
0
;
dev
->
resource
[
i
].
start
+=
offset
;
unsigned
long
size
=
dev
->
resource
[
i
].
end
-
dev
->
resource
[
i
].
start
;
dev
->
resource
[
i
].
end
+=
offset
;
unsigned
long
addr
=
(
unsigned
long
)
__ioremap
(
dev
->
resource
[
i
].
start
+
phb
->
io_base_phys
,
size
,
_PAGE_NO_CACHE
);
if
(
!
addr
)
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
].
end
=
dev
->
resource
[
i
].
start
+
size
;
}
else
{
unsigned
long
offset
=
(
unsigned
long
)
phb
->
io_base_virt
;
dev
->
resource
[
i
].
start
+=
offset
;
dev
->
resource
[
i
].
end
+=
offset
;
}
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
)
{
...
@@ -653,18 +612,8 @@ fixup_resources(struct pci_dev *dev)
...
@@ -653,18 +612,8 @@ 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
{
if
(
is_eeh_implemented
())
{
dev
->
resource
[
i
].
start
+=
phb
->
pci_mem_offset
;
unsigned
int
busno
=
dev
->
bus
?
dev
->
bus
->
number
:
0
;
dev
->
resource
[
i
].
end
+=
phb
->
pci_mem_offset
;
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
);
if
(
!
addr
)
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
].
end
=
dev
->
resource
[
i
].
start
+
size
;
}
else
{
dev
->
resource
[
i
].
start
+=
phb
->
pci_mem_offset
;
dev
->
resource
[
i
].
end
+=
phb
->
pci_mem_offset
;
}
}
}
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 @
e54c378a
...
@@ -31,7 +31,6 @@
...
@@ -31,7 +31,6 @@
#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>
#include <asm/eeh.h>
#include "pci.h"
#include "pci.h"
...
@@ -121,6 +120,43 @@ static void fixup_windbond_82c105(struct pci_dev* dev)
...
@@ -121,6 +120,43 @@ static void fixup_windbond_82c105(struct pci_dev* dev)
}
}
/* Given an mmio phys address, find a pci device that implements
* this address. This is of course expensive, but only used
* for device initialization or error paths.
* For io BARs it is assumed the pci_io_base has already been added
* into addr.
*
* Bridges are ignored although they could be used to optimize the search.
*/
struct
pci_dev
*
pci_find_dev_by_addr
(
unsigned
long
addr
)
{
struct
pci_dev
*
dev
;
int
i
;
unsigned
long
ioaddr
;
ioaddr
=
(
addr
>
_IO_BASE
)
?
addr
-
_IO_BASE
:
0
;
pci_for_each_dev
(
dev
)
{
if
((
dev
->
class
>>
8
)
==
PCI_BASE_CLASS_BRIDGE
)
continue
;
for
(
i
=
0
;
i
<
DEVICE_COUNT_RESOURCE
;
i
++
)
{
unsigned
long
start
=
pci_resource_start
(
dev
,
i
);
unsigned
long
end
=
pci_resource_end
(
dev
,
i
);
unsigned
int
flags
=
pci_resource_flags
(
dev
,
i
);
if
(
start
==
0
||
~
start
==
0
||
end
==
0
||
~
end
==
0
)
continue
;
if
((
flags
&
IORESOURCE_IO
)
&&
(
ioaddr
>=
start
&&
ioaddr
<=
end
))
return
dev
;
else
if
((
flags
&
IORESOURCE_MEM
)
&&
(
addr
>=
start
&&
addr
<=
end
))
return
dev
;
}
}
return
NULL
;
}
void
__devinit
pcibios_fixup_pbus_ranges
(
struct
pci_bus
*
pbus
,
void
__devinit
pcibios_fixup_pbus_ranges
(
struct
pci_bus
*
pbus
,
struct
pbus_set_ranges_data
*
pranges
)
struct
pbus_set_ranges_data
*
pranges
)
{
{
...
@@ -486,21 +522,15 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
...
@@ -486,21 +522,15 @@ 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
;
}
}
if
(
is_eeh_implemented
())
{
if
(
res
->
flags
&
IORESOURCE_IO
)
{
if
(
res
->
flags
&
(
IORESOURCE_IO
|
IORESOURCE_MEM
))
{
unsigned
long
offset
=
(
unsigned
long
)
phb
->
io_base_virt
-
pci_io_base
;
res
->
start
=
eeh_token
(
phb
->
global_number
,
bus
->
number
,
0
,
0
);
res
->
start
+=
offset
;
res
->
end
=
eeh_token
(
phb
->
global_number
,
bus
->
number
,
0xff
,
0xffffffff
);
res
->
end
+=
offset
;
}
}
else
if
(
phb
->
pci_mem_offset
}
else
{
&&
(
res
->
flags
&
IORESOURCE_MEM
))
{
if
(
res
->
flags
&
IORESOURCE_IO
)
{
if
(
res
->
start
<
phb
->
pci_mem_offset
)
{
res
->
start
+=
(
unsigned
long
)
phb
->
io_base_virt
;
res
->
start
+=
phb
->
pci_mem_offset
;
res
->
end
+=
(
unsigned
long
)
phb
->
io_base_virt
;
res
->
end
+=
phb
->
pci_mem_offset
;
}
else
if
(
phb
->
pci_mem_offset
&&
(
res
->
flags
&
IORESOURCE_MEM
))
{
if
(
res
->
start
<
phb
->
pci_mem_offset
)
{
res
->
start
+=
phb
->
pci_mem_offset
;
res
->
end
+=
phb
->
pci_mem_offset
;
}
}
}
}
}
}
}
...
...
arch/ppc64/kernel/pci.h
View file @
e54c378a
...
@@ -56,6 +56,7 @@ typedef void *(*traverse_func)(struct device_node *me, void *data);
...
@@ -56,6 +56,7 @@ typedef void *(*traverse_func)(struct device_node *me, void *data);
void
*
traverse_pci_devices
(
struct
device_node
*
start
,
traverse_func
pre
,
traverse_func
post
,
void
*
data
);
void
*
traverse_pci_devices
(
struct
device_node
*
start
,
traverse_func
pre
,
traverse_func
post
,
void
*
data
);
void
*
traverse_all_pci_devices
(
traverse_func
pre
);
void
*
traverse_all_pci_devices
(
traverse_func
pre
);
struct
pci_dev
*
pci_find_dev_by_addr
(
unsigned
long
addr
);
void
pci_devs_phb_init
(
void
);
void
pci_devs_phb_init
(
void
);
void
pci_fix_bus_sysdata
(
void
);
void
pci_fix_bus_sysdata
(
void
);
struct
device_node
*
fetch_dev_dn
(
struct
pci_dev
*
dev
);
struct
device_node
*
fetch_dev_dn
(
struct
pci_dev
*
dev
);
...
...
arch/ppc64/mm/init.c
View file @
e54c378a
...
@@ -132,12 +132,10 @@ ioremap(unsigned long addr, unsigned long size)
...
@@ -132,12 +132,10 @@ ioremap(unsigned long addr, unsigned long size)
#ifdef CONFIG_PPC_ISERIES
#ifdef CONFIG_PPC_ISERIES
return
(
void
*
)
addr
;
return
(
void
*
)
addr
;
#else
#else
if
(
mem_init_done
&&
(
addr
>>
60UL
))
{
void
*
ret
=
__ioremap
(
addr
,
size
,
_PAGE_NO_CACHE
);
if
(
IS_EEH_TOKEN_DISABLED
(
addr
))
if
(
mem_init_done
)
return
(
void
*
)
IO_TOKEN_TO_ADDR
(
addr
);
return
eeh_ioremap
(
addr
,
ret
);
/* may remap the addr */
return
(
void
*
)
addr
;
/* already mapped address or EEH token. */
return
ret
;
}
return
__ioremap
(
addr
,
size
,
_PAGE_NO_CACHE
);
#endif
#endif
}
}
...
...
include/asm-ppc64/eeh.h
View file @
e54c378a
...
@@ -27,25 +27,26 @@
...
@@ -27,25 +27,26 @@
struct
pci_dev
;
struct
pci_dev
;
#define IO_UNMAPPED_REGION_ID 0xaUL
/* I/O addresses are converted to EEH "tokens" such that a driver will cause
* a bad page fault if the address is used directly (i.e. these addresses are
#define IO_TOKEN_TO_ADDR(token) ((((unsigned long)(token)) & 0xFFFFFFFF) | (0xEUL << 60))
* never actually mapped. Translation between IO <-> EEH region is 1 to 1.
/* Flag bits encoded in the 3 unused function bits of devfn */
*/
#define EEH_TOKEN_DISABLED (1UL << 34UL)
/* eeh is disabled for this token */
#define IO_TOKEN_TO_ADDR(token) (((unsigned long)(token) & ~(0xfUL << REGION_SHIFT)) | \
#define IS_EEH_TOKEN_DISABLED(token) ((unsigned long)(token) & EEH_TOKEN_DISABLED)
(IO_REGION_ID << REGION_SHIFT))
#define IO_ADDR_TO_TOKEN(addr) (((unsigned long)(addr) & ~(0xfUL << REGION_SHIFT)) | \
(EEH_REGION_ID << REGION_SHIFT))
#define EEH_STATE_OVERRIDE 1
/* IOA does not require eeh traps */
/* Values for eeh_mode bits in device_node */
#define EEH_STATE_FAILURE 16
/* */
#define EEH_MODE_SUPPORTED (1<<0)
#define EEH_MODE_NOCHECK (1<<1)
/* This is for profiling only */
/* This is for profiling only */
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
);
void
*
eeh_ioremap
(
unsigned
long
addr
,
void
*
vaddr
);
#define EEH_DISABLE 0
#define EEH_DISABLE 0
#define EEH_ENABLE 1
#define EEH_ENABLE 1
...
@@ -58,15 +59,11 @@ int eeh_set_option(struct pci_dev *dev, int options);
...
@@ -58,15 +59,11 @@ int eeh_set_option(struct pci_dev *dev, int options);
*/
*/
int
is_eeh_configured
(
struct
pci_dev
*
dev
);
int
is_eeh_configured
(
struct
pci_dev
*
dev
);
/* Generate an EEH token.
/* Translate a (possible) eeh token to a physical addr.
* The high nibble of the offset is cleared, otherwise bounds checking is performed.
* If "token" is not an eeh token it is simply returned under
* Use IO_TOKEN_TO_ADDR(token) to translate this token back to a mapped virtual addr.
* the assumption that it is already a physical addr.
* Do NOT do this to perform IO -- use the read/write macros!
*/
*/
unsigned
long
eeh_token
(
unsigned
long
phb
,
unsigned
long
eeh_token_to_phys
(
unsigned
long
token
);
unsigned
long
bus
,
unsigned
long
devfn
,
unsigned
long
offset
);
extern
void
*
memcpy
(
void
*
,
const
void
*
,
unsigned
long
);
extern
void
*
memcpy
(
void
*
,
const
void
*
,
unsigned
long
);
extern
void
*
memset
(
void
*
,
int
,
unsigned
long
);
extern
void
*
memset
(
void
*
,
int
,
unsigned
long
);
...
@@ -77,15 +74,16 @@ extern void *memset(void *,int, unsigned long);
...
@@ -77,15 +74,16 @@ extern void *memset(void *,int, unsigned long);
* If EEH is off for a device and it is a memory BAR, ioremap will
* If EEH is off for a device and it is a memory BAR, ioremap will
* map it to the IOREGION. In this case addr == vaddr and since these
* map it to the IOREGION. In this case addr == vaddr and since these
* should be in registers we compare them first. Next we check for
* should be in registers we compare them first. Next we check for
* all ones which is perhaps fastest as ~val. Finally we weed out
* ff's which indicates a (very) possible failure.
* EEH disabled IO BARs.
*
*
* If this macro yields TRUE, the caller relays to eeh_check_failure()
* If this macro yields TRUE, the caller relays to eeh_check_failure()
* which does further tests out of line.
* which does further tests out of line.
*/
*/
/* #define EEH_POSSIBLE_ERROR(addr, vaddr, val) ((vaddr) != (addr) && ~(val) == 0 && !IS_EEH_TOKEN_DISABLED(addr)) */
/* #define EEH_POSSIBLE_IO_ERROR(val) (~(val) == 0) */
/* #define EEH_POSSIBLE_ERROR(addr, vaddr, val) ((vaddr) != (addr) && EEH_POSSIBLE_IO_ERROR(val) */
/* 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) (~(val) == 0 && (++eeh_total_mmio_ffs, (vaddr) != (addr) && !IS_EEH_TOKEN_DISABLED(addr)))
#define EEH_POSSIBLE_IO_ERROR(val) (~(val) == 0 && ++eeh_total_mmio_ffs)
#define EEH_POSSIBLE_ERROR(addr, vaddr, val) (EEH_POSSIBLE_IO_ERROR(val) && (vaddr) != (addr))
/*
/*
* MMIO read/write operations with EEH support.
* MMIO read/write operations with EEH support.
...
@@ -149,38 +147,56 @@ static inline void eeh_memcpy_toio(void *dest, void *src, unsigned long n) {
...
@@ -149,38 +147,56 @@ static inline void eeh_memcpy_toio(void *dest, void *src, unsigned long n) {
memcpy
(
vdest
,
src
,
n
);
memcpy
(
vdest
,
src
,
n
);
}
}
static
inline
void
eeh_insb
(
volatile
u8
*
addr
,
void
*
buf
,
int
n
)
{
/* The I/O macros must handle ISA ports as well as PCI I/O bars.
volatile
u8
*
vaddr
=
(
volatile
u8
*
)
IO_TOKEN_TO_ADDR
(
addr
);
* ISA does not implement EEH and ISA may not exist in the system.
_insb
(
vaddr
,
buf
,
n
);
* For PCI we check for EEH failures.
/* ToDo: look for ff's in buf[n] */
*/
#define _IO_IS_ISA(port) ((port) < 0x10000)
#define _IO_HAS_ISA_BUS (isa_io_base != 0)
static
inline
u8
eeh_inb
(
unsigned
long
port
)
{
u8
val
;
if
(
_IO_IS_ISA
(
port
)
&&
!
_IO_HAS_ISA_BUS
)
return
~
0
;
val
=
in_8
((
u8
*
)(
port
+
pci_io_base
));
if
(
!
_IO_IS_ISA
(
port
)
&&
EEH_POSSIBLE_IO_ERROR
(
val
))
return
eeh_check_failure
((
void
*
)(
port
+
pci_io_base
),
val
);
return
val
;
}
}
static
inline
void
eeh_out
sb
(
volatile
u8
*
addr
,
const
void
*
buf
,
int
n
)
{
static
inline
void
eeh_out
b
(
u8
val
,
unsigned
long
port
)
{
volatile
u8
*
vaddr
=
(
volatile
u8
*
)
IO_TOKEN_TO_ADDR
(
addr
);
if
(
!
_IO_IS_ISA
(
port
)
||
_IO_HAS_ISA_BUS
)
_outsb
(
vaddr
,
buf
,
n
);
return
out_8
((
u8
*
)(
port
+
pci_io_base
),
val
);
}
}
static
inline
void
eeh_insw_ns
(
volatile
u16
*
addr
,
void
*
buf
,
int
n
)
{
static
inline
u16
eeh_inw
(
unsigned
long
port
)
{
volatile
u16
*
vaddr
=
(
volatile
u16
*
)
IO_TOKEN_TO_ADDR
(
addr
);
u16
val
;
_insw_ns
(
vaddr
,
buf
,
n
);
if
(
_IO_IS_ISA
(
port
)
&&
!
_IO_HAS_ISA_BUS
)
/* ToDo: look for ffff's in buf[n] */
return
~
0
;
val
=
in_le16
((
u16
*
)(
port
+
pci_io_base
));
if
(
!
_IO_IS_ISA
(
port
)
&&
EEH_POSSIBLE_IO_ERROR
(
val
))
return
eeh_check_failure
((
void
*
)(
port
+
pci_io_base
),
val
);
return
val
;
}
}
static
inline
void
eeh_out
sw_ns
(
volatile
u16
*
addr
,
const
void
*
buf
,
int
n
)
{
static
inline
void
eeh_out
w
(
u16
val
,
unsigned
long
port
)
{
volatile
u16
*
vaddr
=
(
volatile
u16
*
)
IO_TOKEN_TO_ADDR
(
addr
);
if
(
!
_IO_IS_ISA
(
port
)
||
_IO_HAS_ISA_BUS
)
_outsw_ns
(
vaddr
,
buf
,
n
);
return
out_le16
((
u16
*
)(
port
+
pci_io_base
),
val
);
}
}
static
inline
void
eeh_insl_ns
(
volatile
u32
*
addr
,
void
*
buf
,
int
n
)
{
static
inline
u32
eeh_inl
(
unsigned
long
port
)
{
volatile
u32
*
vaddr
=
(
volatile
u32
*
)
IO_TOKEN_TO_ADDR
(
addr
);
u32
val
;
_insl_ns
(
vaddr
,
buf
,
n
);
if
(
_IO_IS_ISA
(
port
)
&&
!
_IO_HAS_ISA_BUS
)
/* ToDo: look for ffffffff's in buf[n] */
return
~
0
;
val
=
in_le32
((
u32
*
)(
port
+
pci_io_base
));
if
(
!
_IO_IS_ISA
(
port
)
&&
EEH_POSSIBLE_IO_ERROR
(
val
))
return
eeh_check_failure
((
void
*
)(
port
+
pci_io_base
),
val
);
return
val
;
}
}
static
inline
void
eeh_out
sl_ns
(
volatile
u32
*
addr
,
const
void
*
buf
,
int
n
)
{
static
inline
void
eeh_out
l
(
u32
val
,
unsigned
long
port
)
{
volatile
u32
*
vaddr
=
(
volatile
u32
*
)
IO_TOKEN_TO_ADDR
(
addr
);
if
(
!
_IO_IS_ISA
(
port
)
||
_IO_HAS_ISA_BUS
)
_outsl_ns
(
vaddr
,
buf
,
n
);
return
out_le32
((
u32
*
)(
port
+
pci_io_base
),
val
);
}
}
#endif
/* _EEH_H */
#endif
/* _EEH_H */
include/asm-ppc64/io.h
View file @
e54c378a
...
@@ -50,36 +50,45 @@ extern int have_print;
...
@@ -50,36 +50,45 @@ extern int have_print;
#define outw(data,addr) writew(data,((unsigned long)(addr)))
#define outw(data,addr) writew(data,((unsigned long)(addr)))
#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 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))
#define writeb(data, addr) eeh_writeb((data), ((void*)(addr)))
#define writeb(data, addr) eeh_writeb((data), ((void*)(addr)))
#define writew(data, addr) eeh_writew((data), ((void*)(addr)))
#define writew(data, addr) eeh_writew((data), ((void*)(addr)))
#define writel(data, addr) eeh_writel((data), ((void*)(addr)))
#define writel(data, addr) eeh_writel((data), ((void*)(addr)))
#define memset_io(a,b,c) eeh_memset((void *)(a),(b),(c))
#define memset_io(a,b,c) eeh_memset
_io
((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))
#define inb(port) _inb((unsigned long)port)
#define inb(port)
eeh
_inb((unsigned long)port)
#define outb(val, port) _outb(val, (unsigned long)port)
#define outb(val, port)
eeh
_outb(val, (unsigned long)port)
#define inw(port) _inw((unsigned long)port)
#define inw(port)
eeh
_inw((unsigned long)port)
#define outw(val, port) _outw(val, (unsigned long)port)
#define outw(val, port)
eeh
_outw(val, (unsigned long)port)
#define inl(port) _inl((unsigned long)port)
#define inl(port)
eeh
_inl((unsigned long)port)
#define outl(val, port) _outl(val, (unsigned long)port)
#define outl(val, port)
eeh
_outl(val, (unsigned long)port)
/*
/*
* The insw/outsw/insl/outsl macros don't do byte-swapping.
* The insw/outsw/insl/outsl macros don't do byte-swapping.
* They are only used in practice for transferring buffers which
* They are only used in practice for transferring buffers which
* are arrays of bytes, and byte-swapping is not appropriate in
* are arrays of bytes, and byte-swapping is not appropriate in
* that case. - paulus */
* that case. - paulus */
#define insb(port, buf, ns)
eeh_insb((u8 *)(port
), (buf), (ns))
#define insb(port, buf, ns)
_insb((u8 *)((port)+pci_io_base
), (buf), (ns))
#define outsb(port, buf, ns)
eeh_outsb((u8 *)(port
), (buf), (ns))
#define outsb(port, buf, ns)
_outsb((u8 *)((port)+pci_io_base
), (buf), (ns))
#define insw(port, buf, ns)
eeh_insw_ns((u16 *)(port
), (buf), (ns))
#define insw(port, buf, ns)
_insw_ns((u16 *)((port)+pci_io_base
), (buf), (ns))
#define outsw(port, buf, ns)
eeh_outsw_ns((u16 *)(port
), (buf), (ns))
#define outsw(port, buf, ns)
_outsw_ns((u16 *)((port)+pci_io_base
), (buf), (ns))
#define insl(port, buf, nl)
eeh_insl_ns((u32 *)(port
), (buf), (nl))
#define insl(port, buf, nl)
_insl_ns((u32 *)((port)+pci_io_base
), (buf), (nl))
#define outsl(port, buf, nl)
eeh_outsl_ns((u32 *)(port
), (buf), (nl))
#define outsl(port, buf, nl)
_outsl_ns((u32 *)((port)+pci_io_base
), (buf), (nl))
#endif
#endif
extern
void
_insb
(
volatile
u8
*
port
,
void
*
buf
,
int
ns
);
extern
void
_outsb
(
volatile
u8
*
port
,
const
void
*
buf
,
int
ns
);
extern
void
_insw
(
volatile
u16
*
port
,
void
*
buf
,
int
ns
);
extern
void
_outsw
(
volatile
u16
*
port
,
const
void
*
buf
,
int
ns
);
extern
void
_insl
(
volatile
u32
*
port
,
void
*
buf
,
int
nl
);
extern
void
_outsl
(
volatile
u32
*
port
,
const
void
*
buf
,
int
nl
);
extern
void
_insw_ns
(
volatile
u16
*
port
,
void
*
buf
,
int
ns
);
extern
void
_outsw_ns
(
volatile
u16
*
port
,
const
void
*
buf
,
int
ns
);
extern
void
_insl_ns
(
volatile
u32
*
port
,
void
*
buf
,
int
nl
);
extern
void
_outsl_ns
(
volatile
u32
*
port
,
const
void
*
buf
,
int
nl
);
/*
/*
* output pause versions need a delay at least for the
* output pause versions need a delay at least for the
...
@@ -92,27 +101,15 @@ extern int have_print;
...
@@ -92,27 +101,15 @@ extern int have_print;
#define inl_p(port) inl(port)
#define inl_p(port) inl(port)
#define outl_p(val, port) (udelay(1), outl((val, (port)))
#define outl_p(val, port) (udelay(1), outl((val, (port)))
extern
void
_insb
(
volatile
u8
*
port
,
void
*
buf
,
int
ns
);
extern
void
_outsb
(
volatile
u8
*
port
,
const
void
*
buf
,
int
ns
);
extern
void
_insw
(
volatile
u16
*
port
,
void
*
buf
,
int
ns
);
extern
void
_outsw
(
volatile
u16
*
port
,
const
void
*
buf
,
int
ns
);
extern
void
_insl
(
volatile
u32
*
port
,
void
*
buf
,
int
nl
);
extern
void
_outsl
(
volatile
u32
*
port
,
const
void
*
buf
,
int
nl
);
extern
void
_insw_ns
(
volatile
u16
*
port
,
void
*
buf
,
int
ns
);
extern
void
_outsw_ns
(
volatile
u16
*
port
,
const
void
*
buf
,
int
ns
);
extern
void
_insl_ns
(
volatile
u32
*
port
,
void
*
buf
,
int
nl
);
extern
void
_outsl_ns
(
volatile
u32
*
port
,
const
void
*
buf
,
int
nl
);
/*
/*
* The *_ns versions below don't do byte-swapping.
* The *_ns versions below don't do byte-swapping.
* Neither do the standard versions now, these are just here
* Neither do the standard versions now, these are just here
* for older code.
* for older code.
*/
*/
#define insw_ns(port, buf, ns)
insw(port, buf, ns
)
#define insw_ns(port, buf, ns)
_insw_ns((u16 *)((port)+pci_io_base), (buf), (ns)
)
#define outsw_ns(port, buf, ns)
outsw(port, buf, ns
)
#define outsw_ns(port, buf, ns)
_outsw_ns((u16 *)((port)+pci_io_base), (buf), (ns)
)
#define insl_ns(port, buf, nl)
insl(port, buf, nl
)
#define insl_ns(port, buf, nl)
_insl_ns((u32 *)((port)+pci_io_base), (buf), (nl)
)
#define outsl_ns(port, buf, nl)
outsl(port, buf, nl
)
#define outsl_ns(port, buf, nl)
_outsl_ns((u32 *)((port)+pci_io_base), (buf), (nl)
)
#define IO_SPACE_LIMIT ~(0UL)
#define IO_SPACE_LIMIT ~(0UL)
...
@@ -249,49 +246,6 @@ static inline void out_be32(volatile unsigned *addr, int val)
...
@@ -249,49 +246,6 @@ static inline void out_be32(volatile unsigned *addr, int val)
#ifndef CONFIG_PPC_ISERIES
#ifndef CONFIG_PPC_ISERIES
#include <asm/eeh.h>
#include <asm/eeh.h>
static
inline
u8
_inb
(
unsigned
long
port
)
{
if
(
IS_MAPPED_VADDR
(
port
))
return
readb
((
void
*
)
port
);
else
if
(
_IO_BASE
)
return
in_8
((
u8
*
)((
port
)
+
_IO_BASE
));
else
return
0xff
;
}
static
inline
void
_outb
(
u8
val
,
unsigned
long
port
)
{
if
(
IS_MAPPED_VADDR
(
port
))
return
writeb
(
val
,
(
void
*
)
port
);
else
if
(
_IO_BASE
)
out_8
((
u8
*
)((
port
)
+
_IO_BASE
),
val
);
}
static
inline
u16
_inw
(
unsigned
long
port
)
{
if
(
IS_MAPPED_VADDR
(
port
))
return
readw
((
void
*
)
port
);
else
if
(
_IO_BASE
)
return
in_le16
((
u16
*
)((
port
)
+
_IO_BASE
));
else
return
0xffff
;
}
static
inline
void
_outw
(
u16
val
,
unsigned
long
port
)
{
if
(
IS_MAPPED_VADDR
(
port
))
return
writew
(
val
,
(
void
*
)
port
);
else
if
(
_IO_BASE
)
out_le16
((
u16
*
)((
port
)
+
_IO_BASE
),
val
);
}
static
inline
u32
_inl
(
unsigned
long
port
)
{
if
(
IS_MAPPED_VADDR
(
port
))
return
readl
((
void
*
)
port
);
else
if
(
_IO_BASE
)
return
in_le32
((
u32
*
)((
port
)
+
_IO_BASE
));
else
return
0xffffffff
;
}
static
inline
void
_outl
(
u32
val
,
unsigned
long
port
)
{
if
(
IS_MAPPED_VADDR
(
port
))
return
writel
(
val
,
(
void
*
)
port
);
else
if
(
_IO_BASE
)
out_le32
((
u32
*
)((
port
)
+
_IO_BASE
),
val
);
}
#endif
#endif
#ifdef __KERNEL__
#ifdef __KERNEL__
...
...
include/asm-ppc64/page.h
View file @
e54c378a
...
@@ -168,8 +168,10 @@ static inline int get_order(unsigned long size)
...
@@ -168,8 +168,10 @@ static inline int get_order(unsigned long size)
#define KERNELBASE PAGE_OFFSET
#define KERNELBASE PAGE_OFFSET
#define VMALLOCBASE 0xD000000000000000
#define VMALLOCBASE 0xD000000000000000
#define IOREGIONBASE 0xE000000000000000
#define IOREGIONBASE 0xE000000000000000
#define EEHREGIONBASE 0xA000000000000000
#define IO_REGION_ID (IOREGIONBASE>>REGION_SHIFT)
#define IO_REGION_ID (IOREGIONBASE>>REGION_SHIFT)
#define EEH_REGION_ID (EEHREGIONBASE>>REGION_SHIFT)
#define VMALLOC_REGION_ID (VMALLOCBASE>>REGION_SHIFT)
#define VMALLOC_REGION_ID (VMALLOCBASE>>REGION_SHIFT)
#define KERNEL_REGION_ID (KERNELBASE>>REGION_SHIFT)
#define KERNEL_REGION_ID (KERNELBASE>>REGION_SHIFT)
#define USER_REGION_ID (0UL)
#define USER_REGION_ID (0UL)
...
...
include/asm-ppc64/prom.h
View file @
e54c378a
...
@@ -125,12 +125,18 @@ struct device_node {
...
@@ -125,12 +125,18 @@ struct device_node {
int
n_intrs
;
int
n_intrs
;
struct
interrupt_info
*
intrs
;
struct
interrupt_info
*
intrs
;
char
*
full_name
;
char
*
full_name
;
/* PCI stuff probably doesn't belong here */
int
busno
;
/* for pci devices */
int
busno
;
/* for pci devices */
int
bussubno
;
/* for pci devices */
int
bussubno
;
/* for pci devices */
int
devfn
;
/* for pci devices */
int
devfn
;
/* for pci devices */
#define DN_STATUS_BIST_FAILED (1<<0)
int
status
;
/* Current device status (non-zero is bad) */
int
eeh_mode
;
/* See eeh.h for possible EEH_MODEs */
int
eeh_config_addr
;
struct
pci_controller
*
phb
;
/* for pci devices */
struct
pci_controller
*
phb
;
/* for pci devices */
struct
TceTable
*
tce_table
;
/* for phb's or bridges */
struct
TceTable
*
tce_table
;
/* for phb's or bridges */
#define DN_STATUS_BIST_FAILED (1<<0)
struct
property
*
properties
;
struct
property
*
properties
;
struct
device_node
*
parent
;
struct
device_node
*
parent
;
struct
device_node
*
child
;
struct
device_node
*
child
;
...
...
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