Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Bricked
flo
Commits
6150c325
Commit
6150c325
authored
19 years ago
by
Linus Torvalds
Browse files
Options
Download
Plain Diff
Merge
git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
parents
44637a12
be42d5fa
Changes
287
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
4121 additions
and
369 deletions
+4121
-369
Documentation/filesystems/spufs.txt
Documentation/filesystems/spufs.txt
+521
-0
Documentation/powerpc/00-INDEX
Documentation/powerpc/00-INDEX
+8
-2
arch/powerpc/Kconfig
arch/powerpc/Kconfig
+24
-6
arch/powerpc/Makefile
arch/powerpc/Makefile
+1
-1
arch/powerpc/boot/Makefile
arch/powerpc/boot/Makefile
+30
-0
arch/powerpc/configs/pmac32_defconfig
arch/powerpc/configs/pmac32_defconfig
+1729
-0
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/Makefile
+10
-12
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/asm-offsets.c
+2
-4
arch/powerpc/kernel/btext.c
arch/powerpc/kernel/btext.c
+95
-41
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/cputable.c
+53
-53
arch/powerpc/kernel/crash.c
arch/powerpc/kernel/crash.c
+264
-0
arch/powerpc/kernel/crash_dump.c
arch/powerpc/kernel/crash_dump.c
+109
-0
arch/powerpc/kernel/dma_64.c
arch/powerpc/kernel/dma_64.c
+9
-0
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/entry_32.S
+96
-71
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/entry_64.S
+117
-101
arch/powerpc/kernel/head_32.S
arch/powerpc/kernel/head_32.S
+50
-6
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/head_64.S
+33
-8
arch/powerpc/kernel/ibmebus.c
arch/powerpc/kernel/ibmebus.c
+396
-0
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/irq.c
+17
-64
arch/powerpc/kernel/legacy_serial.c
arch/powerpc/kernel/legacy_serial.c
+557
-0
No files found.
Documentation/filesystems/spufs.txt
0 → 100644
View file @
6150c325
This diff is collapsed.
Click to expand it.
Documentation/powerpc/00-INDEX
View file @
6150c325
...
...
@@ -8,12 +8,18 @@ please mail me.
cpu_features.txt
- info on how we support a variety of CPUs with minimal compile-time
options.
eeh-pci-error-recovery.txt
- info on PCI Bus EEH Error Recovery
hvcs.txt
- IBM "Hypervisor Virtual Console Server" Installation Guide
mpc52xx.txt
- Linux 2.6.x on MPC52xx family
ppc_htab.txt
- info about the Linux/PPC /proc/ppc_htab entry
smp.txt
- use and state info about Linux/PPC on MP machines
SBC8260_memory_mapping.txt
- EST SBC8260 board info
smp.txt
- use and state info about Linux/PPC on MP machines
sound.txt
- info on sound support under Linux/PPC
zImage_layout.txt
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/Kconfig
View file @
6150c325
...
...
@@ -47,7 +47,7 @@ config PPC
config EARLY_PRINTK
bool
default y
if PPC64
default y
config COMPAT
bool
...
...
@@ -297,6 +297,7 @@ config PPC_PMAC64
bool
depends on PPC_PMAC && POWER4
select U3_DART
select MPIC_BROKEN_U3
select GENERIC_TBSYNC
default y
...
...
@@ -325,9 +326,7 @@ config PPC_CELL
select MMIO_NVRAM
config PPC_OF
bool
depends on PPC_MULTIPLATFORM # for now
default y
def_bool y
config XICS
depends on PPC_PSERIES
...
...
@@ -376,11 +375,28 @@ config CELL_IIC
bool
default y
config CRASH_DUMP
bool "kernel crash dumps (EXPERIMENTAL)"
depends on PPC_MULTIPLATFORM
depends on EXPERIMENTAL
help
Build a kernel suitable for use as a kdump capture kernel.
The kernel will be linked at a different address than normal, and
so can only be used for Kdump.
Don't change this unless you know what you are doing.
config IBMVIO
depends on PPC_PSERIES || PPC_ISERIES
bool
default y
config IBMEBUS
depends on PPC_PSERIES
bool "Support for GX bus based adapters"
help
Bus device driver for GX bus based adapters.
config PPC_MPC106
bool
default n
...
...
@@ -472,6 +488,7 @@ source arch/powerpc/platforms/embedded6xx/Kconfig
source arch/powerpc/platforms/4xx/Kconfig
source arch/powerpc/platforms/85xx/Kconfig
source arch/powerpc/platforms/8xx/Kconfig
source arch/powerpc/platforms/cell/Kconfig
menu "Kernel options"
...
...
@@ -575,11 +592,12 @@ config ARCH_SELECT_MEMORY_MODEL
depends on PPC64
config ARCH_FLATMEM_ENABLE
def_bool y
depends on PPC64 && !NUMA
def_bool y
depends on
(
PPC64 && !NUMA
) || PPC32
config ARCH_SPARSEMEM_ENABLE
def_bool y
depends on PPC64
config ARCH_SPARSEMEM_DEFAULT
def_bool y
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/Makefile
View file @
6150c325
...
...
@@ -151,7 +151,7 @@ CPPFLAGS_vmlinux.lds := -Upowerpc
# All the instructions talk about "make bzImage".
bzImage
:
zImage
BOOT_TARGETS
=
zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
BOOT_TARGETS
=
zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
uImage
.PHONY
:
$(BOOT_TARGETS)
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/boot/Makefile
View file @
6150c325
...
...
@@ -143,6 +143,36 @@ $(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote
@
cp
-f
$<
$@
$(
call
if_changed,addnote
)
#-----------------------------------------------------------
# build u-boot images
#-----------------------------------------------------------
quiet_cmd_mygzip
=
GZIP
$@
cmd_mygzip
=
gzip
-f
-9
<
$<
>
$@
.
$$$$
&&
mv
$@
.
$$$$
$@
quiet_cmd_objbin
=
OBJCOPY
$@
cmd_objbin
=
$(OBJCOPY)
-O
binary
$<
$@
quiet_cmd_uimage
=
UIMAGE
$@
cmd_uimage
=
$(CONFIG_SHELL)
$(MKIMAGE)
-A
ppc
-O
linux
-T
kernel
\
-C
gzip
-a
00000000
-e
00000000
-n
'Linux-
$(KERNELRELEASE)
'
\
-d
$<
$@
MKIMAGE
:=
$(srctree)
/scripts/mkuboot.sh
targets
+=
uImage
extra-y
+=
vmlinux.bin vmlinux.gz
$(obj)/vmlinux.bin
:
vmlinux FORCE
$(
call
if_changed,objbin
)
$(obj)/vmlinux.gz
:
$(obj)/vmlinux.bin FORCE
$(
call
if_changed,mygzip
)
$(obj)/uImage
:
$(obj)/vmlinux.gz
$(Q)
rm
-f
$@
$(
call
cmd,uimage
)
@
echo
-n
' Image: $@ '
@
if
[
-f
$@
]
;
then
echo
'is ready'
;
else
echo
'not made'
;
fi
install
:
$(CONFIGURE) $(BOOTIMAGE)
sh
-x
$(srctree)
/
$(src)
/install.sh
"
$(KERNELRELEASE)
"
vmlinux System.map
"
$(INSTALL_PATH)
"
"
$(BOOTIMAGE)
"
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/configs/pmac32_defconfig
0 → 100644
View file @
6150c325
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/Makefile
View file @
6150c325
...
...
@@ -17,11 +17,11 @@ obj-y += vdso32/
obj-$(CONFIG_PPC64)
+=
setup_64.o binfmt_elf32.o sys_ppc32.o
\
signal_64.o ptrace32.o systbl.o
\
paca.o ioctl32.o cpu_setup_power4.o
\
firmware.o sysfs.o
udbg.o
idle_64.o
firmware.o sysfs.o idle_64.o
obj-$(CONFIG_PPC64)
+=
vdso64/
obj-$(CONFIG_ALTIVEC)
+=
vecemu.o vector.o
obj-$(CONFIG_POWER4)
+=
idle_power4.o
obj-$(CONFIG_PPC_OF)
+=
of_device.o
obj-$(CONFIG_PPC_OF)
+=
of_device.o
prom_parse.o
procfs-$(CONFIG_PPC64)
:=
proc_ppc64.o
obj-$(CONFIG_PROC_FS)
+=
$
(
procfs-y
)
rtaspci-$(CONFIG_PPC64)
:=
rtas_pci.o
...
...
@@ -30,12 +30,10 @@ obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
obj-$(CONFIG_RTAS_PROC)
+=
rtas-proc.o
obj-$(CONFIG_LPARCFG)
+=
lparcfg.o
obj-$(CONFIG_IBMVIO)
+=
vio.o
obj-$(CONFIG_IBMEBUS)
+=
ibmebus.o
obj-$(CONFIG_GENERIC_TBSYNC)
+=
smp-tbsync.o
obj-$(CONFIG_PPC_PSERIES)
+=
udbg_16550.o
obj-$(CONFIG_PPC_MAPLE)
+=
udbg_16550.o
udbgscc-$(CONFIG_PPC64)
:=
udbg_scc.o
obj-$(CONFIG_PPC_PMAC)
+=
$
(
udbgscc-y
)
obj64-$(CONFIG_PPC_MULTIPLATFORM)
+=
nvram_64.o
obj-$(CONFIG_CRASH_DUMP)
+=
crash_dump.o
ifeq
($(CONFIG_PPC_MERGE),y)
...
...
@@ -48,25 +46,25 @@ extra-$(CONFIG_8xx) := head_8xx.o
extra-y
+=
vmlinux.lds
obj-y
+=
process.o init_task.o time.o
\
prom.o traps.o setup-common.o
prom.o traps.o setup-common.o
udbg.o
obj-$(CONFIG_PPC32)
+=
entry_32.o setup_32.o misc_32.o systbl.o
obj-$(CONFIG_PPC64)
+=
misc_64.o dma_64.o iommu.o
obj-$(CONFIG_PPC_
OF)
+=
prom_init.o
obj-$(CONFIG_PPC_
MULTIPLATFORM)
+=
prom_init.o
obj-$(CONFIG_MODULES)
+=
ppc_ksyms.o
obj-$(CONFIG_BOOTX_TEXT)
+=
btext.o
obj-$(CONFIG_6xx)
+=
idle_6xx.o
obj-$(CONFIG_SMP)
+=
smp.o
obj-$(CONFIG_KPROBES)
+=
kprobes.o
obj-$(CONFIG_SERIAL_8250)
+=
legacy_serial.o udbg_16550.o
module-$(CONFIG_PPC64)
+=
module_64.o
obj-$(CONFIG_MODULES)
+=
$
(
module-y
)
pci64-$(CONFIG_PPC64)
+=
pci_64.o pci_dn.o pci_iommu.o
\
pci_direct_iommu.o iomap.o
obj-$(CONFIG_PCI)
+=
$
(
pci64-y
)
kexec
64
-$(CONFIG_PPC
64
)
+
=
machine_kexec_
64
.o
obj-$(CONFIG_KEXEC)
+=
$
(
kexec
64
-y
)
kexec-$(CONFIG_PPC64)
:=
machine_kexec_64.o
kexec-$(CONFIG_PPC
32
)
:
=
machine_kexec_
32
.o
obj-$(CONFIG_KEXEC)
+=
machine_kexec.o crash.o
$
(
kexec-y
)
ifeq
($(CONFIG_PPC_ISERIES),y)
$(obj)/head_64.o
:
$(obj)/lparmap.s
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/asm-offsets.c
View file @
6150c325
...
...
@@ -92,9 +92,9 @@ int main(void)
DEFINE
(
TI_FLAGS
,
offsetof
(
struct
thread_info
,
flags
));
DEFINE
(
TI_PREEMPT
,
offsetof
(
struct
thread_info
,
preempt_count
));
DEFINE
(
TI_SC_NOERR
,
offsetof
(
struct
thread_info
,
syscall_noerror
));
#ifdef CONFIG_PPC32
DEFINE
(
TI_SIGFRAME
,
offsetof
(
struct
thread_info
,
nvgprs_frame
));
DEFINE
(
TI_TASK
,
offsetof
(
struct
thread_info
,
task
));
#ifdef CONFIG_PPC32
DEFINE
(
TI_EXECDOMAIN
,
offsetof
(
struct
thread_info
,
exec_domain
));
DEFINE
(
TI_CPU
,
offsetof
(
struct
thread_info
,
cpu
));
#endif
/* CONFIG_PPC32 */
...
...
@@ -131,11 +131,9 @@ int main(void)
DEFINE
(
PACALOWHTLBAREAS
,
offsetof
(
struct
paca_struct
,
context
.
low_htlb_areas
));
DEFINE
(
PACAHIGHHTLBAREAS
,
offsetof
(
struct
paca_struct
,
context
.
high_htlb_areas
));
#endif
/* CONFIG_HUGETLB_PAGE */
DEFINE
(
PACADEFAULTDECR
,
offsetof
(
struct
paca_struct
,
default_decr
));
DEFINE
(
PACA_EXGEN
,
offsetof
(
struct
paca_struct
,
exgen
));
DEFINE
(
PACA_EXMC
,
offsetof
(
struct
paca_struct
,
exmc
));
DEFINE
(
PACA_EXSLB
,
offsetof
(
struct
paca_struct
,
exslb
));
DEFINE
(
PACA_EXDSI
,
offsetof
(
struct
paca_struct
,
exdsi
));
DEFINE
(
PACAEMERGSP
,
offsetof
(
struct
paca_struct
,
emergency_sp
));
DEFINE
(
PACALPPACA
,
offsetof
(
struct
paca_struct
,
lppaca
));
DEFINE
(
PACAHWCPUID
,
offsetof
(
struct
paca_struct
,
hw_cpu_id
));
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/btext.c
View file @
6150c325
...
...
@@ -31,15 +31,18 @@ static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
static
void
draw_byte_16
(
unsigned
char
*
bits
,
unsigned
int
*
base
,
int
rb
);
static
void
draw_byte_8
(
unsigned
char
*
bits
,
unsigned
int
*
base
,
int
rb
);
static
int
g_loc_X
;
static
int
g_loc_Y
;
static
int
g_max_loc_X
;
static
int
g_max_loc_Y
;
#define __force_data __attribute__((__section__(".data")))
static
int
dispDeviceRowBytes
;
static
int
dispDeviceDepth
;
static
int
dispDeviceRect
[
4
];
static
unsigned
char
*
dispDeviceBase
,
*
logicalDisplayBase
;
static
int
g_loc_X
__force_data
;
static
int
g_loc_Y
__force_data
;
static
int
g_max_loc_X
__force_data
;
static
int
g_max_loc_Y
__force_data
;
static
int
dispDeviceRowBytes
__force_data
;
static
int
dispDeviceDepth
__force_data
;
static
int
dispDeviceRect
[
4
]
__force_data
;
static
unsigned
char
*
dispDeviceBase
__force_data
;
static
unsigned
char
*
logicalDisplayBase
__force_data
;
unsigned
long
disp_BAT
[
2
]
__initdata
=
{
0
,
0
};
...
...
@@ -47,7 +50,7 @@ unsigned long disp_BAT[2] __initdata = {0, 0};
static
unsigned
char
vga_font
[
cmapsz
];
int
boot_text_mapped
;
int
boot_text_mapped
__force_data
=
0
;
int
force_printk_to_btext
=
0
;
#ifdef CONFIG_PPC32
...
...
@@ -57,7 +60,7 @@ int force_printk_to_btext = 0;
*
* The display is mapped to virtual address 0xD0000000, rather
* than 1:1, because some some CHRP machines put the frame buffer
* in the region starting at 0xC0000000 (
KERNELBA
SE).
* in the region starting at 0xC0000000 (
PAGE_OFF
SE
T
).
* This mapping is temporary and will disappear as soon as the
* setup done by MMU_Init() is applied.
*
...
...
@@ -66,10 +69,9 @@ int force_printk_to_btext = 0;
* is really badly aligned, but I didn't encounter this case
* yet.
*/
void
__init
btext_prepare_BAT
(
void
)
void
__init
btext_prepare_BAT
(
void
)
{
unsigned
long
vaddr
=
KERNELBA
SE
+
0x10000000
;
unsigned
long
vaddr
=
PAGE_OFF
SE
T
+
0x10000000
;
unsigned
long
addr
;
unsigned
long
lowbits
;
...
...
@@ -95,12 +97,13 @@ btext_prepare_BAT(void)
}
#endif
/* This function will enable the early boot text when doing OF booting. This
* way, xmon output should work too
/* This function can be used to enable the early boot text when doing
* OF booting or within bootx init. It must be followed by a btext_unmap()
* call before the logical address becomes unuseable
*/
void
__init
btext_setup_display
(
int
width
,
int
height
,
int
depth
,
int
pitch
,
unsigned
long
address
)
void
__init
btext_setup_display
(
int
width
,
int
height
,
int
depth
,
int
pitch
,
unsigned
long
address
)
{
g_loc_X
=
0
;
g_loc_Y
=
0
;
...
...
@@ -116,6 +119,11 @@ btext_setup_display(int width, int height, int depth, int pitch,
boot_text_mapped
=
1
;
}
void
__init
btext_unmap
(
void
)
{
boot_text_mapped
=
0
;
}
/* Here's a small text engine to use during early boot
* or for debugging purposes
*
...
...
@@ -127,7 +135,7 @@ btext_setup_display(int width, int height, int depth, int pitch,
* changes.
*/
void
map_boot_text
(
void
)
static
void
map_boot_text
(
void
)
{
unsigned
long
base
,
offset
,
size
;
unsigned
char
*
vbase
;
...
...
@@ -175,8 +183,9 @@ int btext_initialize(struct device_node *np)
if
(
prop
)
address
=
*
prop
;
/* FIXME: Add support for PCI reg properties */
/* FIXME: Add support for PCI reg properties. Right now, only
* reliable on macs
*/
if
(
address
==
0
)
return
-
EINVAL
;
...
...
@@ -184,7 +193,6 @@ int btext_initialize(struct device_node *np)
g_loc_Y
=
0
;
g_max_loc_X
=
width
/
8
;
g_max_loc_Y
=
height
/
16
;
logicalDisplayBase
=
(
unsigned
char
*
)
address
;
dispDeviceBase
=
(
unsigned
char
*
)
address
;
dispDeviceRowBytes
=
pitch
;
dispDeviceDepth
=
depth
;
...
...
@@ -197,14 +205,12 @@ int btext_initialize(struct device_node *np)
return
0
;
}
void
__init
init_boot_display
(
void
)
int
__init
btext_find_display
(
int
allow_nonstdout
)
{
char
*
name
;
struct
device_node
*
np
=
NULL
;
int
rc
=
-
ENODEV
;
printk
(
"trying to initialize btext ...
\n
"
);
name
=
(
char
*
)
get_property
(
of_chosen
,
"linux,stdout-path"
,
NULL
);
if
(
name
!=
NULL
)
{
np
=
of_find_node_by_path
(
name
);
...
...
@@ -218,8 +224,8 @@ void __init init_boot_display(void)
}
if
(
np
)
rc
=
btext_initialize
(
np
);
if
(
rc
==
0
)
return
;
if
(
rc
==
0
||
!
allow_nonstdout
)
return
rc
;
for
(
np
=
NULL
;
(
np
=
of_find_node_by_type
(
np
,
"display"
));)
{
if
(
get_property
(
np
,
"linux,opened"
,
NULL
))
{
...
...
@@ -228,8 +234,9 @@ void __init init_boot_display(void)
printk
(
"result: %d
\n
"
,
rc
);
}
if
(
rc
==
0
)
re
turn
;
b
re
ak
;
}
return
rc
;
}
/* Calc the base address of a given point (x,y) */
...
...
@@ -277,44 +284,83 @@ EXPORT_SYMBOL(btext_update_display);
void
btext_clearscreen
(
void
)
{
unsigned
long
*
base
=
(
unsigned
long
*
)
calc_base
(
0
,
0
);
unsigned
int
*
base
=
(
unsigned
int
*
)
calc_base
(
0
,
0
);
unsigned
long
width
=
((
dispDeviceRect
[
2
]
-
dispDeviceRect
[
0
])
*
(
dispDeviceDepth
>>
3
))
>>
3
;
(
dispDeviceDepth
>>
3
))
>>
2
;
int
i
,
j
;
for
(
i
=
0
;
i
<
(
dispDeviceRect
[
3
]
-
dispDeviceRect
[
1
]);
i
++
)
{
unsigned
long
*
ptr
=
base
;
unsigned
int
*
ptr
=
base
;
for
(
j
=
width
;
j
;
--
j
)
*
(
ptr
++
)
=
0
;
base
+=
(
dispDeviceRowBytes
>>
3
);
base
+=
(
dispDeviceRowBytes
>>
2
);
}
}
void
btext_flushscreen
(
void
)
{
unsigned
int
*
base
=
(
unsigned
int
*
)
calc_base
(
0
,
0
);
unsigned
long
width
=
((
dispDeviceRect
[
2
]
-
dispDeviceRect
[
0
])
*
(
dispDeviceDepth
>>
3
))
>>
2
;
int
i
,
j
;
for
(
i
=
0
;
i
<
(
dispDeviceRect
[
3
]
-
dispDeviceRect
[
1
]);
i
++
)
{
unsigned
int
*
ptr
=
base
;
for
(
j
=
width
;
j
>
0
;
j
-=
8
)
{
__asm__
__volatile__
(
"dcbst 0,%0"
::
"r"
(
ptr
));
ptr
+=
8
;
}
base
+=
(
dispDeviceRowBytes
>>
2
);
}
__asm__
__volatile__
(
"sync"
:::
"memory"
);
}
void
btext_flushline
(
void
)
{
unsigned
int
*
base
=
(
unsigned
int
*
)
calc_base
(
0
,
g_loc_Y
<<
4
);
unsigned
long
width
=
((
dispDeviceRect
[
2
]
-
dispDeviceRect
[
0
])
*
(
dispDeviceDepth
>>
3
))
>>
2
;
int
i
,
j
;
for
(
i
=
0
;
i
<
16
;
i
++
)
{
unsigned
int
*
ptr
=
base
;
for
(
j
=
width
;
j
>
0
;
j
-=
8
)
{
__asm__
__volatile__
(
"dcbst 0,%0"
::
"r"
(
ptr
));
ptr
+=
8
;
}
base
+=
(
dispDeviceRowBytes
>>
2
);
}
__asm__
__volatile__
(
"sync"
:::
"memory"
);
}
#ifndef NO_SCROLL
static
void
scrollscreen
(
void
)
{
unsigned
long
*
src
=
(
unsigned
long
*
)
calc_base
(
0
,
16
);
unsigned
long
*
dst
=
(
unsigned
long
*
)
calc_base
(
0
,
0
);
unsigned
int
*
src
=
(
unsigned
int
*
)
calc_base
(
0
,
16
);
unsigned
int
*
dst
=
(
unsigned
int
*
)
calc_base
(
0
,
0
);
unsigned
long
width
=
((
dispDeviceRect
[
2
]
-
dispDeviceRect
[
0
])
*
(
dispDeviceDepth
>>
3
))
>>
3
;
(
dispDeviceDepth
>>
3
))
>>
2
;
int
i
,
j
;
for
(
i
=
0
;
i
<
(
dispDeviceRect
[
3
]
-
dispDeviceRect
[
1
]
-
16
);
i
++
)
{
unsigned
long
*
src_ptr
=
src
;
unsigned
long
*
dst_ptr
=
dst
;
unsigned
int
*
src_ptr
=
src
;
unsigned
int
*
dst_ptr
=
dst
;
for
(
j
=
width
;
j
;
--
j
)
*
(
dst_ptr
++
)
=
*
(
src_ptr
++
);
src
+=
(
dispDeviceRowBytes
>>
3
);
dst
+=
(
dispDeviceRowBytes
>>
3
);
src
+=
(
dispDeviceRowBytes
>>
2
);
dst
+=
(
dispDeviceRowBytes
>>
2
);
}
for
(
i
=
0
;
i
<
16
;
i
++
)
{
unsigned
long
*
dst_ptr
=
dst
;
unsigned
int
*
dst_ptr
=
dst
;
for
(
j
=
width
;
j
;
--
j
)
*
(
dst_ptr
++
)
=
0
;
dst
+=
(
dispDeviceRowBytes
>>
3
);
dst
+=
(
dispDeviceRowBytes
>>
2
);
}
}
#endif
/* ndef NO_SCROLL */
...
...
@@ -377,6 +423,14 @@ void btext_drawstring(const char *c)
btext_drawchar
(
*
c
++
);
}
void
btext_drawtext
(
const
char
*
c
,
unsigned
int
len
)
{
if
(
!
boot_text_mapped
)
return
;
while
(
len
--
)
btext_drawchar
(
*
c
++
);
}
void
btext_drawhex
(
unsigned
long
v
)
{
char
*
hex_table
=
"0123456789abcdef"
;
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/cputable.c
View file @
6150c325
...
...
@@ -78,10 +78,8 @@ struct cpu_spec cpu_specs[] = {
.
dcache_bsize
=
128
,
.
num_pmcs
=
8
,
.
cpu_setup
=
__setup_cpu_power3
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/power3"
,
.
oprofile_model
=
&
op_model_rs64
,
#endif
.
oprofile_type
=
RS64
,
},
{
/* Power3+ */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -93,10 +91,8 @@ struct cpu_spec cpu_specs[] = {
.
dcache_bsize
=
128
,
.
num_pmcs
=
8
,
.
cpu_setup
=
__setup_cpu_power3
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/power3"
,
.
oprofile_model
=
&
op_model_rs64
,
#endif
.
oprofile_type
=
RS64
,
},
{
/* Northstar */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -108,10 +104,8 @@ struct cpu_spec cpu_specs[] = {
.
dcache_bsize
=
128
,
.
num_pmcs
=
8
,
.
cpu_setup
=
__setup_cpu_power3
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/rs64"
,
.
oprofile_model
=
&
op_model_rs64
,
#endif
.
oprofile_type
=
RS64
,
},
{
/* Pulsar */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -123,10 +117,8 @@ struct cpu_spec cpu_specs[] = {
.
dcache_bsize
=
128
,
.
num_pmcs
=
8
,
.
cpu_setup
=
__setup_cpu_power3
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/rs64"
,
.
oprofile_model
=
&
op_model_rs64
,
#endif
.
oprofile_type
=
RS64
,
},
{
/* I-star */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -138,10 +130,8 @@ struct cpu_spec cpu_specs[] = {
.
dcache_bsize
=
128
,
.
num_pmcs
=
8
,
.
cpu_setup
=
__setup_cpu_power3
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/rs64"
,
.
oprofile_model
=
&
op_model_rs64
,
#endif
.
oprofile_type
=
RS64
,
},
{
/* S-star */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -153,10 +143,8 @@ struct cpu_spec cpu_specs[] = {
.
dcache_bsize
=
128
,
.
num_pmcs
=
8
,
.
cpu_setup
=
__setup_cpu_power3
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/rs64"
,
.
oprofile_model
=
&
op_model_rs64
,
#endif
.
oprofile_type
=
RS64
,
},
{
/* Power4 */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -168,10 +156,8 @@ struct cpu_spec cpu_specs[] = {
.
dcache_bsize
=
128
,
.
num_pmcs
=
8
,
.
cpu_setup
=
__setup_cpu_power4
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/power4"
,
.
oprofile_model
=
&
op_model_rs64
,
#endif
.
oprofile_type
=
POWER4
,
},
{
/* Power4+ */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -183,10 +169,8 @@ struct cpu_spec cpu_specs[] = {
.
dcache_bsize
=
128
,
.
num_pmcs
=
8
,
.
cpu_setup
=
__setup_cpu_power4
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/power4"
,
.
oprofile_model
=
&
op_model_power4
,
#endif
.
oprofile_type
=
POWER4
,
},
{
/* PPC970 */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -199,10 +183,8 @@ struct cpu_spec cpu_specs[] = {
.
dcache_bsize
=
128
,
.
num_pmcs
=
8
,
.
cpu_setup
=
__setup_cpu_ppc970
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/970"
,
.
oprofile_model
=
&
op_model_power4
,
#endif
.
oprofile_type
=
POWER4
,
},
#endif
/* CONFIG_PPC64 */
#if defined(CONFIG_PPC64) || defined(CONFIG_POWER4)
...
...
@@ -221,10 +203,8 @@ struct cpu_spec cpu_specs[] = {
.
dcache_bsize
=
128
,
.
num_pmcs
=
8
,
.
cpu_setup
=
__setup_cpu_ppc970
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/970"
,
.
oprofile_model
=
&
op_model_power4
,
#endif
.
oprofile_type
=
POWER4
,
},
#endif
/* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */
#ifdef CONFIG_PPC64
...
...
@@ -238,10 +218,8 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
128
,
.
dcache_bsize
=
128
,
.
cpu_setup
=
__setup_cpu_ppc970
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/970"
,
.
oprofile_model
=
&
op_model_power4
,
#endif
.
oprofile_type
=
POWER4
,
},
{
/* Power5 GR */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -253,27 +231,23 @@ struct cpu_spec cpu_specs[] = {
.
dcache_bsize
=
128
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_power4
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/power5"
,
.
oprofile_model
=
&
op_model_power4
,
#endif
.
oprofile_type
=
POWER4
,
},
{
/* Power5 GS */
.
pvr_mask
=
0xffff0000
,
.
pvr_value
=
0x003b0000
,
.
cpu_name
=
"POWER5 (gs)"
,
.
cpu_name
=
"POWER5
+
(gs)"
,
.
cpu_features
=
CPU_FTRS_POWER5
,
.
cpu_user_features
=
COMMON_USER_POWER5_PLUS
,
.
icache_bsize
=
128
,
.
dcache_bsize
=
128
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_power4
,
#ifdef CONFIG_OPROFILE
.
oprofile_cpu_type
=
"ppc64/power5"
,
.
oprofile_model
=
&
op_model_power4
,
#endif
.
oprofile_cpu_type
=
"ppc64/power5+"
,
.
oprofile_type
=
POWER4
,
},
{
/*
BE DD1.x
*/
{
/*
Cell Broadband Engine
*/
.
pvr_mask
=
0xffff0000
,
.
pvr_value
=
0x00700000
,
.
cpu_name
=
"Cell Broadband Engine"
,
...
...
@@ -545,7 +519,9 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_745x
.
cpu_setup
=
__setup_cpu_745x
,
.
oprofile_cpu_type
=
"ppc/7450"
,
.
oprofile_type
=
G4
,
},
{
/* 7450 2.1 */
.
pvr_mask
=
0xffffffff
,
...
...
@@ -556,7 +532,9 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_745x
.
cpu_setup
=
__setup_cpu_745x
,
.
oprofile_cpu_type
=
"ppc/7450"
,
.
oprofile_type
=
G4
,
},
{
/* 7450 2.3 and newer */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -567,7 +545,9 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_745x
.
cpu_setup
=
__setup_cpu_745x
,
.
oprofile_cpu_type
=
"ppc/7450"
,
.
oprofile_type
=
G4
,
},
{
/* 7455 rev 1.x */
.
pvr_mask
=
0xffffff00
,
...
...
@@ -578,7 +558,9 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_745x
.
cpu_setup
=
__setup_cpu_745x
,
.
oprofile_cpu_type
=
"ppc/7450"
,
.
oprofile_type
=
G4
,
},
{
/* 7455 rev 2.0 */
.
pvr_mask
=
0xffffffff
,
...
...
@@ -589,7 +571,9 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_745x
.
cpu_setup
=
__setup_cpu_745x
,
.
oprofile_cpu_type
=
"ppc/7450"
,
.
oprofile_type
=
G4
,
},
{
/* 7455 others */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -600,7 +584,9 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_745x
.
cpu_setup
=
__setup_cpu_745x
,
.
oprofile_cpu_type
=
"ppc/7450"
,
.
oprofile_type
=
G4
,
},
{
/* 7447/7457 Rev 1.0 */
.
pvr_mask
=
0xffffffff
,
...
...
@@ -611,7 +597,9 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_745x
.
cpu_setup
=
__setup_cpu_745x
,
.
oprofile_cpu_type
=
"ppc/7450"
,
.
oprofile_type
=
G4
,
},
{
/* 7447/7457 Rev 1.1 */
.
pvr_mask
=
0xffffffff
,
...
...
@@ -622,7 +610,9 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_745x
.
cpu_setup
=
__setup_cpu_745x
,
.
oprofile_cpu_type
=
"ppc/7450"
,
.
oprofile_type
=
G4
,
},
{
/* 7447/7457 Rev 1.2 and later */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -633,7 +623,9 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_745x
.
cpu_setup
=
__setup_cpu_745x
,
.
oprofile_cpu_type
=
"ppc/7450"
,
.
oprofile_type
=
G4
,
},
{
/* 7447A */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -644,7 +636,9 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_745x
.
cpu_setup
=
__setup_cpu_745x
,
.
oprofile_cpu_type
=
"ppc/7450"
,
.
oprofile_type
=
G4
,
},
{
/* 7448 */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -655,7 +649,9 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
6
,
.
cpu_setup
=
__setup_cpu_745x
.
cpu_setup
=
__setup_cpu_745x
,
.
oprofile_cpu_type
=
"ppc/7450"
,
.
oprofile_type
=
G4
,
},
{
/* 82xx (8240, 8245, 8260 are all 603e cores) */
.
pvr_mask
=
0x7fff0000
,
...
...
@@ -979,6 +975,8 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
4
,
.
oprofile_cpu_type
=
"ppc/e500"
,
.
oprofile_type
=
BOOKE
,
},
{
/* e500v2 */
.
pvr_mask
=
0xffff0000
,
...
...
@@ -992,6 +990,8 @@ struct cpu_spec cpu_specs[] = {
.
icache_bsize
=
32
,
.
dcache_bsize
=
32
,
.
num_pmcs
=
4
,
.
oprofile_cpu_type
=
"ppc/e500"
,
.
oprofile_type
=
BOOKE
,
},
#endif
#if !CLASSIC_PPC
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/crash.c
0 → 100644
View file @
6150c325
/*
* Architecture specific (PPC64) functions for kexec based crash dumps.
*
* Copyright (C) 2005, IBM Corp.
*
* Created by: Haren Myneni
*
* This source code is licensed under the GNU General Public License,
* Version 2. See the file COPYING for more details.
*
*/
#undef DEBUG
#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/reboot.h>
#include <linux/kexec.h>
#include <linux/bootmem.h>
#include <linux/crash_dump.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
#include <linux/init.h>
#include <linux/types.h>
#include <asm/processor.h>
#include <asm/machdep.h>
#include <asm/kdump.h>
#include <asm/lmb.h>
#include <asm/firmware.h>
#ifdef DEBUG
#include <asm/udbg.h>
#define DBG(fmt...) udbg_printf(fmt)
#else
#define DBG(fmt...)
#endif
/* This keeps a track of which one is crashing cpu. */
int
crashing_cpu
=
-
1
;
static
u32
*
append_elf_note
(
u32
*
buf
,
char
*
name
,
unsigned
type
,
void
*
data
,
size_t
data_len
)
{
struct
elf_note
note
;
note
.
n_namesz
=
strlen
(
name
)
+
1
;
note
.
n_descsz
=
data_len
;
note
.
n_type
=
type
;
memcpy
(
buf
,
&
note
,
sizeof
(
note
));
buf
+=
(
sizeof
(
note
)
+
3
)
/
4
;
memcpy
(
buf
,
name
,
note
.
n_namesz
);
buf
+=
(
note
.
n_namesz
+
3
)
/
4
;
memcpy
(
buf
,
data
,
note
.
n_descsz
);
buf
+=
(
note
.
n_descsz
+
3
)
/
4
;
return
buf
;
}
static
void
final_note
(
u32
*
buf
)
{
struct
elf_note
note
;
note
.
n_namesz
=
0
;
note
.
n_descsz
=
0
;
note
.
n_type
=
0
;
memcpy
(
buf
,
&
note
,
sizeof
(
note
));
}
static
void
crash_save_this_cpu
(
struct
pt_regs
*
regs
,
int
cpu
)
{
struct
elf_prstatus
prstatus
;
u32
*
buf
;
if
((
cpu
<
0
)
||
(
cpu
>=
NR_CPUS
))
return
;
/* Using ELF notes here is opportunistic.
* I need a well defined structure format
* for the data I pass, and I need tags
* on the data to indicate what information I have
* squirrelled away. ELF notes happen to provide
* all of that that no need to invent something new.
*/
buf
=
&
crash_notes
[
cpu
][
0
];
memset
(
&
prstatus
,
0
,
sizeof
(
prstatus
));
prstatus
.
pr_pid
=
current
->
pid
;
elf_core_copy_regs
(
&
prstatus
.
pr_reg
,
regs
);
buf
=
append_elf_note
(
buf
,
"CORE"
,
NT_PRSTATUS
,
&
prstatus
,
sizeof
(
prstatus
));
final_note
(
buf
);
}
/* FIXME Merge this with xmon_save_regs ?? */
static
inline
void
crash_get_current_regs
(
struct
pt_regs
*
regs
)
{
unsigned
long
tmp1
,
tmp2
;
__asm__
__volatile__
(
"std 0,0(%2)
\n
"
"std 1,8(%2)
\n
"
"std 2,16(%2)
\n
"
"std 3,24(%2)
\n
"
"std 4,32(%2)
\n
"
"std 5,40(%2)
\n
"
"std 6,48(%2)
\n
"
"std 7,56(%2)
\n
"
"std 8,64(%2)
\n
"
"std 9,72(%2)
\n
"
"std 10,80(%2)
\n
"
"std 11,88(%2)
\n
"
"std 12,96(%2)
\n
"
"std 13,104(%2)
\n
"
"std 14,112(%2)
\n
"
"std 15,120(%2)
\n
"
"std 16,128(%2)
\n
"
"std 17,136(%2)
\n
"
"std 18,144(%2)
\n
"
"std 19,152(%2)
\n
"
"std 20,160(%2)
\n
"
"std 21,168(%2)
\n
"
"std 22,176(%2)
\n
"
"std 23,184(%2)
\n
"
"std 24,192(%2)
\n
"
"std 25,200(%2)
\n
"
"std 26,208(%2)
\n
"
"std 27,216(%2)
\n
"
"std 28,224(%2)
\n
"
"std 29,232(%2)
\n
"
"std 30,240(%2)
\n
"
"std 31,248(%2)
\n
"
"mfmsr %0
\n
"
"std %0, 264(%2)
\n
"
"mfctr %0
\n
"
"std %0, 280(%2)
\n
"
"mflr %0
\n
"
"std %0, 288(%2)
\n
"
"bl 1f
\n
"
"1: mflr %1
\n
"
"std %1, 256(%2)
\n
"
"mtlr %0
\n
"
"mfxer %0
\n
"
"std %0, 296(%2)
\n
"
:
"=&r"
(
tmp1
),
"=&r"
(
tmp2
)
:
"b"
(
regs
));
}
/* We may have saved_regs from where the error came from
* or it is NULL if via a direct panic().
*/
static
void
crash_save_self
(
struct
pt_regs
*
saved_regs
)
{
struct
pt_regs
regs
;
int
cpu
;
cpu
=
smp_processor_id
();
if
(
saved_regs
)
memcpy
(
&
regs
,
saved_regs
,
sizeof
(
regs
));
else
crash_get_current_regs
(
&
regs
);
crash_save_this_cpu
(
&
regs
,
cpu
);
}
#ifdef CONFIG_SMP
static
atomic_t
waiting_for_crash_ipi
;
void
crash_ipi_callback
(
struct
pt_regs
*
regs
)
{
int
cpu
=
smp_processor_id
();
if
(
cpu
==
crashing_cpu
)
return
;
if
(
!
cpu_online
(
cpu
))
return
;
if
(
ppc_md
.
kexec_cpu_down
)
ppc_md
.
kexec_cpu_down
(
1
,
1
);
local_irq_disable
();
crash_save_this_cpu
(
regs
,
cpu
);
atomic_dec
(
&
waiting_for_crash_ipi
);
kexec_smp_wait
();
/* NOTREACHED */
}
static
void
crash_kexec_prepare_cpus
(
void
)
{
unsigned
int
msecs
;
atomic_set
(
&
waiting_for_crash_ipi
,
num_online_cpus
()
-
1
);
crash_send_ipi
(
crash_ipi_callback
);
smp_wmb
();
/*
* FIXME: Until we will have the way to stop other CPUSs reliabally,
* the crash CPU will send an IPI and wait for other CPUs to
* respond. If not, proceed the kexec boot even though we failed to
* capture other CPU states.
*/
msecs
=
1000000
;
while
((
atomic_read
(
&
waiting_for_crash_ipi
)
>
0
)
&&
(
--
msecs
>
0
))
{
barrier
();
mdelay
(
1
);
}
/* Would it be better to replace the trap vector here? */
/*
* FIXME: In case if we do not get all CPUs, one possibility: ask the
* user to do soft reset such that we get all.
* IPI handler is already set by the panic cpu initially. Therefore,
* all cpus could invoke this handler from die() and the panic CPU
* will call machine_kexec() directly from this handler to do
* kexec boot.
*/
if
(
atomic_read
(
&
waiting_for_crash_ipi
))
printk
(
KERN_ALERT
"done waiting: %d cpus not responding
\n
"
,
atomic_read
(
&
waiting_for_crash_ipi
));
/* Leave the IPI callback set */
}
#else
static
void
crash_kexec_prepare_cpus
(
void
)
{
/*
* move the secondarys to us so that we can copy
* the new kernel 0-0x100 safely
*
* do this if kexec in setup.c ?
*/
smp_release_cpus
();
}
#endif
void
default_machine_crash_shutdown
(
struct
pt_regs
*
regs
)
{
/*
* This function is only called after the system
* has paniced or is otherwise in a critical state.
* The minimum amount of code to allow a kexec'd kernel
* to run successfully needs to happen here.
*
* In practice this means stopping other cpus in
* an SMP system.
* The kernel is broken so disable interrupts.
*/
local_irq_disable
();
if
(
ppc_md
.
kexec_cpu_down
)
ppc_md
.
kexec_cpu_down
(
1
,
0
);
/*
* Make a note of crashing cpu. Will be used in machine_kexec
* such that another IPI will not be sent.
*/
crashing_cpu
=
smp_processor_id
();
crash_kexec_prepare_cpus
();
crash_save_self
(
regs
);
}
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/crash_dump.c
0 → 100644
View file @
6150c325
/*
* Routines for doing kexec-based kdump.
*
* Copyright (C) 2005, IBM Corp.
*
* Created by: Michael Ellerman
*
* This source code is licensed under the GNU General Public License,
* Version 2. See the file COPYING for more details.
*/
#undef DEBUG
#include <linux/crash_dump.h>
#include <linux/bootmem.h>
#include <asm/kdump.h>
#include <asm/lmb.h>
#include <asm/firmware.h>
#include <asm/uaccess.h>
#ifdef DEBUG
#include <asm/udbg.h>
#define DBG(fmt...) udbg_printf(fmt)
#else
#define DBG(fmt...)
#endif
static
void
__init
create_trampoline
(
unsigned
long
addr
)
{
/* The maximum range of a single instruction branch, is the current
* instruction's address + (32 MB - 4) bytes. For the trampoline we
* need to branch to current address + 32 MB. So we insert a nop at
* the trampoline address, then the next instruction (+ 4 bytes)
* does a branch to (32 MB - 4). The net effect is that when we
* branch to "addr" we jump to ("addr" + 32 MB). Although it requires
* two instructions it doesn't require any registers.
*/
create_instruction
(
addr
,
0x60000000
);
/* nop */
create_branch
(
addr
+
4
,
addr
+
PHYSICAL_START
,
0
);
}
void
__init
kdump_setup
(
void
)
{
unsigned
long
i
;
DBG
(
" -> kdump_setup()
\n
"
);
for
(
i
=
KDUMP_TRAMPOLINE_START
;
i
<
KDUMP_TRAMPOLINE_END
;
i
+=
8
)
{
create_trampoline
(
i
);
}
create_trampoline
(
__pa
(
system_reset_fwnmi
)
-
PHYSICAL_START
);
create_trampoline
(
__pa
(
machine_check_fwnmi
)
-
PHYSICAL_START
);
DBG
(
" <- kdump_setup()
\n
"
);
}
static
int
__init
parse_elfcorehdr
(
char
*
p
)
{
if
(
p
)
elfcorehdr_addr
=
memparse
(
p
,
&
p
);
return
0
;
}
__setup
(
"elfcorehdr="
,
parse_elfcorehdr
);
static
int
__init
parse_savemaxmem
(
char
*
p
)
{
if
(
p
)
saved_max_pfn
=
(
memparse
(
p
,
&
p
)
>>
PAGE_SHIFT
)
-
1
;
return
0
;
}
__setup
(
"savemaxmem="
,
parse_savemaxmem
);
/*
* copy_oldmem_page - copy one page from "oldmem"
* @pfn: page frame number to be copied
* @buf: target memory address for the copy; this can be in kernel address
* space or user address space (see @userbuf)
* @csize: number of bytes to copy
* @offset: offset in bytes into the page (based on pfn) to begin the copy
* @userbuf: if set, @buf is in user address space, use copy_to_user(),
* otherwise @buf is in kernel address space, use memcpy().
*
* Copy a page from "oldmem". For this page, there is no pte mapped
* in the current kernel. We stitch up a pte, similar to kmap_atomic.
*/
ssize_t
copy_oldmem_page
(
unsigned
long
pfn
,
char
*
buf
,
size_t
csize
,
unsigned
long
offset
,
int
userbuf
)
{
void
*
vaddr
;
if
(
!
csize
)
return
0
;
vaddr
=
__ioremap
(
pfn
<<
PAGE_SHIFT
,
PAGE_SIZE
,
0
);
if
(
userbuf
)
{
if
(
copy_to_user
((
char
__user
*
)
buf
,
(
vaddr
+
offset
),
csize
))
{
iounmap
(
vaddr
);
return
-
EFAULT
;
}
}
else
memcpy
(
buf
,
(
vaddr
+
offset
),
csize
);
iounmap
(
vaddr
);
return
csize
;
}
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/dma_64.c
View file @
6150c325
...
...
@@ -10,6 +10,7 @@
/* Include the busses we support */
#include <linux/pci.h>
#include <asm/vio.h>
#include <asm/ibmebus.h>
#include <asm/scatterlist.h>
#include <asm/bug.h>
...
...
@@ -22,6 +23,10 @@ static struct dma_mapping_ops *get_dma_ops(struct device *dev)
#ifdef CONFIG_IBMVIO
if
(
dev
->
bus
==
&
vio_bus_type
)
return
&
vio_dma_ops
;
#endif
#ifdef CONFIG_IBMEBUS
if
(
dev
->
bus
==
&
ibmebus_bus_type
)
return
&
ibmebus_dma_ops
;
#endif
return
NULL
;
}
...
...
@@ -47,6 +52,10 @@ int dma_set_mask(struct device *dev, u64 dma_mask)
if
(
dev
->
bus
==
&
vio_bus_type
)
return
-
EIO
;
#endif
/* CONFIG_IBMVIO */
#ifdef CONFIG_IBMEBUS
if
(
dev
->
bus
==
&
ibmebus_bus_type
)
return
-
EIO
;
#endif
BUG
();
return
0
;
}
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/entry_32.S
View file @
6150c325
...
...
@@ -200,8 +200,6 @@ _GLOBAL(DoSyscall)
bl
do_show_syscall
#endif /* SHOW_SYSCALLS */
rlwinm
r10
,
r1
,
0
,
0
,(
31
-
THREAD_SHIFT
)
/*
current_thread_info
()
*/
li
r11
,
0
stb
r11
,
TI_SC_NOERR
(
r10
)
lwz
r11
,
TI_FLAGS
(
r10
)
andi
.
r11
,
r11
,
_TIF_SYSCALL_T_OR_A
bne
-
syscall_dotrace
...
...
@@ -222,25 +220,21 @@ ret_from_syscall:
bl
do_show_syscall_exit
#endif
mr
r6
,
r3
li
r11
,-
_LAST_ERRNO
cmplw
0
,
r3
,
r11
rlwinm
r12
,
r1
,
0
,
0
,(
31
-
THREAD_SHIFT
)
/*
current_thread_info
()
*/
blt
+
30
f
lbz
r11
,
TI_SC_NOERR
(
r12
)
cmpwi
r11
,
0
bne
30
f
neg
r3
,
r3
lwz
r10
,
_CCR
(
r1
)
/*
Set
SO
bit
in
CR
*/
oris
r10
,
r10
,
0x1000
stw
r10
,
_CCR
(
r1
)
/
*
disable
interrupts
so
current_thread_info
()->
flags
can
't change */
30
:
LOAD_MSR_KERNEL
(
r10
,
MSR_KERNEL
)
/*
doesn
't include MSR_EE */
LOAD_MSR_KERNEL
(
r10
,
MSR_KERNEL
)
/*
doesn
't include MSR_EE */
SYNC
MTMSRD
(
r10
)
lwz
r9
,
TI_FLAGS
(
r12
)
andi
.
r0
,
r9
,(
_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED
)
li
r8
,-
_LAST_ERRNO
andi
.
r0
,
r9
,(
_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED
|
_TIF_RESTOREALL
)
bne
-
syscall_exit_work
cmplw
0
,
r3
,
r8
blt
+
syscall_exit_cont
lwz
r11
,
_CCR
(
r1
)
/*
Load
CR
*/
neg
r3
,
r3
oris
r11
,
r11
,
0x1000
/*
Set
SO
bit
in
CR
*/
stw
r11
,
_CCR
(
r1
)
syscall_exit_cont
:
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
/
*
If
the
process
has
its
own
DBCR0
value
,
load
it
up
.
The
single
...
...
@@ -292,46 +286,113 @@ syscall_dotrace:
b
syscall_dotrace_cont
syscall_exit_work
:
stw
r6
,
RESULT
(
r1
)
/*
Save
result
*/
andi
.
r0
,
r9
,
_TIF_RESTOREALL
bne
-
2
f
cmplw
0
,
r3
,
r8
blt
+
1
f
andi
.
r0
,
r9
,
_TIF_NOERROR
bne
-
1
f
lwz
r11
,
_CCR
(
r1
)
/*
Load
CR
*/
neg
r3
,
r3
oris
r11
,
r11
,
0x1000
/*
Set
SO
bit
in
CR
*/
stw
r11
,
_CCR
(
r1
)
1
:
stw
r6
,
RESULT
(
r1
)
/*
Save
result
*/
stw
r3
,
GPR3
(
r1
)
/*
Update
return
value
*/
andi
.
r0
,
r9
,
_TIF_SYSCALL_T_OR_A
beq
5
f
ori
r10
,
r10
,
MSR_EE
SYNC
MTMSRD
(
r10
)
/*
re
-
enable
interrupts
*/
2
:
andi
.
r0
,
r9
,(
_TIF_PERSYSCALL_MASK
)
beq
4
f
/
*
Clear
per
-
syscall
TIF
flags
if
any
are
set
,
but
_leave_
_TIF_SAVE_NVGPRS
set
in
r9
since
we
haven
't dealt with that
yet
.
*/
li
r11
,
_TIF_PERSYSCALL_MASK
addi
r12
,
r12
,
TI_FLAGS
3
:
lwarx
r8
,
0
,
r12
andc
r8
,
r8
,
r11
#ifdef CONFIG_IBM405_ERR77
dcbt
0
,
r12
#endif
stwcx
.
r8
,
0
,
r12
bne
-
3
b
subi
r12
,
r12
,
TI_FLAGS
4
:
/
*
Anything
which
requires
enabling
interrupts
?
*/
andi
.
r0
,
r9
,(
_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS
)
beq
7
f
/
*
Save
NVGPRS
if
they
're not saved already */
lwz
r4
,
_TRAP
(
r1
)
andi
.
r4
,
r4
,
1
beq
4
f
beq
5
f
SAVE_NVGPRS
(
r1
)
li
r4
,
0xc00
stw
r4
,
_TRAP
(
r1
)
4
:
/
*
Re
-
enable
interrupts
*/
5
:
ori
r10
,
r10
,
MSR_EE
SYNC
MTMSRD
(
r10
)
andi
.
r0
,
r9
,
_TIF_SAVE_NVGPRS
bne
save_user_nvgprs
save_user_nvgprs_cont
:
andi
.
r0
,
r9
,(
_TIF_SYSCALL_T_OR_A
|
_TIF_SINGLESTEP
)
beq
7
f
addi
r3
,
r1
,
STACK_FRAME_OVERHEAD
bl
do_syscall_trace_leave
REST_NVGPRS
(
r1
)
2
:
lwz
r3
,
GPR3
(
r1
)
6
:
lwz
r3
,
GPR3
(
r1
)
LOAD_MSR_KERNEL
(
r10
,
MSR_KERNEL
)
/*
doesn
't include MSR_EE */
SYNC
MTMSRD
(
r10
)
/*
disable
interrupts
again
*/
rlwinm
r12
,
r1
,
0
,
0
,(
31
-
THREAD_SHIFT
)
/*
current_thread_info
()
*/
lwz
r9
,
TI_FLAGS
(
r12
)
5
:
7
:
andi
.
r0
,
r9
,
_TIF_NEED_RESCHED
bne
1
f
bne
8
f
lwz
r5
,
_MSR
(
r1
)
andi
.
r5
,
r5
,
MSR_PR
beq
syscall_exit_con
t
beq
ret_from_excep
t
andi
.
r0
,
r9
,
_TIF_SIGPENDING
beq
syscall_exit_con
t
beq
ret_from_excep
t
b
do_user_signal
1
:
8
:
ori
r10
,
r10
,
MSR_EE
SYNC
MTMSRD
(
r10
)
/*
re
-
enable
interrupts
*/
bl
schedule
b
2
b
b
6
b
save_user_nvgprs
:
lwz
r8
,
TI_SIGFRAME
(
r12
)
.
macro
savewords
start
,
end
1:
stw
\
start
,
4
*(
\
start
)(
r8
)
.
section
__ex_table
,
"a"
.
align
2
.
long
1
b
,
save_user_nvgprs_fault
.
previous
.
if
\
end
-
\
start
savewords
"(\start+1)"
,
\
end
.
endif
.
endm
savewords
14
,
31
b
save_user_nvgprs_cont
save_user_nvgprs_fault
:
li
r3
,
11
/*
SIGSEGV
*/
lwz
r4
,
TI_TASK
(
r12
)
bl
force_sigsegv
rlwinm
r12
,
r1
,
0
,
0
,(
31
-
THREAD_SHIFT
)
/*
current_thread_info
()
*/
lwz
r9
,
TI_FLAGS
(
r12
)
b
save_user_nvgprs_cont
#ifdef SHOW_SYSCALLS
do_show_syscall
:
#ifdef SHOW_SYSCALLS_TASK
...
...
@@ -401,28 +462,10 @@ show_syscalls_task:
#endif /* SHOW_SYSCALLS */
/*
*
The
sigsuspend
and
rt_sigsuspend
system
calls
can
call
do_signal
*
and
thus
put
the
process
into
the
stopped
state
where
we
might
*
want
to
examine
its
user
state
with
ptrace
.
Therefore
we
need
*
to
save
all
the
nonvolatile
registers
(
r13
-
r31
)
before
calling
*
the
C
code
.
*
The
fork
/
clone
functions
need
to
copy
the
full
register
set
into
*
the
child
process
.
Therefore
we
need
to
save
all
the
nonvolatile
*
registers
(
r13
-
r31
)
before
calling
the
C
code
.
*/
.
globl
ppc_sigsuspend
ppc_sigsuspend
:
SAVE_NVGPRS
(
r1
)
lwz
r0
,
_TRAP
(
r1
)
rlwinm
r0
,
r0
,
0
,
0
,
30
/*
clear
LSB
to
indicate
full
*/
stw
r0
,
_TRAP
(
r1
)
/*
register
set
saved
*/
b
sys_sigsuspend
.
globl
ppc_rt_sigsuspend
ppc_rt_sigsuspend
:
SAVE_NVGPRS
(
r1
)
lwz
r0
,
_TRAP
(
r1
)
rlwinm
r0
,
r0
,
0
,
0
,
30
stw
r0
,
_TRAP
(
r1
)
b
sys_rt_sigsuspend
.
globl
ppc_fork
ppc_fork
:
SAVE_NVGPRS
(
r1
)
...
...
@@ -447,14 +490,6 @@ ppc_clone:
stw
r0
,
_TRAP
(
r1
)
/*
register
set
saved
*/
b
sys_clone
.
globl
ppc_swapcontext
ppc_swapcontext
:
SAVE_NVGPRS
(
r1
)
lwz
r0
,
_TRAP
(
r1
)
rlwinm
r0
,
r0
,
0
,
0
,
30
/*
clear
LSB
to
indicate
full
*/
stw
r0
,
_TRAP
(
r1
)
/*
register
set
saved
*/
b
sys_swapcontext
/*
*
Top
-
level
page
fault
handling
.
*
This
is
in
assembler
because
if
do_page_fault
tells
us
that
...
...
@@ -626,16 +661,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
.
long
ret_from_except
#endif
.
globl
sigreturn_exit
sigreturn_exit
:
subi
r1
,
r3
,
STACK_FRAME_OVERHEAD
rlwinm
r12
,
r1
,
0
,
0
,(
31
-
THREAD_SHIFT
)
/*
current_thread_info
()
*/
lwz
r9
,
TI_FLAGS
(
r12
)
andi
.
r0
,
r9
,
_TIF_SYSCALL_T_OR_A
beq
+
ret_from_except_full
bl
do_syscall_trace_leave
/
*
fall
through
*/
.
globl
ret_from_except_full
ret_from_except_full
:
REST_NVGPRS
(
r1
)
...
...
@@ -658,7 +683,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */
/
*
Check
current_thread_info
()->
flags
*/
rlwinm
r9
,
r1
,
0
,
0
,(
31
-
THREAD_SHIFT
)
lwz
r9
,
TI_FLAGS
(
r9
)
andi
.
r0
,
r9
,(
_TIF_SIGPENDING
|
_TIF_NEED_RESCHED
)
andi
.
r0
,
r9
,(
_TIF_SIGPENDING|_TIF_NEED_RESCHED
|_TIF_RESTOREALL
)
bne
do_work
restore_user
:
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/entry_64.S
View file @
6150c325
...
...
@@ -113,9 +113,7 @@ system_call_common:
addi
r9
,
r1
,
STACK_FRAME_OVERHEAD
#endif
clrrdi
r11
,
r1
,
THREAD_SHIFT
li
r12
,
0
ld
r10
,
TI_FLAGS
(
r11
)
stb
r12
,
TI_SC_NOERR
(
r11
)
andi
.
r11
,
r10
,
_TIF_SYSCALL_T_OR_A
bne
-
syscall_dotrace
syscall_dotrace_cont
:
...
...
@@ -144,24 +142,12 @@ system_call: /* label this so stack traces look sane */
bctrl
/*
Call
handler
*/
syscall_exit
:
std
r3
,
RESULT
(
r1
)
#ifdef SHOW_SYSCALLS
std
r3
,
GPR3
(
r1
)
bl
.
do_show_syscall_exit
ld
r3
,
GPR3
(
r1
)
ld
r3
,
RESULT
(
r1
)
#endif
std
r3
,
RESULT
(
r1
)
ld
r5
,
_CCR
(
r1
)
li
r10
,-
_LAST_ERRNO
cmpld
r3
,
r10
clrrdi
r12
,
r1
,
THREAD_SHIFT
bge
-
syscall_error
syscall_error_cont
:
/
*
check
for
syscall
tracing
or
audit
*/
ld
r9
,
TI_FLAGS
(
r12
)
andi
.
r0
,
r9
,(
_TIF_SYSCALL_T_OR_A
|
_TIF_SINGLESTEP
)
bne
-
syscall_exit_trace
syscall_exit_trace_cont
:
/
*
disable
interrupts
so
current_thread_info
()->
flags
can
't change,
and
so
that
we
don
't get interrupted after loading SRR0/1. */
...
...
@@ -173,8 +159,13 @@ syscall_exit_trace_cont:
rotldi
r10
,
r10
,
16
mtmsrd
r10
,
1
ld
r9
,
TI_FLAGS
(
r12
)
andi
.
r0
,
r9
,(
_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED
)
li
r11
,-
_LAST_ERRNO
andi
.
r0
,
r9
,(
_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR
)
bne
-
syscall_exit_work
cmpld
r3
,
r11
ld
r5
,
_CCR
(
r1
)
bge
-
syscall_error
syscall_error_cont
:
ld
r7
,
_NIP
(
r1
)
stdcx
.
r0
,
0
,
r1
/*
to
clear
the
reservation
*/
andi
.
r6
,
r8
,
MSR_PR
...
...
@@ -193,21 +184,12 @@ syscall_exit_trace_cont:
rfid
b
.
/*
prevent
speculative
execution
*/
syscall_enosys
:
li
r3
,-
ENOSYS
std
r3
,
RESULT
(
r1
)
clrrdi
r12
,
r1
,
THREAD_SHIFT
ld
r5
,
_CCR
(
r1
)
syscall_error
:
lbz
r11
,
TI_SC_NOERR
(
r12
)
cmpwi
0
,
r11
,
0
bne
-
syscall_error_cont
neg
r3
,
r3
syscall_error
:
oris
r5
,
r5
,
0x1000
/*
Set
SO
bit
in
CR
*/
neg
r3
,
r3
std
r5
,
_CCR
(
r1
)
b
syscall_error_cont
/*
Traced
system
call
support
*/
syscall_dotrace
:
bl
.
save_nvgprs
...
...
@@ -225,21 +207,69 @@ syscall_dotrace:
ld
r10
,
TI_FLAGS
(
r10
)
b
syscall_dotrace_cont
syscall_exit_trace
:
std
r3
,
GPR3
(
r1
)
bl
.
save_nvgprs
syscall_enosys
:
li
r3
,-
ENOSYS
b
syscall_exit
syscall_exit_work
:
/
*
If
TIF_RESTOREALL
is
set
,
don
't scribble on either r3 or ccr.
If
TIF_NOERROR
is
set
,
just
save
r3
as
it
is
.
*/
andi
.
r0
,
r9
,
_TIF_RESTOREALL
bne
-
2
f
cmpld
r3
,
r11
/*
r10
is
-
LAST_ERRNO
*/
blt
+
1
f
andi
.
r0
,
r9
,
_TIF_NOERROR
bne
-
1
f
ld
r5
,
_CCR
(
r1
)
neg
r3
,
r3
oris
r5
,
r5
,
0x1000
/*
Set
SO
bit
in
CR
*/
std
r5
,
_CCR
(
r1
)
1
:
std
r3
,
GPR3
(
r1
)
2
:
andi
.
r0
,
r9
,(
_TIF_PERSYSCALL_MASK
)
beq
4
f
/
*
Clear
per
-
syscall
TIF
flags
if
any
are
set
,
but
_leave_
_TIF_SAVE_NVGPRS
set
in
r9
since
we
haven
't dealt with that
yet
.
*/
li
r11
,
_TIF_PERSYSCALL_MASK
addi
r12
,
r12
,
TI_FLAGS
3
:
ldarx
r10
,
0
,
r12
andc
r10
,
r10
,
r11
stdcx
.
r10
,
0
,
r12
bne
-
3
b
subi
r12
,
r12
,
TI_FLAGS
4
:
bl
.
save_nvgprs
/
*
Anything
else
left
to
do
?
*/
andi
.
r0
,
r9
,(
_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS
)
beq
.
ret_from_except_lite
/
*
Re
-
enable
interrupts
*/
mfmsr
r10
ori
r10
,
r10
,
MSR_EE
mtmsrd
r10
,
1
andi
.
r0
,
r9
,
_TIF_SAVE_NVGPRS
bne
save_user_nvgprs
/
*
If
tracing
,
re
-
enable
interrupts
and
do
it
*/
save_user_nvgprs_cont
:
andi
.
r0
,
r9
,(
_TIF_SYSCALL_T_OR_A
|
_TIF_SINGLESTEP
)
beq
5
f
addi
r3
,
r1
,
STACK_FRAME_OVERHEAD
bl
.
do_syscall_trace_leave
REST_NVGPRS
(
r1
)
ld
r3
,
GPR3
(
r1
)
ld
r5
,
_CCR
(
r1
)
clrrdi
r12
,
r1
,
THREAD_SHIFT
b
syscall_exit_trace_cont
/*
Stuff
to
do
on
exit
from
a
system
call
.
*/
syscall_exit_work
:
std
r3
,
GPR3
(
r1
)
std
r5
,
_CCR
(
r1
)
/
*
Disable
interrupts
again
and
handle
other
work
if
any
*/
5
:
mfmsr
r10
rldicl
r10
,
r10
,
48
,
1
rotldi
r10
,
r10
,
16
mtmsrd
r10
,
1
b
.
ret_from_except_lite
/*
Save
non
-
volatile
GPRs
,
if
not
already
saved
.
*/
...
...
@@ -252,6 +282,52 @@ _GLOBAL(save_nvgprs)
std
r0
,
_TRAP
(
r1
)
blr
save_user_nvgprs
:
ld
r10
,
TI_SIGFRAME
(
r12
)
andi
.
r0
,
r9
,
_TIF_32BIT
beq
-
save_user_nvgprs_64
/
*
32
-
bit
save
to
userspace
*/
.
macro
savewords
start
,
end
1:
stw
\
start
,
4
*(
\
start
)(
r10
)
.
section
__ex_table
,
"a"
.
align
3
.
llong
1
b
,
save_user_nvgprs_fault
.
previous
.
if
\
end
-
\
start
savewords
"(\start+1)"
,
\
end
.
endif
.
endm
savewords
14
,
31
b
save_user_nvgprs_cont
save_user_nvgprs_64
:
/
*
64
-
bit
save
to
userspace
*/
.
macro
savelongs
start
,
end
1:
std
\
start
,
8
*(
\
start
)(
r10
)
.
section
__ex_table
,
"a"
.
align
3
.
llong
1
b
,
save_user_nvgprs_fault
.
previous
.
if
\
end
-
\
start
savelongs
"(\start+1)"
,
\
end
.
endif
.
endm
savelongs
14
,
31
b
save_user_nvgprs_cont
save_user_nvgprs_fault
:
li
r3
,
11
/*
SIGSEGV
*/
ld
r4
,
TI_TASK
(
r12
)
bl
.
force_sigsegv
clrrdi
r12
,
r1
,
THREAD_SHIFT
ld
r9
,
TI_FLAGS
(
r12
)
b
save_user_nvgprs_cont
/*
*
The
sigsuspend
and
rt_sigsuspend
system
calls
can
call
do_signal
*
and
thus
put
the
process
into
the
stopped
state
where
we
might
...
...
@@ -260,35 +336,6 @@ _GLOBAL(save_nvgprs)
*
the
C
code
.
Similarly
,
fork
,
vfork
and
clone
need
the
full
*
register
state
on
the
stack
so
that
it
can
be
copied
to
the
child
.
*/
_GLOBAL
(
ppc32_sigsuspend
)
bl
.
save_nvgprs
bl
.
compat_sys_sigsuspend
b
70
f
_GLOBAL
(
ppc64_rt_sigsuspend
)
bl
.
save_nvgprs
bl
.
sys_rt_sigsuspend
b
70
f
_GLOBAL
(
ppc32_rt_sigsuspend
)
bl
.
save_nvgprs
bl
.
compat_sys_rt_sigsuspend
70
:
cmpdi
0
,
r3
,
0
/
*
If
it
returned
an
error
,
we
need
to
return
via
syscall_exit
to
set
the
SO
bit
in
cr0
and
potentially
stop
for
ptrace
.
*/
bne
syscall_exit
/
*
If
sigsuspend
()
returns
zero
,
we
are
going
into
a
signal
handler
.
We
may
need
to
call
audit_syscall_exit
()
to
mark
the
exit
from
sigsuspend
()
*/
#ifdef CONFIG_AUDITSYSCALL
ld
r3
,
PACACURRENT
(
r13
)
ld
r4
,
AUDITCONTEXT
(
r3
)
cmpdi
0
,
r4
,
0
beq
.
ret_from_except
/*
No
audit_context
:
Leave
immediately
.
*/
li
r4
,
2
/*
AUDITSC_FAILURE
*/
li
r5
,-
4
/*
It
's always -EINTR */
bl
.
audit_syscall_exit
#endif
b
.
ret_from_except
_GLOBAL
(
ppc_fork
)
bl
.
save_nvgprs
...
...
@@ -305,37 +352,6 @@ _GLOBAL(ppc_clone)
bl
.
sys_clone
b
syscall_exit
_GLOBAL
(
ppc32_swapcontext
)
bl
.
save_nvgprs
bl
.
compat_sys_swapcontext
b
80
f
_GLOBAL
(
ppc64_swapcontext
)
bl
.
save_nvgprs
bl
.
sys_swapcontext
b
80
f
_GLOBAL
(
ppc32_sigreturn
)
bl
.
compat_sys_sigreturn
b
80
f
_GLOBAL
(
ppc32_rt_sigreturn
)
bl
.
compat_sys_rt_sigreturn
b
80
f
_GLOBAL
(
ppc64_rt_sigreturn
)
bl
.
sys_rt_sigreturn
80
:
cmpdi
0
,
r3
,
0
blt
syscall_exit
clrrdi
r4
,
r1
,
THREAD_SHIFT
ld
r4
,
TI_FLAGS
(
r4
)
andi
.
r4
,
r4
,(
_TIF_SYSCALL_T_OR_A
|
_TIF_SINGLESTEP
)
beq
+
81
f
addi
r3
,
r1
,
STACK_FRAME_OVERHEAD
bl
.
do_syscall_trace_leave
81
:
b
.
ret_from_except
_GLOBAL
(
ret_from_fork
)
bl
.
schedule_tail
REST_NVGPRS
(
r1
)
...
...
@@ -674,7 +690,7 @@ _GLOBAL(enter_rtas)
/
*
Setup
our
real
return
addr
*/
SET_REG_TO_LABEL
(
r4
,.
rtas_return_loc
)
SET_REG_TO_CONST
(
r9
,
KERNELBA
SE
)
SET_REG_TO_CONST
(
r9
,
PAGE_OFF
SE
T
)
sub
r4
,
r4
,
r9
mtlr
r4
...
...
@@ -702,7 +718,7 @@ _GLOBAL(enter_rtas)
_STATIC
(
rtas_return_loc
)
/
*
relocation
is
off
at
this
point
*/
mfspr
r4
,
SPRN_SPRG3
/*
Get
PACA
*/
SET_REG_TO_CONST
(
r5
,
KERNELBA
SE
)
SET_REG_TO_CONST
(
r5
,
PAGE_OFF
SE
T
)
sub
r4
,
r4
,
r5
/*
RELOC
the
PACA
base
pointer
*/
mfmsr
r6
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/head_32.S
View file @
6150c325
...
...
@@ -120,10 +120,25 @@ __start:
*
because
OF
may
have
I
/
O
devices
mapped
into
that
area
*
(
particularly
on
CHRP
)
.
*/
#ifdef CONFIG_PPC_MULTIPLATFORM
cmpwi
0
,
r5
,
0
beq
1
f
bl
prom_init
trap
#endif
/*
*
Check
for
BootX
signature
when
supporting
PowerMac
and
branch
to
*
appropriate
trampoline
if
it
's present
*/
#ifdef CONFIG_PPC_PMAC
1
:
lis
r31
,
0x426f
ori
r31
,
r31
,
0x6f58
cmpw
0
,
r3
,
r31
bne
1
f
bl
bootx_init
trap
#endif /* CONFIG_PPC_PMAC */
1
:
mr
r31
,
r3
/*
save
parameters
*/
mr
r30
,
r4
...
...
@@ -153,6 +168,9 @@ __after_mmu_off:
bl
flush_tlbs
bl
initial_bats
#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
bl
setup_disp_bat
#endif
/*
*
Call
setup_cpu
for
CPU
0
and
initialize
6
xx
Idle
...
...
@@ -450,16 +468,11 @@ SystemCall:
*
by
executing
an
altivec
instruction
.
*/
.
=
0xf00
b
Trap_0f
b
PerformanceMonitor
.
=
0xf20
b
AltiVecUnavailable
Trap_0f
:
EXCEPTION_PROLOG
addi
r3
,
r1
,
STACK_FRAME_OVERHEAD
EXC_XFER_EE
(0
xf00
,
unknown_exception
)
/*
*
Handle
TLB
miss
for
instruction
on
603
/
60
3
e
.
*
Note
:
we
get
an
alternate
set
of
r0
-
r3
to
use
automatically
.
...
...
@@ -703,6 +716,11 @@ AltiVecUnavailable:
#endif /* CONFIG_ALTIVEC */
EXC_XFER_EE_LITE
(0
xf20
,
altivec_unavailable_exception
)
PerformanceMonitor
:
EXCEPTION_PROLOG
addi
r3
,
r1
,
STACK_FRAME_OVERHEAD
EXC_XFER_STD
(0
xf00
,
performance_monitor_exception
)
#ifdef CONFIG_ALTIVEC
/*
Note
that
the
AltiVec
support
is
closely
modeled
after
the
FP
*
support
.
Changes
to
one
are
likely
to
be
applicable
to
the
...
...
@@ -1306,6 +1324,32 @@ initial_bats:
blr
#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
setup_disp_bat
:
/
*
*
setup
the
display
bat
prepared
for
us
in
prom
.
c
*/
mflr
r8
bl
reloc_offset
mtlr
r8
addis
r8
,
r3
,
disp_BAT
@
ha
addi
r8
,
r8
,
disp_BAT
@
l
cmpwi
cr0
,
r8
,
0
beqlr
lwz
r11
,
0
(
r8
)
lwz
r8
,
4
(
r8
)
mfspr
r9
,
SPRN_PVR
rlwinm
r9
,
r9
,
16
,
16
,
31
/*
r9
=
1
for
601
,
4
for
604
*/
cmpwi
0
,
r9
,
1
beq
1
f
mtspr
SPRN_DBAT3L
,
r8
mtspr
SPRN_DBAT3U
,
r11
blr
1
:
mtspr
SPRN_IBAT3L
,
r8
mtspr
SPRN_IBAT3U
,
r11
blr
#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
#ifdef CONFIG_8260
/*
Jump
into
the
system
reset
for
the
rom
.
*
We
first
disable
the
MMU
,
and
then
jump
to
the
ROM
reset
address
.
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/head_64.S
View file @
6150c325
...
...
@@ -154,11 +154,15 @@ _GLOBAL(__secondary_hold)
bne
100
b
#ifdef CONFIG_HMT
b
.
hmt_init
LOADADDR
(
r4
,
.
hmt_init
)
mtctr
r4
bctr
#else
#ifdef CONFIG_SMP
LOADADDR
(
r4
,
.
pSeries_secondary_smp_init
)
mtctr
r4
mr
r3
,
r24
b
.
pSeries_secondary_smp_init
b
ctr
#else
BUG_OPCODE
#endif
...
...
@@ -200,6 +204,20 @@ exception_marker:
#define EX_R3 64
#define EX_LR 72
/*
*
We
're short on space and time in the exception prolog, so we can'
t
use
*
the
normal
LOADADDR
macro
.
Normally
we
just
need
the
low
halfword
of
the
*
address
,
but
for
Kdump
we
need
the
whole
low
word
.
*/
#ifdef CONFIG_CRASH_DUMP
#define LOAD_HANDLER(reg, label) \
oris
reg
,
reg
,(
label
)
@
h
; /* virt addr of handler ... */ \
ori
reg
,
reg
,(
label
)
@
l
; /* .. and the rest */
#else
#define LOAD_HANDLER(reg, label) \
ori
reg
,
reg
,(
label
)
@
l
; /* virt addr of handler ... */
#endif
#define EXCEPTION_PROLOG_PSERIES(area, label) \
mfspr
r13
,
SPRN_SPRG3
; /* get paca address into r13 */ \
std
r9
,
area
+
EX_R9
(
r13
)
; /* save r9 - r12 */ \
...
...
@@ -212,7 +230,7 @@ exception_marker:
clrrdi
r12
,
r13
,
32
; /* get high part of &label */ \
mfmsr
r10
; \
mfspr
r11
,
SPRN_SRR0
; /* save SRR0 */ \
ori
r12
,
r12
,
(
label
)
@
l
; /* virt addr of handler */
\
LOAD_HANDLER
(
r12
,
label
)
\
ori
r10
,
r10
,
MSR_IR|MSR_DR|MSR_RI
; \
mtspr
SPRN_SRR0
,
r12
; \
mfspr
r12
,
SPRN_SRR1
; /* and SRR1 */ \
...
...
@@ -553,6 +571,7 @@ slb_miss_user_pseries:
*
Vectors
for
the
FWNMI
option
.
Share
common
code
.
*/
.
globl
system_reset_fwnmi
.
align
7
system_reset_fwnmi
:
HMT_MEDIUM
mtspr
SPRN_SPRG1
,
r13
/*
save
r13
*/
...
...
@@ -560,6 +579,7 @@ system_reset_fwnmi:
EXCEPTION_PROLOG_PSERIES
(
PACA_EXGEN
,
system_reset_common
)
.
globl
machine_check_fwnmi
.
align
7
machine_check_fwnmi
:
HMT_MEDIUM
mtspr
SPRN_SPRG1
,
r13
/*
save
r13
*/
...
...
@@ -726,7 +746,8 @@ iSeries_secondary_smp_loop:
decrementer_iSeries_masked
:
li
r11
,
1
stb
r11
,
PACALPPACA
+
LPPACADECRINT
(
r13
)
lwz
r12
,
PACADEFAULTDECR
(
r13
)
LOADBASE
(
r12
,
tb_ticks_per_jiffy
)
lwz
r12
,
OFF
(
tb_ticks_per_jiffy
)(
r12
)
mtspr
SPRN_DEC
,
r12
/
*
fall
through
*/
...
...
@@ -1345,7 +1366,7 @@ _GLOBAL(do_stab_bolted)
*
fixed
address
(
the
linker
can
't compute (u64)&initial_stab >>
*
PAGE_SHIFT
)
.
*/
.
=
STAB0_
PHYS_ADDR
/*
0x6000
*/
.
=
STAB0_
OFFSET
/*
0x6000
*/
.
globl
initial_stab
initial_stab
:
.
space
4096
...
...
@@ -1485,11 +1506,13 @@ _STATIC(__mmu_off)
*
*/
_GLOBAL
(
__start_initialization_multiplatform
)
#ifdef CONFIG_PPC_MULTIPLATFORM
/
*
*
Are
we
booted
from
a
PROM
Of
-
type
client
-
interface
?
*/
cmpldi
cr0
,
r5
,
0
bne
.
__boot_from_prom
/*
yes
->
prom
*/
#endif
/
*
Save
parameters
*/
mr
r31
,
r3
...
...
@@ -1510,6 +1533,7 @@ _GLOBAL(__start_initialization_multiplatform)
bl
.
__mmu_off
b
.
__after_prom_start
#ifdef CONFIG_PPC_MULTIPLATFORM
_STATIC
(
__boot_from_prom
)
/
*
Save
parameters
*/
mr
r31
,
r3
...
...
@@ -1542,6 +1566,7 @@ _STATIC(__boot_from_prom)
bl
.
prom_init
/
*
We
never
return
*/
trap
#endif
/*
*
At
this
point
,
r3
contains
the
physical
address
we
are
running
at
,
...
...
@@ -1550,7 +1575,7 @@ _STATIC(__boot_from_prom)
_STATIC
(
__after_prom_start
)
/*
*
We
need
to
run
with
__start
at
physical
address
0
.
*
We
need
to
run
with
__start
at
physical
address
PHYSICAL_START
.
*
This
will
leave
some
code
in
the
first
256
B
of
*
real
memory
,
which
are
reserved
for
software
use
.
*
The
remainder
of
the
first
page
is
loaded
with
the
fixed
...
...
@@ -1565,7 +1590,7 @@ _STATIC(__after_prom_start)
mr
r26
,
r3
SET_REG_TO_CONST
(
r27
,
KERNELBASE
)
li
r3
,
0
/*
target
addr
*/
LOADADDR
(
r3
,
PHYSICAL_START
)
/*
target
addr
*/
//
XXX
FIXME
:
Use
phys
returned
by
OF
(
r30
)
add
r4
,
r27
,
r26
/*
source
addr
*/
...
...
@@ -1846,7 +1871,7 @@ _STATIC(start_here_multiplatform)
mulli
r13
,
r27
,
PACA_SIZE
/*
Calculate
vaddr
of
right
paca
*/
add
r13
,
r13
,
r24
/*
for
this
processor
.
*/
add
r13
,
r13
,
r26
/*
convert
to
physical
addr
*/
mtspr
SPRN_SPRG3
,
r13
/*
PPPBBB
:
Temp
...
-
Peter
*/
mtspr
SPRN_SPRG3
,
r13
/
*
Do
very
early
kernel
initializations
,
including
initial
hash
table
,
*
stab
and
slb
setup
before
we
turn
on
relocation
.
*/
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/ibmebus.c
0 → 100644
View file @
6150c325
/*
* IBM PowerPC IBM eBus Infrastructure Support.
*
* Copyright (c) 2005 IBM Corporation
* Heiko J Schick <schickhj@de.ibm.com>
*
* All rights reserved.
*
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
* BSD.
*
* OpenIB BSD License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/init.h>
#include <linux/console.h>
#include <linux/kobject.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <asm/ibmebus.h>
#include <asm/abs_addr.h>
static
struct
ibmebus_dev
ibmebus_bus_device
=
{
/* fake "parent" device */
.
name
=
ibmebus_bus_device
.
ofdev
.
dev
.
bus_id
,
.
ofdev
.
dev
.
bus_id
=
"ibmebus"
,
.
ofdev
.
dev
.
bus
=
&
ibmebus_bus_type
,
};
static
void
*
ibmebus_alloc_coherent
(
struct
device
*
dev
,
size_t
size
,
dma_addr_t
*
dma_handle
,
gfp_t
flag
)
{
void
*
mem
;
mem
=
kmalloc
(
size
,
flag
);
*
dma_handle
=
(
dma_addr_t
)
mem
;
return
mem
;
}
static
void
ibmebus_free_coherent
(
struct
device
*
dev
,
size_t
size
,
void
*
vaddr
,
dma_addr_t
dma_handle
)
{
kfree
(
vaddr
);
}
static
dma_addr_t
ibmebus_map_single
(
struct
device
*
dev
,
void
*
ptr
,
size_t
size
,
enum
dma_data_direction
direction
)
{
return
(
dma_addr_t
)(
ptr
);
}
static
void
ibmebus_unmap_single
(
struct
device
*
dev
,
dma_addr_t
dma_addr
,
size_t
size
,
enum
dma_data_direction
direction
)
{
return
;
}
static
int
ibmebus_map_sg
(
struct
device
*
dev
,
struct
scatterlist
*
sg
,
int
nents
,
enum
dma_data_direction
direction
)
{
int
i
;
for
(
i
=
0
;
i
<
nents
;
i
++
)
{
sg
[
i
].
dma_address
=
(
dma_addr_t
)
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
;
sg
[
i
].
dma_length
=
sg
[
i
].
length
;
}
return
nents
;
}
static
void
ibmebus_unmap_sg
(
struct
device
*
dev
,
struct
scatterlist
*
sg
,
int
nents
,
enum
dma_data_direction
direction
)
{
return
;
}
static
int
ibmebus_dma_supported
(
struct
device
*
dev
,
u64
mask
)
{
return
1
;
}
struct
dma_mapping_ops
ibmebus_dma_ops
=
{
.
alloc_coherent
=
ibmebus_alloc_coherent
,
.
free_coherent
=
ibmebus_free_coherent
,
.
map_single
=
ibmebus_map_single
,
.
unmap_single
=
ibmebus_unmap_single
,
.
map_sg
=
ibmebus_map_sg
,
.
unmap_sg
=
ibmebus_unmap_sg
,
.
dma_supported
=
ibmebus_dma_supported
,
};
static
int
ibmebus_bus_probe
(
struct
device
*
dev
)
{
struct
ibmebus_dev
*
ibmebusdev
=
to_ibmebus_dev
(
dev
);
struct
ibmebus_driver
*
ibmebusdrv
=
to_ibmebus_driver
(
dev
->
driver
);
const
struct
of_device_id
*
id
;
int
error
=
-
ENODEV
;
if
(
!
ibmebusdrv
->
probe
)
return
error
;
id
=
of_match_device
(
ibmebusdrv
->
id_table
,
&
ibmebusdev
->
ofdev
);
if
(
id
)
{
error
=
ibmebusdrv
->
probe
(
ibmebusdev
,
id
);
}
return
error
;
}
static
int
ibmebus_bus_remove
(
struct
device
*
dev
)
{
struct
ibmebus_dev
*
ibmebusdev
=
to_ibmebus_dev
(
dev
);
struct
ibmebus_driver
*
ibmebusdrv
=
to_ibmebus_driver
(
dev
->
driver
);
if
(
ibmebusdrv
->
remove
)
{
return
ibmebusdrv
->
remove
(
ibmebusdev
);
}
return
0
;
}
static
void
__devinit
ibmebus_dev_release
(
struct
device
*
dev
)
{
of_node_put
(
to_ibmebus_dev
(
dev
)
->
ofdev
.
node
);
kfree
(
to_ibmebus_dev
(
dev
));
}
static
ssize_t
ibmebusdev_show_name
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
return
sprintf
(
buf
,
"%s
\n
"
,
to_ibmebus_dev
(
dev
)
->
name
);
}
static
DEVICE_ATTR
(
name
,
S_IRUSR
|
S_IRGRP
|
S_IROTH
,
ibmebusdev_show_name
,
NULL
);
static
struct
ibmebus_dev
*
__devinit
ibmebus_register_device_common
(
struct
ibmebus_dev
*
dev
,
char
*
name
)
{
int
err
=
0
;
dev
->
name
=
name
;
dev
->
ofdev
.
dev
.
parent
=
&
ibmebus_bus_device
.
ofdev
.
dev
;
dev
->
ofdev
.
dev
.
bus
=
&
ibmebus_bus_type
;
dev
->
ofdev
.
dev
.
release
=
ibmebus_dev_release
;
/* An ibmebusdev is based on a of_device. We have to change the
* bus type to use our own DMA mapping operations.
*/
if
((
err
=
of_device_register
(
&
dev
->
ofdev
))
!=
0
)
{
printk
(
KERN_ERR
"%s: failed to register device (%d).
\n
"
,
__FUNCTION__
,
err
);
return
NULL
;
}
device_create_file
(
&
dev
->
ofdev
.
dev
,
&
dev_attr_name
);
return
dev
;
}
static
struct
ibmebus_dev
*
__devinit
ibmebus_register_device_node
(
struct
device_node
*
dn
)
{
struct
ibmebus_dev
*
dev
;
char
*
loc_code
;
int
length
;
loc_code
=
(
char
*
)
get_property
(
dn
,
"ibm,loc-code"
,
NULL
);
if
(
!
loc_code
)
{
printk
(
KERN_WARNING
"%s: node %s missing 'ibm,loc-code'
\n
"
,
__FUNCTION__
,
dn
->
name
?
dn
->
name
:
"<unknown>"
);
return
NULL
;
}
if
(
strlen
(
loc_code
)
==
0
)
{
printk
(
KERN_WARNING
"%s: 'ibm,loc-code' is invalid
\n
"
,
__FUNCTION__
);
return
NULL
;
}
dev
=
kmalloc
(
sizeof
(
struct
ibmebus_dev
),
GFP_KERNEL
);
if
(
!
dev
)
{
return
NULL
;
}
memset
(
dev
,
0
,
sizeof
(
struct
ibmebus_dev
));
dev
->
ofdev
.
node
=
of_node_get
(
dn
);
length
=
strlen
(
loc_code
);
memcpy
(
dev
->
ofdev
.
dev
.
bus_id
,
loc_code
+
(
length
-
min
(
length
,
BUS_ID_SIZE
-
1
)),
min
(
length
,
BUS_ID_SIZE
-
1
));
/* Register with generic device framework. */
if
(
ibmebus_register_device_common
(
dev
,
dn
->
name
)
==
NULL
)
{
kfree
(
dev
);
return
NULL
;
}
return
dev
;
}
static
void
ibmebus_probe_of_nodes
(
char
*
name
)
{
struct
device_node
*
dn
=
NULL
;
while
((
dn
=
of_find_node_by_name
(
dn
,
name
)))
{
if
(
ibmebus_register_device_node
(
dn
)
==
NULL
)
{
of_node_put
(
dn
);
return
;
}
}
of_node_put
(
dn
);
return
;
}
static
void
ibmebus_add_devices_by_id
(
struct
of_device_id
*
idt
)
{
while
(
strlen
(
idt
->
name
)
>
0
)
{
ibmebus_probe_of_nodes
(
idt
->
name
);
idt
++
;
}
return
;
}
static
int
ibmebus_match_helper
(
struct
device
*
dev
,
void
*
data
)
{
if
(
strcmp
((
char
*
)
data
,
to_ibmebus_dev
(
dev
)
->
name
)
==
0
)
return
1
;
return
0
;
}
static
int
ibmebus_unregister_device
(
struct
device
*
dev
)
{
device_remove_file
(
dev
,
&
dev_attr_name
);
of_device_unregister
(
to_of_device
(
dev
));
return
0
;
}
static
void
ibmebus_remove_devices_by_id
(
struct
of_device_id
*
idt
)
{
struct
device
*
dev
;
while
(
strlen
(
idt
->
name
)
>
0
)
{
while
((
dev
=
bus_find_device
(
&
ibmebus_bus_type
,
NULL
,
(
void
*
)
idt
->
name
,
ibmebus_match_helper
)))
{
ibmebus_unregister_device
(
dev
);
}
idt
++
;
}
return
;
}
int
ibmebus_register_driver
(
struct
ibmebus_driver
*
drv
)
{
int
err
=
0
;
drv
->
driver
.
name
=
drv
->
name
;
drv
->
driver
.
bus
=
&
ibmebus_bus_type
;
drv
->
driver
.
probe
=
ibmebus_bus_probe
;
drv
->
driver
.
remove
=
ibmebus_bus_remove
;
if
((
err
=
driver_register
(
&
drv
->
driver
)
!=
0
))
return
err
;
ibmebus_add_devices_by_id
(
drv
->
id_table
);
return
0
;
}
EXPORT_SYMBOL
(
ibmebus_register_driver
);
void
ibmebus_unregister_driver
(
struct
ibmebus_driver
*
drv
)
{
driver_unregister
(
&
drv
->
driver
);
ibmebus_remove_devices_by_id
(
drv
->
id_table
);
}
EXPORT_SYMBOL
(
ibmebus_unregister_driver
);
int
ibmebus_request_irq
(
struct
ibmebus_dev
*
dev
,
u32
ist
,
irqreturn_t
(
*
handler
)(
int
,
void
*
,
struct
pt_regs
*
),
unsigned
long
irq_flags
,
const
char
*
devname
,
void
*
dev_id
)
{
unsigned
int
irq
=
virt_irq_create_mapping
(
ist
);
if
(
irq
==
NO_IRQ
)
return
-
EINVAL
;
irq
=
irq_offset_up
(
irq
);
return
request_irq
(
irq
,
handler
,
irq_flags
,
devname
,
dev_id
);
}
EXPORT_SYMBOL
(
ibmebus_request_irq
);
void
ibmebus_free_irq
(
struct
ibmebus_dev
*
dev
,
u32
ist
,
void
*
dev_id
)
{
unsigned
int
irq
=
virt_irq_create_mapping
(
ist
);
irq
=
irq_offset_up
(
irq
);
free_irq
(
irq
,
dev_id
);
return
;
}
EXPORT_SYMBOL
(
ibmebus_free_irq
);
static
int
ibmebus_bus_match
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
const
struct
ibmebus_dev
*
ebus_dev
=
to_ibmebus_dev
(
dev
);
struct
ibmebus_driver
*
ebus_drv
=
to_ibmebus_driver
(
drv
);
const
struct
of_device_id
*
ids
=
ebus_drv
->
id_table
;
const
struct
of_device_id
*
found_id
;
if
(
!
ids
)
return
0
;
found_id
=
of_match_device
(
ids
,
&
ebus_dev
->
ofdev
);
if
(
found_id
)
return
1
;
return
0
;
}
struct
bus_type
ibmebus_bus_type
=
{
.
name
=
"ibmebus"
,
.
match
=
ibmebus_bus_match
,
};
EXPORT_SYMBOL
(
ibmebus_bus_type
);
static
int
__init
ibmebus_bus_init
(
void
)
{
int
err
;
printk
(
KERN_INFO
"IBM eBus Device Driver
\n
"
);
err
=
bus_register
(
&
ibmebus_bus_type
);
if
(
err
)
{
printk
(
KERN_ERR
":%s: failed to register IBM eBus.
\n
"
,
__FUNCTION__
);
return
err
;
}
err
=
device_register
(
&
ibmebus_bus_device
.
ofdev
.
dev
);
if
(
err
)
{
printk
(
KERN_WARNING
"%s: device_register returned %i
\n
"
,
__FUNCTION__
,
err
);
bus_unregister
(
&
ibmebus_bus_type
);
return
err
;
}
return
0
;
}
__initcall
(
ibmebus_bus_init
);
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/irq.c
View file @
6150c325
...
...
@@ -31,7 +31,6 @@
* to reduce code space and undefined function references.
*/
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/threads.h>
#include <linux/kernel_stat.h>
...
...
@@ -44,18 +43,12 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/proc_fs.h>
#include <linux/random.h>
#include <linux/seq_file.h>
#include <linux/cpumask.h>
#include <linux/profile.h>
#include <linux/bitops.h>
#ifdef CONFIG_PPC64
#include <linux/kallsyms.h>
#endif
#include <asm/uaccess.h>
#include <asm/system.h>
...
...
@@ -66,8 +59,7 @@
#include <asm/prom.h>
#include <asm/ptrace.h>
#include <asm/machdep.h>
#ifdef CONFIG_PPC64
#include <asm/iseries/it_lp_queue.h>
#ifdef CONFIG_PPC_ISERIES
#include <asm/paca.h>
#endif
...
...
@@ -78,10 +70,6 @@ EXPORT_SYMBOL(__irq_offset_value);
static
int
ppc_spurious_interrupts
;
#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
extern
void
iSeries_smp_message_recv
(
struct
pt_regs
*
);
#endif
#ifdef CONFIG_PPC32
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
...
...
@@ -195,49 +183,6 @@ void fixup_irqs(cpumask_t map)
}
#endif
#ifdef CONFIG_PPC_ISERIES
void
do_IRQ
(
struct
pt_regs
*
regs
)
{
struct
paca_struct
*
lpaca
;
irq_enter
();
#ifdef CONFIG_DEBUG_STACKOVERFLOW
/* Debugging check for stack overflow: is there less than 2KB free? */
{
long
sp
;
sp
=
__get_SP
()
&
(
THREAD_SIZE
-
1
);
if
(
unlikely
(
sp
<
(
sizeof
(
struct
thread_info
)
+
2048
)))
{
printk
(
"do_IRQ: stack overflow: %ld
\n
"
,
sp
-
sizeof
(
struct
thread_info
));
dump_stack
();
}
}
#endif
lpaca
=
get_paca
();
#ifdef CONFIG_SMP
if
(
lpaca
->
lppaca
.
int_dword
.
fields
.
ipi_cnt
)
{
lpaca
->
lppaca
.
int_dword
.
fields
.
ipi_cnt
=
0
;
iSeries_smp_message_recv
(
regs
);
}
#endif
/* CONFIG_SMP */
if
(
hvlpevent_is_pending
())
process_hvlpevents
(
regs
);
irq_exit
();
if
(
lpaca
->
lppaca
.
int_dword
.
fields
.
decr_int
)
{
lpaca
->
lppaca
.
int_dword
.
fields
.
decr_int
=
0
;
/* Signal a fake decrementer interrupt */
timer_interrupt
(
regs
);
}
}
#else
/* CONFIG_PPC_ISERIES */
void
do_IRQ
(
struct
pt_regs
*
regs
)
{
int
irq
;
...
...
@@ -286,16 +231,24 @@ void do_IRQ(struct pt_regs *regs)
}
else
#endif
__do_IRQ
(
irq
,
regs
);
}
else
#ifdef CONFIG_PPC32
if
(
irq
!=
-
2
)
#endif
/* That's not SMP safe ... but who cares ? */
ppc_spurious_interrupts
++
;
}
else
if
(
irq
!=
-
2
)
/* That's not SMP safe ... but who cares ? */
ppc_spurious_interrupts
++
;
irq_exit
();
}
#endif
/* CONFIG_PPC_ISERIES */
#ifdef CONFIG_PPC_ISERIES
{
struct
paca_struct
*
lpaca
=
get_paca
();
if
(
lpaca
->
lppaca
.
int_dword
.
fields
.
decr_int
)
{
lpaca
->
lppaca
.
int_dword
.
fields
.
decr_int
=
0
;
/* Signal a fake decrementer interrupt */
timer_interrupt
(
regs
);
}
}
#endif
}
void
__init
init_IRQ
(
void
)
{
...
...
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/legacy_serial.c
0 → 100644
View file @
6150c325
This diff is collapsed.
Click to expand it.
Prev
1
2
3
4
5
…
15
Next
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