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
dada8441
Commit
dada8441
authored
Mar 08, 2003
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Plain Diff
Merge samba.org:/scratch/anton/linux-2.5
into samba.org:/scratch/anton/sfr
parents
d0c451f8
bb0fd83e
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
286 additions
and
438 deletions
+286
-438
arch/ppc64/boot/main.c
arch/ppc64/boot/main.c
+1
-2
arch/ppc64/kernel/chrp_setup.c
arch/ppc64/kernel/chrp_setup.c
+2
-0
arch/ppc64/kernel/eeh.c
arch/ppc64/kernel/eeh.c
+1
-0
arch/ppc64/kernel/entry.S
arch/ppc64/kernel/entry.S
+4
-4
arch/ppc64/kernel/head.S
arch/ppc64/kernel/head.S
+3
-3
arch/ppc64/kernel/irq.c
arch/ppc64/kernel/irq.c
+0
-79
arch/ppc64/kernel/pSeries_pci.c
arch/ppc64/kernel/pSeries_pci.c
+249
-292
arch/ppc64/kernel/pci.c
arch/ppc64/kernel/pci.c
+21
-54
arch/ppc64/kernel/pci.h
arch/ppc64/kernel/pci.h
+1
-1
arch/ppc64/kernel/prom.c
arch/ppc64/kernel/prom.c
+2
-2
include/asm-ppc64/pci-bridge.h
include/asm-ppc64/pci-bridge.h
+2
-1
No files found.
arch/ppc64/boot/main.c
View file @
dada8441
...
...
@@ -12,12 +12,11 @@
#include "ppc32-types.h"
#include "zlib.h"
#include <linux/elf.h>
#include <linux/string.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/bootinfo.h>
void
memmove
(
void
*
dst
,
void
*
im
,
int
len
);
extern
void
*
finddevice
(
const
char
*
);
extern
int
getprop
(
void
*
,
const
char
*
,
void
*
,
int
);
extern
void
printk
(
char
*
fmt
,
...);
...
...
arch/ppc64/kernel/chrp_setup.c
View file @
dada8441
...
...
@@ -72,6 +72,7 @@ extern void init_ras_IRQ(void);
extern
void
find_and_init_phbs
(
void
);
extern
void
pSeries_pcibios_fixup
(
void
);
extern
void
pSeries_pcibios_fixup_bus
(
struct
pci_bus
*
bus
);
extern
void
iSeries_pcibios_fixup
(
void
);
extern
void
pSeries_get_rtc_time
(
struct
rtc_time
*
rtc_time
);
...
...
@@ -245,6 +246,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
#ifndef CONFIG_PPC_ISERIES
ppc_md
.
pcibios_fixup
=
pSeries_pcibios_fixup
;
ppc_md
.
pcibios_fixup_bus
=
pSeries_pcibios_fixup_bus
;
#else
ppc_md
.
pcibios_fixup
=
NULL
;
// ppc_md.pcibios_fixup = iSeries_pcibios_fixup;
...
...
arch/ppc64/kernel/eeh.c
View file @
dada8441
...
...
@@ -26,6 +26,7 @@
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/bootmem.h>
#include <linux/mm.h>
#include <asm/paca.h>
#include <asm/processor.h>
#include <asm/naca.h>
...
...
arch/ppc64/kernel/entry.S
View file @
dada8441
...
...
@@ -344,8 +344,8 @@ irq_recheck:
recheck
:
mfmsr
r10
/*
Get
current
interrupt
state
*/
li
r4
,
0
ori
r4
,
r4
,
MSR_EE
|
MSR_RI
andc
r10
,
r10
,
r4
/*
clear
MSR_EE
and
MSR_RI
*/
ori
r4
,
r4
,
MSR_EE
andc
r10
,
r10
,
r4
/*
clear
MSR_EE
*/
mtmsrd
r10
,
1
/*
Update
machine
state
*/
#ifdef CONFIG_PPC_ISERIES
...
...
@@ -396,7 +396,7 @@ restore:
mfmsr
r0
li
r2
,
MSR_RI
andc
r0
,
r0
,
r2
mtmsrd
r0
mtmsrd
r0
,
1
ld
r0
,
_MSR
(
r1
)
mtspr
SRR1
,
r0
...
...
@@ -422,7 +422,7 @@ restore:
/*
Note
:
this
must
change
if
we
start
using
the
TIF_NOTIFY_RESUME
bit
*/
do_work
:
/
*
Enable
interrupts
*/
ori
r10
,
r10
,
MSR_EE
|
MSR_RI
ori
r10
,
r10
,
MSR_EE
mtmsrd
r10
,
1
andi
.
r0
,
r3
,
_TIF_NEED_RESCHED
...
...
arch/ppc64/kernel/head.S
View file @
dada8441
...
...
@@ -562,7 +562,7 @@ fast_exception_return:
mfmsr
r20
li
r21
,
MSR_RI
andc
r20
,
r20
,
r21
mtmsrd
r20
mtmsrd
r20
,
1
mtspr
SRR1
,
r23
mtspr
SRR0
,
r22
...
...
@@ -989,7 +989,7 @@ _GLOBAL(do_stab_bolted)
mfmsr
r22
li
r23
,
MSR_RI
andc
r22
,
r22
,
r23
mtmsrd
r22
mtmsrd
r22
,
1
ld
r22
,
EX_SRR0
(
r21
)
/*
Get
SRR0
from
exc
.
frame
*/
ld
r23
,
EX_SRR1
(
r21
)
/*
Get
SRR1
from
exc
.
frame
*/
...
...
@@ -1094,7 +1094,7 @@ SLB_NUM_ENTRIES = 64
mfmsr
r22
li
r23
,
MSR_RI
andc
r22
,
r22
,
r23
mtmsrd
r22
mtmsrd
r22
,
1
ld
r22
,
EX_SRR0
(
r21
)
/*
Get
SRR0
from
exc
.
frame
*/
ld
r23
,
EX_SRR1
(
r21
)
/*
Get
SRR1
from
exc
.
frame
*/
...
...
arch/ppc64/kernel/irq.c
View file @
dada8441
...
...
@@ -394,81 +394,6 @@ handle_irq_event(int irq, struct pt_regs *regs, struct irqaction *action)
local_irq_disable
();
}
#ifdef CONFIG_SMP
extern
unsigned
long
irq_affinity
[
NR_IRQS
];
typedef
struct
{
unsigned
long
cpu
;
unsigned
long
timestamp
;
}
____cacheline_aligned
irq_balance_t
;
static
irq_balance_t
irq_balance
[
NR_IRQS
]
__cacheline_aligned
=
{
[
0
...
NR_IRQS
-
1
]
=
{
0
,
0
}
};
#define IDLE_ENOUGH(cpu,now) \
(idle_cpu(cpu) && ((now) - irq_stat[(cpu)].idle_timestamp > 1))
#define IRQ_ALLOWED(cpu,allowed_mask) \
((1UL << cpu) & (allowed_mask))
#define IRQ_BALANCE_INTERVAL (HZ/50)
static
unsigned
long
move
(
unsigned
long
curr_cpu
,
unsigned
long
allowed_mask
,
unsigned
long
now
,
int
direction
)
{
int
search_idle
=
1
;
int
cpu
=
curr_cpu
;
goto
inside
;
do
{
if
(
unlikely
(
cpu
==
curr_cpu
))
search_idle
=
0
;
inside:
if
(
direction
==
1
)
{
cpu
++
;
if
(
cpu
>=
NR_CPUS
)
cpu
=
0
;
}
else
{
cpu
--
;
if
(
cpu
==
-
1
)
cpu
=
NR_CPUS
-
1
;
}
}
while
(
!
cpu_online
(
cpu
)
||
!
IRQ_ALLOWED
(
cpu
,
allowed_mask
)
||
(
search_idle
&&
!
IDLE_ENOUGH
(
cpu
,
now
)));
return
cpu
;
}
static
inline
void
balance_irq
(
int
irq
)
{
irq_balance_t
*
entry
=
irq_balance
+
irq
;
unsigned
long
now
=
jiffies
;
if
(
unlikely
(
time_after
(
now
,
entry
->
timestamp
+
IRQ_BALANCE_INTERVAL
)))
{
unsigned
long
allowed_mask
;
unsigned
int
new_cpu
;
unsigned
long
random_number
;
if
(
!
irq_desc
[
irq
].
handler
->
set_affinity
)
return
;
random_number
=
mftb
();
random_number
&=
1
;
allowed_mask
=
cpu_online_map
&
irq_affinity
[
irq
];
entry
->
timestamp
=
now
;
new_cpu
=
move
(
entry
->
cpu
,
allowed_mask
,
now
,
random_number
);
if
(
entry
->
cpu
!=
new_cpu
)
{
entry
->
cpu
=
new_cpu
;
irq_desc
[
irq
].
handler
->
set_affinity
(
irq
,
1UL
<<
new_cpu
);
}
}
}
#else
#define balance_irq(irq) do { } while (0)
#endif
/*
* Eventually, this should take an array of interrupts and an array size
* so it can dispatch multiple interrupts.
...
...
@@ -480,10 +405,6 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
int
cpu
=
smp_processor_id
();
irq_desc_t
*
desc
=
irq_desc
+
irq
;
/* XXX This causes bad performance and lockups on XICS - Anton */
if
(
naca
->
interrupt_controller
==
IC_OPEN_PIC
)
balance_irq
(
irq
);
kstat_cpu
(
cpu
).
irqs
[
irq
]
++
;
spin_lock
(
&
desc
->
lock
);
ack_irq
(
irq
);
...
...
arch/ppc64/kernel/pSeries_pci.c
View file @
dada8441
...
...
@@ -43,12 +43,6 @@
#include "open_pic.h"
#include "pci.h"
/*******************************************************************
* Forward declares of prototypes.
*******************************************************************/
struct
pci_controller
*
alloc_phb
(
struct
device_node
*
dev
,
char
*
model
,
unsigned
int
addr_size_words
)
;
/* RTAS tokens */
static
int
read_pci_config
;
static
int
write_pci_config
;
...
...
@@ -144,242 +138,173 @@ struct pci_ops rtas_pci_ops = {
* openfirmware and sets it in the pci_dev and pci_config line.
*
******************************************************************/
int
pci_read_irq_line
(
struct
pci_dev
*
Pci_Dev
)
int
pci_read_irq_line
(
struct
pci_dev
*
pci_dev
)
{
u8
InterruptPin
;
struct
device_node
*
Node
;
u8
intpin
;
struct
device_node
*
node
;
pci_read_config_byte
(
pci_dev
,
PCI_INTERRUPT_PIN
,
&
intpin
);
pci_read_config_byte
(
Pci_Dev
,
PCI_INTERRUPT_PIN
,
&
InterruptPin
);
if
(
InterruptPin
==
0
)
{
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s No Interrupt used by device.
\n
"
,
Pci_Dev
->
slot_name
);
if
(
intpin
==
0
)
{
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s No Interrupt used by device.
\n
"
,
pci_dev
->
slot_name
);
return
0
;
}
Node
=
pci_device_to_OF_node
(
Pci_Dev
);
if
(
Node
==
NULL
)
{
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s Device Node not found.
\n
"
,
Pci_Dev
->
slot_name
);
node
=
pci_device_to_OF_node
(
pci_dev
);
if
(
node
==
NULL
)
{
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s Device Node not found.
\n
"
,
pci_dev
->
slot_name
);
return
-
1
;
}
if
(
N
ode
->
n_intrs
==
0
)
{
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s No Device OF interrupts defined.
\n
"
,
Pci_D
ev
->
slot_name
);
if
(
n
ode
->
n_intrs
==
0
)
{
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s No Device OF interrupts defined.
\n
"
,
pci_d
ev
->
slot_name
);
return
-
1
;
}
Pci_Dev
->
irq
=
N
ode
->
intrs
[
0
].
line
;
pci_dev
->
irq
=
n
ode
->
intrs
[
0
].
line
;
if
(
s7a_workaround
)
{
if
(
Pci_D
ev
->
irq
>
16
)
Pci_D
ev
->
irq
-=
3
;
if
(
pci_d
ev
->
irq
>
16
)
pci_d
ev
->
irq
-=
3
;
}
pci_write_config_byte
(
Pci_Dev
,
PCI_INTERRUPT_LINE
,
Pci_D
ev
->
irq
);
pci_write_config_byte
(
pci_dev
,
PCI_INTERRUPT_LINE
,
pci_d
ev
->
irq
);
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s pci_dev->irq = 0x%02X
\n
"
,
Pci_Dev
->
slot_name
,
Pci_Dev
->
irq
);
PPCDBG
(
PPCDBG_BUSWALK
,
"
\t
Device: %s pci_dev->irq = 0x%02X
\n
"
,
pci_dev
->
slot_name
,
pci_dev
->
irq
);
return
0
;
}
/******************************************************************
* Find all PHBs in the system and initialize a set of data
* structures to represent them.
******************************************************************/
unsigned
long
__init
find_and_init_phbs
(
void
)
static
void
__init
pci_process_bridge_OF_ranges
(
struct
pci_controller
*
hose
,
struct
device_node
*
dev
,
int
primary
)
{
struct
device_node
*
Pci_Node
;
struct
pci_controller
*
phb
;
unsigned
int
root_addr_size_words
=
0
,
this_addr_size_words
=
0
;
unsigned
int
this_addr_count
=
0
,
range_stride
;
unsigned
int
*
ui_ptr
=
NULL
,
*
ranges
;
char
*
model
;
struct
pci_range64
range
;
unsigned
int
*
ranges
;
unsigned
long
size
;
int
rlen
=
0
;
int
memno
=
0
;
struct
resource
*
res
;
unsigned
int
memno
,
rlen
,
i
,
index
;
unsigned
int
*
opprop
;
int
has_isa
=
0
;
PPCDBG
(
PPCDBG_PHBINIT
,
"find_and_init_phbs
\n
"
);
read_pci_config
=
rtas_token
(
"read-pci-config"
);
write_pci_config
=
rtas_token
(
"write-pci-config"
);
ibm_read_pci_config
=
rtas_token
(
"ibm,read-pci-config"
);
ibm_write_pci_config
=
rtas_token
(
"ibm,write-pci-config"
);
int
np
,
na
=
prom_n_addr_cells
(
dev
);
unsigned
long
pci_addr
,
cpu_phys_addr
;
np
=
na
+
5
;
/*
* The ranges property is laid out as an array of elements,
* each of which comprises:
* cells 0 - 2: a PCI address
* cells 3 or 3+4: a CPU physical address
* (size depending on dev->n_addr_cells)
* cells 4+5 or 5+6: the size of the range
*/
rlen
=
0
;
hose
->
io_base_phys
=
0
;
ranges
=
(
unsigned
int
*
)
get_property
(
dev
,
"ranges"
,
&
rlen
);
while
((
rlen
-=
np
*
sizeof
(
unsigned
int
))
>=
0
)
{
res
=
NULL
;
pci_addr
=
(
unsigned
long
)
ranges
[
1
]
<<
32
|
ranges
[
2
];
cpu_phys_addr
=
ranges
[
3
];
if
(
na
==
2
)
cpu_phys_addr
=
cpu_phys_addr
<<
32
|
ranges
[
4
];
size
=
(
unsigned
long
)
ranges
[
na
+
3
]
<<
32
|
ranges
[
na
+
4
];
switch
(
ranges
[
0
]
>>
24
)
{
case
1
:
/* I/O space */
hose
->
io_base_phys
=
cpu_phys_addr
;
hose
->
io_base_virt
=
__ioremap
(
hose
->
io_base_phys
,
size
,
_PAGE_NO_CACHE
);
if
(
primary
)
{
pci_io_base
=
(
unsigned
long
)
hose
->
io_base_virt
;
if
(
find_type_devices
(
"isa"
))
isa_io_base
=
pci_io_base
;
}
if
(
naca
->
interrupt_controller
==
IC_OPEN_PIC
)
{
opprop
=
(
unsigned
int
*
)
get_property
(
find_path_device
(
"/"
),
"platform-open-pic"
,
NULL
);
res
=
&
hose
->
io_resource
;
res
->
flags
=
IORESOURCE_IO
;
res
->
start
=
pci_addr
;
res
->
start
+=
(
unsigned
long
)
hose
->
io_base_virt
-
pci_io_base
;
break
;
case
2
:
/* memory space */
memno
=
0
;
while
(
memno
<
3
&&
hose
->
mem_resources
[
memno
].
flags
)
++
memno
;
if
(
memno
==
0
)
hose
->
pci_mem_offset
=
cpu_phys_addr
-
pci_addr
;
if
(
memno
<
3
)
{
res
=
&
hose
->
mem_resources
[
memno
];
res
->
flags
=
IORESOURCE_MEM
;
res
->
start
=
cpu_phys_addr
;
}
break
;
}
if
(
res
!=
NULL
)
{
res
->
name
=
dev
->
full_name
;
res
->
end
=
res
->
start
+
size
-
1
;
res
->
parent
=
NULL
;
res
->
sibling
=
NULL
;
res
->
child
=
NULL
;
}
ranges
+=
np
;
}
}
/* Get the root address word size. */
ui_ptr
=
(
unsigned
int
*
)
get_property
(
find_path_device
(
"/"
),
"#size-cells"
,
NULL
);
if
(
ui_ptr
)
{
root_addr_size_words
=
*
ui_ptr
;
}
else
{
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
get #size-cells failed.
\n
"
);
return
(
-
1
);
}
static
void
python_countermeasures
(
unsigned
long
addr
)
{
void
*
chip_regs
;
volatile
u32
*
tmp
,
i
;
if
(
find_type_devices
(
"isa"
))
{
has_isa
=
1
;
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
Found an ISA bus.
\n
"
);
}
/* Python's register file is 1 MB in size. */
chip_regs
=
ioremap
(
addr
&
~
(
0xfffffUL
),
0x100000
);
index
=
0
;
/*
* Firmware doesn't always clear this bit which is critical
* for good performance - Anton
*/
/******************************************************************
* Find all PHB devices and create an object for them.
******************************************************************/
for
(
Pci_Node
=
find_devices
(
"pci"
);
Pci_Node
!=
NULL
;
Pci_Node
=
Pci_Node
->
next
)
{
model
=
(
char
*
)
get_property
(
Pci_Node
,
"model"
,
NULL
);
if
(
model
!=
NULL
)
{
phb
=
alloc_phb
(
Pci_Node
,
model
,
root_addr_size_words
);
if
(
phb
==
NULL
)
return
(
-
1
);
}
else
{
continue
;
}
/* Get this node's address word size. */
ui_ptr
=
(
unsigned
int
*
)
get_property
(
Pci_Node
,
"#size-cells"
,
NULL
);
if
(
ui_ptr
)
this_addr_size_words
=
*
ui_ptr
;
else
this_addr_size_words
=
1
;
/* Get this node's address word count. */
ui_ptr
=
(
unsigned
int
*
)
get_property
(
Pci_Node
,
"#address-cells"
,
NULL
);
if
(
ui_ptr
)
this_addr_count
=
*
ui_ptr
;
else
this_addr_count
=
3
;
range_stride
=
this_addr_count
+
root_addr_size_words
+
this_addr_size_words
;
memno
=
0
;
phb
->
io_base_phys
=
0
;
ranges
=
(
unsigned
int
*
)
get_property
(
Pci_Node
,
"ranges"
,
&
rlen
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range_stride = 0x%lx, rlen = 0x%x
\n
"
,
range_stride
,
rlen
);
for
(
i
=
0
;
i
<
(
rlen
/
sizeof
(
*
ranges
));
i
+=
range_stride
)
{
/* Put the PCI addr part of the current element into a
* '64' struct.
*/
range
=
*
((
struct
pci_range64
*
)(
ranges
+
i
));
/* If this is a '32' element, map into a 64 struct. */
if
((
range_stride
*
sizeof
(
int
))
==
sizeof
(
struct
pci_range32
))
{
range
.
parent_addr
=
(
unsigned
long
)(
*
(
ranges
+
i
+
3
));
range
.
size
=
(((
unsigned
long
)(
*
(
ranges
+
i
+
4
)))
<<
32
)
|
(
*
(
ranges
+
i
+
5
));
}
else
{
range
.
parent_addr
=
(((
unsigned
long
)(
*
(
ranges
+
i
+
3
)))
<<
32
)
|
(
*
(
ranges
+
i
+
4
));
range
.
size
=
(((
unsigned
long
)(
*
(
ranges
+
i
+
5
)))
<<
32
)
|
(
*
(
ranges
+
i
+
6
));
}
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range.parent_addr = 0x%lx
\n
"
,
range
.
parent_addr
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range.child_addr.hi = 0x%lx
\n
"
,
range
.
child_addr
.
a_hi
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range.child_addr.mid = 0x%lx
\n
"
,
range
.
child_addr
.
a_mid
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range.child_addr.lo = 0x%lx
\n
"
,
range
.
child_addr
.
a_lo
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
range.size = 0x%lx
\n
"
,
range
.
size
);
res
=
NULL
;
switch
((
range
.
child_addr
.
a_hi
>>
24
)
&
0x3
)
{
case
1
:
/* I/O space */
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
IO Space
\n
"
);
phb
->
io_base_phys
=
range
.
parent_addr
;
res
=
&
phb
->
io_resource
;
res
->
name
=
Pci_Node
->
full_name
;
res
->
flags
=
IORESOURCE_IO
;
phb
->
io_base_virt
=
__ioremap
(
phb
->
io_base_phys
,
range
.
size
,
_PAGE_NO_CACHE
);
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
-
pci_io_base
;
res
->
end
=
res
->
start
+
range
.
size
-
1
;
res
->
parent
=
NULL
;
res
->
sibling
=
NULL
;
res
->
child
=
NULL
;
phb
->
pci_io_offset
=
range
.
parent_addr
-
((((
unsigned
long
)
range
.
child_addr
.
a_mid
)
<<
32
)
|
(
range
.
child_addr
.
a_lo
));
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
pci_io_offset = 0x%lx
\n
"
,
phb
->
pci_io_offset
);
break
;
case
2
:
/* mem space */
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
Mem Space
\n
"
);
phb
->
pci_mem_offset
=
range
.
parent_addr
-
((((
unsigned
long
)
range
.
child_addr
.
a_mid
)
<<
32
)
|
(
range
.
child_addr
.
a_lo
));
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
pci_mem_offset = 0x%lx
\n
"
,
phb
->
pci_mem_offset
);
if
(
memno
<
sizeof
(
phb
->
mem_resources
)
/
sizeof
(
phb
->
mem_resources
[
0
]))
{
res
=
&
(
phb
->
mem_resources
[
memno
]);
++
memno
;
res
->
name
=
Pci_Node
->
full_name
;
res
->
flags
=
IORESOURCE_MEM
;
res
->
start
=
range
.
parent_addr
;
res
->
end
=
range
.
parent_addr
+
range
.
size
-
1
;
res
->
parent
=
NULL
;
res
->
sibling
=
NULL
;
res
->
child
=
NULL
;
}
break
;
}
}
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
phb->io_base_phys = 0x%lx
\n
"
,
phb
->
io_base_phys
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
phb->pci_mem_offset = 0x%lx
\n
"
,
phb
->
pci_mem_offset
);
#define PRG_CL_RESET_VALID 0x00010000
if
(
naca
->
interrupt_controller
==
IC_OPEN_PIC
)
{
int
addr
=
root_addr_size_words
*
(
index
+
2
)
-
1
;
openpic_setup_ISU
(
index
,
opprop
[
addr
]);
}
index
++
;
tmp
=
(
u32
*
)((
unsigned
long
)
chip_regs
+
0xf6030
);
if
(
*
tmp
&
PRG_CL_RESET_VALID
)
{
printk
(
KERN_INFO
"Python workaround: "
);
*
tmp
&=
~
PRG_CL_RESET_VALID
;
/*
* We must read it back for changes to
* take effect
*/
i
=
*
tmp
;
printk
(
"reg0: %x
\n
"
,
i
);
}
pci_devs_phb_init
();
return
0
;
/*Success */
iounmap
(
chip_regs
);
}
/******************************************************************
*
* Allocate and partially initialize a structure to represent a PHB.
*
******************************************************************/
struct
pci_controller
*
alloc_phb
(
struct
device_node
*
dev
,
char
*
model
,
unsigned
int
addr_size_words
)
struct
pci_controller
*
alloc_phb
(
struct
device_node
*
dev
,
unsigned
int
addr_size_words
)
{
struct
pci_controller
*
phb
;
unsigned
int
*
ui_ptr
=
NULL
,
len
;
struct
reg_property64
reg_struct
;
int
*
bus_range
;
int
*
buid_vals
;
char
*
model
;
enum
phb_types
phb_type
;
model
=
(
char
*
)
get_property
(
dev
,
"model"
,
NULL
);
if
(
!
model
)
{
printk
(
KERN_ERR
"alloc_phb: phb has no model property
\n
"
);
model
=
"<empty>"
;
}
PPCDBG
(
PPCDBG_PHBINIT
,
"alloc_phb: %s
\n
"
,
dev
->
full_name
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
dev = 0x%lx
\n
"
,
dev
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
model = 0x%lx
\n
"
,
model
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
addr_size_words = 0x%lx
\n
"
,
addr_size_words
);
/* Found a PHB, now figure out where his registers are mapped. */
ui_ptr
=
(
unsigned
int
*
)
get_property
(
dev
,
"reg"
,
&
len
);
if
(
ui_ptr
==
NULL
)
{
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
get reg failed.
\n
"
);
return
(
NULL
)
;
return
NULL
;
}
if
(
addr_size_words
==
1
)
{
...
...
@@ -389,83 +314,30 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
reg_struct
=
*
((
struct
reg_property64
*
)
ui_ptr
);
}
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
reg_struct.address = 0x%lx
\n
"
,
reg_struct
.
address
);
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
reg_struct.size = 0x%lx
\n
"
,
reg_struct
.
size
);
/***************************************************************
* Set chip specific data in the phb, including types &
* register pointers.
***************************************************************/
/****************************************************************
* Python
***************************************************************/
if
(
strstr
(
model
,
"Python"
))
{
void
*
chip_regs
;
volatile
u32
*
tmp
,
i
;
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
Create python
\n
"
);
phb
=
pci_alloc_pci_controller
(
"PHB PY"
,
phb_type_python
);
if
(
phb
==
NULL
)
return
NULL
;
/* Python's register file is 1 MB in size. */
chip_regs
=
ioremap
(
reg_struct
.
address
&
~
(
0xfffffUL
),
0x100000
);
/*
* Firmware doesn't always clear this bit which is critical
* for good performance - Anton
*/
#define PRG_CL_RESET_VALID 0x00010000
tmp
=
(
u32
*
)((
unsigned
long
)
chip_regs
+
0xf6030
);
if
(
*
tmp
&
PRG_CL_RESET_VALID
)
{
printk
(
"Python workaround: "
);
*
tmp
&=
~
PRG_CL_RESET_VALID
;
/*
* We must read it back for changes to
* take effect
*/
i
=
*
tmp
;
printk
(
"reg0: %x
\n
"
,
i
);
}
phb_type
=
phb_type_python
;
}
else
if
(
strstr
(
model
,
"Speedwagon"
))
{
phb_type
=
phb_type_speedwagon
;
}
else
if
(
strstr
(
model
,
"Winnipeg"
))
{
phb_type
=
phb_type_winnipeg
;
}
else
{
printk
(
KERN_ERR
"alloc_phb: unknown PHB %s
\n
"
,
model
);
phb_type
=
phb_type_unknown
;
}
/***************************************************************
* Speedwagon
* include Winnipeg as well for the time being.
***************************************************************/
}
else
if
((
strstr
(
model
,
"Speedwagon"
))
||
(
strstr
(
model
,
"Winnipeg"
)))
{
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
Create speedwagon
\n
"
);
phb
=
pci_alloc_pci_controller
(
"PHB SW"
,
phb_type_speedwagon
);
if
(
phb
==
NULL
)
return
NULL
;
phb
->
local_number
=
((
reg_struct
.
address
>>
12
)
&
0xf
)
-
0x8
;
/***************************************************************
* Trying to build a known just gets the code in trouble.
***************************************************************/
}
else
{
PPCDBG
(
PPCDBG_PHBINIT
,
"
\t
Unknown PHB Type!
\n
"
);
printk
(
"PCI: Unknown Phb Type!
\n
"
);
phb
=
pci_alloc_pci_controller
(
phb_type
);
if
(
phb
==
NULL
)
return
NULL
;
}
if
(
phb_type
==
phb_type_python
)
python_countermeasures
(
reg_struct
.
address
);
bus_range
=
(
int
*
)
get_property
(
dev
,
"bus-range"
,
&
len
);
if
(
bus_range
==
NULL
||
len
<
2
*
sizeof
(
int
))
{
PPCDBG
(
PPCDBG_PHBINIT
,
"Can't get bus-range for %s
\n
"
,
dev
->
full_name
);
kfree
(
phb
);
return
(
NULL
)
;
return
NULL
;
}
/***************************************************************
* Finished with the initialization
***************************************************************/
phb
->
first_busno
=
bus_range
[
0
];
phb
->
last_busno
=
bus_range
[
1
];
...
...
@@ -473,7 +345,7 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
phb
->
ops
=
&
rtas_pci_ops
;
buid_vals
=
(
int
*
)
get_property
(
dev
,
"ibm,fw-phb-id"
,
&
len
);
if
(
buid_vals
==
NULL
)
{
phb
->
buid
=
0
;
}
else
{
...
...
@@ -486,24 +358,71 @@ 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
"
"built with the patch that fixes include/linux/pci.h struct pci_bus so
\n
"
"number, primary, secondary and subordinate are ints.
\n
"
);
}
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
);
}
if
(
len
<
2
*
sizeof
(
int
))
// Support for new OF that only has 1 integer for buid.
phb
->
buid
=
(
unsigned
long
)
buid_vals
[
0
];
else
phb
->
buid
=
(((
unsigned
long
)
buid_vals
[
0
])
<<
32UL
)
|
(((
unsigned
long
)
buid_vals
[
1
])
&
0xffffffff
);
phb
->
first_busno
+=
(
phb
->
global_number
<<
8
);
phb
->
last_busno
+=
(
phb
->
global_number
<<
8
);
}
/* Dump PHB information for Debug */
PPCDBGCALL
(
PPCDBG_PHBINIT
,
dumpPci_Controller
(
phb
)
);
PPCDBGCALL
(
PPCDBG_PHBINIT
,
dumpPci_Controller
(
phb
)
);
return
phb
;
}
unsigned
long
__init
find_and_init_phbs
(
void
)
{
struct
device_node
*
node
;
struct
pci_controller
*
phb
;
unsigned
int
root_size_cells
=
0
;
unsigned
int
index
;
unsigned
int
*
opprop
;
struct
device_node
*
root
=
find_path_device
(
"/"
);
read_pci_config
=
rtas_token
(
"read-pci-config"
);
write_pci_config
=
rtas_token
(
"write-pci-config"
);
ibm_read_pci_config
=
rtas_token
(
"ibm,read-pci-config"
);
ibm_write_pci_config
=
rtas_token
(
"ibm,write-pci-config"
);
if
(
naca
->
interrupt_controller
==
IC_OPEN_PIC
)
{
opprop
=
(
unsigned
int
*
)
get_property
(
root
,
"platform-open-pic"
,
NULL
);
}
root_size_cells
=
prom_n_size_cells
(
root
);
index
=
0
;
for
(
node
=
root
->
child
;
node
!=
NULL
;
node
=
node
->
sibling
)
{
if
(
node
->
type
==
NULL
||
strcmp
(
node
->
type
,
"pci"
)
!=
0
)
continue
;
phb
=
alloc_phb
(
node
,
root_size_cells
);
if
(
!
phb
)
continue
;
pci_process_bridge_OF_ranges
(
phb
,
node
,
index
==
0
);
if
(
naca
->
interrupt_controller
==
IC_OPEN_PIC
)
{
int
addr
=
root_size_cells
*
(
index
+
2
)
-
1
;
openpic_setup_ISU
(
index
,
opprop
[
addr
]);
}
index
++
;
}
pci_devs_phb_init
();
return
0
;
}
void
fixup_resources
(
struct
pci_dev
*
dev
)
{
...
...
@@ -581,6 +500,55 @@ fixup_resources(struct pci_dev *dev)
}
}
void
__init
pSeries_pcibios_fixup_bus
(
struct
pci_bus
*
bus
)
{
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
bus
);
struct
resource
*
res
;
int
i
;
if
(
bus
->
parent
==
NULL
)
{
/* This is a host bridge - fill in its resources */
phb
->
bus
=
bus
;
bus
->
resource
[
0
]
=
res
=
&
phb
->
io_resource
;
if
(
!
res
->
flags
)
BUG
();
/* No I/O resource for this PHB? */
for
(
i
=
0
;
i
<
3
;
++
i
)
{
res
=
&
phb
->
mem_resources
[
i
];
if
(
!
res
->
flags
)
{
if
(
i
==
0
)
BUG
();
/* No memory resource for this PHB? */
}
bus
->
resource
[
i
+
1
]
=
res
;
}
}
else
{
/* This is a subordinate bridge */
pci_read_bridge_bases
(
bus
);
for
(
i
=
0
;
i
<
4
;
++
i
)
{
if
((
res
=
bus
->
resource
[
i
])
==
NULL
)
continue
;
if
(
!
res
->
flags
)
continue
;
if
(
res
==
pci_find_parent_resource
(
bus
->
self
,
res
))
{
/* Transparent resource -- don't try to "fix" it. */
continue
;
}
if
(
res
->
flags
&
IORESOURCE_IO
)
{
unsigned
long
offset
=
(
unsigned
long
)
phb
->
io_base_virt
-
pci_io_base
;
res
->
start
+=
offset
;
res
->
end
+=
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
;
}
}
}
}
}
static
void
check_s7a
(
void
)
{
struct
device_node
*
root
;
...
...
@@ -629,17 +597,6 @@ pci_find_hose_for_OF_device(struct device_node *node)
return
NULL
;
}
/***********************************************************************
* ppc64_pcibios_init
*
* Chance to initialize and structures or variable before PCI Bus walk.
*
***********************************************************************/
void
pSeries_pcibios_init
(
void
)
{
}
/*
* This is called very early before the page table is setup.
*/
...
...
arch/ppc64/kernel/pci.c
View file @
dada8441
...
...
@@ -49,7 +49,6 @@ static void fixup_windbond_82c105(struct pci_dev* dev);
void
fixup_resources
(
struct
pci_dev
*
dev
);
void
iSeries_pcibios_init
(
void
);
void
pSeries_pcibios_init
(
void
);
struct
pci_controller
*
hose_head
;
struct
pci_controller
**
hose_tail
=
&
hose_head
;
...
...
@@ -363,16 +362,33 @@ pcibios_assign_resources(void)
* Allocate pci_controller(phb) initialized common variables.
*/
struct
pci_controller
*
__init
pci_alloc_pci_controller
(
char
*
model
,
enum
phb_types
controller_type
)
pci_alloc_pci_controller
(
enum
phb_types
controller_type
)
{
struct
pci_controller
*
hose
;
PPCDBG
(
PPCDBG_PHBINIT
,
"PCI: Allocate pci_controller for %s
\n
"
,
model
);
char
*
model
;
hose
=
(
struct
pci_controller
*
)
alloc_bootmem
(
sizeof
(
struct
pci_controller
));
if
(
hose
==
NULL
)
{
printk
(
KERN_ERR
"PCI: Allocate pci_controller failed.
\n
"
);
return
NULL
;
}
memset
(
hose
,
0
,
sizeof
(
struct
pci_controller
));
switch
(
controller_type
)
{
case
phb_type_python
:
model
=
"PHB PY"
;
break
;
case
phb_type_speedwagon
:
model
=
"PHB SW"
;
break
;
case
phb_type_winnipeg
:
model
=
"PHB WP"
;
break
;
default:
model
=
"PHB UK"
;
break
;
}
if
(
strlen
(
model
)
<
8
)
strcpy
(
hose
->
what
,
model
);
else
...
...
@@ -393,9 +409,7 @@ pcibios_init(void)
struct
pci_bus
*
bus
;
int
next_busno
;
#ifndef CONFIG_PPC_ISERIES
pSeries_pcibios_init
();
#else
#ifdef CONFIG_PPC_ISERIES
iSeries_pcibios_init
();
#endif
...
...
@@ -450,54 +464,7 @@ subsys_initcall(pcibios_init);
void
__init
pcibios_fixup_bus
(
struct
pci_bus
*
bus
)
{
#ifndef CONFIG_PPC_ISERIES
struct
pci_controller
*
phb
=
PCI_GET_PHB_PTR
(
bus
);
struct
resource
*
res
;
int
i
;
if
(
bus
->
parent
==
NULL
)
{
/* This is a host bridge - fill in its resources */
phb
->
bus
=
bus
;
bus
->
resource
[
0
]
=
res
=
&
phb
->
io_resource
;
if
(
!
res
->
flags
)
BUG
();
/* No I/O resource for this PHB? */
for
(
i
=
0
;
i
<
3
;
++
i
)
{
res
=
&
phb
->
mem_resources
[
i
];
if
(
!
res
->
flags
)
{
if
(
i
==
0
)
BUG
();
/* No memory resource for this PHB? */
}
bus
->
resource
[
i
+
1
]
=
res
;
}
}
else
{
/* This is a subordinate bridge */
pci_read_bridge_bases
(
bus
);
for
(
i
=
0
;
i
<
4
;
++
i
)
{
if
((
res
=
bus
->
resource
[
i
])
==
NULL
)
continue
;
if
(
!
res
->
flags
)
continue
;
if
(
res
==
pci_find_parent_resource
(
bus
->
self
,
res
))
{
/* Transparent resource -- don't try to "fix" it. */
continue
;
}
if
(
res
->
flags
&
IORESOURCE_IO
)
{
unsigned
long
offset
=
(
unsigned
long
)
phb
->
io_base_virt
-
pci_io_base
;
res
->
start
+=
offset
;
res
->
end
+=
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
;
}
}
}
}
#endif
if
(
ppc_md
.
pcibios_fixup_bus
)
if
(
ppc_md
.
pcibios_fixup_bus
)
ppc_md
.
pcibios_fixup_bus
(
bus
);
}
...
...
arch/ppc64/kernel/pci.h
View file @
dada8441
...
...
@@ -14,7 +14,7 @@
extern
unsigned
long
isa_io_base
;
extern
struct
pci_controller
*
pci_alloc_pci_controller
(
char
*
model
,
enum
phb_types
controller_type
);
extern
struct
pci_controller
*
pci_alloc_pci_controller
(
enum
phb_types
controller_type
);
extern
struct
pci_controller
*
pci_find_hose_for_OF_device
(
struct
device_node
*
node
);
extern
struct
pci_controller
*
hose_head
;
...
...
arch/ppc64/kernel/prom.c
View file @
dada8441
...
...
@@ -2040,11 +2040,11 @@ prom_bi_rec_verify(struct bi_record *bi_recs)
if
(
bi_recs
==
NULL
||
bi_recs
->
tag
!=
BI_FIRST
)
return
NULL
;
last
=
(
struct
bi_record
*
)
bi_recs
->
data
[
0
];
last
=
(
struct
bi_record
*
)
(
long
)
bi_recs
->
data
[
0
];
if
(
last
==
NULL
||
last
->
tag
!=
BI_LAST
)
return
NULL
;
first
=
(
struct
bi_record
*
)
last
->
data
[
0
];
first
=
(
struct
bi_record
*
)
(
long
)
last
->
data
[
0
];
if
(
first
==
NULL
||
first
!=
bi_recs
)
return
NULL
;
...
...
include/asm-ppc64/pci-bridge.h
View file @
dada8441
...
...
@@ -20,7 +20,8 @@ enum phb_types {
phb_type_unknown
=
0x0
,
phb_type_hypervisor
=
0x1
,
phb_type_python
=
0x10
,
phb_type_speedwagon
=
0x11
phb_type_speedwagon
=
0x11
,
phb_type_winnipeg
=
0x12
};
/*
...
...
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