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
51a0885e
Commit
51a0885e
authored
Sep 26, 2005
by
Paul Mackerras
Browse files
Options
Browse Files
Download
Plain Diff
Merge refs/heads/devtree from
rsync://oak/kernels/iseries/work/.git
parents
14cf11af
3d8a66cc
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
313 additions
and
273 deletions
+313
-273
arch/ppc64/Kconfig
arch/ppc64/Kconfig
+0
-1
arch/ppc64/kernel/Makefile
arch/ppc64/kernel/Makefile
+2
-2
arch/ppc64/kernel/head.S
arch/ppc64/kernel/head.S
+5
-2
arch/ppc64/kernel/iSeries_htab.c
arch/ppc64/kernel/iSeries_htab.c
+19
-0
arch/ppc64/kernel/iSeries_irq.c
arch/ppc64/kernel/iSeries_irq.c
+13
-0
arch/ppc64/kernel/iSeries_setup.c
arch/ppc64/kernel/iSeries_setup.c
+245
-215
arch/ppc64/kernel/iSeries_smp.c
arch/ppc64/kernel/iSeries_smp.c
+1
-29
arch/ppc64/kernel/setup.c
arch/ppc64/kernel/setup.c
+11
-19
arch/ppc64/kernel/time.c
arch/ppc64/kernel/time.c
+1
-1
arch/ppc64/mm/hash_utils.c
arch/ppc64/mm/hash_utils.c
+11
-4
include/asm-ppc64/mmu.h
include/asm-ppc64/mmu.h
+4
-0
include/asm-ppc64/processor.h
include/asm-ppc64/processor.h
+1
-0
No files found.
arch/ppc64/Kconfig
View file @
51a0885e
...
...
@@ -357,7 +357,6 @@ config HOTPLUG_CPU
config PROC_DEVICETREE
bool "Support for Open Firmware device tree in /proc"
depends on !PPC_ISERIES
help
This option adds a device-tree directory under /proc which contains
an image of the device tree that the kernel copies from Open
...
...
arch/ppc64/kernel/Makefile
View file @
51a0885e
...
...
@@ -11,7 +11,7 @@ obj-y := setup.o entry.o traps.o irq.o idle.o dma.o \
udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o
\
ptrace32.o signal32.o rtc.o init_task.o
\
lmb.o cputable.o cpu_setup_power4.o idle_power4.o
\
iommu.o sysfs.o vdso.o pmc.o firmware.o
iommu.o sysfs.o vdso.o pmc.o firmware.o
prom.o
obj-y
+=
vdso32/ vdso64/
obj-$(CONFIG_PPC_OF)
+=
of_device.o
...
...
@@ -27,7 +27,7 @@ obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \
mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o
\
iSeries_iommu.o
obj-$(CONFIG_PPC_MULTIPLATFORM)
+=
nvram.o i8259.o prom_init.o
prom.o
obj-$(CONFIG_PPC_MULTIPLATFORM)
+=
nvram.o i8259.o prom_init.o
obj-$(CONFIG_PPC_PSERIES)
+=
pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o
\
pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o
\
...
...
arch/ppc64/kernel/head.S
View file @
51a0885e
...
...
@@ -1364,6 +1364,7 @@ _STATIC(__start_initialization_iSeries)
addi
r2
,
r2
,
0x4000
bl
.
iSeries_early_setup
bl
.
early_setup
/
*
relocation
is
on
at
this
point
*/
...
...
@@ -1970,20 +1971,22 @@ _GLOBAL(hmt_start_secondary)
blr
#endif
#if defined(CONFIG_KEXEC) ||
(defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)
)
#if defined(CONFIG_KEXEC) ||
defined(CONFIG_SMP
)
_GLOBAL
(
smp_release_cpus
)
/
*
All
secondary
cpus
are
spinning
on
a
common
*
spinloop
,
release
them
all
now
so
they
can
start
*
to
spin
on
their
individual
paca
spinloops
.
*
For
non
SMP
kernels
,
the
secondary
cpus
never
*
get
out
of
the
common
spinloop
.
*
XXX
This
does
nothing
useful
on
iSeries
,
secondaries
are
*
already
waiting
on
their
paca
.
*/
li
r3
,
1
LOADADDR
(
r5
,
__secondary_hold_spinloop
)
std
r3
,
0
(
r5
)
sync
blr
#endif /* CONFIG_SMP
&& !CONFIG_PPC_ISERIES
*/
#endif /* CONFIG_SMP */
/*
...
...
arch/ppc64/kernel/iSeries_htab.c
View file @
51a0885e
...
...
@@ -84,6 +84,25 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
return
(
secondary
<<
3
)
|
(
slot
&
7
);
}
long
iSeries_hpte_bolt_or_insert
(
unsigned
long
hpte_group
,
unsigned
long
va
,
unsigned
long
prpn
,
unsigned
long
vflags
,
unsigned
long
rflags
)
{
long
slot
;
hpte_t
lhpte
;
slot
=
HvCallHpt_findValid
(
&
lhpte
,
va
>>
PAGE_SHIFT
);
if
(
lhpte
.
v
&
HPTE_V_VALID
)
{
/* Bolt the existing HPTE */
HvCallHpt_setSwBits
(
slot
,
0x10
,
0
);
HvCallHpt_setPp
(
slot
,
PP_RWXX
);
return
0
;
}
return
iSeries_hpte_insert
(
hpte_group
,
va
,
prpn
,
vflags
,
rflags
);
}
static
unsigned
long
iSeries_hpte_getword0
(
unsigned
long
slot
)
{
hpte_t
hpte
;
...
...
arch/ppc64/kernel/iSeries_irq.c
View file @
51a0885e
...
...
@@ -351,3 +351,16 @@ int __init iSeries_allocate_IRQ(HvBusNumber busNumber,
irq_desc
[
virtirq
].
handler
=
&
iSeries_IRQ_handler
;
return
virtirq
;
}
int
virt_irq_create_mapping
(
unsigned
int
real_irq
)
{
BUG
();
/* Don't call this on iSeries, yet */
return
0
;
}
void
virt_irq_init
(
void
)
{
return
;
}
arch/ppc64/kernel/iSeries_setup.c
View file @
51a0885e
...
...
@@ -74,8 +74,8 @@ extern void hvlog(char *fmt, ...);
extern
void
ppcdbg_initialize
(
void
);
static
void
build_iSeries_Memory_Map
(
void
);
static
void
setup_iSeries_cache_sizes
(
void
);
static
void
iSeries_bolt_kernel
(
unsigned
long
saddr
,
unsigned
long
eaddr
);
static
int
iseries_shared_idle
(
void
);
static
int
iseries_dedicated_idle
(
void
);
#ifdef CONFIG_PCI
extern
void
iSeries_pci_final_fixup
(
void
);
#else
...
...
@@ -83,14 +83,6 @@ static void iSeries_pci_final_fixup(void) { }
#endif
/* Global Variables */
static
unsigned
long
procFreqHz
;
static
unsigned
long
procFreqMhz
;
static
unsigned
long
procFreqMhzHundreths
;
static
unsigned
long
tbFreqHz
;
static
unsigned
long
tbFreqMhz
;
static
unsigned
long
tbFreqMhzHundreths
;
int
piranha_simulator
;
extern
int
rd_size
;
/* Defined in drivers/block/rd.c */
...
...
@@ -319,6 +311,8 @@ static void __init iSeries_init_early(void)
ppcdbg_initialize
();
ppc64_interrupt_controller
=
IC_ISERIES
;
#if defined(CONFIG_BLK_DEV_INITRD)
/*
* If the init RAM disk has been configured and there is
...
...
@@ -340,12 +334,6 @@ static void __init iSeries_init_early(void)
iSeries_recal_tb
=
get_tb
();
iSeries_recal_titan
=
HvCallXm_loadTod
();
/*
* Cache sizes must be initialized before hpte_init_iSeries is called
* as the later need them for flush_icache_range()
*/
setup_iSeries_cache_sizes
();
/*
* Initialize the hash table management pointers
*/
...
...
@@ -356,12 +344,6 @@ static void __init iSeries_init_early(void)
*/
iommu_init_early_iSeries
();
/*
* Initialize the table which translate Linux physical addresses to
* AS/400 absolute addresses
*/
build_iSeries_Memory_Map
();
iSeries_get_cmdline
();
/* Save unparsed command line copy for /proc/cmdline */
...
...
@@ -379,14 +361,6 @@ static void __init iSeries_init_early(void)
}
}
/* Bolt kernel mappings for all of memory (or just a bit if we've got a limit) */
iSeries_bolt_kernel
(
0
,
systemcfg
->
physicalMemorySize
);
lmb_init
();
lmb_add
(
0
,
systemcfg
->
physicalMemorySize
);
lmb_analyze
();
lmb_reserve
(
0
,
__pa
(
klimit
));
/* Initialize machine-dependency vectors */
#ifdef CONFIG_SMP
smp_init_iSeries
();
...
...
@@ -591,103 +565,6 @@ static void __init build_iSeries_Memory_Map(void)
systemcfg
->
physicalMemorySize
=
chunk_to_addr
(
nextPhysChunk
);
}
/*
* Set up the variables that describe the cache line sizes
* for this machine.
*/
static
void
__init
setup_iSeries_cache_sizes
(
void
)
{
unsigned
int
i
,
n
;
unsigned
int
procIx
=
get_paca
()
->
lppaca
.
dyn_hv_phys_proc_index
;
systemcfg
->
icache_size
=
ppc64_caches
.
isize
=
xIoHriProcessorVpd
[
procIx
].
xInstCacheSize
*
1024
;
systemcfg
->
icache_line_size
=
ppc64_caches
.
iline_size
=
xIoHriProcessorVpd
[
procIx
].
xInstCacheOperandSize
;
systemcfg
->
dcache_size
=
ppc64_caches
.
dsize
=
xIoHriProcessorVpd
[
procIx
].
xDataL1CacheSizeKB
*
1024
;
systemcfg
->
dcache_line_size
=
ppc64_caches
.
dline_size
=
xIoHriProcessorVpd
[
procIx
].
xDataCacheOperandSize
;
ppc64_caches
.
ilines_per_page
=
PAGE_SIZE
/
ppc64_caches
.
iline_size
;
ppc64_caches
.
dlines_per_page
=
PAGE_SIZE
/
ppc64_caches
.
dline_size
;
i
=
ppc64_caches
.
iline_size
;
n
=
0
;
while
((
i
=
(
i
/
2
)))
++
n
;
ppc64_caches
.
log_iline_size
=
n
;
i
=
ppc64_caches
.
dline_size
;
n
=
0
;
while
((
i
=
(
i
/
2
)))
++
n
;
ppc64_caches
.
log_dline_size
=
n
;
printk
(
"D-cache line size = %d
\n
"
,
(
unsigned
int
)
ppc64_caches
.
dline_size
);
printk
(
"I-cache line size = %d
\n
"
,
(
unsigned
int
)
ppc64_caches
.
iline_size
);
}
/*
* Create a pte. Used during initialization only.
*/
static
void
iSeries_make_pte
(
unsigned
long
va
,
unsigned
long
pa
,
int
mode
)
{
hpte_t
local_hpte
,
rhpte
;
unsigned
long
hash
,
vpn
;
long
slot
;
vpn
=
va
>>
PAGE_SHIFT
;
hash
=
hpt_hash
(
vpn
,
0
);
local_hpte
.
r
=
pa
|
mode
;
local_hpte
.
v
=
((
va
>>
23
)
<<
HPTE_V_AVPN_SHIFT
)
|
HPTE_V_BOLTED
|
HPTE_V_VALID
;
slot
=
HvCallHpt_findValid
(
&
rhpte
,
vpn
);
if
(
slot
<
0
)
{
/* Must find space in primary group */
panic
(
"hash_page: hpte already exists
\n
"
);
}
HvCallHpt_addValidate
(
slot
,
0
,
&
local_hpte
);
}
/*
* Bolt the kernel addr space into the HPT
*/
static
void
__init
iSeries_bolt_kernel
(
unsigned
long
saddr
,
unsigned
long
eaddr
)
{
unsigned
long
pa
;
unsigned
long
mode_rw
=
_PAGE_ACCESSED
|
_PAGE_COHERENT
|
PP_RWXX
;
hpte_t
hpte
;
for
(
pa
=
saddr
;
pa
<
eaddr
;
pa
+=
PAGE_SIZE
)
{
unsigned
long
ea
=
(
unsigned
long
)
__va
(
pa
);
unsigned
long
vsid
=
get_kernel_vsid
(
ea
);
unsigned
long
va
=
(
vsid
<<
28
)
|
(
pa
&
0xfffffff
);
unsigned
long
vpn
=
va
>>
PAGE_SHIFT
;
unsigned
long
slot
=
HvCallHpt_findValid
(
&
hpte
,
vpn
);
/* Make non-kernel text non-executable */
if
(
!
in_kernel_text
(
ea
))
mode_rw
|=
HW_NO_EXEC
;
if
(
hpte
.
v
&
HPTE_V_VALID
)
{
/* HPTE exists, so just bolt it */
HvCallHpt_setSwBits
(
slot
,
0x10
,
0
);
/* And make sure the pp bits are correct */
HvCallHpt_setPp
(
slot
,
PP_RWXX
);
}
else
/* No HPTE exists, so create a new bolted one */
iSeries_make_pte
(
va
,
phys_to_abs
(
pa
),
mode_rw
);
}
}
/*
* Document me.
*/
...
...
@@ -695,36 +572,22 @@ static void __init iSeries_setup_arch(void)
{
unsigned
procIx
=
get_paca
()
->
lppaca
.
dyn_hv_phys_proc_index
;
/* Add an eye catcher and the systemcfg layout version number */
strcpy
(
systemcfg
->
eye_catcher
,
"SYSTEMCFG:PPC64"
);
systemcfg
->
version
.
major
=
SYSTEMCFG_MAJOR
;
systemcfg
->
version
.
minor
=
SYSTEMCFG_MINOR
;
if
(
get_paca
()
->
lppaca
.
shared_proc
)
{
ppc_md
.
idle_loop
=
iseries_shared_idle
;
printk
(
KERN_INFO
"Using shared processor idle loop
\n
"
);
}
else
{
ppc_md
.
idle_loop
=
iseries_dedicated_idle
;
printk
(
KERN_INFO
"Using dedicated idle loop
\n
"
);
}
/* Setup the Lp Event Queue */
setup_hvlpevent_queue
();
/* Compute processor frequency */
procFreqHz
=
((
1UL
<<
34
)
*
1000000
)
/
xIoHriProcessorVpd
[
procIx
].
xProcFreq
;
procFreqMhz
=
procFreqHz
/
1000000
;
procFreqMhzHundreths
=
(
procFreqHz
/
10000
)
-
(
procFreqMhz
*
100
);
ppc_proc_freq
=
procFreqHz
;
/* Compute time base frequency */
tbFreqHz
=
((
1UL
<<
32
)
*
1000000
)
/
xIoHriProcessorVpd
[
procIx
].
xTimeBaseFreq
;
tbFreqMhz
=
tbFreqHz
/
1000000
;
tbFreqMhzHundreths
=
(
tbFreqHz
/
10000
)
-
(
tbFreqMhz
*
100
);
ppc_tb_freq
=
tbFreqHz
;
printk
(
"Max logical processors = %d
\n
"
,
itVpdAreas
.
xSlicMaxLogicalProcs
);
printk
(
"Max physical processors = %d
\n
"
,
itVpdAreas
.
xSlicMaxPhysicalProcs
);
printk
(
"Processor frequency = %lu.%02lu
\n
"
,
procFreqMhz
,
procFreqMhzHundreths
);
printk
(
"Time base frequency = %lu.%02lu
\n
"
,
tbFreqMhz
,
tbFreqMhzHundreths
);
systemcfg
->
processor
=
xIoHriProcessorVpd
[
procIx
].
xPVR
;
printk
(
"Processor version = %x
\n
"
,
systemcfg
->
processor
);
}
...
...
@@ -768,49 +631,6 @@ static void iSeries_halt(void)
mf_power_off
();
}
/*
* void __init iSeries_calibrate_decr()
*
* Description:
* This routine retrieves the internal processor frequency from the VPD,
* and sets up the kernel timer decrementer based on that value.
*
*/
static
void
__init
iSeries_calibrate_decr
(
void
)
{
unsigned
long
cyclesPerUsec
;
struct
div_result
divres
;
/* Compute decrementer (and TB) frequency in cycles/sec */
cyclesPerUsec
=
ppc_tb_freq
/
1000000
;
/*
* Set the amount to refresh the decrementer by. This
* is the number of decrementer ticks it takes for
* 1/HZ seconds.
*/
tb_ticks_per_jiffy
=
ppc_tb_freq
/
HZ
;
#if 0
/* TEST CODE FOR ADJTIME */
tb_ticks_per_jiffy += tb_ticks_per_jiffy / 5000;
/* END OF TEST CODE */
#endif
/*
* tb_ticks_per_sec = freq; would give better accuracy
* but tb_ticks_per_sec = tb_ticks_per_jiffy*HZ; assures
* that jiffies (and xtime) will match the time returned
* by do_gettimeofday.
*/
tb_ticks_per_sec
=
tb_ticks_per_jiffy
*
HZ
;
tb_ticks_per_usec
=
cyclesPerUsec
;
tb_to_us
=
mulhwu_scale_factor
(
ppc_tb_freq
,
1000000
);
div128_by_32
(
1024
*
1024
,
0
,
tb_ticks_per_sec
,
&
divres
);
tb_to_xs
=
divres
.
result_low
;
setup_default_decr
();
}
static
void
__init
iSeries_progress
(
char
*
st
,
unsigned
short
code
)
{
printk
(
"Progress: [%04x] - %s
\n
"
,
(
unsigned
)
code
,
st
);
...
...
@@ -942,36 +762,246 @@ static int iseries_dedicated_idle(void)
void
__init
iSeries_init_IRQ
(
void
)
{
}
#endif
void
__init
iSeries_early_setup
(
void
)
static
int
__init
iseries_probe
(
int
platform
)
{
iSeries_fixup_klimit
();
return
PLATFORM_ISERIES_LPAR
==
platform
;
}
ppc_md
.
setup_arch
=
iSeries_setup_arch
;
ppc_md
.
get_cpuinfo
=
iSeries_get_cpuinfo
;
ppc_md
.
init_IRQ
=
iSeries_init_IRQ
;
ppc_md
.
get_irq
=
iSeries_get_irq
;
ppc_md
.
init_early
=
iSeries_init_early
,
struct
machdep_calls
__initdata
iseries_md
=
{
.
setup_arch
=
iSeries_setup_arch
,
.
get_cpuinfo
=
iSeries_get_cpuinfo
,
.
init_IRQ
=
iSeries_init_IRQ
,
.
get_irq
=
iSeries_get_irq
,
.
init_early
=
iSeries_init_early
,
.
pcibios_fixup
=
iSeries_pci_final_fixup
,
.
restart
=
iSeries_restart
,
.
power_off
=
iSeries_power_off
,
.
halt
=
iSeries_halt
,
.
get_boot_time
=
iSeries_get_boot_time
,
.
set_rtc_time
=
iSeries_set_rtc_time
,
.
get_rtc_time
=
iSeries_get_rtc_time
,
.
calibrate_decr
=
generic_calibrate_decr
,
.
progress
=
iSeries_progress
,
.
probe
=
iseries_probe
,
/* XXX Implement enable_pmcs for iSeries */
};
ppc_md
.
pcibios_fixup
=
iSeries_pci_final_fixup
;
struct
blob
{
unsigned
char
data
[
PAGE_SIZE
];
unsigned
long
next
;
};
ppc_md
.
restart
=
iSeries_restart
;
ppc_md
.
power_off
=
iSeries_power_off
;
ppc_md
.
halt
=
iSeries_halt
;
struct
iseries_flat_dt
{
struct
boot_param_header
header
;
u64
reserve_map
[
2
];
struct
blob
dt
;
struct
blob
strings
;
};
ppc_md
.
get_boot_time
=
iSeries_get_boot_time
;
ppc_md
.
set_rtc_time
=
iSeries_set_rtc_time
;
ppc_md
.
get_rtc_time
=
iSeries_get_rtc_time
;
ppc_md
.
calibrate_decr
=
iSeries_calibrate_decr
;
ppc_md
.
progress
=
iSeries_progress
;
struct
iseries_flat_dt
iseries_dt
;
/* XXX Implement enable_pmcs for iSeries */
void
dt_init
(
struct
iseries_flat_dt
*
dt
)
{
dt
->
header
.
off_mem_rsvmap
=
offsetof
(
struct
iseries_flat_dt
,
reserve_map
);
dt
->
header
.
off_dt_struct
=
offsetof
(
struct
iseries_flat_dt
,
dt
);
dt
->
header
.
off_dt_strings
=
offsetof
(
struct
iseries_flat_dt
,
strings
);
dt
->
header
.
totalsize
=
sizeof
(
struct
iseries_flat_dt
);
dt
->
header
.
dt_strings_size
=
sizeof
(
struct
blob
);
if
(
get_paca
()
->
lppaca
.
shared_proc
)
{
ppc_md
.
idle_loop
=
iseries_shared_idle
;
printk
(
KERN_INFO
"Using shared processor idle loop
\n
"
);
}
else
{
ppc_md
.
idle_loop
=
iseries_dedicated_idle
;
printk
(
KERN_INFO
"Using dedicated idle loop
\n
"
);
/* There is no notion of hardware cpu id on iSeries */
dt
->
header
.
boot_cpuid_phys
=
smp_processor_id
();
dt
->
dt
.
next
=
(
unsigned
long
)
&
dt
->
dt
.
data
;
dt
->
strings
.
next
=
(
unsigned
long
)
&
dt
->
strings
.
data
;
dt
->
header
.
magic
=
OF_DT_HEADER
;
dt
->
header
.
version
=
0x10
;
dt
->
header
.
last_comp_version
=
0x10
;
dt
->
reserve_map
[
0
]
=
0
;
dt
->
reserve_map
[
1
]
=
0
;
}
void
dt_check_blob
(
struct
blob
*
b
)
{
if
(
b
->
next
>=
(
unsigned
long
)
&
b
->
next
)
{
DBG
(
"Ran out of space in flat device tree blob!
\n
"
);
BUG
();
}
}
void
dt_push_u32
(
struct
iseries_flat_dt
*
dt
,
u32
value
)
{
*
((
u32
*
)
dt
->
dt
.
next
)
=
value
;
dt
->
dt
.
next
+=
sizeof
(
u32
);
dt_check_blob
(
&
dt
->
dt
);
}
void
dt_push_u64
(
struct
iseries_flat_dt
*
dt
,
u64
value
)
{
*
((
u64
*
)
dt
->
dt
.
next
)
=
value
;
dt
->
dt
.
next
+=
sizeof
(
u64
);
dt_check_blob
(
&
dt
->
dt
);
}
unsigned
long
dt_push_bytes
(
struct
blob
*
blob
,
char
*
data
,
int
len
)
{
unsigned
long
start
=
blob
->
next
-
(
unsigned
long
)
blob
->
data
;
memcpy
((
char
*
)
blob
->
next
,
data
,
len
);
blob
->
next
=
_ALIGN
(
blob
->
next
+
len
,
4
);
dt_check_blob
(
blob
);
return
start
;
}
void
dt_start_node
(
struct
iseries_flat_dt
*
dt
,
char
*
name
)
{
dt_push_u32
(
dt
,
OF_DT_BEGIN_NODE
);
dt_push_bytes
(
&
dt
->
dt
,
name
,
strlen
(
name
)
+
1
);
}
#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE)
void
dt_prop
(
struct
iseries_flat_dt
*
dt
,
char
*
name
,
char
*
data
,
int
len
)
{
unsigned
long
offset
;
dt_push_u32
(
dt
,
OF_DT_PROP
);
/* Length of the data */
dt_push_u32
(
dt
,
len
);
/* Put the property name in the string blob. */
offset
=
dt_push_bytes
(
&
dt
->
strings
,
name
,
strlen
(
name
)
+
1
);
/* The offset of the properties name in the string blob. */
dt_push_u32
(
dt
,
(
u32
)
offset
);
/* The actual data. */
dt_push_bytes
(
&
dt
->
dt
,
data
,
len
);
}
void
dt_prop_str
(
struct
iseries_flat_dt
*
dt
,
char
*
name
,
char
*
data
)
{
dt_prop
(
dt
,
name
,
data
,
strlen
(
data
)
+
1
);
/* + 1 for NULL */
}
void
dt_prop_u32
(
struct
iseries_flat_dt
*
dt
,
char
*
name
,
u32
data
)
{
dt_prop
(
dt
,
name
,
(
char
*
)
&
data
,
sizeof
(
u32
));
}
void
dt_prop_u64
(
struct
iseries_flat_dt
*
dt
,
char
*
name
,
u64
data
)
{
dt_prop
(
dt
,
name
,
(
char
*
)
&
data
,
sizeof
(
u64
));
}
void
dt_prop_u64_list
(
struct
iseries_flat_dt
*
dt
,
char
*
name
,
u64
*
data
,
int
n
)
{
dt_prop
(
dt
,
name
,
(
char
*
)
data
,
sizeof
(
u64
)
*
n
);
}
void
dt_prop_empty
(
struct
iseries_flat_dt
*
dt
,
char
*
name
)
{
dt_prop
(
dt
,
name
,
NULL
,
0
);
}
void
dt_cpus
(
struct
iseries_flat_dt
*
dt
)
{
unsigned
char
buf
[
32
];
unsigned
char
*
p
;
unsigned
int
i
,
index
;
struct
IoHriProcessorVpd
*
d
;
/* yuck */
snprintf
(
buf
,
32
,
"PowerPC,%s"
,
cur_cpu_spec
->
cpu_name
);
p
=
strchr
(
buf
,
' '
);
if
(
!
p
)
p
=
buf
+
strlen
(
buf
);
dt_start_node
(
dt
,
"cpus"
);
dt_prop_u32
(
dt
,
"#address-cells"
,
1
);
dt_prop_u32
(
dt
,
"#size-cells"
,
0
);
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
paca
[
i
].
lppaca
.
dyn_proc_status
>=
2
)
continue
;
snprintf
(
p
,
32
-
(
p
-
buf
),
"@%d"
,
i
);
dt_start_node
(
dt
,
buf
);
dt_prop_str
(
dt
,
"device_type"
,
"cpu"
);
index
=
paca
[
i
].
lppaca
.
dyn_hv_phys_proc_index
;
d
=
&
xIoHriProcessorVpd
[
index
];
dt_prop_u32
(
dt
,
"i-cache-size"
,
d
->
xInstCacheSize
*
1024
);
dt_prop_u32
(
dt
,
"i-cache-line-size"
,
d
->
xInstCacheOperandSize
);
dt_prop_u32
(
dt
,
"d-cache-size"
,
d
->
xDataL1CacheSizeKB
*
1024
);
dt_prop_u32
(
dt
,
"d-cache-line-size"
,
d
->
xDataCacheOperandSize
);
/* magic conversions to Hz copied from old code */
dt_prop_u32
(
dt
,
"clock-frequency"
,
((
1UL
<<
34
)
*
1000000
)
/
d
->
xProcFreq
);
dt_prop_u32
(
dt
,
"timebase-frequency"
,
((
1UL
<<
32
)
*
1000000
)
/
d
->
xTimeBaseFreq
);
dt_prop_u32
(
dt
,
"reg"
,
i
);
dt_end_node
(
dt
);
}
dt_end_node
(
dt
);
}
void
build_flat_dt
(
struct
iseries_flat_dt
*
dt
)
{
u64
tmp
[
2
];
dt_init
(
dt
);
dt_start_node
(
dt
,
""
);
dt_prop_u32
(
dt
,
"#address-cells"
,
2
);
dt_prop_u32
(
dt
,
"#size-cells"
,
2
);
/* /memory */
dt_start_node
(
dt
,
"memory@0"
);
dt_prop_str
(
dt
,
"name"
,
"memory"
);
dt_prop_str
(
dt
,
"device_type"
,
"memory"
);
tmp
[
0
]
=
0
;
tmp
[
1
]
=
systemcfg
->
physicalMemorySize
;
dt_prop_u64_list
(
dt
,
"reg"
,
tmp
,
2
);
dt_end_node
(
dt
);
/* /chosen */
dt_start_node
(
dt
,
"chosen"
);
dt_prop_u32
(
dt
,
"linux,platform"
,
PLATFORM_ISERIES_LPAR
);
dt_end_node
(
dt
);
dt_cpus
(
dt
);
dt_end_node
(
dt
);
dt_push_u32
(
dt
,
OF_DT_END
);
}
void
*
__init
iSeries_early_setup
(
void
)
{
iSeries_fixup_klimit
();
/*
* Initialize the table which translate Linux physical addresses to
* AS/400 absolute addresses
*/
build_iSeries_Memory_Map
();
build_flat_dt
(
&
iseries_dt
);
return
(
void
*
)
__pa
(
&
iseries_dt
);
}
arch/ppc64/kernel/iSeries_smp.c
View file @
51a0885e
...
...
@@ -82,35 +82,9 @@ static void smp_iSeries_message_pass(int target, int msg)
}
}
static
int
smp_iSeries_numProcs
(
void
)
{
unsigned
np
,
i
;
np
=
0
;
for
(
i
=
0
;
i
<
NR_CPUS
;
++
i
)
{
if
(
paca
[
i
].
lppaca
.
dyn_proc_status
<
2
)
{
cpu_set
(
i
,
cpu_possible_map
);
cpu_set
(
i
,
cpu_present_map
);
cpu_set
(
i
,
cpu_sibling_map
[
i
]);
++
np
;
}
}
return
np
;
}
static
int
smp_iSeries_probe
(
void
)
{
unsigned
i
;
unsigned
np
=
0
;
for
(
i
=
0
;
i
<
NR_CPUS
;
++
i
)
{
if
(
paca
[
i
].
lppaca
.
dyn_proc_status
<
2
)
{
/*paca[i].active = 1;*/
++
np
;
}
}
return
np
;
return
cpus_weight
(
cpu_possible_map
);
}
static
void
smp_iSeries_kick_cpu
(
int
nr
)
...
...
@@ -144,6 +118,4 @@ static struct smp_ops_t iSeries_smp_ops = {
void
__init
smp_init_iSeries
(
void
)
{
smp_ops
=
&
iSeries_smp_ops
;
systemcfg
->
processorCount
=
smp_iSeries_numProcs
();
}
arch/ppc64/kernel/setup.c
View file @
51a0885e
...
...
@@ -58,6 +58,7 @@
#include <asm/mmu.h>
#include <asm/lmb.h>
#include <asm/iSeries/ItLpNaca.h>
#include <asm/firmware.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
...
...
@@ -153,7 +154,7 @@ struct screen_info screen_info = {
.
orig_video_points
=
16
};
#if
defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP)
#if
def CONFIG_SMP
static
int
smt_enabled_cmdline
;
...
...
@@ -306,15 +307,13 @@ static void __init setup_cpu_maps(void)
systemcfg
->
processorCount
=
num_present_cpus
();
}
#endif
/* defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP) */
#ifdef CONFIG_PPC_MULTIPLATFORM
#endif
/* CONFIG_SMP */
extern
struct
machdep_calls
pSeries_md
;
extern
struct
machdep_calls
pmac_md
;
extern
struct
machdep_calls
maple_md
;
extern
struct
machdep_calls
bpa_md
;
extern
struct
machdep_calls
iseries_md
;
/* Ultimately, stuff them in an elf section like initcalls... */
static
struct
machdep_calls
__initdata
*
machines
[]
=
{
...
...
@@ -329,6 +328,9 @@ static struct machdep_calls __initdata *machines[] = {
#endif
/* CONFIG_PPC_MAPLE */
#ifdef CONFIG_PPC_BPA
&
bpa_md
,
#endif
#ifdef CONFIG_PPC_ISERIES
&
iseries_md
,
#endif
NULL
};
...
...
@@ -401,6 +403,7 @@ void __init early_setup(unsigned long dt_ptr)
/*
* Initialize stab / SLB management
*/
if
(
!
firmware_has_feature
(
FW_FEATURE_ISERIES
))
stab_initialize
(
lpaca
->
stab_real
);
/*
...
...
@@ -532,8 +535,6 @@ static void __init check_for_initrd(void)
#endif
/* CONFIG_BLK_DEV_INITRD */
}
#endif
/* CONFIG_PPC_MULTIPLATFORM */
/*
* Do some initial setup of the system. The parameters are those which
* were passed in from the bootloader.
...
...
@@ -542,14 +543,6 @@ void __init setup_system(void)
{
DBG
(
" -> setup_system()
\n
"
);
#ifdef CONFIG_PPC_ISERIES
/* pSeries systems are identified in prom.c via OF. */
if
(
itLpNaca
.
xLparInstalled
==
1
)
systemcfg
->
platform
=
PLATFORM_ISERIES_LPAR
;
ppc_md
.
init_early
();
#else
/* CONFIG_PPC_ISERIES */
/*
* Unflatten the device-tree passed by prom_init or kexec
*/
...
...
@@ -607,9 +600,8 @@ void __init setup_system(void)
strlcpy
(
saved_command_line
,
cmd_line
,
COMMAND_LINE_SIZE
);
parse_early_param
();
#endif
/* !CONFIG_PPC_ISERIES */
#if
defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)
#if
def CONFIG_SMP
/*
* iSeries has already initialized the cpu maps at this point.
*/
...
...
@@ -619,7 +611,7 @@ void __init setup_system(void)
* we can map physical -> logical CPU ids
*/
smp_release_cpus
();
#endif
/* defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) */
#endif
printk
(
"Starting Linux PPC64 %s
\n
"
,
system_utsname
.
version
);
...
...
arch/ppc64/kernel/time.c
View file @
51a0885e
...
...
@@ -465,7 +465,7 @@ int do_settimeofday(struct timespec *tv)
EXPORT_SYMBOL
(
do_settimeofday
);
#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA)
#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA)
|| defined(CONFIG_PPC_ISERIES)
void
__init
generic_calibrate_decr
(
void
)
{
struct
device_node
*
cpu
;
...
...
arch/ppc64/mm/hash_utils.c
View file @
51a0885e
...
...
@@ -90,7 +90,6 @@ static inline void loop_forever(void)
;
}
#ifdef CONFIG_PPC_MULTIPLATFORM
static
inline
void
create_pte_mapping
(
unsigned
long
start
,
unsigned
long
end
,
unsigned
long
mode
,
int
large
)
{
...
...
@@ -111,7 +110,7 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end,
unsigned
long
vpn
,
hash
,
hpteg
;
unsigned
long
vsid
=
get_kernel_vsid
(
addr
);
unsigned
long
va
=
(
vsid
<<
28
)
|
(
addr
&
0xfffffff
);
int
ret
;
int
ret
=
-
1
;
if
(
large
)
vpn
=
va
>>
HPAGE_SHIFT
;
...
...
@@ -129,16 +128,25 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end,
hpteg
=
((
hash
&
htab_hash_mask
)
*
HPTES_PER_GROUP
);
#ifdef CONFIG_PPC_ISERIES
if
(
systemcfg
->
platform
&
PLATFORM_ISERIES_LPAR
)
ret
=
iSeries_hpte_bolt_or_insert
(
hpteg
,
va
,
virt_to_abs
(
addr
)
>>
PAGE_SHIFT
,
vflags
,
tmp_mode
);
else
#endif
#ifdef CONFIG_PPC_PSERIES
if
(
systemcfg
->
platform
&
PLATFORM_LPAR
)
ret
=
pSeries_lpar_hpte_insert
(
hpteg
,
va
,
virt_to_abs
(
addr
)
>>
PAGE_SHIFT
,
vflags
,
tmp_mode
);
else
#endif
/* CONFIG_PPC_PSERIES */
#endif
#ifdef CONFIG_PPC_MULTIPLATFORM
ret
=
native_hpte_insert
(
hpteg
,
va
,
virt_to_abs
(
addr
)
>>
PAGE_SHIFT
,
vflags
,
tmp_mode
);
#endif
if
(
ret
==
-
1
)
{
ppc64_terminate_msg
(
0x20
,
"create_pte_mapping"
);
...
...
@@ -261,7 +269,6 @@ void __init htab_initialize(void)
}
#undef KB
#undef MB
#endif
/* CONFIG_PPC_MULTIPLATFORM */
/*
* Called by asm hashtable.S for doing lazy icache flush
...
...
include/asm-ppc64/mmu.h
View file @
51a0885e
...
...
@@ -206,6 +206,10 @@ extern long native_hpte_insert(unsigned long hpte_group, unsigned long va,
unsigned
long
prpn
,
unsigned
long
vflags
,
unsigned
long
rflags
);
extern
long
iSeries_hpte_bolt_or_insert
(
unsigned
long
hpte_group
,
unsigned
long
va
,
unsigned
long
prpn
,
unsigned
long
vflags
,
unsigned
long
rflags
);
extern
void
stabs_alloc
(
void
);
#endif
/* __ASSEMBLY__ */
...
...
include/asm-ppc64/processor.h
View file @
51a0885e
...
...
@@ -291,6 +291,7 @@
#define IC_OPEN_PIC 1
#define IC_PPC_XIC 2
#define IC_BPA_IIC 3
#define IC_ISERIES 4
#define XGLUE(a,b) a##b
#define GLUE(a,b) XGLUE(a,b)
...
...
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