diff options
Diffstat (limited to 'arch/powerpc')
85 files changed, 10389 insertions, 554 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index c523029674e6..bb2efdd566a9 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -261,7 +261,7 @@ config PPC_ISERIES | |||
261 | 261 | ||
262 | config EMBEDDED6xx | 262 | config EMBEDDED6xx |
263 | bool "Embedded 6xx/7xx/7xxx-based board" | 263 | bool "Embedded 6xx/7xx/7xxx-based board" |
264 | depends on PPC32 | 264 | depends on PPC32 && BROKEN |
265 | 265 | ||
266 | config APUS | 266 | config APUS |
267 | bool "Amiga-APUS" | 267 | bool "Amiga-APUS" |
@@ -305,7 +305,7 @@ config PPC_PMAC64 | |||
305 | 305 | ||
306 | config PPC_PREP | 306 | config PPC_PREP |
307 | bool " PowerPC Reference Platform (PReP) based machines" | 307 | bool " PowerPC Reference Platform (PReP) based machines" |
308 | depends on PPC_MULTIPLATFORM && PPC32 | 308 | depends on PPC_MULTIPLATFORM && PPC32 && BROKEN |
309 | select PPC_I8259 | 309 | select PPC_I8259 |
310 | select PPC_INDIRECT_PCI | 310 | select PPC_INDIRECT_PCI |
311 | default y | 311 | default y |
@@ -598,19 +598,6 @@ config ARCH_MEMORY_PROBE | |||
598 | def_bool y | 598 | def_bool y |
599 | depends on MEMORY_HOTPLUG | 599 | depends on MEMORY_HOTPLUG |
600 | 600 | ||
601 | # Some NUMA nodes have memory ranges that span | ||
602 | # other nodes. Even though a pfn is valid and | ||
603 | # between a node's start and end pfns, it may not | ||
604 | # reside on that node. | ||
605 | # | ||
606 | # This is a relatively temporary hack that should | ||
607 | # be able to go away when sparsemem is fully in | ||
608 | # place | ||
609 | |||
610 | config NODES_SPAN_OTHER_NODES | ||
611 | def_bool y | ||
612 | depends on NEED_MULTIPLE_NODES | ||
613 | |||
614 | config PPC_64K_PAGES | 601 | config PPC_64K_PAGES |
615 | bool "64k page size" | 602 | bool "64k page size" |
616 | depends on PPC64 | 603 | depends on PPC64 |
@@ -932,6 +919,7 @@ source "arch/powerpc/oprofile/Kconfig" | |||
932 | 919 | ||
933 | config KPROBES | 920 | config KPROBES |
934 | bool "Kprobes (EXPERIMENTAL)" | 921 | bool "Kprobes (EXPERIMENTAL)" |
922 | depends on PPC64 | ||
935 | help | 923 | help |
936 | Kprobes allows you to trap at almost any kernel address and | 924 | Kprobes allows you to trap at almost any kernel address and |
937 | execute a callback function. register_kprobe() establishes | 925 | execute a callback function. register_kprobe() establishes |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 5bc11bd36c1f..98f67c78d1bd 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -14,10 +14,6 @@ | |||
14 | 14 | ||
15 | HAS_BIARCH := $(call cc-option-yn, -m32) | 15 | HAS_BIARCH := $(call cc-option-yn, -m32) |
16 | 16 | ||
17 | ifeq ($(CONFIG_PPC64),y) | ||
18 | OLDARCH := ppc64 | ||
19 | SZ := 64 | ||
20 | |||
21 | # Set default 32 bits cross compilers for vdso and boot wrapper | 17 | # Set default 32 bits cross compilers for vdso and boot wrapper |
22 | CROSS32_COMPILE ?= | 18 | CROSS32_COMPILE ?= |
23 | 19 | ||
@@ -37,6 +33,12 @@ endif | |||
37 | 33 | ||
38 | export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY | 34 | export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY |
39 | 35 | ||
36 | KBUILD_DEFCONFIG := $(shell uname -m)_defconfig | ||
37 | |||
38 | ifeq ($(CONFIG_PPC64),y) | ||
39 | OLDARCH := ppc64 | ||
40 | SZ := 64 | ||
41 | |||
40 | new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi) | 42 | new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi) |
41 | 43 | ||
42 | ifeq ($(new_nm),y) | 44 | ifeq ($(new_nm),y) |
@@ -111,9 +113,6 @@ cpu-as-$(CONFIG_E200) += -Wa,-me200 | |||
111 | AFLAGS += $(cpu-as-y) | 113 | AFLAGS += $(cpu-as-y) |
112 | CFLAGS += $(cpu-as-y) | 114 | CFLAGS += $(cpu-as-y) |
113 | 115 | ||
114 | # Default to the common case. | ||
115 | KBUILD_DEFCONFIG := common_defconfig | ||
116 | |||
117 | head-y := arch/powerpc/kernel/head_32.o | 116 | head-y := arch/powerpc/kernel/head_32.o |
118 | head-$(CONFIG_PPC64) := arch/powerpc/kernel/head_64.o | 117 | head-$(CONFIG_PPC64) := arch/powerpc/kernel/head_64.o |
119 | head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o | 118 | head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o |
@@ -125,11 +124,11 @@ head-$(CONFIG_PPC64) += arch/powerpc/kernel/entry_64.o | |||
125 | head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o | 124 | head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o |
126 | 125 | ||
127 | core-y += arch/powerpc/kernel/ \ | 126 | core-y += arch/powerpc/kernel/ \ |
128 | arch/$(OLDARCH)/kernel/ \ | ||
129 | arch/powerpc/mm/ \ | 127 | arch/powerpc/mm/ \ |
130 | arch/powerpc/lib/ \ | 128 | arch/powerpc/lib/ \ |
131 | arch/powerpc/sysdev/ \ | 129 | arch/powerpc/sysdev/ \ |
132 | arch/powerpc/platforms/ | 130 | arch/powerpc/platforms/ |
131 | core-$(CONFIG_PPC32) += arch/ppc/kernel/ | ||
133 | core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ | 132 | core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ |
134 | core-$(CONFIG_XMON) += arch/powerpc/xmon/ | 133 | core-$(CONFIG_XMON) += arch/powerpc/xmon/ |
135 | core-$(CONFIG_APUS) += arch/ppc/amiga/ | 134 | core-$(CONFIG_APUS) += arch/ppc/amiga/ |
@@ -139,7 +138,7 @@ drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/ | |||
139 | 138 | ||
140 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ | 139 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ |
141 | 140 | ||
142 | defaultimage-$(CONFIG_PPC32) := uImage zImage | 141 | defaultimage-$(CONFIG_PPC32) := zImage |
143 | defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux | 142 | defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux |
144 | defaultimage-$(CONFIG_PPC_PSERIES) := zImage | 143 | defaultimage-$(CONFIG_PPC_PSERIES) := zImage |
145 | KBUILD_IMAGE := $(defaultimage-y) | 144 | KBUILD_IMAGE := $(defaultimage-y) |
@@ -154,40 +153,29 @@ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm | |||
154 | 153 | ||
155 | .PHONY: $(BOOT_TARGETS) | 154 | .PHONY: $(BOOT_TARGETS) |
156 | 155 | ||
157 | boot := arch/$(OLDARCH)/boot | 156 | boot := arch/$(ARCH)/boot |
158 | 157 | ||
159 | # urk | ||
160 | ifeq ($(CONFIG_PPC64),y) | ||
161 | $(BOOT_TARGETS): vmlinux | 158 | $(BOOT_TARGETS): vmlinux |
162 | $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) | 159 | $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) |
163 | else | ||
164 | $(BOOT_TARGETS): vmlinux | ||
165 | $(Q)$(MAKE) ARCH=ppc $(build)=$(boot) $@ | ||
166 | endif | ||
167 | |||
168 | uImage: vmlinux | ||
169 | $(Q)$(MAKE) ARCH=$(OLDARCH) $(build)=$(boot)/images $(boot)/images/$@ | ||
170 | 160 | ||
171 | define archhelp | 161 | define archhelp |
172 | @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/images/zImage.*)' | 162 | @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)' |
173 | @echo ' uImage - Create a bootable image for U-Boot / PPCBoot' | ||
174 | @echo ' install - Install kernel using' | 163 | @echo ' install - Install kernel using' |
175 | @echo ' (your) ~/bin/installkernel or' | 164 | @echo ' (your) ~/bin/installkernel or' |
176 | @echo ' (distribution) /sbin/installkernel or' | 165 | @echo ' (distribution) /sbin/installkernel or' |
177 | @echo ' install to $$(INSTALL_PATH) and run lilo' | 166 | @echo ' install to $$(INSTALL_PATH) and run lilo' |
178 | @echo ' *_defconfig - Select default config from arch/$(ARCH)/ppc/configs' | 167 | @echo ' *_defconfig - Select default config from arch/$(ARCH)/configs' |
179 | endef | 168 | endef |
180 | 169 | ||
181 | archclean: | 170 | archclean: |
182 | $(Q)$(MAKE) $(clean)=$(boot) | 171 | $(Q)$(MAKE) $(clean)=$(boot) |
183 | # Temporary hack until we have migrated to asm-powerpc | ||
184 | $(Q)rm -rf arch/$(ARCH)/include | 172 | $(Q)rm -rf arch/$(ARCH)/include |
185 | 173 | ||
186 | archprepare: checkbin | 174 | archprepare: checkbin |
187 | 175 | ||
188 | # Temporary hack until we have migrated to asm-powerpc | 176 | # Temporary hack until we have migrated to asm-powerpc |
189 | include/asm: arch/$(ARCH)/include/asm | 177 | include/asm: arch/$(ARCH)/include/asm |
190 | arch/$(ARCH)/include/asm: | 178 | arch/$(ARCH)/include/asm: FORCE |
191 | $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi | 179 | $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi |
192 | $(Q)ln -fsn $(srctree)/include/asm-$(OLDARCH) arch/$(ARCH)/include/asm | 180 | $(Q)ln -fsn $(srctree)/include/asm-$(OLDARCH) arch/$(ARCH)/include/asm |
193 | 181 | ||
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile new file mode 100644 index 000000000000..9770f587af73 --- /dev/null +++ b/arch/powerpc/boot/Makefile | |||
@@ -0,0 +1,149 @@ | |||
1 | # Makefile for making ELF bootable images for booting on CHRP | ||
2 | # using Open Firmware. | ||
3 | # | ||
4 | # Geert Uytterhoeven September 1997 | ||
5 | # | ||
6 | # Based on coffboot by Paul Mackerras | ||
7 | # Simplified for ppc64 by Todd Inglett | ||
8 | # | ||
9 | # NOTE: this code is built for 32 bit in ELF32 format even though | ||
10 | # it packages a 64 bit kernel. We do this to simplify the | ||
11 | # bootloader and increase compatibility with OpenFirmware. | ||
12 | # | ||
13 | # To this end we need to define BOOTCC, etc, as the tools | ||
14 | # needed to build the 32 bit image. These are normally HOSTCC, | ||
15 | # but may be a third compiler if, for example, you are cross | ||
16 | # compiling from an intel box. Once the 64bit ppc gcc is | ||
17 | # stable it will probably simply be a compiler switch to | ||
18 | # compile for 32bit mode. | ||
19 | # To make it easier to setup a cross compiler, | ||
20 | # CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE | ||
21 | # in the toplevel makefile. | ||
22 | |||
23 | |||
24 | HOSTCC := gcc | ||
25 | BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \ | ||
26 | $(shell $(CROSS32CC) -print-file-name=include) -fPIC | ||
27 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc | ||
28 | BOOTLFLAGS := -T $(srctree)/$(src)/zImage.lds | ||
29 | OBJCOPYFLAGS := contents,alloc,load,readonly,data | ||
30 | |||
31 | zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c | ||
32 | zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h | ||
33 | zliblinuxheader := zlib.h zconf.h zutil.h | ||
34 | |||
35 | $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) | ||
36 | #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) | ||
37 | |||
38 | src-boot := string.S prom.c main.c div64.S crt0.S | ||
39 | src-boot += $(zlib) | ||
40 | src-boot := $(addprefix $(obj)/, $(src-boot)) | ||
41 | obj-boot := $(addsuffix .o, $(basename $(src-boot))) | ||
42 | |||
43 | BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) | ||
44 | |||
45 | quiet_cmd_copy_zlib = COPY $@ | ||
46 | cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@ | ||
47 | |||
48 | quiet_cmd_copy_zlibheader = COPY $@ | ||
49 | cmd_copy_zlibheader = sed "s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@ | ||
50 | # stddef.h for NULL | ||
51 | quiet_cmd_copy_zliblinuxheader = COPY $@ | ||
52 | cmd_copy_zliblinuxheader = sed "s@<linux/string.h>@\"string.h\"@;s@<linux/kernel.h>@<stddef.h>@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@ | ||
53 | |||
54 | $(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/% | ||
55 | $(call cmd,copy_zlib) | ||
56 | |||
57 | $(addprefix $(obj)/,$(zlibheader)): $(obj)/%: $(srctree)/lib/zlib_inflate/% | ||
58 | $(call cmd,copy_zlibheader) | ||
59 | |||
60 | $(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/% | ||
61 | $(call cmd,copy_zliblinuxheader) | ||
62 | |||
63 | clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) | ||
64 | |||
65 | |||
66 | quiet_cmd_bootcc = BOOTCC $@ | ||
67 | cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< | ||
68 | |||
69 | quiet_cmd_bootas = BOOTAS $@ | ||
70 | cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< | ||
71 | |||
72 | quiet_cmd_bootld = BOOTLD $@ | ||
73 | cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2) | ||
74 | |||
75 | $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c | ||
76 | $(call if_changed_dep,bootcc) | ||
77 | $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S | ||
78 | $(call if_changed_dep,bootas) | ||
79 | |||
80 | #----------------------------------------------------------- | ||
81 | # ELF sections within the zImage bootloader/wrapper | ||
82 | #----------------------------------------------------------- | ||
83 | required := vmlinux.strip | ||
84 | initrd := initrd | ||
85 | |||
86 | obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section))) | ||
87 | src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) | ||
88 | gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) | ||
89 | |||
90 | hostprogs-y := addnote addRamDisk | ||
91 | targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \ | ||
92 | $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ | ||
93 | $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ | ||
94 | $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ | ||
95 | vmlinux.initrd | ||
96 | extra-y := initrd.o | ||
97 | |||
98 | quiet_cmd_ramdisk = RAMDISK $@ | ||
99 | cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@ | ||
100 | |||
101 | quiet_cmd_stripvm = STRIP $@ | ||
102 | cmd_stripvm = $(STRIP) -s -R .comment $< -o $@ | ||
103 | |||
104 | vmlinux.strip: vmlinux | ||
105 | $(call if_changed,stripvm) | ||
106 | $(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz | ||
107 | $(call if_changed,ramdisk) | ||
108 | |||
109 | quiet_cmd_addsection = ADDSEC $@ | ||
110 | cmd_addsection = $(CROSS32OBJCOPY) $@ \ | ||
111 | --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \ | ||
112 | --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS) | ||
113 | |||
114 | quiet_cmd_addnote = ADDNOTE $@ | ||
115 | cmd_addnote = $(obj)/addnote $@ | ||
116 | |||
117 | $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % | ||
118 | $(call if_changed,gzip) | ||
119 | |||
120 | $(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz | ||
121 | cp -f $(obj)/ramdisk.image.gz $@ | ||
122 | |||
123 | $(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz | ||
124 | @touch $@ | ||
125 | |||
126 | $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c | ||
127 | $(call if_changed_dep,bootcc) | ||
128 | $(call cmd,addsection) | ||
129 | |||
130 | $(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required)) | ||
131 | $(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds | ||
132 | $(call cmd,bootld,$(obj-boot)) | ||
133 | |||
134 | $(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd)) | ||
135 | $(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds | ||
136 | $(call cmd,bootld,$(obj-boot)) | ||
137 | |||
138 | $(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote | ||
139 | @cp -f $< $@ | ||
140 | $(call if_changed,addnote) | ||
141 | |||
142 | $(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote | ||
143 | @cp -f $< $@ | ||
144 | $(call if_changed,addnote) | ||
145 | |||
146 | install: $(CONFIGURE) $(BOOTIMAGE) | ||
147 | sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" | ||
148 | |||
149 | clean-files := $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip) | ||
diff --git a/arch/powerpc/boot/README b/arch/powerpc/boot/README new file mode 100644 index 000000000000..3e11058760e4 --- /dev/null +++ b/arch/powerpc/boot/README | |||
@@ -0,0 +1,11 @@ | |||
1 | |||
2 | To extract the kernel vmlinux, System.map, .config or initrd from the zImage binary: | ||
3 | |||
4 | objcopy -j .kernel:vmlinux -O binary zImage vmlinux.gz | ||
5 | objcopy -j .kernel:System.map -O binary zImage System.map.gz | ||
6 | objcopy -j .kernel:.config -O binary zImage config.gz | ||
7 | objcopy -j .kernel:initrd -O binary zImage.initrd initrd.gz | ||
8 | |||
9 | |||
10 | Peter | ||
11 | |||
diff --git a/arch/powerpc/boot/addRamDisk.c b/arch/powerpc/boot/addRamDisk.c new file mode 100644 index 000000000000..c02a99952be7 --- /dev/null +++ b/arch/powerpc/boot/addRamDisk.c | |||
@@ -0,0 +1,311 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <netinet/in.h> | ||
4 | #include <unistd.h> | ||
5 | #include <sys/types.h> | ||
6 | #include <sys/stat.h> | ||
7 | #include <string.h> | ||
8 | #include <elf.h> | ||
9 | |||
10 | #define ElfHeaderSize (64 * 1024) | ||
11 | #define ElfPages (ElfHeaderSize / 4096) | ||
12 | #define KERNELBASE (0xc000000000000000) | ||
13 | #define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) | ||
14 | |||
15 | struct addr_range { | ||
16 | unsigned long long addr; | ||
17 | unsigned long memsize; | ||
18 | unsigned long offset; | ||
19 | }; | ||
20 | |||
21 | static int check_elf64(void *p, int size, struct addr_range *r) | ||
22 | { | ||
23 | Elf64_Ehdr *elf64 = p; | ||
24 | Elf64_Phdr *elf64ph; | ||
25 | |||
26 | if (elf64->e_ident[EI_MAG0] != ELFMAG0 || | ||
27 | elf64->e_ident[EI_MAG1] != ELFMAG1 || | ||
28 | elf64->e_ident[EI_MAG2] != ELFMAG2 || | ||
29 | elf64->e_ident[EI_MAG3] != ELFMAG3 || | ||
30 | elf64->e_ident[EI_CLASS] != ELFCLASS64 || | ||
31 | elf64->e_ident[EI_DATA] != ELFDATA2MSB || | ||
32 | elf64->e_type != ET_EXEC || elf64->e_machine != EM_PPC64) | ||
33 | return 0; | ||
34 | |||
35 | if ((elf64->e_phoff + sizeof(Elf64_Phdr)) > size) | ||
36 | return 0; | ||
37 | |||
38 | elf64ph = (Elf64_Phdr *) ((unsigned long)elf64 + | ||
39 | (unsigned long)elf64->e_phoff); | ||
40 | |||
41 | r->memsize = (unsigned long)elf64ph->p_memsz; | ||
42 | r->offset = (unsigned long)elf64ph->p_offset; | ||
43 | r->addr = (unsigned long long)elf64ph->p_vaddr; | ||
44 | |||
45 | #ifdef DEBUG | ||
46 | printf("PPC64 ELF file, ph:\n"); | ||
47 | printf("p_type 0x%08x\n", elf64ph->p_type); | ||
48 | printf("p_flags 0x%08x\n", elf64ph->p_flags); | ||
49 | printf("p_offset 0x%016llx\n", elf64ph->p_offset); | ||
50 | printf("p_vaddr 0x%016llx\n", elf64ph->p_vaddr); | ||
51 | printf("p_paddr 0x%016llx\n", elf64ph->p_paddr); | ||
52 | printf("p_filesz 0x%016llx\n", elf64ph->p_filesz); | ||
53 | printf("p_memsz 0x%016llx\n", elf64ph->p_memsz); | ||
54 | printf("p_align 0x%016llx\n", elf64ph->p_align); | ||
55 | printf("... skipping 0x%08lx bytes of ELF header\n", | ||
56 | (unsigned long)elf64ph->p_offset); | ||
57 | #endif | ||
58 | |||
59 | return 64; | ||
60 | } | ||
61 | void get4k(FILE *file, char *buf ) | ||
62 | { | ||
63 | unsigned j; | ||
64 | unsigned num = fread(buf, 1, 4096, file); | ||
65 | for ( j=num; j<4096; ++j ) | ||
66 | buf[j] = 0; | ||
67 | } | ||
68 | |||
69 | void put4k(FILE *file, char *buf ) | ||
70 | { | ||
71 | fwrite(buf, 1, 4096, file); | ||
72 | } | ||
73 | |||
74 | void death(const char *msg, FILE *fdesc, const char *fname) | ||
75 | { | ||
76 | fprintf(stderr, msg); | ||
77 | fclose(fdesc); | ||
78 | unlink(fname); | ||
79 | exit(1); | ||
80 | } | ||
81 | |||
82 | int main(int argc, char **argv) | ||
83 | { | ||
84 | char inbuf[4096]; | ||
85 | struct addr_range vmlinux; | ||
86 | FILE *ramDisk; | ||
87 | FILE *inputVmlinux; | ||
88 | FILE *outputVmlinux; | ||
89 | |||
90 | char *rd_name, *lx_name, *out_name; | ||
91 | |||
92 | size_t i; | ||
93 | unsigned long ramFileLen; | ||
94 | unsigned long ramLen; | ||
95 | unsigned long roundR; | ||
96 | unsigned long offset_end; | ||
97 | |||
98 | unsigned long kernelLen; | ||
99 | unsigned long actualKernelLen; | ||
100 | unsigned long round; | ||
101 | unsigned long roundedKernelLen; | ||
102 | unsigned long ramStartOffs; | ||
103 | unsigned long ramPages; | ||
104 | unsigned long roundedKernelPages; | ||
105 | unsigned long hvReleaseData; | ||
106 | u_int32_t eyeCatcher = 0xc8a5d9c4; | ||
107 | unsigned long naca; | ||
108 | unsigned long xRamDisk; | ||
109 | unsigned long xRamDiskSize; | ||
110 | long padPages; | ||
111 | |||
112 | |||
113 | if (argc < 2) { | ||
114 | fprintf(stderr, "Name of RAM disk file missing.\n"); | ||
115 | exit(1); | ||
116 | } | ||
117 | rd_name = argv[1]; | ||
118 | |||
119 | if (argc < 3) { | ||
120 | fprintf(stderr, "Name of vmlinux file missing.\n"); | ||
121 | exit(1); | ||
122 | } | ||
123 | lx_name = argv[2]; | ||
124 | |||
125 | if (argc < 4) { | ||
126 | fprintf(stderr, "Name of vmlinux output file missing.\n"); | ||
127 | exit(1); | ||
128 | } | ||
129 | out_name = argv[3]; | ||
130 | |||
131 | |||
132 | ramDisk = fopen(rd_name, "r"); | ||
133 | if ( ! ramDisk ) { | ||
134 | fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", rd_name); | ||
135 | exit(1); | ||
136 | } | ||
137 | |||
138 | inputVmlinux = fopen(lx_name, "r"); | ||
139 | if ( ! inputVmlinux ) { | ||
140 | fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", lx_name); | ||
141 | exit(1); | ||
142 | } | ||
143 | |||
144 | outputVmlinux = fopen(out_name, "w+"); | ||
145 | if ( ! outputVmlinux ) { | ||
146 | fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", out_name); | ||
147 | exit(1); | ||
148 | } | ||
149 | |||
150 | i = fread(inbuf, 1, sizeof(inbuf), inputVmlinux); | ||
151 | if (i != sizeof(inbuf)) { | ||
152 | fprintf(stderr, "can not read vmlinux file %s: %u\n", lx_name, i); | ||
153 | exit(1); | ||
154 | } | ||
155 | |||
156 | i = check_elf64(inbuf, sizeof(inbuf), &vmlinux); | ||
157 | if (i == 0) { | ||
158 | fprintf(stderr, "You must have a linux kernel specified as argv[2]\n"); | ||
159 | exit(1); | ||
160 | } | ||
161 | |||
162 | /* Input Vmlinux file */ | ||
163 | fseek(inputVmlinux, 0, SEEK_END); | ||
164 | kernelLen = ftell(inputVmlinux); | ||
165 | fseek(inputVmlinux, 0, SEEK_SET); | ||
166 | printf("kernel file size = %lu\n", kernelLen); | ||
167 | |||
168 | actualKernelLen = kernelLen - ElfHeaderSize; | ||
169 | |||
170 | printf("actual kernel length (minus ELF header) = %lu\n", actualKernelLen); | ||
171 | |||
172 | round = actualKernelLen % 4096; | ||
173 | roundedKernelLen = actualKernelLen; | ||
174 | if ( round ) | ||
175 | roundedKernelLen += (4096 - round); | ||
176 | printf("Vmlinux length rounded up to a 4k multiple = %ld/0x%lx \n", roundedKernelLen, roundedKernelLen); | ||
177 | roundedKernelPages = roundedKernelLen / 4096; | ||
178 | printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages); | ||
179 | |||
180 | offset_end = _ALIGN_UP(vmlinux.memsize, 4096); | ||
181 | /* calc how many pages we need to insert between the vmlinux and the start of the ram disk */ | ||
182 | padPages = offset_end/4096 - roundedKernelPages; | ||
183 | |||
184 | /* Check and see if the vmlinux is already larger than _end in System.map */ | ||
185 | if (padPages < 0) { | ||
186 | /* vmlinux is larger than _end - adjust the offset to the start of the embedded ram disk */ | ||
187 | offset_end = roundedKernelLen; | ||
188 | printf("vmlinux is larger than _end indicates it needs to be - offset_end = %lx \n", offset_end); | ||
189 | padPages = 0; | ||
190 | printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages); | ||
191 | } | ||
192 | else { | ||
193 | /* _end is larger than vmlinux - use the offset to _end that we calculated from the system map */ | ||
194 | printf("vmlinux is smaller than _end indicates is needed - offset_end = %lx \n", offset_end); | ||
195 | printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages); | ||
196 | } | ||
197 | |||
198 | |||
199 | |||
200 | /* Input Ram Disk file */ | ||
201 | // Set the offset that the ram disk will be started at. | ||
202 | ramStartOffs = offset_end; /* determined from the input vmlinux file and the system map */ | ||
203 | printf("Ram Disk will start at offset = 0x%lx \n", ramStartOffs); | ||
204 | |||
205 | fseek(ramDisk, 0, SEEK_END); | ||
206 | ramFileLen = ftell(ramDisk); | ||
207 | fseek(ramDisk, 0, SEEK_SET); | ||
208 | printf("%s file size = %ld/0x%lx \n", rd_name, ramFileLen, ramFileLen); | ||
209 | |||
210 | ramLen = ramFileLen; | ||
211 | |||
212 | roundR = 4096 - (ramLen % 4096); | ||
213 | if ( roundR ) { | ||
214 | printf("Rounding RAM disk file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR); | ||
215 | ramLen += roundR; | ||
216 | } | ||
217 | |||
218 | printf("Rounded RAM disk size is %ld/0x%lx \n", ramLen, ramLen); | ||
219 | ramPages = ramLen / 4096; | ||
220 | printf("RAM disk pages to copy = %ld/0x%lx\n", ramPages, ramPages); | ||
221 | |||
222 | |||
223 | |||
224 | // Copy 64K ELF header | ||
225 | for (i=0; i<(ElfPages); ++i) { | ||
226 | get4k( inputVmlinux, inbuf ); | ||
227 | put4k( outputVmlinux, inbuf ); | ||
228 | } | ||
229 | |||
230 | /* Copy the vmlinux (as full pages). */ | ||
231 | fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); | ||
232 | for ( i=0; i<roundedKernelPages; ++i ) { | ||
233 | get4k( inputVmlinux, inbuf ); | ||
234 | put4k( outputVmlinux, inbuf ); | ||
235 | } | ||
236 | |||
237 | /* Insert pad pages (if appropriate) that are needed between */ | ||
238 | /* | the end of the vmlinux and the ram disk. */ | ||
239 | for (i=0; i<padPages; ++i) { | ||
240 | memset(inbuf, 0, 4096); | ||
241 | put4k(outputVmlinux, inbuf); | ||
242 | } | ||
243 | |||
244 | /* Copy the ram disk (as full pages). */ | ||
245 | for ( i=0; i<ramPages; ++i ) { | ||
246 | get4k( ramDisk, inbuf ); | ||
247 | put4k( outputVmlinux, inbuf ); | ||
248 | } | ||
249 | |||
250 | /* Close the input files */ | ||
251 | fclose(ramDisk); | ||
252 | fclose(inputVmlinux); | ||
253 | /* And flush the written output file */ | ||
254 | fflush(outputVmlinux); | ||
255 | |||
256 | |||
257 | |||
258 | /* Fixup the new vmlinux to contain the ram disk starting offset (xRamDisk) and the ram disk size (xRamDiskSize) */ | ||
259 | /* fseek to the hvReleaseData pointer */ | ||
260 | fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET); | ||
261 | if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) { | ||
262 | death("Could not read hvReleaseData pointer\n", outputVmlinux, out_name); | ||
263 | } | ||
264 | hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */ | ||
265 | printf("hvReleaseData is at %08lx\n", hvReleaseData); | ||
266 | |||
267 | /* fseek to the hvReleaseData */ | ||
268 | fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET); | ||
269 | if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) { | ||
270 | death("Could not read hvReleaseData\n", outputVmlinux, out_name); | ||
271 | } | ||
272 | /* Check hvReleaseData sanity */ | ||
273 | if (memcmp(inbuf, &eyeCatcher, 4) != 0) { | ||
274 | death("hvReleaseData is invalid\n", outputVmlinux, out_name); | ||
275 | } | ||
276 | /* Get the naca pointer */ | ||
277 | naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE; | ||
278 | printf("Naca is at offset 0x%lx \n", naca); | ||
279 | |||
280 | /* fseek to the naca */ | ||
281 | fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); | ||
282 | if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) { | ||
283 | death("Could not read naca\n", outputVmlinux, out_name); | ||
284 | } | ||
285 | xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c])); | ||
286 | xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14])); | ||
287 | /* Make sure a RAM disk isn't already present */ | ||
288 | if ((xRamDisk != 0) || (xRamDiskSize != 0)) { | ||
289 | death("RAM disk is already attached to this kernel\n", outputVmlinux, out_name); | ||
290 | } | ||
291 | /* Fill in the values */ | ||
292 | *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs); | ||
293 | *((u_int32_t *) &inbuf[0x14]) = htonl(ramPages); | ||
294 | |||
295 | /* Write out the new naca */ | ||
296 | fflush(outputVmlinux); | ||
297 | fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); | ||
298 | if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) { | ||
299 | death("Could not write naca\n", outputVmlinux, out_name); | ||
300 | } | ||
301 | printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08lx\n", | ||
302 | ramPages, ramStartOffs); | ||
303 | |||
304 | /* Done */ | ||
305 | fclose(outputVmlinux); | ||
306 | /* Set permission to executable */ | ||
307 | chmod(out_name, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c new file mode 100644 index 000000000000..8041a9845ab7 --- /dev/null +++ b/arch/powerpc/boot/addnote.c | |||
@@ -0,0 +1,205 @@ | |||
1 | /* | ||
2 | * Program to hack in a PT_NOTE program header entry in an ELF file. | ||
3 | * This is needed for OF on RS/6000s to load an image correctly. | ||
4 | * Note that OF needs a program header entry for the note, not an | ||
5 | * ELF section. | ||
6 | * | ||
7 | * Copyright 2000 Paul Mackerras. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | * | ||
14 | * Usage: addnote zImage | ||
15 | */ | ||
16 | #include <stdio.h> | ||
17 | #include <stdlib.h> | ||
18 | #include <fcntl.h> | ||
19 | #include <unistd.h> | ||
20 | #include <string.h> | ||
21 | |||
22 | /* CHRP note section */ | ||
23 | char arch[] = "PowerPC"; | ||
24 | |||
25 | #define N_DESCR 6 | ||
26 | unsigned int descr[N_DESCR] = { | ||
27 | 0xffffffff, /* real-mode = true */ | ||
28 | 0x00c00000, /* real-base, i.e. where we expect OF to be */ | ||
29 | 0xffffffff, /* real-size */ | ||
30 | 0xffffffff, /* virt-base */ | ||
31 | 0xffffffff, /* virt-size */ | ||
32 | 0x4000, /* load-base */ | ||
33 | }; | ||
34 | |||
35 | /* RPA note section */ | ||
36 | char rpaname[] = "IBM,RPA-Client-Config"; | ||
37 | |||
38 | /* | ||
39 | * Note: setting ignore_my_client_config *should* mean that OF ignores | ||
40 | * all the other fields, but there is a firmware bug which means that | ||
41 | * it looks at the splpar field at least. So these values need to be | ||
42 | * reasonable. | ||
43 | */ | ||
44 | #define N_RPA_DESCR 8 | ||
45 | unsigned int rpanote[N_RPA_DESCR] = { | ||
46 | 0, /* lparaffinity */ | ||
47 | 64, /* min_rmo_size */ | ||
48 | 0, /* min_rmo_percent */ | ||
49 | 40, /* max_pft_size */ | ||
50 | 1, /* splpar */ | ||
51 | -1, /* min_load */ | ||
52 | 0, /* new_mem_def */ | ||
53 | 1, /* ignore_my_client_config */ | ||
54 | }; | ||
55 | |||
56 | #define ROUNDUP(len) (((len) + 3) & ~3) | ||
57 | |||
58 | unsigned char buf[512]; | ||
59 | |||
60 | #define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) | ||
61 | #define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2)) | ||
62 | |||
63 | #define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \ | ||
64 | buf[(off) + 1] = (v) & 0xff) | ||
65 | #define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \ | ||
66 | PUT_16BE((off) + 2, (v))) | ||
67 | |||
68 | /* Structure of an ELF file */ | ||
69 | #define E_IDENT 0 /* ELF header */ | ||
70 | #define E_PHOFF 28 | ||
71 | #define E_PHENTSIZE 42 | ||
72 | #define E_PHNUM 44 | ||
73 | #define E_HSIZE 52 /* size of ELF header */ | ||
74 | |||
75 | #define EI_MAGIC 0 /* offsets in E_IDENT area */ | ||
76 | #define EI_CLASS 4 | ||
77 | #define EI_DATA 5 | ||
78 | |||
79 | #define PH_TYPE 0 /* ELF program header */ | ||
80 | #define PH_OFFSET 4 | ||
81 | #define PH_FILESZ 16 | ||
82 | #define PH_HSIZE 32 /* size of program header */ | ||
83 | |||
84 | #define PT_NOTE 4 /* Program header type = note */ | ||
85 | |||
86 | #define ELFCLASS32 1 | ||
87 | #define ELFDATA2MSB 2 | ||
88 | |||
89 | unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; | ||
90 | |||
91 | int | ||
92 | main(int ac, char **av) | ||
93 | { | ||
94 | int fd, n, i; | ||
95 | int ph, ps, np; | ||
96 | int nnote, nnote2, ns; | ||
97 | |||
98 | if (ac != 2) { | ||
99 | fprintf(stderr, "Usage: %s elf-file\n", av[0]); | ||
100 | exit(1); | ||
101 | } | ||
102 | fd = open(av[1], O_RDWR); | ||
103 | if (fd < 0) { | ||
104 | perror(av[1]); | ||
105 | exit(1); | ||
106 | } | ||
107 | |||
108 | nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr); | ||
109 | nnote2 = 12 + ROUNDUP(strlen(rpaname) + 1) + sizeof(rpanote); | ||
110 | |||
111 | n = read(fd, buf, sizeof(buf)); | ||
112 | if (n < 0) { | ||
113 | perror("read"); | ||
114 | exit(1); | ||
115 | } | ||
116 | |||
117 | if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0) | ||
118 | goto notelf; | ||
119 | |||
120 | if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 | ||
121 | || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { | ||
122 | fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", | ||
123 | av[1]); | ||
124 | exit(1); | ||
125 | } | ||
126 | |||
127 | ph = GET_32BE(E_PHOFF); | ||
128 | ps = GET_16BE(E_PHENTSIZE); | ||
129 | np = GET_16BE(E_PHNUM); | ||
130 | if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) | ||
131 | goto notelf; | ||
132 | if (ph + (np + 2) * ps + nnote + nnote2 > n) | ||
133 | goto nospace; | ||
134 | |||
135 | for (i = 0; i < np; ++i) { | ||
136 | if (GET_32BE(ph + PH_TYPE) == PT_NOTE) { | ||
137 | fprintf(stderr, "%s already has a note entry\n", | ||
138 | av[1]); | ||
139 | exit(0); | ||
140 | } | ||
141 | ph += ps; | ||
142 | } | ||
143 | |||
144 | /* XXX check that the area we want to use is all zeroes */ | ||
145 | for (i = 0; i < 2 * ps + nnote + nnote2; ++i) | ||
146 | if (buf[ph + i] != 0) | ||
147 | goto nospace; | ||
148 | |||
149 | /* fill in the program header entry */ | ||
150 | ns = ph + 2 * ps; | ||
151 | PUT_32BE(ph + PH_TYPE, PT_NOTE); | ||
152 | PUT_32BE(ph + PH_OFFSET, ns); | ||
153 | PUT_32BE(ph + PH_FILESZ, nnote); | ||
154 | |||
155 | /* fill in the note area we point to */ | ||
156 | /* XXX we should probably make this a proper section */ | ||
157 | PUT_32BE(ns, strlen(arch) + 1); | ||
158 | PUT_32BE(ns + 4, N_DESCR * 4); | ||
159 | PUT_32BE(ns + 8, 0x1275); | ||
160 | strcpy((char *) &buf[ns + 12], arch); | ||
161 | ns += 12 + strlen(arch) + 1; | ||
162 | for (i = 0; i < N_DESCR; ++i, ns += 4) | ||
163 | PUT_32BE(ns, descr[i]); | ||
164 | |||
165 | /* fill in the second program header entry and the RPA note area */ | ||
166 | ph += ps; | ||
167 | PUT_32BE(ph + PH_TYPE, PT_NOTE); | ||
168 | PUT_32BE(ph + PH_OFFSET, ns); | ||
169 | PUT_32BE(ph + PH_FILESZ, nnote2); | ||
170 | |||
171 | /* fill in the note area we point to */ | ||
172 | PUT_32BE(ns, strlen(rpaname) + 1); | ||
173 | PUT_32BE(ns + 4, sizeof(rpanote)); | ||
174 | PUT_32BE(ns + 8, 0x12759999); | ||
175 | strcpy((char *) &buf[ns + 12], rpaname); | ||
176 | ns += 12 + ROUNDUP(strlen(rpaname) + 1); | ||
177 | for (i = 0; i < N_RPA_DESCR; ++i, ns += 4) | ||
178 | PUT_32BE(ns, rpanote[i]); | ||
179 | |||
180 | /* Update the number of program headers */ | ||
181 | PUT_16BE(E_PHNUM, np + 2); | ||
182 | |||
183 | /* write back */ | ||
184 | lseek(fd, (long) 0, SEEK_SET); | ||
185 | i = write(fd, buf, n); | ||
186 | if (i < 0) { | ||
187 | perror("write"); | ||
188 | exit(1); | ||
189 | } | ||
190 | if (i < n) { | ||
191 | fprintf(stderr, "%s: write truncated\n", av[1]); | ||
192 | exit(1); | ||
193 | } | ||
194 | |||
195 | exit(0); | ||
196 | |||
197 | notelf: | ||
198 | fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]); | ||
199 | exit(1); | ||
200 | |||
201 | nospace: | ||
202 | fprintf(stderr, "sorry, I can't find space in %s to put the note\n", | ||
203 | av[1]); | ||
204 | exit(1); | ||
205 | } | ||
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S new file mode 100644 index 000000000000..d2f2ace56cd3 --- /dev/null +++ b/arch/powerpc/boot/crt0.S | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * NOTE: this code runs in 32 bit mode and is packaged as ELF32. | ||
10 | */ | ||
11 | |||
12 | #include "ppc_asm.h" | ||
13 | |||
14 | .text | ||
15 | .globl _zimage_start | ||
16 | _zimage_start: | ||
17 | bl 1f | ||
18 | |||
19 | 1: | ||
20 | mflr r0 | ||
21 | lis r9,1b@ha | ||
22 | addi r9,r9,1b@l | ||
23 | subf. r0,r9,r0 | ||
24 | beq 3f | ||
25 | |||
26 | lis r9,__got2_start@ha | ||
27 | addi r9,r9,__got2_start@l | ||
28 | lis r8,__got2_end@ha | ||
29 | addi r8,r8,__got2_end@l | ||
30 | subf. r8,r9,r8 | ||
31 | beq 3f | ||
32 | srwi. r8,r8,2 | ||
33 | mtctr r8 | ||
34 | add r9,r0,r9 | ||
35 | 2: | ||
36 | lwz r8,0(r9) | ||
37 | add r8,r8,r0 | ||
38 | stw r8,0(r9) | ||
39 | addi r9,r9,4 | ||
40 | bdnz 2b | ||
41 | |||
42 | 3: | ||
43 | lis r9,_start@h | ||
44 | add r9,r0,r9 | ||
45 | lis r8,_etext@ha | ||
46 | addi r8,r8,_etext@l | ||
47 | add r8,r0,r8 | ||
48 | 4: dcbf r0,r9 | ||
49 | icbi r0,r9 | ||
50 | addi r9,r9,0x20 | ||
51 | cmplwi 0,r9,8 | ||
52 | blt 4b | ||
53 | sync | ||
54 | isync | ||
55 | |||
56 | mr r6,r1 | ||
57 | b start | ||
58 | |||
diff --git a/arch/powerpc/boot/div64.S b/arch/powerpc/boot/div64.S new file mode 100644 index 000000000000..722f360a32a9 --- /dev/null +++ b/arch/powerpc/boot/div64.S | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Divide a 64-bit unsigned number by a 32-bit unsigned number. | ||
3 | * This routine assumes that the top 32 bits of the dividend are | ||
4 | * non-zero to start with. | ||
5 | * On entry, r3 points to the dividend, which get overwritten with | ||
6 | * the 64-bit quotient, and r4 contains the divisor. | ||
7 | * On exit, r3 contains the remainder. | ||
8 | * | ||
9 | * Copyright (C) 2002 Paul Mackerras, IBM Corp. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | #include "ppc_asm.h" | ||
17 | |||
18 | .globl __div64_32 | ||
19 | __div64_32: | ||
20 | lwz r5,0(r3) # get the dividend into r5/r6 | ||
21 | lwz r6,4(r3) | ||
22 | cmplw r5,r4 | ||
23 | li r7,0 | ||
24 | li r8,0 | ||
25 | blt 1f | ||
26 | divwu r7,r5,r4 # if dividend.hi >= divisor, | ||
27 | mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor | ||
28 | subf. r5,r0,r5 # dividend.hi %= divisor | ||
29 | beq 3f | ||
30 | 1: mr r11,r5 # here dividend.hi != 0 | ||
31 | andis. r0,r5,0xc000 | ||
32 | bne 2f | ||
33 | cntlzw r0,r5 # we are shifting the dividend right | ||
34 | li r10,-1 # to make it < 2^32, and shifting | ||
35 | srw r10,r10,r0 # the divisor right the same amount, | ||
36 | add r9,r4,r10 # rounding up (so the estimate cannot | ||
37 | andc r11,r6,r10 # ever be too large, only too small) | ||
38 | andc r9,r9,r10 | ||
39 | or r11,r5,r11 | ||
40 | rotlw r9,r9,r0 | ||
41 | rotlw r11,r11,r0 | ||
42 | divwu r11,r11,r9 # then we divide the shifted quantities | ||
43 | 2: mullw r10,r11,r4 # to get an estimate of the quotient, | ||
44 | mulhwu r9,r11,r4 # multiply the estimate by the divisor, | ||
45 | subfc r6,r10,r6 # take the product from the divisor, | ||
46 | add r8,r8,r11 # and add the estimate to the accumulated | ||
47 | subfe. r5,r9,r5 # quotient | ||
48 | bne 1b | ||
49 | 3: cmplw r6,r4 | ||
50 | blt 4f | ||
51 | divwu r0,r6,r4 # perform the remaining 32-bit division | ||
52 | mullw r10,r0,r4 # and get the remainder | ||
53 | add r8,r8,r0 | ||
54 | subf r6,r10,r6 | ||
55 | 4: stw r7,0(r3) # return the quotient in *r3 | ||
56 | stw r8,4(r3) | ||
57 | mr r3,r6 # return the remainder in r3 | ||
58 | blr | ||
diff --git a/arch/powerpc/boot/elf.h b/arch/powerpc/boot/elf.h new file mode 100644 index 000000000000..d4828fcf1cb9 --- /dev/null +++ b/arch/powerpc/boot/elf.h | |||
@@ -0,0 +1,149 @@ | |||
1 | #ifndef _PPC_BOOT_ELF_H_ | ||
2 | #define _PPC_BOOT_ELF_H_ | ||
3 | |||
4 | /* 32-bit ELF base types. */ | ||
5 | typedef unsigned int Elf32_Addr; | ||
6 | typedef unsigned short Elf32_Half; | ||
7 | typedef unsigned int Elf32_Off; | ||
8 | typedef signed int Elf32_Sword; | ||
9 | typedef unsigned int Elf32_Word; | ||
10 | |||
11 | /* 64-bit ELF base types. */ | ||
12 | typedef unsigned long long Elf64_Addr; | ||
13 | typedef unsigned short Elf64_Half; | ||
14 | typedef signed short Elf64_SHalf; | ||
15 | typedef unsigned long long Elf64_Off; | ||
16 | typedef signed int Elf64_Sword; | ||
17 | typedef unsigned int Elf64_Word; | ||
18 | typedef unsigned long long Elf64_Xword; | ||
19 | typedef signed long long Elf64_Sxword; | ||
20 | |||
21 | /* These constants are for the segment types stored in the image headers */ | ||
22 | #define PT_NULL 0 | ||
23 | #define PT_LOAD 1 | ||
24 | #define PT_DYNAMIC 2 | ||
25 | #define PT_INTERP 3 | ||
26 | #define PT_NOTE 4 | ||
27 | #define PT_SHLIB 5 | ||
28 | #define PT_PHDR 6 | ||
29 | #define PT_TLS 7 /* Thread local storage segment */ | ||
30 | #define PT_LOOS 0x60000000 /* OS-specific */ | ||
31 | #define PT_HIOS 0x6fffffff /* OS-specific */ | ||
32 | #define PT_LOPROC 0x70000000 | ||
33 | #define PT_HIPROC 0x7fffffff | ||
34 | #define PT_GNU_EH_FRAME 0x6474e550 | ||
35 | |||
36 | #define PT_GNU_STACK (PT_LOOS + 0x474e551) | ||
37 | |||
38 | /* These constants define the different elf file types */ | ||
39 | #define ET_NONE 0 | ||
40 | #define ET_REL 1 | ||
41 | #define ET_EXEC 2 | ||
42 | #define ET_DYN 3 | ||
43 | #define ET_CORE 4 | ||
44 | #define ET_LOPROC 0xff00 | ||
45 | #define ET_HIPROC 0xffff | ||
46 | |||
47 | /* These constants define the various ELF target machines */ | ||
48 | #define EM_NONE 0 | ||
49 | #define EM_PPC 20 /* PowerPC */ | ||
50 | #define EM_PPC64 21 /* PowerPC64 */ | ||
51 | |||
52 | #define EI_NIDENT 16 | ||
53 | |||
54 | typedef struct elf32_hdr { | ||
55 | unsigned char e_ident[EI_NIDENT]; | ||
56 | Elf32_Half e_type; | ||
57 | Elf32_Half e_machine; | ||
58 | Elf32_Word e_version; | ||
59 | Elf32_Addr e_entry; /* Entry point */ | ||
60 | Elf32_Off e_phoff; | ||
61 | Elf32_Off e_shoff; | ||
62 | Elf32_Word e_flags; | ||
63 | Elf32_Half e_ehsize; | ||
64 | Elf32_Half e_phentsize; | ||
65 | Elf32_Half e_phnum; | ||
66 | Elf32_Half e_shentsize; | ||
67 | Elf32_Half e_shnum; | ||
68 | Elf32_Half e_shstrndx; | ||
69 | } Elf32_Ehdr; | ||
70 | |||
71 | typedef struct elf64_hdr { | ||
72 | unsigned char e_ident[16]; /* ELF "magic number" */ | ||
73 | Elf64_Half e_type; | ||
74 | Elf64_Half e_machine; | ||
75 | Elf64_Word e_version; | ||
76 | Elf64_Addr e_entry; /* Entry point virtual address */ | ||
77 | Elf64_Off e_phoff; /* Program header table file offset */ | ||
78 | Elf64_Off e_shoff; /* Section header table file offset */ | ||
79 | Elf64_Word e_flags; | ||
80 | Elf64_Half e_ehsize; | ||
81 | Elf64_Half e_phentsize; | ||
82 | Elf64_Half e_phnum; | ||
83 | Elf64_Half e_shentsize; | ||
84 | Elf64_Half e_shnum; | ||
85 | Elf64_Half e_shstrndx; | ||
86 | } Elf64_Ehdr; | ||
87 | |||
88 | /* These constants define the permissions on sections in the program | ||
89 | header, p_flags. */ | ||
90 | #define PF_R 0x4 | ||
91 | #define PF_W 0x2 | ||
92 | #define PF_X 0x1 | ||
93 | |||
94 | typedef struct elf32_phdr { | ||
95 | Elf32_Word p_type; | ||
96 | Elf32_Off p_offset; | ||
97 | Elf32_Addr p_vaddr; | ||
98 | Elf32_Addr p_paddr; | ||
99 | Elf32_Word p_filesz; | ||
100 | Elf32_Word p_memsz; | ||
101 | Elf32_Word p_flags; | ||
102 | Elf32_Word p_align; | ||
103 | } Elf32_Phdr; | ||
104 | |||
105 | typedef struct elf64_phdr { | ||
106 | Elf64_Word p_type; | ||
107 | Elf64_Word p_flags; | ||
108 | Elf64_Off p_offset; /* Segment file offset */ | ||
109 | Elf64_Addr p_vaddr; /* Segment virtual address */ | ||
110 | Elf64_Addr p_paddr; /* Segment physical address */ | ||
111 | Elf64_Xword p_filesz; /* Segment size in file */ | ||
112 | Elf64_Xword p_memsz; /* Segment size in memory */ | ||
113 | Elf64_Xword p_align; /* Segment alignment, file & memory */ | ||
114 | } Elf64_Phdr; | ||
115 | |||
116 | #define EI_MAG0 0 /* e_ident[] indexes */ | ||
117 | #define EI_MAG1 1 | ||
118 | #define EI_MAG2 2 | ||
119 | #define EI_MAG3 3 | ||
120 | #define EI_CLASS 4 | ||
121 | #define EI_DATA 5 | ||
122 | #define EI_VERSION 6 | ||
123 | #define EI_OSABI 7 | ||
124 | #define EI_PAD 8 | ||
125 | |||
126 | #define ELFMAG0 0x7f /* EI_MAG */ | ||
127 | #define ELFMAG1 'E' | ||
128 | #define ELFMAG2 'L' | ||
129 | #define ELFMAG3 'F' | ||
130 | #define ELFMAG "\177ELF" | ||
131 | #define SELFMAG 4 | ||
132 | |||
133 | #define ELFCLASSNONE 0 /* EI_CLASS */ | ||
134 | #define ELFCLASS32 1 | ||
135 | #define ELFCLASS64 2 | ||
136 | #define ELFCLASSNUM 3 | ||
137 | |||
138 | #define ELFDATANONE 0 /* e_ident[EI_DATA] */ | ||
139 | #define ELFDATA2LSB 1 | ||
140 | #define ELFDATA2MSB 2 | ||
141 | |||
142 | #define EV_NONE 0 /* e_version, EI_VERSION */ | ||
143 | #define EV_CURRENT 1 | ||
144 | #define EV_NUM 2 | ||
145 | |||
146 | #define ELFOSABI_NONE 0 | ||
147 | #define ELFOSABI_LINUX 3 | ||
148 | |||
149 | #endif /* _PPC_BOOT_ELF_H_ */ | ||
diff --git a/arch/powerpc/boot/install.sh b/arch/powerpc/boot/install.sh new file mode 100644 index 000000000000..eacce9590816 --- /dev/null +++ b/arch/powerpc/boot/install.sh | |||
@@ -0,0 +1,42 @@ | |||
1 | #!/bin/sh | ||
2 | # | ||
3 | # arch/ppc64/boot/install.sh | ||
4 | # | ||
5 | # This file is subject to the terms and conditions of the GNU General Public | ||
6 | # License. See the file "COPYING" in the main directory of this archive | ||
7 | # for more details. | ||
8 | # | ||
9 | # Copyright (C) 1995 by Linus Torvalds | ||
10 | # | ||
11 | # Blatantly stolen from in arch/i386/boot/install.sh by Dave Hansen | ||
12 | # | ||
13 | # "make install" script for ppc64 architecture | ||
14 | # | ||
15 | # Arguments: | ||
16 | # $1 - kernel version | ||
17 | # $2 - kernel image file | ||
18 | # $3 - kernel map file | ||
19 | # $4 - default install path (blank if root directory) | ||
20 | # $5 - kernel boot file, the zImage | ||
21 | # | ||
22 | |||
23 | # User may have a custom install script | ||
24 | |||
25 | if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi | ||
26 | if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi | ||
27 | |||
28 | # Default install | ||
29 | |||
30 | # this should work for both the pSeries zImage and the iSeries vmlinux.sm | ||
31 | image_name=`basename $2` | ||
32 | |||
33 | if [ -f $4/$image_name ]; then | ||
34 | mv $4/$image_name $4/$image_name.old | ||
35 | fi | ||
36 | |||
37 | if [ -f $4/System.map ]; then | ||
38 | mv $4/System.map $4/System.old | ||
39 | fi | ||
40 | |||
41 | cat $2 > $4/$image_name | ||
42 | cp $3 $4/System.map | ||
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c new file mode 100644 index 000000000000..64ec93116fa6 --- /dev/null +++ b/arch/powerpc/boot/main.c | |||
@@ -0,0 +1,321 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <stdarg.h> | ||
12 | #include <stddef.h> | ||
13 | #include "elf.h" | ||
14 | #include "page.h" | ||
15 | #include "string.h" | ||
16 | #include "stdio.h" | ||
17 | #include "prom.h" | ||
18 | #include "zlib.h" | ||
19 | |||
20 | extern void flush_cache(void *, unsigned long); | ||
21 | |||
22 | |||
23 | /* Value picked to match that used by yaboot */ | ||
24 | #define PROG_START 0x01400000 | ||
25 | #define RAM_END (512<<20) // Fixme: use OF */ | ||
26 | #define ONE_MB 0x100000 | ||
27 | |||
28 | extern char _start[]; | ||
29 | extern char __bss_start[]; | ||
30 | extern char _end[]; | ||
31 | extern char _vmlinux_start[]; | ||
32 | extern char _vmlinux_end[]; | ||
33 | extern char _initrd_start[]; | ||
34 | extern char _initrd_end[]; | ||
35 | |||
36 | struct addr_range { | ||
37 | unsigned long addr; | ||
38 | unsigned long size; | ||
39 | unsigned long memsize; | ||
40 | }; | ||
41 | static struct addr_range vmlinux; | ||
42 | static struct addr_range vmlinuz; | ||
43 | static struct addr_range initrd; | ||
44 | |||
45 | static unsigned long elfoffset; | ||
46 | |||
47 | static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */ | ||
48 | static char elfheader[256]; | ||
49 | |||
50 | |||
51 | typedef void (*kernel_entry_t)( unsigned long, | ||
52 | unsigned long, | ||
53 | void *, | ||
54 | void *); | ||
55 | |||
56 | |||
57 | #undef DEBUG | ||
58 | |||
59 | static unsigned long claim_base; | ||
60 | |||
61 | #define HEAD_CRC 2 | ||
62 | #define EXTRA_FIELD 4 | ||
63 | #define ORIG_NAME 8 | ||
64 | #define COMMENT 0x10 | ||
65 | #define RESERVED 0xe0 | ||
66 | |||
67 | static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) | ||
68 | { | ||
69 | z_stream s; | ||
70 | int r, i, flags; | ||
71 | |||
72 | /* skip header */ | ||
73 | i = 10; | ||
74 | flags = src[3]; | ||
75 | if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { | ||
76 | printf("bad gzipped data\n\r"); | ||
77 | exit(); | ||
78 | } | ||
79 | if ((flags & EXTRA_FIELD) != 0) | ||
80 | i = 12 + src[10] + (src[11] << 8); | ||
81 | if ((flags & ORIG_NAME) != 0) | ||
82 | while (src[i++] != 0) | ||
83 | ; | ||
84 | if ((flags & COMMENT) != 0) | ||
85 | while (src[i++] != 0) | ||
86 | ; | ||
87 | if ((flags & HEAD_CRC) != 0) | ||
88 | i += 2; | ||
89 | if (i >= *lenp) { | ||
90 | printf("gunzip: ran out of data in header\n\r"); | ||
91 | exit(); | ||
92 | } | ||
93 | |||
94 | if (zlib_inflate_workspacesize() > sizeof(scratch)) { | ||
95 | printf("gunzip needs more mem\n"); | ||
96 | exit(); | ||
97 | } | ||
98 | memset(&s, 0, sizeof(s)); | ||
99 | s.workspace = scratch; | ||
100 | r = zlib_inflateInit2(&s, -MAX_WBITS); | ||
101 | if (r != Z_OK) { | ||
102 | printf("inflateInit2 returned %d\n\r", r); | ||
103 | exit(); | ||
104 | } | ||
105 | s.next_in = src + i; | ||
106 | s.avail_in = *lenp - i; | ||
107 | s.next_out = dst; | ||
108 | s.avail_out = dstlen; | ||
109 | r = zlib_inflate(&s, Z_FULL_FLUSH); | ||
110 | if (r != Z_OK && r != Z_STREAM_END) { | ||
111 | printf("inflate returned %d msg: %s\n\r", r, s.msg); | ||
112 | exit(); | ||
113 | } | ||
114 | *lenp = s.next_out - (unsigned char *) dst; | ||
115 | zlib_inflateEnd(&s); | ||
116 | } | ||
117 | |||
118 | static unsigned long try_claim(unsigned long size) | ||
119 | { | ||
120 | unsigned long addr = 0; | ||
121 | |||
122 | for(; claim_base < RAM_END; claim_base += ONE_MB) { | ||
123 | #ifdef DEBUG | ||
124 | printf(" trying: 0x%08lx\n\r", claim_base); | ||
125 | #endif | ||
126 | addr = (unsigned long)claim(claim_base, size, 0); | ||
127 | if ((void *)addr != (void *)-1) | ||
128 | break; | ||
129 | } | ||
130 | if (addr == 0) | ||
131 | return 0; | ||
132 | claim_base = PAGE_ALIGN(claim_base + size); | ||
133 | return addr; | ||
134 | } | ||
135 | |||
136 | static int is_elf64(void *hdr) | ||
137 | { | ||
138 | Elf64_Ehdr *elf64 = hdr; | ||
139 | Elf64_Phdr *elf64ph; | ||
140 | unsigned int i; | ||
141 | |||
142 | if (!(elf64->e_ident[EI_MAG0] == ELFMAG0 && | ||
143 | elf64->e_ident[EI_MAG1] == ELFMAG1 && | ||
144 | elf64->e_ident[EI_MAG2] == ELFMAG2 && | ||
145 | elf64->e_ident[EI_MAG3] == ELFMAG3 && | ||
146 | elf64->e_ident[EI_CLASS] == ELFCLASS64 && | ||
147 | elf64->e_ident[EI_DATA] == ELFDATA2MSB && | ||
148 | elf64->e_type == ET_EXEC && | ||
149 | elf64->e_machine == EM_PPC64)) | ||
150 | return 0; | ||
151 | |||
152 | elf64ph = (Elf64_Phdr *)((unsigned long)elf64 + | ||
153 | (unsigned long)elf64->e_phoff); | ||
154 | for (i = 0; i < (unsigned int)elf64->e_phnum; i++, elf64ph++) | ||
155 | if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0) | ||
156 | break; | ||
157 | if (i >= (unsigned int)elf64->e_phnum) | ||
158 | return 0; | ||
159 | |||
160 | elfoffset = (unsigned long)elf64ph->p_offset; | ||
161 | vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset; | ||
162 | vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset; | ||
163 | return 1; | ||
164 | } | ||
165 | |||
166 | static int is_elf32(void *hdr) | ||
167 | { | ||
168 | Elf32_Ehdr *elf32 = hdr; | ||
169 | Elf32_Phdr *elf32ph; | ||
170 | unsigned int i; | ||
171 | |||
172 | if (!(elf32->e_ident[EI_MAG0] == ELFMAG0 && | ||
173 | elf32->e_ident[EI_MAG1] == ELFMAG1 && | ||
174 | elf32->e_ident[EI_MAG2] == ELFMAG2 && | ||
175 | elf32->e_ident[EI_MAG3] == ELFMAG3 && | ||
176 | elf32->e_ident[EI_CLASS] == ELFCLASS32 && | ||
177 | elf32->e_ident[EI_DATA] == ELFDATA2MSB && | ||
178 | elf32->e_type == ET_EXEC && | ||
179 | elf32->e_machine == EM_PPC)) | ||
180 | return 0; | ||
181 | |||
182 | elf32 = (Elf32_Ehdr *)elfheader; | ||
183 | elf32ph = (Elf32_Phdr *) ((unsigned long)elf32 + elf32->e_phoff); | ||
184 | for (i = 0; i < elf32->e_phnum; i++, elf32ph++) | ||
185 | if (elf32ph->p_type == PT_LOAD && elf32ph->p_offset != 0) | ||
186 | break; | ||
187 | if (i >= elf32->e_phnum) | ||
188 | return 0; | ||
189 | |||
190 | elfoffset = elf32ph->p_offset; | ||
191 | vmlinux.size = elf32ph->p_filesz + elf32ph->p_offset; | ||
192 | vmlinux.memsize = elf32ph->p_memsz + elf32ph->p_offset; | ||
193 | return 1; | ||
194 | } | ||
195 | |||
196 | void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | ||
197 | { | ||
198 | int len; | ||
199 | kernel_entry_t kernel_entry; | ||
200 | |||
201 | memset(__bss_start, 0, _end - __bss_start); | ||
202 | |||
203 | prom = (int (*)(void *)) promptr; | ||
204 | chosen_handle = finddevice("/chosen"); | ||
205 | if (chosen_handle == (void *) -1) | ||
206 | exit(); | ||
207 | if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) | ||
208 | exit(); | ||
209 | stderr = stdout; | ||
210 | if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) | ||
211 | exit(); | ||
212 | |||
213 | printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp); | ||
214 | |||
215 | vmlinuz.addr = (unsigned long)_vmlinux_start; | ||
216 | vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); | ||
217 | |||
218 | /* gunzip the ELF header of the kernel */ | ||
219 | if (*(unsigned short *)vmlinuz.addr == 0x1f8b) { | ||
220 | len = vmlinuz.size; | ||
221 | gunzip(elfheader, sizeof(elfheader), | ||
222 | (unsigned char *)vmlinuz.addr, &len); | ||
223 | } else | ||
224 | memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader)); | ||
225 | |||
226 | if (!is_elf64(elfheader) && !is_elf32(elfheader)) { | ||
227 | printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r"); | ||
228 | exit(); | ||
229 | } | ||
230 | |||
231 | /* | ||
232 | * The first available claim_base must be above the end of the | ||
233 | * the loaded kernel wrapper file (_start to _end includes the | ||
234 | * initrd image if it is present) and rounded up to a nice | ||
235 | * 1 MB boundary for good measure. | ||
236 | */ | ||
237 | |||
238 | claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); | ||
239 | |||
240 | #if defined(PROG_START) | ||
241 | /* | ||
242 | * Maintain a "magic" minimum address. This keeps some older | ||
243 | * firmware platforms running. | ||
244 | */ | ||
245 | |||
246 | if (claim_base < PROG_START) | ||
247 | claim_base = PROG_START; | ||
248 | #endif | ||
249 | |||
250 | /* We need to claim the memsize plus the file offset since gzip | ||
251 | * will expand the header (file offset), then the kernel, then | ||
252 | * possible rubbish we don't care about. But the kernel bss must | ||
253 | * be claimed (it will be zero'd by the kernel itself) | ||
254 | */ | ||
255 | printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize); | ||
256 | vmlinux.addr = try_claim(vmlinux.memsize); | ||
257 | if (vmlinux.addr == 0) { | ||
258 | printf("Can't allocate memory for kernel image !\n\r"); | ||
259 | exit(); | ||
260 | } | ||
261 | |||
262 | /* | ||
263 | * Now we try to claim memory for the initrd (and copy it there) | ||
264 | */ | ||
265 | initrd.size = (unsigned long)(_initrd_end - _initrd_start); | ||
266 | initrd.memsize = initrd.size; | ||
267 | if ( initrd.size > 0 ) { | ||
268 | printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size); | ||
269 | initrd.addr = try_claim(initrd.size); | ||
270 | if (initrd.addr == 0) { | ||
271 | printf("Can't allocate memory for initial ramdisk !\n\r"); | ||
272 | exit(); | ||
273 | } | ||
274 | a1 = initrd.addr; | ||
275 | a2 = initrd.size; | ||
276 | printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r", | ||
277 | initrd.addr, (unsigned long)_initrd_start, initrd.size); | ||
278 | memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size); | ||
279 | printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr)); | ||
280 | } | ||
281 | |||
282 | /* Eventually gunzip the kernel */ | ||
283 | if (*(unsigned short *)vmlinuz.addr == 0x1f8b) { | ||
284 | printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...", | ||
285 | vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size); | ||
286 | len = vmlinuz.size; | ||
287 | gunzip((void *)vmlinux.addr, vmlinux.memsize, | ||
288 | (unsigned char *)vmlinuz.addr, &len); | ||
289 | printf("done 0x%lx bytes\n\r", len); | ||
290 | } else { | ||
291 | memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size); | ||
292 | } | ||
293 | |||
294 | /* Skip over the ELF header */ | ||
295 | #ifdef DEBUG | ||
296 | printf("... skipping 0x%lx bytes of ELF header\n\r", | ||
297 | elfoffset); | ||
298 | #endif | ||
299 | vmlinux.addr += elfoffset; | ||
300 | |||
301 | flush_cache((void *)vmlinux.addr, vmlinux.size); | ||
302 | |||
303 | kernel_entry = (kernel_entry_t)vmlinux.addr; | ||
304 | #ifdef DEBUG | ||
305 | printf( "kernel:\n\r" | ||
306 | " entry addr = 0x%lx\n\r" | ||
307 | " a1 = 0x%lx,\n\r" | ||
308 | " a2 = 0x%lx,\n\r" | ||
309 | " prom = 0x%lx,\n\r" | ||
310 | " bi_recs = 0x%lx,\n\r", | ||
311 | (unsigned long)kernel_entry, a1, a2, | ||
312 | (unsigned long)prom, NULL); | ||
313 | #endif | ||
314 | |||
315 | kernel_entry(a1, a2, prom, NULL); | ||
316 | |||
317 | printf("Error: Linux kernel returned to zImage bootloader!\n\r"); | ||
318 | |||
319 | exit(); | ||
320 | } | ||
321 | |||
diff --git a/arch/powerpc/boot/page.h b/arch/powerpc/boot/page.h new file mode 100644 index 000000000000..14eca30fef64 --- /dev/null +++ b/arch/powerpc/boot/page.h | |||
@@ -0,0 +1,34 @@ | |||
1 | #ifndef _PPC_BOOT_PAGE_H | ||
2 | #define _PPC_BOOT_PAGE_H | ||
3 | /* | ||
4 | * Copyright (C) 2001 PPC64 Team, IBM Corp | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifdef __ASSEMBLY__ | ||
13 | #define ASM_CONST(x) x | ||
14 | #else | ||
15 | #define __ASM_CONST(x) x##UL | ||
16 | #define ASM_CONST(x) __ASM_CONST(x) | ||
17 | #endif | ||
18 | |||
19 | /* PAGE_SHIFT determines the page size */ | ||
20 | #define PAGE_SHIFT 12 | ||
21 | #define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) | ||
22 | #define PAGE_MASK (~(PAGE_SIZE-1)) | ||
23 | |||
24 | /* align addr on a size boundary - adjust address up/down if needed */ | ||
25 | #define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) | ||
26 | #define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1))) | ||
27 | |||
28 | /* align addr on a size boundary - adjust address up if needed */ | ||
29 | #define _ALIGN(addr,size) _ALIGN_UP(addr,size) | ||
30 | |||
31 | /* to align the pointer to the (next) page boundary */ | ||
32 | #define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE) | ||
33 | |||
34 | #endif /* _PPC_BOOT_PAGE_H */ | ||
diff --git a/arch/powerpc/boot/ppc_asm.h b/arch/powerpc/boot/ppc_asm.h new file mode 100644 index 000000000000..1c2c2817f9b7 --- /dev/null +++ b/arch/powerpc/boot/ppc_asm.h | |||
@@ -0,0 +1,62 @@ | |||
1 | #ifndef _PPC64_PPC_ASM_H | ||
2 | #define _PPC64_PPC_ASM_H | ||
3 | /* | ||
4 | * | ||
5 | * Definitions used by various bits of low-level assembly code on PowerPC. | ||
6 | * | ||
7 | * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | /* Condition Register Bit Fields */ | ||
16 | |||
17 | #define cr0 0 | ||
18 | #define cr1 1 | ||
19 | #define cr2 2 | ||
20 | #define cr3 3 | ||
21 | #define cr4 4 | ||
22 | #define cr5 5 | ||
23 | #define cr6 6 | ||
24 | #define cr7 7 | ||
25 | |||
26 | |||
27 | /* General Purpose Registers (GPRs) */ | ||
28 | |||
29 | #define r0 0 | ||
30 | #define r1 1 | ||
31 | #define r2 2 | ||
32 | #define r3 3 | ||
33 | #define r4 4 | ||
34 | #define r5 5 | ||
35 | #define r6 6 | ||
36 | #define r7 7 | ||
37 | #define r8 8 | ||
38 | #define r9 9 | ||
39 | #define r10 10 | ||
40 | #define r11 11 | ||
41 | #define r12 12 | ||
42 | #define r13 13 | ||
43 | #define r14 14 | ||
44 | #define r15 15 | ||
45 | #define r16 16 | ||
46 | #define r17 17 | ||
47 | #define r18 18 | ||
48 | #define r19 19 | ||
49 | #define r20 20 | ||
50 | #define r21 21 | ||
51 | #define r22 22 | ||
52 | #define r23 23 | ||
53 | #define r24 24 | ||
54 | #define r25 25 | ||
55 | #define r26 26 | ||
56 | #define r27 27 | ||
57 | #define r28 28 | ||
58 | #define r29 29 | ||
59 | #define r30 30 | ||
60 | #define r31 31 | ||
61 | |||
62 | #endif /* _PPC64_PPC_ASM_H */ | ||
diff --git a/arch/powerpc/boot/prom.c b/arch/powerpc/boot/prom.c new file mode 100644 index 000000000000..4bea2f4dcb06 --- /dev/null +++ b/arch/powerpc/boot/prom.c | |||
@@ -0,0 +1,499 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <stdarg.h> | ||
10 | #include <stddef.h> | ||
11 | #include "string.h" | ||
12 | #include "stdio.h" | ||
13 | #include "prom.h" | ||
14 | |||
15 | int (*prom)(void *); | ||
16 | |||
17 | void *chosen_handle; | ||
18 | |||
19 | void *stdin; | ||
20 | void *stdout; | ||
21 | void *stderr; | ||
22 | |||
23 | |||
24 | int | ||
25 | write(void *handle, void *ptr, int nb) | ||
26 | { | ||
27 | struct prom_args { | ||
28 | char *service; | ||
29 | int nargs; | ||
30 | int nret; | ||
31 | void *ihandle; | ||
32 | void *addr; | ||
33 | int len; | ||
34 | int actual; | ||
35 | } args; | ||
36 | |||
37 | args.service = "write"; | ||
38 | args.nargs = 3; | ||
39 | args.nret = 1; | ||
40 | args.ihandle = handle; | ||
41 | args.addr = ptr; | ||
42 | args.len = nb; | ||
43 | args.actual = -1; | ||
44 | (*prom)(&args); | ||
45 | return args.actual; | ||
46 | } | ||
47 | |||
48 | int | ||
49 | read(void *handle, void *ptr, int nb) | ||
50 | { | ||
51 | struct prom_args { | ||
52 | char *service; | ||
53 | int nargs; | ||
54 | int nret; | ||
55 | void *ihandle; | ||
56 | void *addr; | ||
57 | int len; | ||
58 | int actual; | ||
59 | } args; | ||
60 | |||
61 | args.service = "read"; | ||
62 | args.nargs = 3; | ||
63 | args.nret = 1; | ||
64 | args.ihandle = handle; | ||
65 | args.addr = ptr; | ||
66 | args.len = nb; | ||
67 | args.actual = -1; | ||
68 | (*prom)(&args); | ||
69 | return args.actual; | ||
70 | } | ||
71 | |||
72 | void | ||
73 | exit() | ||
74 | { | ||
75 | struct prom_args { | ||
76 | char *service; | ||
77 | } args; | ||
78 | |||
79 | for (;;) { | ||
80 | args.service = "exit"; | ||
81 | (*prom)(&args); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | void | ||
86 | pause(void) | ||
87 | { | ||
88 | struct prom_args { | ||
89 | char *service; | ||
90 | } args; | ||
91 | |||
92 | args.service = "enter"; | ||
93 | (*prom)(&args); | ||
94 | } | ||
95 | |||
96 | void * | ||
97 | finddevice(const char *name) | ||
98 | { | ||
99 | struct prom_args { | ||
100 | char *service; | ||
101 | int nargs; | ||
102 | int nret; | ||
103 | const char *devspec; | ||
104 | void *phandle; | ||
105 | } args; | ||
106 | |||
107 | args.service = "finddevice"; | ||
108 | args.nargs = 1; | ||
109 | args.nret = 1; | ||
110 | args.devspec = name; | ||
111 | args.phandle = (void *) -1; | ||
112 | (*prom)(&args); | ||
113 | return args.phandle; | ||
114 | } | ||
115 | |||
116 | void * | ||
117 | claim(unsigned long virt, unsigned long size, unsigned long align) | ||
118 | { | ||
119 | struct prom_args { | ||
120 | char *service; | ||
121 | int nargs; | ||
122 | int nret; | ||
123 | unsigned int virt; | ||
124 | unsigned int size; | ||
125 | unsigned int align; | ||
126 | void *ret; | ||
127 | } args; | ||
128 | |||
129 | args.service = "claim"; | ||
130 | args.nargs = 3; | ||
131 | args.nret = 1; | ||
132 | args.virt = virt; | ||
133 | args.size = size; | ||
134 | args.align = align; | ||
135 | (*prom)(&args); | ||
136 | return args.ret; | ||
137 | } | ||
138 | |||
139 | int | ||
140 | getprop(void *phandle, const char *name, void *buf, int buflen) | ||
141 | { | ||
142 | struct prom_args { | ||
143 | char *service; | ||
144 | int nargs; | ||
145 | int nret; | ||
146 | void *phandle; | ||
147 | const char *name; | ||
148 | void *buf; | ||
149 | int buflen; | ||
150 | int size; | ||
151 | } args; | ||
152 | |||
153 | args.service = "getprop"; | ||
154 | args.nargs = 4; | ||
155 | args.nret = 1; | ||
156 | args.phandle = phandle; | ||
157 | args.name = name; | ||
158 | args.buf = buf; | ||
159 | args.buflen = buflen; | ||
160 | args.size = -1; | ||
161 | (*prom)(&args); | ||
162 | return args.size; | ||
163 | } | ||
164 | |||
165 | int | ||
166 | putc(int c, void *f) | ||
167 | { | ||
168 | char ch = c; | ||
169 | |||
170 | if (c == '\n') | ||
171 | putc('\r', f); | ||
172 | return write(f, &ch, 1) == 1? c: -1; | ||
173 | } | ||
174 | |||
175 | int | ||
176 | putchar(int c) | ||
177 | { | ||
178 | return putc(c, stdout); | ||
179 | } | ||
180 | |||
181 | int | ||
182 | fputs(char *str, void *f) | ||
183 | { | ||
184 | int n = strlen(str); | ||
185 | |||
186 | return write(f, str, n) == n? 0: -1; | ||
187 | } | ||
188 | |||
189 | size_t strnlen(const char * s, size_t count) | ||
190 | { | ||
191 | const char *sc; | ||
192 | |||
193 | for (sc = s; count-- && *sc != '\0'; ++sc) | ||
194 | /* nothing */; | ||
195 | return sc - s; | ||
196 | } | ||
197 | |||
198 | extern unsigned int __div64_32(unsigned long long *dividend, | ||
199 | unsigned int divisor); | ||
200 | |||
201 | /* The unnecessary pointer compare is there | ||
202 | * to check for type safety (n must be 64bit) | ||
203 | */ | ||
204 | # define do_div(n,base) ({ \ | ||
205 | unsigned int __base = (base); \ | ||
206 | unsigned int __rem; \ | ||
207 | (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ | ||
208 | if (((n) >> 32) == 0) { \ | ||
209 | __rem = (unsigned int)(n) % __base; \ | ||
210 | (n) = (unsigned int)(n) / __base; \ | ||
211 | } else \ | ||
212 | __rem = __div64_32(&(n), __base); \ | ||
213 | __rem; \ | ||
214 | }) | ||
215 | |||
216 | static int skip_atoi(const char **s) | ||
217 | { | ||
218 | int i, c; | ||
219 | |||
220 | for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s) | ||
221 | i = i*10 + c - '0'; | ||
222 | return i; | ||
223 | } | ||
224 | |||
225 | #define ZEROPAD 1 /* pad with zero */ | ||
226 | #define SIGN 2 /* unsigned/signed long */ | ||
227 | #define PLUS 4 /* show plus */ | ||
228 | #define SPACE 8 /* space if plus */ | ||
229 | #define LEFT 16 /* left justified */ | ||
230 | #define SPECIAL 32 /* 0x */ | ||
231 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ | ||
232 | |||
233 | static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) | ||
234 | { | ||
235 | char c,sign,tmp[66]; | ||
236 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; | ||
237 | int i; | ||
238 | |||
239 | if (type & LARGE) | ||
240 | digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
241 | if (type & LEFT) | ||
242 | type &= ~ZEROPAD; | ||
243 | if (base < 2 || base > 36) | ||
244 | return 0; | ||
245 | c = (type & ZEROPAD) ? '0' : ' '; | ||
246 | sign = 0; | ||
247 | if (type & SIGN) { | ||
248 | if ((signed long long)num < 0) { | ||
249 | sign = '-'; | ||
250 | num = - (signed long long)num; | ||
251 | size--; | ||
252 | } else if (type & PLUS) { | ||
253 | sign = '+'; | ||
254 | size--; | ||
255 | } else if (type & SPACE) { | ||
256 | sign = ' '; | ||
257 | size--; | ||
258 | } | ||
259 | } | ||
260 | if (type & SPECIAL) { | ||
261 | if (base == 16) | ||
262 | size -= 2; | ||
263 | else if (base == 8) | ||
264 | size--; | ||
265 | } | ||
266 | i = 0; | ||
267 | if (num == 0) | ||
268 | tmp[i++]='0'; | ||
269 | else while (num != 0) { | ||
270 | tmp[i++] = digits[do_div(num, base)]; | ||
271 | } | ||
272 | if (i > precision) | ||
273 | precision = i; | ||
274 | size -= precision; | ||
275 | if (!(type&(ZEROPAD+LEFT))) | ||
276 | while(size-->0) | ||
277 | *str++ = ' '; | ||
278 | if (sign) | ||
279 | *str++ = sign; | ||
280 | if (type & SPECIAL) { | ||
281 | if (base==8) | ||
282 | *str++ = '0'; | ||
283 | else if (base==16) { | ||
284 | *str++ = '0'; | ||
285 | *str++ = digits[33]; | ||
286 | } | ||
287 | } | ||
288 | if (!(type & LEFT)) | ||
289 | while (size-- > 0) | ||
290 | *str++ = c; | ||
291 | while (i < precision--) | ||
292 | *str++ = '0'; | ||
293 | while (i-- > 0) | ||
294 | *str++ = tmp[i]; | ||
295 | while (size-- > 0) | ||
296 | *str++ = ' '; | ||
297 | return str; | ||
298 | } | ||
299 | |||
300 | int vsprintf(char *buf, const char *fmt, va_list args) | ||
301 | { | ||
302 | int len; | ||
303 | unsigned long long num; | ||
304 | int i, base; | ||
305 | char * str; | ||
306 | const char *s; | ||
307 | |||
308 | int flags; /* flags to number() */ | ||
309 | |||
310 | int field_width; /* width of output field */ | ||
311 | int precision; /* min. # of digits for integers; max | ||
312 | number of chars for from string */ | ||
313 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ | ||
314 | /* 'z' support added 23/7/1999 S.H. */ | ||
315 | /* 'z' changed to 'Z' --davidm 1/25/99 */ | ||
316 | |||
317 | |||
318 | for (str=buf ; *fmt ; ++fmt) { | ||
319 | if (*fmt != '%') { | ||
320 | *str++ = *fmt; | ||
321 | continue; | ||
322 | } | ||
323 | |||
324 | /* process flags */ | ||
325 | flags = 0; | ||
326 | repeat: | ||
327 | ++fmt; /* this also skips first '%' */ | ||
328 | switch (*fmt) { | ||
329 | case '-': flags |= LEFT; goto repeat; | ||
330 | case '+': flags |= PLUS; goto repeat; | ||
331 | case ' ': flags |= SPACE; goto repeat; | ||
332 | case '#': flags |= SPECIAL; goto repeat; | ||
333 | case '0': flags |= ZEROPAD; goto repeat; | ||
334 | } | ||
335 | |||
336 | /* get field width */ | ||
337 | field_width = -1; | ||
338 | if ('0' <= *fmt && *fmt <= '9') | ||
339 | field_width = skip_atoi(&fmt); | ||
340 | else if (*fmt == '*') { | ||
341 | ++fmt; | ||
342 | /* it's the next argument */ | ||
343 | field_width = va_arg(args, int); | ||
344 | if (field_width < 0) { | ||
345 | field_width = -field_width; | ||
346 | flags |= LEFT; | ||
347 | } | ||
348 | } | ||
349 | |||
350 | /* get the precision */ | ||
351 | precision = -1; | ||
352 | if (*fmt == '.') { | ||
353 | ++fmt; | ||
354 | if ('0' <= *fmt && *fmt <= '9') | ||
355 | precision = skip_atoi(&fmt); | ||
356 | else if (*fmt == '*') { | ||
357 | ++fmt; | ||
358 | /* it's the next argument */ | ||
359 | precision = va_arg(args, int); | ||
360 | } | ||
361 | if (precision < 0) | ||
362 | precision = 0; | ||
363 | } | ||
364 | |||
365 | /* get the conversion qualifier */ | ||
366 | qualifier = -1; | ||
367 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { | ||
368 | qualifier = *fmt; | ||
369 | ++fmt; | ||
370 | } | ||
371 | |||
372 | /* default base */ | ||
373 | base = 10; | ||
374 | |||
375 | switch (*fmt) { | ||
376 | case 'c': | ||
377 | if (!(flags & LEFT)) | ||
378 | while (--field_width > 0) | ||
379 | *str++ = ' '; | ||
380 | *str++ = (unsigned char) va_arg(args, int); | ||
381 | while (--field_width > 0) | ||
382 | *str++ = ' '; | ||
383 | continue; | ||
384 | |||
385 | case 's': | ||
386 | s = va_arg(args, char *); | ||
387 | if (!s) | ||
388 | s = "<NULL>"; | ||
389 | |||
390 | len = strnlen(s, precision); | ||
391 | |||
392 | if (!(flags & LEFT)) | ||
393 | while (len < field_width--) | ||
394 | *str++ = ' '; | ||
395 | for (i = 0; i < len; ++i) | ||
396 | *str++ = *s++; | ||
397 | while (len < field_width--) | ||
398 | *str++ = ' '; | ||
399 | continue; | ||
400 | |||
401 | case 'p': | ||
402 | if (field_width == -1) { | ||
403 | field_width = 2*sizeof(void *); | ||
404 | flags |= ZEROPAD; | ||
405 | } | ||
406 | str = number(str, | ||
407 | (unsigned long) va_arg(args, void *), 16, | ||
408 | field_width, precision, flags); | ||
409 | continue; | ||
410 | |||
411 | |||
412 | case 'n': | ||
413 | if (qualifier == 'l') { | ||
414 | long * ip = va_arg(args, long *); | ||
415 | *ip = (str - buf); | ||
416 | } else if (qualifier == 'Z') { | ||
417 | size_t * ip = va_arg(args, size_t *); | ||
418 | *ip = (str - buf); | ||
419 | } else { | ||
420 | int * ip = va_arg(args, int *); | ||
421 | *ip = (str - buf); | ||
422 | } | ||
423 | continue; | ||
424 | |||
425 | case '%': | ||
426 | *str++ = '%'; | ||
427 | continue; | ||
428 | |||
429 | /* integer number formats - set up the flags and "break" */ | ||
430 | case 'o': | ||
431 | base = 8; | ||
432 | break; | ||
433 | |||
434 | case 'X': | ||
435 | flags |= LARGE; | ||
436 | case 'x': | ||
437 | base = 16; | ||
438 | break; | ||
439 | |||
440 | case 'd': | ||
441 | case 'i': | ||
442 | flags |= SIGN; | ||
443 | case 'u': | ||
444 | break; | ||
445 | |||
446 | default: | ||
447 | *str++ = '%'; | ||
448 | if (*fmt) | ||
449 | *str++ = *fmt; | ||
450 | else | ||
451 | --fmt; | ||
452 | continue; | ||
453 | } | ||
454 | if (qualifier == 'l') { | ||
455 | num = va_arg(args, unsigned long); | ||
456 | if (flags & SIGN) | ||
457 | num = (signed long) num; | ||
458 | } else if (qualifier == 'Z') { | ||
459 | num = va_arg(args, size_t); | ||
460 | } else if (qualifier == 'h') { | ||
461 | num = (unsigned short) va_arg(args, int); | ||
462 | if (flags & SIGN) | ||
463 | num = (signed short) num; | ||
464 | } else { | ||
465 | num = va_arg(args, unsigned int); | ||
466 | if (flags & SIGN) | ||
467 | num = (signed int) num; | ||
468 | } | ||
469 | str = number(str, num, base, field_width, precision, flags); | ||
470 | } | ||
471 | *str = '\0'; | ||
472 | return str-buf; | ||
473 | } | ||
474 | |||
475 | int sprintf(char * buf, const char *fmt, ...) | ||
476 | { | ||
477 | va_list args; | ||
478 | int i; | ||
479 | |||
480 | va_start(args, fmt); | ||
481 | i=vsprintf(buf,fmt,args); | ||
482 | va_end(args); | ||
483 | return i; | ||
484 | } | ||
485 | |||
486 | static char sprint_buf[1024]; | ||
487 | |||
488 | int | ||
489 | printf(const char *fmt, ...) | ||
490 | { | ||
491 | va_list args; | ||
492 | int n; | ||
493 | |||
494 | va_start(args, fmt); | ||
495 | n = vsprintf(sprint_buf, fmt, args); | ||
496 | va_end(args); | ||
497 | write(stdout, sprint_buf, n); | ||
498 | return n; | ||
499 | } | ||
diff --git a/arch/powerpc/boot/prom.h b/arch/powerpc/boot/prom.h new file mode 100644 index 000000000000..96ab5aec740c --- /dev/null +++ b/arch/powerpc/boot/prom.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef _PPC_BOOT_PROM_H_ | ||
2 | #define _PPC_BOOT_PROM_H_ | ||
3 | |||
4 | extern int (*prom) (void *); | ||
5 | extern void *chosen_handle; | ||
6 | |||
7 | extern void *stdin; | ||
8 | extern void *stdout; | ||
9 | extern void *stderr; | ||
10 | |||
11 | extern int write(void *handle, void *ptr, int nb); | ||
12 | extern int read(void *handle, void *ptr, int nb); | ||
13 | extern void exit(void); | ||
14 | extern void pause(void); | ||
15 | extern void *finddevice(const char *); | ||
16 | extern void *claim(unsigned long virt, unsigned long size, unsigned long align); | ||
17 | extern int getprop(void *phandle, const char *name, void *buf, int buflen); | ||
18 | #endif /* _PPC_BOOT_PROM_H_ */ | ||
diff --git a/arch/powerpc/boot/stdio.h b/arch/powerpc/boot/stdio.h new file mode 100644 index 000000000000..24bd3a8dee94 --- /dev/null +++ b/arch/powerpc/boot/stdio.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef _PPC_BOOT_STDIO_H_ | ||
2 | #define _PPC_BOOT_STDIO_H_ | ||
3 | |||
4 | extern int printf(const char *fmt, ...); | ||
5 | |||
6 | extern int sprintf(char *buf, const char *fmt, ...); | ||
7 | |||
8 | extern int vsprintf(char *buf, const char *fmt, va_list args); | ||
9 | |||
10 | extern int putc(int c, void *f); | ||
11 | extern int putchar(int c); | ||
12 | extern int getchar(void); | ||
13 | |||
14 | extern int fputs(char *str, void *f); | ||
15 | |||
16 | #endif /* _PPC_BOOT_STDIO_H_ */ | ||
diff --git a/arch/powerpc/boot/string.S b/arch/powerpc/boot/string.S new file mode 100644 index 000000000000..b1eeaed7db17 --- /dev/null +++ b/arch/powerpc/boot/string.S | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * NOTE: this code runs in 32 bit mode and is packaged as ELF32. | ||
10 | */ | ||
11 | |||
12 | #include "ppc_asm.h" | ||
13 | |||
14 | .text | ||
15 | .globl strcpy | ||
16 | strcpy: | ||
17 | addi r5,r3,-1 | ||
18 | addi r4,r4,-1 | ||
19 | 1: lbzu r0,1(r4) | ||
20 | cmpwi 0,r0,0 | ||
21 | stbu r0,1(r5) | ||
22 | bne 1b | ||
23 | blr | ||
24 | |||
25 | .globl strncpy | ||
26 | strncpy: | ||
27 | cmpwi 0,r5,0 | ||
28 | beqlr | ||
29 | mtctr r5 | ||
30 | addi r6,r3,-1 | ||
31 | addi r4,r4,-1 | ||
32 | 1: lbzu r0,1(r4) | ||
33 | cmpwi 0,r0,0 | ||
34 | stbu r0,1(r6) | ||
35 | bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ | ||
36 | blr | ||
37 | |||
38 | .globl strcat | ||
39 | strcat: | ||
40 | addi r5,r3,-1 | ||
41 | addi r4,r4,-1 | ||
42 | 1: lbzu r0,1(r5) | ||
43 | cmpwi 0,r0,0 | ||
44 | bne 1b | ||
45 | addi r5,r5,-1 | ||
46 | 1: lbzu r0,1(r4) | ||
47 | cmpwi 0,r0,0 | ||
48 | stbu r0,1(r5) | ||
49 | bne 1b | ||
50 | blr | ||
51 | |||
52 | .globl strcmp | ||
53 | strcmp: | ||
54 | addi r5,r3,-1 | ||
55 | addi r4,r4,-1 | ||
56 | 1: lbzu r3,1(r5) | ||
57 | cmpwi 1,r3,0 | ||
58 | lbzu r0,1(r4) | ||
59 | subf. r3,r0,r3 | ||
60 | beqlr 1 | ||
61 | beq 1b | ||
62 | blr | ||
63 | |||
64 | .globl strlen | ||
65 | strlen: | ||
66 | addi r4,r3,-1 | ||
67 | 1: lbzu r0,1(r4) | ||
68 | cmpwi 0,r0,0 | ||
69 | bne 1b | ||
70 | subf r3,r3,r4 | ||
71 | blr | ||
72 | |||
73 | .globl memset | ||
74 | memset: | ||
75 | rlwimi r4,r4,8,16,23 | ||
76 | rlwimi r4,r4,16,0,15 | ||
77 | addi r6,r3,-4 | ||
78 | cmplwi 0,r5,4 | ||
79 | blt 7f | ||
80 | stwu r4,4(r6) | ||
81 | beqlr | ||
82 | andi. r0,r6,3 | ||
83 | add r5,r0,r5 | ||
84 | subf r6,r0,r6 | ||
85 | rlwinm r0,r5,32-2,2,31 | ||
86 | mtctr r0 | ||
87 | bdz 6f | ||
88 | 1: stwu r4,4(r6) | ||
89 | bdnz 1b | ||
90 | 6: andi. r5,r5,3 | ||
91 | 7: cmpwi 0,r5,0 | ||
92 | beqlr | ||
93 | mtctr r5 | ||
94 | addi r6,r6,3 | ||
95 | 8: stbu r4,1(r6) | ||
96 | bdnz 8b | ||
97 | blr | ||
98 | |||
99 | .globl memmove | ||
100 | memmove: | ||
101 | cmplw 0,r3,r4 | ||
102 | bgt backwards_memcpy | ||
103 | /* fall through */ | ||
104 | |||
105 | .globl memcpy | ||
106 | memcpy: | ||
107 | rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ | ||
108 | addi r6,r3,-4 | ||
109 | addi r4,r4,-4 | ||
110 | beq 2f /* if less than 8 bytes to do */ | ||
111 | andi. r0,r6,3 /* get dest word aligned */ | ||
112 | mtctr r7 | ||
113 | bne 5f | ||
114 | 1: lwz r7,4(r4) | ||
115 | lwzu r8,8(r4) | ||
116 | stw r7,4(r6) | ||
117 | stwu r8,8(r6) | ||
118 | bdnz 1b | ||
119 | andi. r5,r5,7 | ||
120 | 2: cmplwi 0,r5,4 | ||
121 | blt 3f | ||
122 | lwzu r0,4(r4) | ||
123 | addi r5,r5,-4 | ||
124 | stwu r0,4(r6) | ||
125 | 3: cmpwi 0,r5,0 | ||
126 | beqlr | ||
127 | mtctr r5 | ||
128 | addi r4,r4,3 | ||
129 | addi r6,r6,3 | ||
130 | 4: lbzu r0,1(r4) | ||
131 | stbu r0,1(r6) | ||
132 | bdnz 4b | ||
133 | blr | ||
134 | 5: subfic r0,r0,4 | ||
135 | mtctr r0 | ||
136 | 6: lbz r7,4(r4) | ||
137 | addi r4,r4,1 | ||
138 | stb r7,4(r6) | ||
139 | addi r6,r6,1 | ||
140 | bdnz 6b | ||
141 | subf r5,r0,r5 | ||
142 | rlwinm. r7,r5,32-3,3,31 | ||
143 | beq 2b | ||
144 | mtctr r7 | ||
145 | b 1b | ||
146 | |||
147 | .globl backwards_memcpy | ||
148 | backwards_memcpy: | ||
149 | rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ | ||
150 | add r6,r3,r5 | ||
151 | add r4,r4,r5 | ||
152 | beq 2f | ||
153 | andi. r0,r6,3 | ||
154 | mtctr r7 | ||
155 | bne 5f | ||
156 | 1: lwz r7,-4(r4) | ||
157 | lwzu r8,-8(r4) | ||
158 | stw r7,-4(r6) | ||
159 | stwu r8,-8(r6) | ||
160 | bdnz 1b | ||
161 | andi. r5,r5,7 | ||
162 | 2: cmplwi 0,r5,4 | ||
163 | blt 3f | ||
164 | lwzu r0,-4(r4) | ||
165 | subi r5,r5,4 | ||
166 | stwu r0,-4(r6) | ||
167 | 3: cmpwi 0,r5,0 | ||
168 | beqlr | ||
169 | mtctr r5 | ||
170 | 4: lbzu r0,-1(r4) | ||
171 | stbu r0,-1(r6) | ||
172 | bdnz 4b | ||
173 | blr | ||
174 | 5: mtctr r0 | ||
175 | 6: lbzu r7,-1(r4) | ||
176 | stbu r7,-1(r6) | ||
177 | bdnz 6b | ||
178 | subf r5,r0,r5 | ||
179 | rlwinm. r7,r5,32-3,3,31 | ||
180 | beq 2b | ||
181 | mtctr r7 | ||
182 | b 1b | ||
183 | |||
184 | .globl memcmp | ||
185 | memcmp: | ||
186 | cmpwi 0,r5,0 | ||
187 | blelr | ||
188 | mtctr r5 | ||
189 | addi r6,r3,-1 | ||
190 | addi r4,r4,-1 | ||
191 | 1: lbzu r3,1(r6) | ||
192 | lbzu r0,1(r4) | ||
193 | subf. r3,r0,r3 | ||
194 | bdnzt 2,1b | ||
195 | blr | ||
196 | |||
197 | |||
198 | /* | ||
199 | * Flush the dcache and invalidate the icache for a range of addresses. | ||
200 | * | ||
201 | * flush_cache(addr, len) | ||
202 | */ | ||
203 | .global flush_cache | ||
204 | flush_cache: | ||
205 | addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ | ||
206 | rlwinm. 4,4,27,5,31 | ||
207 | mtctr 4 | ||
208 | beqlr | ||
209 | 1: dcbf 0,3 | ||
210 | icbi 0,3 | ||
211 | addi 3,3,0x20 | ||
212 | bdnz 1b | ||
213 | sync | ||
214 | isync | ||
215 | blr | ||
216 | |||
diff --git a/arch/powerpc/boot/string.h b/arch/powerpc/boot/string.h new file mode 100644 index 000000000000..9fdff1cc0d70 --- /dev/null +++ b/arch/powerpc/boot/string.h | |||
@@ -0,0 +1,17 @@ | |||
1 | #ifndef _PPC_BOOT_STRING_H_ | ||
2 | #define _PPC_BOOT_STRING_H_ | ||
3 | #include <stddef.h> | ||
4 | |||
5 | extern char *strcpy(char *dest, const char *src); | ||
6 | extern char *strncpy(char *dest, const char *src, size_t n); | ||
7 | extern char *strcat(char *dest, const char *src); | ||
8 | extern int strcmp(const char *s1, const char *s2); | ||
9 | extern size_t strlen(const char *s); | ||
10 | extern size_t strnlen(const char *s, size_t count); | ||
11 | |||
12 | extern void *memset(void *s, int c, size_t n); | ||
13 | extern void *memmove(void *dest, const void *src, unsigned long n); | ||
14 | extern void *memcpy(void *dest, const void *src, unsigned long n); | ||
15 | extern int memcmp(const void *s1, const void *s2, size_t n); | ||
16 | |||
17 | #endif /* _PPC_BOOT_STRING_H_ */ | ||
diff --git a/arch/powerpc/boot/zImage.lds b/arch/powerpc/boot/zImage.lds new file mode 100644 index 000000000000..4b6bb3ffe3dc --- /dev/null +++ b/arch/powerpc/boot/zImage.lds | |||
@@ -0,0 +1,46 @@ | |||
1 | OUTPUT_ARCH(powerpc:common) | ||
2 | ENTRY(_zimage_start) | ||
3 | SECTIONS | ||
4 | { | ||
5 | . = (4*1024*1024); | ||
6 | _start = .; | ||
7 | .text : | ||
8 | { | ||
9 | *(.text) | ||
10 | *(.fixup) | ||
11 | } | ||
12 | _etext = .; | ||
13 | . = ALIGN(4096); | ||
14 | .data : | ||
15 | { | ||
16 | *(.rodata*) | ||
17 | *(.data*) | ||
18 | *(.sdata*) | ||
19 | __got2_start = .; | ||
20 | *(.got2) | ||
21 | __got2_end = .; | ||
22 | } | ||
23 | |||
24 | . = ALIGN(4096); | ||
25 | _vmlinux_start = .; | ||
26 | .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) } | ||
27 | _vmlinux_end = .; | ||
28 | |||
29 | . = ALIGN(4096); | ||
30 | _initrd_start = .; | ||
31 | .kernel:initrd : { *(.kernel:initrd) } | ||
32 | _initrd_end = .; | ||
33 | |||
34 | . = ALIGN(4096); | ||
35 | _edata = .; | ||
36 | |||
37 | . = ALIGN(4096); | ||
38 | __bss_start = .; | ||
39 | .bss : | ||
40 | { | ||
41 | *(.sbss) | ||
42 | *(.bss) | ||
43 | } | ||
44 | . = ALIGN(4096); | ||
45 | _end = . ; | ||
46 | } | ||
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index 67ffecbc05cb..4b433411b9e3 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig | |||
@@ -1,18 +1,33 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.14-rc4 | 3 | # Linux kernel version: 2.6.15-rc1 |
4 | # Thu Oct 20 08:29:10 2005 | 4 | # Tue Nov 15 14:36:20 2005 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | ||
6 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
8 | CONFIG_PPC_MERGE=y | ||
7 | CONFIG_MMU=y | 9 | CONFIG_MMU=y |
10 | CONFIG_GENERIC_HARDIRQS=y | ||
8 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
9 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 12 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
10 | CONFIG_GENERIC_ISA_DMA=y | 13 | CONFIG_PPC=y |
11 | CONFIG_EARLY_PRINTK=y | 14 | CONFIG_EARLY_PRINTK=y |
12 | CONFIG_COMPAT=y | 15 | CONFIG_COMPAT=y |
16 | CONFIG_SYSVIPC_COMPAT=y | ||
13 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | 17 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y |
14 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | 18 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y |
15 | CONFIG_FORCE_MAX_ZONEORDER=13 | 19 | |
20 | # | ||
21 | # Processor support | ||
22 | # | ||
23 | # CONFIG_POWER4_ONLY is not set | ||
24 | CONFIG_POWER3=y | ||
25 | CONFIG_POWER4=y | ||
26 | CONFIG_PPC_FPU=y | ||
27 | CONFIG_ALTIVEC=y | ||
28 | CONFIG_PPC_STD_MMU=y | ||
29 | CONFIG_SMP=y | ||
30 | CONFIG_NR_CPUS=4 | ||
16 | 31 | ||
17 | # | 32 | # |
18 | # Code maturity level options | 33 | # Code maturity level options |
@@ -66,31 +81,69 @@ CONFIG_OBSOLETE_MODPARM=y | |||
66 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 81 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
67 | # CONFIG_KMOD is not set | 82 | # CONFIG_KMOD is not set |
68 | CONFIG_STOP_MACHINE=y | 83 | CONFIG_STOP_MACHINE=y |
69 | CONFIG_SYSVIPC_COMPAT=y | 84 | |
85 | # | ||
86 | # Block layer | ||
87 | # | ||
88 | |||
89 | # | ||
90 | # IO Schedulers | ||
91 | # | ||
92 | CONFIG_IOSCHED_NOOP=y | ||
93 | CONFIG_IOSCHED_AS=y | ||
94 | CONFIG_IOSCHED_DEADLINE=y | ||
95 | CONFIG_IOSCHED_CFQ=y | ||
96 | CONFIG_DEFAULT_AS=y | ||
97 | # CONFIG_DEFAULT_DEADLINE is not set | ||
98 | # CONFIG_DEFAULT_CFQ is not set | ||
99 | # CONFIG_DEFAULT_NOOP is not set | ||
100 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
70 | 101 | ||
71 | # | 102 | # |
72 | # Platform support | 103 | # Platform support |
73 | # | 104 | # |
74 | # CONFIG_PPC_ISERIES is not set | ||
75 | CONFIG_PPC_MULTIPLATFORM=y | 105 | CONFIG_PPC_MULTIPLATFORM=y |
106 | # CONFIG_PPC_ISERIES is not set | ||
107 | # CONFIG_EMBEDDED6xx is not set | ||
108 | # CONFIG_APUS is not set | ||
76 | # CONFIG_PPC_PSERIES is not set | 109 | # CONFIG_PPC_PSERIES is not set |
77 | CONFIG_PPC_BPA=y | ||
78 | # CONFIG_PPC_PMAC is not set | 110 | # CONFIG_PPC_PMAC is not set |
79 | # CONFIG_PPC_MAPLE is not set | 111 | # CONFIG_PPC_MAPLE is not set |
80 | CONFIG_PPC=y | 112 | CONFIG_PPC_CELL=y |
81 | CONFIG_PPC64=y | ||
82 | CONFIG_PPC_OF=y | 113 | CONFIG_PPC_OF=y |
83 | CONFIG_BPA_IIC=y | ||
84 | CONFIG_ALTIVEC=y | ||
85 | CONFIG_KEXEC=y | ||
86 | # CONFIG_U3_DART is not set | 114 | # CONFIG_U3_DART is not set |
87 | # CONFIG_BOOTX_TEXT is not set | 115 | CONFIG_PPC_RTAS=y |
88 | # CONFIG_POWER4_ONLY is not set | 116 | # CONFIG_RTAS_ERROR_LOGGING is not set |
117 | CONFIG_RTAS_PROC=y | ||
118 | CONFIG_RTAS_FLASH=y | ||
119 | CONFIG_MMIO_NVRAM=y | ||
120 | CONFIG_CELL_IIC=y | ||
121 | # CONFIG_PPC_MPC106 is not set | ||
122 | # CONFIG_GENERIC_TBSYNC is not set | ||
123 | # CONFIG_CPU_FREQ is not set | ||
124 | # CONFIG_WANT_EARLY_SERIAL is not set | ||
125 | |||
126 | # | ||
127 | # Kernel options | ||
128 | # | ||
129 | # CONFIG_HZ_100 is not set | ||
130 | CONFIG_HZ_250=y | ||
131 | # CONFIG_HZ_1000 is not set | ||
132 | CONFIG_HZ=250 | ||
133 | CONFIG_PREEMPT_NONE=y | ||
134 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
135 | # CONFIG_PREEMPT is not set | ||
136 | CONFIG_PREEMPT_BKL=y | ||
137 | CONFIG_BINFMT_ELF=y | ||
138 | # CONFIG_BINFMT_MISC is not set | ||
139 | CONFIG_FORCE_MAX_ZONEORDER=13 | ||
89 | # CONFIG_IOMMU_VMERGE is not set | 140 | # CONFIG_IOMMU_VMERGE is not set |
90 | CONFIG_SMP=y | 141 | CONFIG_KEXEC=y |
91 | CONFIG_NR_CPUS=4 | 142 | CONFIG_IRQ_ALL_CPUS=y |
143 | # CONFIG_NUMA is not set | ||
92 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y | 144 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y |
93 | CONFIG_ARCH_FLATMEM_ENABLE=y | 145 | CONFIG_ARCH_FLATMEM_ENABLE=y |
146 | CONFIG_ARCH_SPARSEMEM_ENABLE=y | ||
94 | CONFIG_SELECT_MEMORY_MODEL=y | 147 | CONFIG_SELECT_MEMORY_MODEL=y |
95 | CONFIG_FLATMEM_MANUAL=y | 148 | CONFIG_FLATMEM_MANUAL=y |
96 | # CONFIG_DISCONTIGMEM_MANUAL is not set | 149 | # CONFIG_DISCONTIGMEM_MANUAL is not set |
@@ -98,30 +151,21 @@ CONFIG_FLATMEM_MANUAL=y | |||
98 | CONFIG_FLATMEM=y | 151 | CONFIG_FLATMEM=y |
99 | CONFIG_FLAT_NODE_MEM_MAP=y | 152 | CONFIG_FLAT_NODE_MEM_MAP=y |
100 | # CONFIG_SPARSEMEM_STATIC is not set | 153 | # CONFIG_SPARSEMEM_STATIC is not set |
101 | # CONFIG_NUMA is not set | 154 | CONFIG_SPLIT_PTLOCK_CPUS=4096 |
155 | # CONFIG_PPC_64K_PAGES is not set | ||
102 | CONFIG_SCHED_SMT=y | 156 | CONFIG_SCHED_SMT=y |
103 | CONFIG_PREEMPT_NONE=y | ||
104 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
105 | # CONFIG_PREEMPT is not set | ||
106 | CONFIG_PREEMPT_BKL=y | ||
107 | # CONFIG_HZ_100 is not set | ||
108 | CONFIG_HZ_250=y | ||
109 | # CONFIG_HZ_1000 is not set | ||
110 | CONFIG_HZ=250 | ||
111 | CONFIG_GENERIC_HARDIRQS=y | ||
112 | CONFIG_PPC_RTAS=y | ||
113 | CONFIG_RTAS_PROC=y | ||
114 | CONFIG_RTAS_FLASH=y | ||
115 | CONFIG_SECCOMP=y | ||
116 | CONFIG_BINFMT_ELF=y | ||
117 | # CONFIG_BINFMT_MISC is not set | ||
118 | CONFIG_PROC_DEVICETREE=y | 157 | CONFIG_PROC_DEVICETREE=y |
119 | # CONFIG_CMDLINE_BOOL is not set | 158 | # CONFIG_CMDLINE_BOOL is not set |
159 | # CONFIG_PM is not set | ||
160 | CONFIG_SECCOMP=y | ||
120 | CONFIG_ISA_DMA_API=y | 161 | CONFIG_ISA_DMA_API=y |
121 | 162 | ||
122 | # | 163 | # |
123 | # Bus Options | 164 | # Bus options |
124 | # | 165 | # |
166 | CONFIG_GENERIC_ISA_DMA=y | ||
167 | # CONFIG_PPC_I8259 is not set | ||
168 | # CONFIG_PPC_INDIRECT_PCI is not set | ||
125 | CONFIG_PCI=y | 169 | CONFIG_PCI=y |
126 | CONFIG_PCI_DOMAINS=y | 170 | CONFIG_PCI_DOMAINS=y |
127 | CONFIG_PCI_LEGACY_PROC=y | 171 | CONFIG_PCI_LEGACY_PROC=y |
@@ -136,6 +180,7 @@ CONFIG_PCI_LEGACY_PROC=y | |||
136 | # PCI Hotplug Support | 180 | # PCI Hotplug Support |
137 | # | 181 | # |
138 | # CONFIG_HOTPLUG_PCI is not set | 182 | # CONFIG_HOTPLUG_PCI is not set |
183 | CONFIG_KERNEL_START=0xc000000000000000 | ||
139 | 184 | ||
140 | # | 185 | # |
141 | # Networking | 186 | # Networking |
@@ -183,6 +228,10 @@ CONFIG_INET6_TUNNEL=m | |||
183 | CONFIG_IPV6_TUNNEL=m | 228 | CONFIG_IPV6_TUNNEL=m |
184 | CONFIG_NETFILTER=y | 229 | CONFIG_NETFILTER=y |
185 | # CONFIG_NETFILTER_DEBUG is not set | 230 | # CONFIG_NETFILTER_DEBUG is not set |
231 | |||
232 | # | ||
233 | # Core Netfilter Configuration | ||
234 | # | ||
186 | # CONFIG_NETFILTER_NETLINK is not set | 235 | # CONFIG_NETFILTER_NETLINK is not set |
187 | 236 | ||
188 | # | 237 | # |
@@ -284,6 +333,10 @@ CONFIG_IP_NF_ARP_MANGLE=m | |||
284 | # CONFIG_NET_DIVERT is not set | 333 | # CONFIG_NET_DIVERT is not set |
285 | # CONFIG_ECONET is not set | 334 | # CONFIG_ECONET is not set |
286 | # CONFIG_WAN_ROUTER is not set | 335 | # CONFIG_WAN_ROUTER is not set |
336 | |||
337 | # | ||
338 | # QoS and/or fair queueing | ||
339 | # | ||
287 | # CONFIG_NET_SCHED is not set | 340 | # CONFIG_NET_SCHED is not set |
288 | CONFIG_NET_CLS_ROUTE=y | 341 | CONFIG_NET_CLS_ROUTE=y |
289 | 342 | ||
@@ -345,14 +398,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16 | |||
345 | CONFIG_BLK_DEV_RAM_SIZE=131072 | 398 | CONFIG_BLK_DEV_RAM_SIZE=131072 |
346 | CONFIG_BLK_DEV_INITRD=y | 399 | CONFIG_BLK_DEV_INITRD=y |
347 | # CONFIG_CDROM_PKTCDVD is not set | 400 | # CONFIG_CDROM_PKTCDVD is not set |
348 | |||
349 | # | ||
350 | # IO Schedulers | ||
351 | # | ||
352 | CONFIG_IOSCHED_NOOP=y | ||
353 | CONFIG_IOSCHED_AS=y | ||
354 | CONFIG_IOSCHED_DEADLINE=y | ||
355 | CONFIG_IOSCHED_CFQ=y | ||
356 | # CONFIG_ATA_OVER_ETH is not set | 401 | # CONFIG_ATA_OVER_ETH is not set |
357 | 402 | ||
358 | # | 403 | # |
@@ -442,6 +487,7 @@ CONFIG_IDEDMA_AUTO=y | |||
442 | # | 487 | # |
443 | # Macintosh device drivers | 488 | # Macintosh device drivers |
444 | # | 489 | # |
490 | # CONFIG_WINDFARM is not set | ||
445 | 491 | ||
446 | # | 492 | # |
447 | # Network device support | 493 | # Network device support |
@@ -495,7 +541,6 @@ CONFIG_SKGE=m | |||
495 | # CONFIG_SK98LIN is not set | 541 | # CONFIG_SK98LIN is not set |
496 | # CONFIG_TIGON3 is not set | 542 | # CONFIG_TIGON3 is not set |
497 | # CONFIG_BNX2 is not set | 543 | # CONFIG_BNX2 is not set |
498 | # CONFIG_SPIDER_NET is not set | ||
499 | # CONFIG_MV643XX_ETH is not set | 544 | # CONFIG_MV643XX_ETH is not set |
500 | 545 | ||
501 | # | 546 | # |
@@ -625,7 +670,7 @@ CONFIG_WATCHDOG=y | |||
625 | # Watchdog Device Drivers | 670 | # Watchdog Device Drivers |
626 | # | 671 | # |
627 | # CONFIG_SOFT_WATCHDOG is not set | 672 | # CONFIG_SOFT_WATCHDOG is not set |
628 | CONFIG_WATCHDOG_RTAS=y | 673 | # CONFIG_WATCHDOG_RTAS is not set |
629 | 674 | ||
630 | # | 675 | # |
631 | # PCI-based Watchdog Cards | 676 | # PCI-based Watchdog Cards |
@@ -633,6 +678,8 @@ CONFIG_WATCHDOG_RTAS=y | |||
633 | # CONFIG_PCIPCWATCHDOG is not set | 678 | # CONFIG_PCIPCWATCHDOG is not set |
634 | # CONFIG_WDTPCI is not set | 679 | # CONFIG_WDTPCI is not set |
635 | # CONFIG_RTC is not set | 680 | # CONFIG_RTC is not set |
681 | CONFIG_GEN_RTC=y | ||
682 | # CONFIG_GEN_RTC_X is not set | ||
636 | # CONFIG_DTLK is not set | 683 | # CONFIG_DTLK is not set |
637 | # CONFIG_R3964 is not set | 684 | # CONFIG_R3964 is not set |
638 | # CONFIG_APPLICOM is not set | 685 | # CONFIG_APPLICOM is not set |
@@ -649,6 +696,7 @@ CONFIG_WATCHDOG_RTAS=y | |||
649 | # TPM devices | 696 | # TPM devices |
650 | # | 697 | # |
651 | # CONFIG_TCG_TPM is not set | 698 | # CONFIG_TCG_TPM is not set |
699 | # CONFIG_TELCLOCK is not set | ||
652 | 700 | ||
653 | # | 701 | # |
654 | # I2C support | 702 | # I2C support |
@@ -699,6 +747,7 @@ CONFIG_I2C_ALGOBIT=y | |||
699 | # CONFIG_SENSORS_PCF8591 is not set | 747 | # CONFIG_SENSORS_PCF8591 is not set |
700 | # CONFIG_SENSORS_RTC8564 is not set | 748 | # CONFIG_SENSORS_RTC8564 is not set |
701 | # CONFIG_SENSORS_MAX6875 is not set | 749 | # CONFIG_SENSORS_MAX6875 is not set |
750 | # CONFIG_RTC_X1205_I2C is not set | ||
702 | # CONFIG_I2C_DEBUG_CORE is not set | 751 | # CONFIG_I2C_DEBUG_CORE is not set |
703 | # CONFIG_I2C_DEBUG_ALGO is not set | 752 | # CONFIG_I2C_DEBUG_ALGO is not set |
704 | # CONFIG_I2C_DEBUG_BUS is not set | 753 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -757,6 +806,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y | |||
757 | # CONFIG_USB is not set | 806 | # CONFIG_USB is not set |
758 | 807 | ||
759 | # | 808 | # |
809 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
810 | # | ||
811 | |||
812 | # | ||
760 | # USB Gadget Support | 813 | # USB Gadget Support |
761 | # | 814 | # |
762 | # CONFIG_USB_GADGET is not set | 815 | # CONFIG_USB_GADGET is not set |
@@ -943,9 +996,24 @@ CONFIG_NLS_ISO8859_15=m | |||
943 | # CONFIG_NLS_UTF8 is not set | 996 | # CONFIG_NLS_UTF8 is not set |
944 | 997 | ||
945 | # | 998 | # |
946 | # Profiling support | 999 | # Library routines |
1000 | # | ||
1001 | # CONFIG_CRC_CCITT is not set | ||
1002 | # CONFIG_CRC16 is not set | ||
1003 | CONFIG_CRC32=y | ||
1004 | # CONFIG_LIBCRC32C is not set | ||
1005 | CONFIG_ZLIB_INFLATE=m | ||
1006 | CONFIG_ZLIB_DEFLATE=m | ||
1007 | CONFIG_TEXTSEARCH=y | ||
1008 | CONFIG_TEXTSEARCH_KMP=m | ||
1009 | CONFIG_TEXTSEARCH_BM=m | ||
1010 | CONFIG_TEXTSEARCH_FSM=m | ||
1011 | |||
1012 | # | ||
1013 | # Instrumentation Support | ||
947 | # | 1014 | # |
948 | # CONFIG_PROFILING is not set | 1015 | # CONFIG_PROFILING is not set |
1016 | # CONFIG_KPROBES is not set | ||
949 | 1017 | ||
950 | # | 1018 | # |
951 | # Kernel hacking | 1019 | # Kernel hacking |
@@ -962,13 +1030,14 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y | |||
962 | # CONFIG_DEBUG_KOBJECT is not set | 1030 | # CONFIG_DEBUG_KOBJECT is not set |
963 | # CONFIG_DEBUG_INFO is not set | 1031 | # CONFIG_DEBUG_INFO is not set |
964 | CONFIG_DEBUG_FS=y | 1032 | CONFIG_DEBUG_FS=y |
1033 | # CONFIG_DEBUG_VM is not set | ||
1034 | # CONFIG_RCU_TORTURE_TEST is not set | ||
965 | # CONFIG_DEBUG_STACKOVERFLOW is not set | 1035 | # CONFIG_DEBUG_STACKOVERFLOW is not set |
966 | # CONFIG_KPROBES is not set | ||
967 | # CONFIG_DEBUG_STACK_USAGE is not set | 1036 | # CONFIG_DEBUG_STACK_USAGE is not set |
968 | CONFIG_DEBUGGER=y | 1037 | CONFIG_DEBUGGER=y |
969 | # CONFIG_XMON is not set | 1038 | # CONFIG_XMON is not set |
970 | # CONFIG_PPCDBG is not set | ||
971 | CONFIG_IRQSTACKS=y | 1039 | CONFIG_IRQSTACKS=y |
1040 | # CONFIG_BOOTX_TEXT is not set | ||
972 | 1041 | ||
973 | # | 1042 | # |
974 | # Security options | 1043 | # Security options |
@@ -1008,17 +1077,3 @@ CONFIG_CRYPTO_DEFLATE=m | |||
1008 | # | 1077 | # |
1009 | # Hardware crypto devices | 1078 | # Hardware crypto devices |
1010 | # | 1079 | # |
1011 | |||
1012 | # | ||
1013 | # Library routines | ||
1014 | # | ||
1015 | # CONFIG_CRC_CCITT is not set | ||
1016 | # CONFIG_CRC16 is not set | ||
1017 | CONFIG_CRC32=y | ||
1018 | # CONFIG_LIBCRC32C is not set | ||
1019 | CONFIG_ZLIB_INFLATE=m | ||
1020 | CONFIG_ZLIB_DEFLATE=m | ||
1021 | CONFIG_TEXTSEARCH=y | ||
1022 | CONFIG_TEXTSEARCH_KMP=m | ||
1023 | CONFIG_TEXTSEARCH_BM=m | ||
1024 | CONFIG_TEXTSEARCH_FSM=m | ||
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index e76854f8c121..e7c23e3902b8 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.14 | 3 | # Linux kernel version: 2.6.15-rc1 |
4 | # Mon Nov 7 13:37:59 2005 | 4 | # Tue Nov 15 14:39:20 2005 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -83,6 +83,23 @@ CONFIG_KMOD=y | |||
83 | CONFIG_STOP_MACHINE=y | 83 | CONFIG_STOP_MACHINE=y |
84 | 84 | ||
85 | # | 85 | # |
86 | # Block layer | ||
87 | # | ||
88 | |||
89 | # | ||
90 | # IO Schedulers | ||
91 | # | ||
92 | CONFIG_IOSCHED_NOOP=y | ||
93 | CONFIG_IOSCHED_AS=y | ||
94 | CONFIG_IOSCHED_DEADLINE=y | ||
95 | CONFIG_IOSCHED_CFQ=y | ||
96 | CONFIG_DEFAULT_AS=y | ||
97 | # CONFIG_DEFAULT_DEADLINE is not set | ||
98 | # CONFIG_DEFAULT_CFQ is not set | ||
99 | # CONFIG_DEFAULT_NOOP is not set | ||
100 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
101 | |||
102 | # | ||
86 | # Platform support | 103 | # Platform support |
87 | # | 104 | # |
88 | CONFIG_PPC_MULTIPLATFORM=y | 105 | CONFIG_PPC_MULTIPLATFORM=y |
@@ -137,6 +154,7 @@ CONFIG_IRQ_ALL_CPUS=y | |||
137 | # CONFIG_NUMA is not set | 154 | # CONFIG_NUMA is not set |
138 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y | 155 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y |
139 | CONFIG_ARCH_FLATMEM_ENABLE=y | 156 | CONFIG_ARCH_FLATMEM_ENABLE=y |
157 | CONFIG_ARCH_SPARSEMEM_ENABLE=y | ||
140 | CONFIG_SELECT_MEMORY_MODEL=y | 158 | CONFIG_SELECT_MEMORY_MODEL=y |
141 | CONFIG_FLATMEM_MANUAL=y | 159 | CONFIG_FLATMEM_MANUAL=y |
142 | # CONFIG_DISCONTIGMEM_MANUAL is not set | 160 | # CONFIG_DISCONTIGMEM_MANUAL is not set |
@@ -144,7 +162,7 @@ CONFIG_FLATMEM_MANUAL=y | |||
144 | CONFIG_FLATMEM=y | 162 | CONFIG_FLATMEM=y |
145 | CONFIG_FLAT_NODE_MEM_MAP=y | 163 | CONFIG_FLAT_NODE_MEM_MAP=y |
146 | # CONFIG_SPARSEMEM_STATIC is not set | 164 | # CONFIG_SPARSEMEM_STATIC is not set |
147 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 165 | CONFIG_SPLIT_PTLOCK_CPUS=4096 |
148 | # CONFIG_PPC_64K_PAGES is not set | 166 | # CONFIG_PPC_64K_PAGES is not set |
149 | # CONFIG_SCHED_SMT is not set | 167 | # CONFIG_SCHED_SMT is not set |
150 | CONFIG_PROC_DEVICETREE=y | 168 | CONFIG_PROC_DEVICETREE=y |
@@ -215,6 +233,10 @@ CONFIG_TCP_CONG_BIC=y | |||
215 | # CONFIG_IPV6 is not set | 233 | # CONFIG_IPV6 is not set |
216 | CONFIG_NETFILTER=y | 234 | CONFIG_NETFILTER=y |
217 | # CONFIG_NETFILTER_DEBUG is not set | 235 | # CONFIG_NETFILTER_DEBUG is not set |
236 | |||
237 | # | ||
238 | # Core Netfilter Configuration | ||
239 | # | ||
218 | # CONFIG_NETFILTER_NETLINK is not set | 240 | # CONFIG_NETFILTER_NETLINK is not set |
219 | 241 | ||
220 | # | 242 | # |
@@ -382,19 +404,6 @@ CONFIG_BLK_DEV_INITRD=y | |||
382 | CONFIG_CDROM_PKTCDVD=m | 404 | CONFIG_CDROM_PKTCDVD=m |
383 | CONFIG_CDROM_PKTCDVD_BUFFERS=8 | 405 | CONFIG_CDROM_PKTCDVD_BUFFERS=8 |
384 | # CONFIG_CDROM_PKTCDVD_WCACHE is not set | 406 | # CONFIG_CDROM_PKTCDVD_WCACHE is not set |
385 | |||
386 | # | ||
387 | # IO Schedulers | ||
388 | # | ||
389 | CONFIG_IOSCHED_NOOP=y | ||
390 | CONFIG_IOSCHED_AS=y | ||
391 | CONFIG_IOSCHED_DEADLINE=y | ||
392 | CONFIG_IOSCHED_CFQ=y | ||
393 | CONFIG_DEFAULT_AS=y | ||
394 | # CONFIG_DEFAULT_DEADLINE is not set | ||
395 | # CONFIG_DEFAULT_CFQ is not set | ||
396 | # CONFIG_DEFAULT_NOOP is not set | ||
397 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
398 | # CONFIG_ATA_OVER_ETH is not set | 407 | # CONFIG_ATA_OVER_ETH is not set |
399 | 408 | ||
400 | # | 409 | # |
@@ -656,7 +665,6 @@ CONFIG_SUNGEM=y | |||
656 | # CONFIG_NET_TULIP is not set | 665 | # CONFIG_NET_TULIP is not set |
657 | # CONFIG_HP100 is not set | 666 | # CONFIG_HP100 is not set |
658 | # CONFIG_NET_PCI is not set | 667 | # CONFIG_NET_PCI is not set |
659 | # CONFIG_FEC_8XX is not set | ||
660 | 668 | ||
661 | # | 669 | # |
662 | # Ethernet (1000 Mbit) | 670 | # Ethernet (1000 Mbit) |
@@ -710,6 +718,7 @@ CONFIG_PPP_ASYNC=m | |||
710 | CONFIG_PPP_SYNC_TTY=m | 718 | CONFIG_PPP_SYNC_TTY=m |
711 | CONFIG_PPP_DEFLATE=m | 719 | CONFIG_PPP_DEFLATE=m |
712 | CONFIG_PPP_BSDCOMP=m | 720 | CONFIG_PPP_BSDCOMP=m |
721 | # CONFIG_PPP_MPPE is not set | ||
713 | CONFIG_PPPOE=m | 722 | CONFIG_PPPOE=m |
714 | # CONFIG_SLIP is not set | 723 | # CONFIG_SLIP is not set |
715 | # CONFIG_NET_FC is not set | 724 | # CONFIG_NET_FC is not set |
@@ -804,6 +813,8 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
804 | # | 813 | # |
805 | # CONFIG_WATCHDOG is not set | 814 | # CONFIG_WATCHDOG is not set |
806 | # CONFIG_RTC is not set | 815 | # CONFIG_RTC is not set |
816 | CONFIG_GEN_RTC=y | ||
817 | # CONFIG_GEN_RTC_X is not set | ||
807 | # CONFIG_DTLK is not set | 818 | # CONFIG_DTLK is not set |
808 | # CONFIG_R3964 is not set | 819 | # CONFIG_R3964 is not set |
809 | # CONFIG_APPLICOM is not set | 820 | # CONFIG_APPLICOM is not set |
@@ -917,7 +928,6 @@ CONFIG_FB=y | |||
917 | CONFIG_FB_CFB_FILLRECT=y | 928 | CONFIG_FB_CFB_FILLRECT=y |
918 | CONFIG_FB_CFB_COPYAREA=y | 929 | CONFIG_FB_CFB_COPYAREA=y |
919 | CONFIG_FB_CFB_IMAGEBLIT=y | 930 | CONFIG_FB_CFB_IMAGEBLIT=y |
920 | CONFIG_FB_SOFT_CURSOR=y | ||
921 | CONFIG_FB_MACMODES=y | 931 | CONFIG_FB_MACMODES=y |
922 | CONFIG_FB_MODE_HELPERS=y | 932 | CONFIG_FB_MODE_HELPERS=y |
923 | CONFIG_FB_TILEBLITTING=y | 933 | CONFIG_FB_TILEBLITTING=y |
@@ -932,6 +942,7 @@ CONFIG_FB_OF=y | |||
932 | # CONFIG_FB_ASILIANT is not set | 942 | # CONFIG_FB_ASILIANT is not set |
933 | # CONFIG_FB_IMSTT is not set | 943 | # CONFIG_FB_IMSTT is not set |
934 | # CONFIG_FB_VGA16 is not set | 944 | # CONFIG_FB_VGA16 is not set |
945 | # CONFIG_FB_S1D13XXX is not set | ||
935 | CONFIG_FB_NVIDIA=y | 946 | CONFIG_FB_NVIDIA=y |
936 | CONFIG_FB_NVIDIA_I2C=y | 947 | CONFIG_FB_NVIDIA_I2C=y |
937 | # CONFIG_FB_RIVA is not set | 948 | # CONFIG_FB_RIVA is not set |
@@ -950,7 +961,6 @@ CONFIG_FB_RADEON_I2C=y | |||
950 | # CONFIG_FB_VOODOO1 is not set | 961 | # CONFIG_FB_VOODOO1 is not set |
951 | # CONFIG_FB_CYBLA is not set | 962 | # CONFIG_FB_CYBLA is not set |
952 | # CONFIG_FB_TRIDENT is not set | 963 | # CONFIG_FB_TRIDENT is not set |
953 | # CONFIG_FB_S1D13XXX is not set | ||
954 | # CONFIG_FB_VIRTUAL is not set | 964 | # CONFIG_FB_VIRTUAL is not set |
955 | 965 | ||
956 | # | 966 | # |
@@ -959,6 +969,7 @@ CONFIG_FB_RADEON_I2C=y | |||
959 | # CONFIG_VGA_CONSOLE is not set | 969 | # CONFIG_VGA_CONSOLE is not set |
960 | CONFIG_DUMMY_CONSOLE=y | 970 | CONFIG_DUMMY_CONSOLE=y |
961 | CONFIG_FRAMEBUFFER_CONSOLE=y | 971 | CONFIG_FRAMEBUFFER_CONSOLE=y |
972 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | ||
962 | # CONFIG_FONTS is not set | 973 | # CONFIG_FONTS is not set |
963 | CONFIG_FONT_8x8=y | 974 | CONFIG_FONT_8x8=y |
964 | CONFIG_FONT_8x16=y | 975 | CONFIG_FONT_8x16=y |
@@ -1474,10 +1485,11 @@ CONFIG_TEXTSEARCH_BM=m | |||
1474 | CONFIG_TEXTSEARCH_FSM=m | 1485 | CONFIG_TEXTSEARCH_FSM=m |
1475 | 1486 | ||
1476 | # | 1487 | # |
1477 | # Profiling support | 1488 | # Instrumentation Support |
1478 | # | 1489 | # |
1479 | CONFIG_PROFILING=y | 1490 | CONFIG_PROFILING=y |
1480 | CONFIG_OPROFILE=y | 1491 | CONFIG_OPROFILE=y |
1492 | # CONFIG_KPROBES is not set | ||
1481 | 1493 | ||
1482 | # | 1494 | # |
1483 | # Kernel hacking | 1495 | # Kernel hacking |
@@ -1497,7 +1509,6 @@ CONFIG_DEBUG_FS=y | |||
1497 | # CONFIG_DEBUG_VM is not set | 1509 | # CONFIG_DEBUG_VM is not set |
1498 | # CONFIG_RCU_TORTURE_TEST is not set | 1510 | # CONFIG_RCU_TORTURE_TEST is not set |
1499 | # CONFIG_DEBUG_STACKOVERFLOW is not set | 1511 | # CONFIG_DEBUG_STACKOVERFLOW is not set |
1500 | # CONFIG_KPROBES is not set | ||
1501 | # CONFIG_DEBUG_STACK_USAGE is not set | 1512 | # CONFIG_DEBUG_STACK_USAGE is not set |
1502 | # CONFIG_DEBUGGER is not set | 1513 | # CONFIG_DEBUGGER is not set |
1503 | CONFIG_IRQSTACKS=y | 1514 | CONFIG_IRQSTACKS=y |
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig index 62e92c7e9e27..5d0866707a75 100644 --- a/arch/powerpc/configs/iseries_defconfig +++ b/arch/powerpc/configs/iseries_defconfig | |||
@@ -1,18 +1,33 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.14-rc4 | 3 | # Linux kernel version: 2.6.15-rc1 |
4 | # Thu Oct 20 08:30:56 2005 | 4 | # Tue Nov 15 14:38:09 2005 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | ||
6 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
8 | CONFIG_PPC_MERGE=y | ||
7 | CONFIG_MMU=y | 9 | CONFIG_MMU=y |
10 | CONFIG_GENERIC_HARDIRQS=y | ||
8 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
9 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 12 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
10 | CONFIG_GENERIC_ISA_DMA=y | 13 | CONFIG_PPC=y |
11 | CONFIG_EARLY_PRINTK=y | 14 | CONFIG_EARLY_PRINTK=y |
12 | CONFIG_COMPAT=y | 15 | CONFIG_COMPAT=y |
16 | CONFIG_SYSVIPC_COMPAT=y | ||
13 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | 17 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y |
14 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | 18 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y |
15 | CONFIG_FORCE_MAX_ZONEORDER=13 | 19 | |
20 | # | ||
21 | # Processor support | ||
22 | # | ||
23 | # CONFIG_POWER4_ONLY is not set | ||
24 | CONFIG_POWER3=y | ||
25 | CONFIG_POWER4=y | ||
26 | CONFIG_PPC_FPU=y | ||
27 | # CONFIG_ALTIVEC is not set | ||
28 | CONFIG_PPC_STD_MMU=y | ||
29 | CONFIG_SMP=y | ||
30 | CONFIG_NR_CPUS=32 | ||
16 | 31 | ||
17 | # | 32 | # |
18 | # Code maturity level options | 33 | # Code maturity level options |
@@ -68,22 +83,60 @@ CONFIG_MODVERSIONS=y | |||
68 | CONFIG_MODULE_SRCVERSION_ALL=y | 83 | CONFIG_MODULE_SRCVERSION_ALL=y |
69 | CONFIG_KMOD=y | 84 | CONFIG_KMOD=y |
70 | CONFIG_STOP_MACHINE=y | 85 | CONFIG_STOP_MACHINE=y |
71 | CONFIG_SYSVIPC_COMPAT=y | 86 | |
87 | # | ||
88 | # Block layer | ||
89 | # | ||
90 | |||
91 | # | ||
92 | # IO Schedulers | ||
93 | # | ||
94 | CONFIG_IOSCHED_NOOP=y | ||
95 | CONFIG_IOSCHED_AS=y | ||
96 | CONFIG_IOSCHED_DEADLINE=y | ||
97 | CONFIG_IOSCHED_CFQ=y | ||
98 | CONFIG_DEFAULT_AS=y | ||
99 | # CONFIG_DEFAULT_DEADLINE is not set | ||
100 | # CONFIG_DEFAULT_CFQ is not set | ||
101 | # CONFIG_DEFAULT_NOOP is not set | ||
102 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
72 | 103 | ||
73 | # | 104 | # |
74 | # Platform support | 105 | # Platform support |
75 | # | 106 | # |
76 | CONFIG_PPC_ISERIES=y | ||
77 | # CONFIG_PPC_MULTIPLATFORM is not set | 107 | # CONFIG_PPC_MULTIPLATFORM is not set |
78 | CONFIG_PPC=y | 108 | CONFIG_PPC_ISERIES=y |
79 | CONFIG_PPC64=y | 109 | # CONFIG_EMBEDDED6xx is not set |
110 | # CONFIG_APUS is not set | ||
111 | # CONFIG_PPC_RTAS is not set | ||
112 | # CONFIG_MMIO_NVRAM is not set | ||
80 | CONFIG_IBMVIO=y | 113 | CONFIG_IBMVIO=y |
81 | # CONFIG_POWER4_ONLY is not set | 114 | # CONFIG_PPC_MPC106 is not set |
115 | # CONFIG_GENERIC_TBSYNC is not set | ||
116 | # CONFIG_CPU_FREQ is not set | ||
117 | # CONFIG_WANT_EARLY_SERIAL is not set | ||
118 | |||
119 | # | ||
120 | # Kernel options | ||
121 | # | ||
122 | # CONFIG_HZ_100 is not set | ||
123 | CONFIG_HZ_250=y | ||
124 | # CONFIG_HZ_1000 is not set | ||
125 | CONFIG_HZ=250 | ||
126 | CONFIG_PREEMPT_NONE=y | ||
127 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
128 | # CONFIG_PREEMPT is not set | ||
129 | # CONFIG_PREEMPT_BKL is not set | ||
130 | CONFIG_BINFMT_ELF=y | ||
131 | # CONFIG_BINFMT_MISC is not set | ||
132 | CONFIG_FORCE_MAX_ZONEORDER=13 | ||
82 | CONFIG_IOMMU_VMERGE=y | 133 | CONFIG_IOMMU_VMERGE=y |
83 | CONFIG_SMP=y | 134 | CONFIG_IRQ_ALL_CPUS=y |
84 | CONFIG_NR_CPUS=32 | 135 | CONFIG_LPARCFG=y |
136 | # CONFIG_NUMA is not set | ||
85 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y | 137 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y |
86 | CONFIG_ARCH_FLATMEM_ENABLE=y | 138 | CONFIG_ARCH_FLATMEM_ENABLE=y |
139 | CONFIG_ARCH_SPARSEMEM_ENABLE=y | ||
87 | CONFIG_SELECT_MEMORY_MODEL=y | 140 | CONFIG_SELECT_MEMORY_MODEL=y |
88 | CONFIG_FLATMEM_MANUAL=y | 141 | CONFIG_FLATMEM_MANUAL=y |
89 | # CONFIG_DISCONTIGMEM_MANUAL is not set | 142 | # CONFIG_DISCONTIGMEM_MANUAL is not set |
@@ -91,26 +144,20 @@ CONFIG_FLATMEM_MANUAL=y | |||
91 | CONFIG_FLATMEM=y | 144 | CONFIG_FLATMEM=y |
92 | CONFIG_FLAT_NODE_MEM_MAP=y | 145 | CONFIG_FLAT_NODE_MEM_MAP=y |
93 | # CONFIG_SPARSEMEM_STATIC is not set | 146 | # CONFIG_SPARSEMEM_STATIC is not set |
94 | # CONFIG_NUMA is not set | 147 | CONFIG_SPLIT_PTLOCK_CPUS=4096 |
148 | # CONFIG_PPC_64K_PAGES is not set | ||
95 | # CONFIG_SCHED_SMT is not set | 149 | # CONFIG_SCHED_SMT is not set |
96 | CONFIG_PREEMPT_NONE=y | 150 | CONFIG_PROC_DEVICETREE=y |
97 | # CONFIG_PREEMPT_VOLUNTARY is not set | 151 | # CONFIG_PM is not set |
98 | # CONFIG_PREEMPT is not set | ||
99 | # CONFIG_PREEMPT_BKL is not set | ||
100 | # CONFIG_HZ_100 is not set | ||
101 | CONFIG_HZ_250=y | ||
102 | # CONFIG_HZ_1000 is not set | ||
103 | CONFIG_HZ=250 | ||
104 | CONFIG_GENERIC_HARDIRQS=y | ||
105 | CONFIG_LPARCFG=y | ||
106 | CONFIG_SECCOMP=y | 152 | CONFIG_SECCOMP=y |
107 | CONFIG_BINFMT_ELF=y | ||
108 | # CONFIG_BINFMT_MISC is not set | ||
109 | CONFIG_ISA_DMA_API=y | 153 | CONFIG_ISA_DMA_API=y |
110 | 154 | ||
111 | # | 155 | # |
112 | # Bus Options | 156 | # Bus options |
113 | # | 157 | # |
158 | CONFIG_GENERIC_ISA_DMA=y | ||
159 | # CONFIG_PPC_I8259 is not set | ||
160 | # CONFIG_PPC_INDIRECT_PCI is not set | ||
114 | CONFIG_PCI=y | 161 | CONFIG_PCI=y |
115 | CONFIG_PCI_DOMAINS=y | 162 | CONFIG_PCI_DOMAINS=y |
116 | CONFIG_PCI_LEGACY_PROC=y | 163 | CONFIG_PCI_LEGACY_PROC=y |
@@ -125,6 +172,7 @@ CONFIG_PCI_LEGACY_PROC=y | |||
125 | # PCI Hotplug Support | 172 | # PCI Hotplug Support |
126 | # | 173 | # |
127 | # CONFIG_HOTPLUG_PCI is not set | 174 | # CONFIG_HOTPLUG_PCI is not set |
175 | CONFIG_KERNEL_START=0xc000000000000000 | ||
128 | 176 | ||
129 | # | 177 | # |
130 | # Networking | 178 | # Networking |
@@ -166,6 +214,10 @@ CONFIG_TCP_CONG_BIC=y | |||
166 | # CONFIG_IPV6 is not set | 214 | # CONFIG_IPV6 is not set |
167 | CONFIG_NETFILTER=y | 215 | CONFIG_NETFILTER=y |
168 | # CONFIG_NETFILTER_DEBUG is not set | 216 | # CONFIG_NETFILTER_DEBUG is not set |
217 | |||
218 | # | ||
219 | # Core Netfilter Configuration | ||
220 | # | ||
169 | # CONFIG_NETFILTER_NETLINK is not set | 221 | # CONFIG_NETFILTER_NETLINK is not set |
170 | 222 | ||
171 | # | 223 | # |
@@ -265,6 +317,10 @@ CONFIG_LLC=y | |||
265 | # CONFIG_NET_DIVERT is not set | 317 | # CONFIG_NET_DIVERT is not set |
266 | # CONFIG_ECONET is not set | 318 | # CONFIG_ECONET is not set |
267 | # CONFIG_WAN_ROUTER is not set | 319 | # CONFIG_WAN_ROUTER is not set |
320 | |||
321 | # | ||
322 | # QoS and/or fair queueing | ||
323 | # | ||
268 | # CONFIG_NET_SCHED is not set | 324 | # CONFIG_NET_SCHED is not set |
269 | CONFIG_NET_CLS_ROUTE=y | 325 | CONFIG_NET_CLS_ROUTE=y |
270 | 326 | ||
@@ -326,14 +382,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16 | |||
326 | CONFIG_BLK_DEV_RAM_SIZE=65536 | 382 | CONFIG_BLK_DEV_RAM_SIZE=65536 |
327 | CONFIG_BLK_DEV_INITRD=y | 383 | CONFIG_BLK_DEV_INITRD=y |
328 | # CONFIG_CDROM_PKTCDVD is not set | 384 | # CONFIG_CDROM_PKTCDVD is not set |
329 | |||
330 | # | ||
331 | # IO Schedulers | ||
332 | # | ||
333 | CONFIG_IOSCHED_NOOP=y | ||
334 | CONFIG_IOSCHED_AS=y | ||
335 | CONFIG_IOSCHED_DEADLINE=y | ||
336 | CONFIG_IOSCHED_CFQ=y | ||
337 | # CONFIG_ATA_OVER_ETH is not set | 385 | # CONFIG_ATA_OVER_ETH is not set |
338 | 386 | ||
339 | # | 387 | # |
@@ -377,6 +425,7 @@ CONFIG_SCSI_FC_ATTRS=y | |||
377 | # | 425 | # |
378 | # SCSI low-level drivers | 426 | # SCSI low-level drivers |
379 | # | 427 | # |
428 | # CONFIG_ISCSI_TCP is not set | ||
380 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | 429 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
381 | # CONFIG_SCSI_3W_9XXX is not set | 430 | # CONFIG_SCSI_3W_9XXX is not set |
382 | # CONFIG_SCSI_ACARD is not set | 431 | # CONFIG_SCSI_ACARD is not set |
@@ -454,6 +503,7 @@ CONFIG_DM_ZERO=m | |||
454 | # | 503 | # |
455 | # Macintosh device drivers | 504 | # Macintosh device drivers |
456 | # | 505 | # |
506 | # CONFIG_WINDFARM is not set | ||
457 | 507 | ||
458 | # | 508 | # |
459 | # Network device support | 509 | # Network device support |
@@ -561,6 +611,7 @@ CONFIG_PPP_ASYNC=m | |||
561 | CONFIG_PPP_SYNC_TTY=m | 611 | CONFIG_PPP_SYNC_TTY=m |
562 | CONFIG_PPP_DEFLATE=m | 612 | CONFIG_PPP_DEFLATE=m |
563 | CONFIG_PPP_BSDCOMP=m | 613 | CONFIG_PPP_BSDCOMP=m |
614 | # CONFIG_PPP_MPPE is not set | ||
564 | CONFIG_PPPOE=m | 615 | CONFIG_PPPOE=m |
565 | # CONFIG_SLIP is not set | 616 | # CONFIG_SLIP is not set |
566 | # CONFIG_NET_FC is not set | 617 | # CONFIG_NET_FC is not set |
@@ -643,6 +694,8 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
643 | # | 694 | # |
644 | # CONFIG_WATCHDOG is not set | 695 | # CONFIG_WATCHDOG is not set |
645 | # CONFIG_RTC is not set | 696 | # CONFIG_RTC is not set |
697 | CONFIG_GEN_RTC=y | ||
698 | # CONFIG_GEN_RTC_X is not set | ||
646 | # CONFIG_DTLK is not set | 699 | # CONFIG_DTLK is not set |
647 | # CONFIG_R3964 is not set | 700 | # CONFIG_R3964 is not set |
648 | # CONFIG_APPLICOM is not set | 701 | # CONFIG_APPLICOM is not set |
@@ -660,6 +713,7 @@ CONFIG_MAX_RAW_DEVS=256 | |||
660 | # TPM devices | 713 | # TPM devices |
661 | # | 714 | # |
662 | # CONFIG_TCG_TPM is not set | 715 | # CONFIG_TCG_TPM is not set |
716 | # CONFIG_TELCLOCK is not set | ||
663 | 717 | ||
664 | # | 718 | # |
665 | # I2C support | 719 | # I2C support |
@@ -713,6 +767,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y | |||
713 | # CONFIG_USB is not set | 767 | # CONFIG_USB is not set |
714 | 768 | ||
715 | # | 769 | # |
770 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
771 | # | ||
772 | |||
773 | # | ||
716 | # USB Gadget Support | 774 | # USB Gadget Support |
717 | # | 775 | # |
718 | # CONFIG_USB_GADGET is not set | 776 | # CONFIG_USB_GADGET is not set |
@@ -917,10 +975,25 @@ CONFIG_VIOTAPE=m | |||
917 | CONFIG_VIOPATH=y | 975 | CONFIG_VIOPATH=y |
918 | 976 | ||
919 | # | 977 | # |
920 | # Profiling support | 978 | # Library routines |
979 | # | ||
980 | CONFIG_CRC_CCITT=m | ||
981 | # CONFIG_CRC16 is not set | ||
982 | CONFIG_CRC32=y | ||
983 | CONFIG_LIBCRC32C=m | ||
984 | CONFIG_ZLIB_INFLATE=y | ||
985 | CONFIG_ZLIB_DEFLATE=m | ||
986 | CONFIG_TEXTSEARCH=y | ||
987 | CONFIG_TEXTSEARCH_KMP=m | ||
988 | CONFIG_TEXTSEARCH_BM=m | ||
989 | CONFIG_TEXTSEARCH_FSM=m | ||
990 | |||
991 | # | ||
992 | # Instrumentation Support | ||
921 | # | 993 | # |
922 | CONFIG_PROFILING=y | 994 | CONFIG_PROFILING=y |
923 | CONFIG_OPROFILE=y | 995 | CONFIG_OPROFILE=y |
996 | # CONFIG_KPROBES is not set | ||
924 | 997 | ||
925 | # | 998 | # |
926 | # Kernel hacking | 999 | # Kernel hacking |
@@ -937,11 +1010,11 @@ CONFIG_DETECT_SOFTLOCKUP=y | |||
937 | # CONFIG_DEBUG_KOBJECT is not set | 1010 | # CONFIG_DEBUG_KOBJECT is not set |
938 | # CONFIG_DEBUG_INFO is not set | 1011 | # CONFIG_DEBUG_INFO is not set |
939 | CONFIG_DEBUG_FS=y | 1012 | CONFIG_DEBUG_FS=y |
1013 | # CONFIG_DEBUG_VM is not set | ||
1014 | # CONFIG_RCU_TORTURE_TEST is not set | ||
940 | CONFIG_DEBUG_STACKOVERFLOW=y | 1015 | CONFIG_DEBUG_STACKOVERFLOW=y |
941 | # CONFIG_KPROBES is not set | ||
942 | CONFIG_DEBUG_STACK_USAGE=y | 1016 | CONFIG_DEBUG_STACK_USAGE=y |
943 | # CONFIG_DEBUGGER is not set | 1017 | # CONFIG_DEBUGGER is not set |
944 | # CONFIG_PPCDBG is not set | ||
945 | CONFIG_IRQSTACKS=y | 1018 | CONFIG_IRQSTACKS=y |
946 | 1019 | ||
947 | # | 1020 | # |
@@ -982,17 +1055,3 @@ CONFIG_CRYPTO_TEST=m | |||
982 | # | 1055 | # |
983 | # Hardware crypto devices | 1056 | # Hardware crypto devices |
984 | # | 1057 | # |
985 | |||
986 | # | ||
987 | # Library routines | ||
988 | # | ||
989 | CONFIG_CRC_CCITT=m | ||
990 | # CONFIG_CRC16 is not set | ||
991 | CONFIG_CRC32=y | ||
992 | CONFIG_LIBCRC32C=m | ||
993 | CONFIG_ZLIB_INFLATE=y | ||
994 | CONFIG_ZLIB_DEFLATE=m | ||
995 | CONFIG_TEXTSEARCH=y | ||
996 | CONFIG_TEXTSEARCH_KMP=m | ||
997 | CONFIG_TEXTSEARCH_BM=m | ||
998 | CONFIG_TEXTSEARCH_FSM=m | ||
diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig index 7b480f3d1406..92e42613ef06 100644 --- a/arch/powerpc/configs/maple_defconfig +++ b/arch/powerpc/configs/maple_defconfig | |||
@@ -1,18 +1,32 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.14-rc4 | 3 | # Linux kernel version: 2.6.15-rc1 |
4 | # Thu Oct 20 08:31:24 2005 | 4 | # Tue Nov 15 14:38:58 2005 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | ||
6 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
8 | CONFIG_PPC_MERGE=y | ||
7 | CONFIG_MMU=y | 9 | CONFIG_MMU=y |
10 | CONFIG_GENERIC_HARDIRQS=y | ||
8 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
9 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 12 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
10 | CONFIG_GENERIC_ISA_DMA=y | 13 | CONFIG_PPC=y |
11 | CONFIG_EARLY_PRINTK=y | 14 | CONFIG_EARLY_PRINTK=y |
12 | CONFIG_COMPAT=y | 15 | CONFIG_COMPAT=y |
16 | CONFIG_SYSVIPC_COMPAT=y | ||
13 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | 17 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y |
14 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | 18 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y |
15 | CONFIG_FORCE_MAX_ZONEORDER=13 | 19 | |
20 | # | ||
21 | # Processor support | ||
22 | # | ||
23 | CONFIG_POWER4_ONLY=y | ||
24 | CONFIG_POWER4=y | ||
25 | CONFIG_PPC_FPU=y | ||
26 | # CONFIG_ALTIVEC is not set | ||
27 | CONFIG_PPC_STD_MMU=y | ||
28 | CONFIG_SMP=y | ||
29 | CONFIG_NR_CPUS=2 | ||
16 | 30 | ||
17 | # | 31 | # |
18 | # Code maturity level options | 32 | # Code maturity level options |
@@ -67,32 +81,67 @@ CONFIG_MODVERSIONS=y | |||
67 | CONFIG_MODULE_SRCVERSION_ALL=y | 81 | CONFIG_MODULE_SRCVERSION_ALL=y |
68 | CONFIG_KMOD=y | 82 | CONFIG_KMOD=y |
69 | CONFIG_STOP_MACHINE=y | 83 | CONFIG_STOP_MACHINE=y |
70 | CONFIG_SYSVIPC_COMPAT=y | 84 | |
85 | # | ||
86 | # Block layer | ||
87 | # | ||
88 | |||
89 | # | ||
90 | # IO Schedulers | ||
91 | # | ||
92 | CONFIG_IOSCHED_NOOP=y | ||
93 | CONFIG_IOSCHED_AS=y | ||
94 | CONFIG_IOSCHED_DEADLINE=y | ||
95 | CONFIG_IOSCHED_CFQ=y | ||
96 | CONFIG_DEFAULT_AS=y | ||
97 | # CONFIG_DEFAULT_DEADLINE is not set | ||
98 | # CONFIG_DEFAULT_CFQ is not set | ||
99 | # CONFIG_DEFAULT_NOOP is not set | ||
100 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
71 | 101 | ||
72 | # | 102 | # |
73 | # Platform support | 103 | # Platform support |
74 | # | 104 | # |
75 | # CONFIG_PPC_ISERIES is not set | ||
76 | CONFIG_PPC_MULTIPLATFORM=y | 105 | CONFIG_PPC_MULTIPLATFORM=y |
106 | # CONFIG_PPC_ISERIES is not set | ||
107 | # CONFIG_EMBEDDED6xx is not set | ||
108 | # CONFIG_APUS is not set | ||
77 | # CONFIG_PPC_PSERIES is not set | 109 | # CONFIG_PPC_PSERIES is not set |
78 | # CONFIG_PPC_BPA is not set | ||
79 | # CONFIG_PPC_PMAC is not set | 110 | # CONFIG_PPC_PMAC is not set |
80 | CONFIG_PPC_MAPLE=y | 111 | CONFIG_PPC_MAPLE=y |
81 | CONFIG_PPC=y | 112 | # CONFIG_PPC_CELL is not set |
82 | CONFIG_PPC64=y | ||
83 | CONFIG_PPC_OF=y | 113 | CONFIG_PPC_OF=y |
84 | CONFIG_MPIC=y | ||
85 | # CONFIG_ALTIVEC is not set | ||
86 | CONFIG_KEXEC=y | ||
87 | CONFIG_U3_DART=y | 114 | CONFIG_U3_DART=y |
115 | CONFIG_MPIC=y | ||
116 | # CONFIG_PPC_RTAS is not set | ||
117 | # CONFIG_MMIO_NVRAM is not set | ||
88 | CONFIG_MPIC_BROKEN_U3=y | 118 | CONFIG_MPIC_BROKEN_U3=y |
89 | CONFIG_BOOTX_TEXT=y | 119 | # CONFIG_PPC_MPC106 is not set |
90 | CONFIG_POWER4_ONLY=y | 120 | CONFIG_GENERIC_TBSYNC=y |
121 | # CONFIG_CPU_FREQ is not set | ||
122 | # CONFIG_WANT_EARLY_SERIAL is not set | ||
123 | |||
124 | # | ||
125 | # Kernel options | ||
126 | # | ||
127 | # CONFIG_HZ_100 is not set | ||
128 | CONFIG_HZ_250=y | ||
129 | # CONFIG_HZ_1000 is not set | ||
130 | CONFIG_HZ=250 | ||
131 | CONFIG_PREEMPT_NONE=y | ||
132 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
133 | # CONFIG_PREEMPT is not set | ||
134 | # CONFIG_PREEMPT_BKL is not set | ||
135 | CONFIG_BINFMT_ELF=y | ||
136 | # CONFIG_BINFMT_MISC is not set | ||
137 | CONFIG_FORCE_MAX_ZONEORDER=13 | ||
91 | CONFIG_IOMMU_VMERGE=y | 138 | CONFIG_IOMMU_VMERGE=y |
92 | CONFIG_SMP=y | 139 | CONFIG_KEXEC=y |
93 | CONFIG_NR_CPUS=2 | 140 | CONFIG_IRQ_ALL_CPUS=y |
141 | # CONFIG_NUMA is not set | ||
94 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y | 142 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y |
95 | CONFIG_ARCH_FLATMEM_ENABLE=y | 143 | CONFIG_ARCH_FLATMEM_ENABLE=y |
144 | CONFIG_ARCH_SPARSEMEM_ENABLE=y | ||
96 | CONFIG_SELECT_MEMORY_MODEL=y | 145 | CONFIG_SELECT_MEMORY_MODEL=y |
97 | CONFIG_FLATMEM_MANUAL=y | 146 | CONFIG_FLATMEM_MANUAL=y |
98 | # CONFIG_DISCONTIGMEM_MANUAL is not set | 147 | # CONFIG_DISCONTIGMEM_MANUAL is not set |
@@ -100,27 +149,21 @@ CONFIG_FLATMEM_MANUAL=y | |||
100 | CONFIG_FLATMEM=y | 149 | CONFIG_FLATMEM=y |
101 | CONFIG_FLAT_NODE_MEM_MAP=y | 150 | CONFIG_FLAT_NODE_MEM_MAP=y |
102 | # CONFIG_SPARSEMEM_STATIC is not set | 151 | # CONFIG_SPARSEMEM_STATIC is not set |
103 | # CONFIG_NUMA is not set | 152 | CONFIG_SPLIT_PTLOCK_CPUS=4096 |
153 | # CONFIG_PPC_64K_PAGES is not set | ||
104 | # CONFIG_SCHED_SMT is not set | 154 | # CONFIG_SCHED_SMT is not set |
105 | CONFIG_PREEMPT_NONE=y | ||
106 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
107 | # CONFIG_PREEMPT is not set | ||
108 | # CONFIG_PREEMPT_BKL is not set | ||
109 | # CONFIG_HZ_100 is not set | ||
110 | CONFIG_HZ_250=y | ||
111 | # CONFIG_HZ_1000 is not set | ||
112 | CONFIG_HZ=250 | ||
113 | CONFIG_GENERIC_HARDIRQS=y | ||
114 | CONFIG_SECCOMP=y | ||
115 | CONFIG_BINFMT_ELF=y | ||
116 | # CONFIG_BINFMT_MISC is not set | ||
117 | CONFIG_PROC_DEVICETREE=y | 155 | CONFIG_PROC_DEVICETREE=y |
118 | # CONFIG_CMDLINE_BOOL is not set | 156 | # CONFIG_CMDLINE_BOOL is not set |
157 | # CONFIG_PM is not set | ||
158 | CONFIG_SECCOMP=y | ||
119 | CONFIG_ISA_DMA_API=y | 159 | CONFIG_ISA_DMA_API=y |
120 | 160 | ||
121 | # | 161 | # |
122 | # Bus Options | 162 | # Bus options |
123 | # | 163 | # |
164 | CONFIG_GENERIC_ISA_DMA=y | ||
165 | # CONFIG_PPC_I8259 is not set | ||
166 | # CONFIG_PPC_INDIRECT_PCI is not set | ||
124 | CONFIG_PCI=y | 167 | CONFIG_PCI=y |
125 | CONFIG_PCI_DOMAINS=y | 168 | CONFIG_PCI_DOMAINS=y |
126 | CONFIG_PCI_LEGACY_PROC=y | 169 | CONFIG_PCI_LEGACY_PROC=y |
@@ -135,6 +178,7 @@ CONFIG_PCI_LEGACY_PROC=y | |||
135 | # PCI Hotplug Support | 178 | # PCI Hotplug Support |
136 | # | 179 | # |
137 | # CONFIG_HOTPLUG_PCI is not set | 180 | # CONFIG_HOTPLUG_PCI is not set |
181 | CONFIG_KERNEL_START=0xc000000000000000 | ||
138 | 182 | ||
139 | # | 183 | # |
140 | # Networking | 184 | # Networking |
@@ -193,6 +237,10 @@ CONFIG_TCP_CONG_BIC=y | |||
193 | # CONFIG_NET_DIVERT is not set | 237 | # CONFIG_NET_DIVERT is not set |
194 | # CONFIG_ECONET is not set | 238 | # CONFIG_ECONET is not set |
195 | # CONFIG_WAN_ROUTER is not set | 239 | # CONFIG_WAN_ROUTER is not set |
240 | |||
241 | # | ||
242 | # QoS and/or fair queueing | ||
243 | # | ||
196 | # CONFIG_NET_SCHED is not set | 244 | # CONFIG_NET_SCHED is not set |
197 | # CONFIG_NET_CLS_ROUTE is not set | 245 | # CONFIG_NET_CLS_ROUTE is not set |
198 | 246 | ||
@@ -254,14 +302,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16 | |||
254 | CONFIG_BLK_DEV_RAM_SIZE=8192 | 302 | CONFIG_BLK_DEV_RAM_SIZE=8192 |
255 | # CONFIG_BLK_DEV_INITRD is not set | 303 | # CONFIG_BLK_DEV_INITRD is not set |
256 | # CONFIG_CDROM_PKTCDVD is not set | 304 | # CONFIG_CDROM_PKTCDVD is not set |
257 | |||
258 | # | ||
259 | # IO Schedulers | ||
260 | # | ||
261 | CONFIG_IOSCHED_NOOP=y | ||
262 | CONFIG_IOSCHED_AS=y | ||
263 | CONFIG_IOSCHED_DEADLINE=y | ||
264 | CONFIG_IOSCHED_CFQ=y | ||
265 | # CONFIG_ATA_OVER_ETH is not set | 305 | # CONFIG_ATA_OVER_ETH is not set |
266 | 306 | ||
267 | # | 307 | # |
@@ -351,6 +391,7 @@ CONFIG_IDEDMA_AUTO=y | |||
351 | # | 391 | # |
352 | # Macintosh device drivers | 392 | # Macintosh device drivers |
353 | # | 393 | # |
394 | # CONFIG_WINDFARM is not set | ||
354 | 395 | ||
355 | # | 396 | # |
356 | # Network device support | 397 | # Network device support |
@@ -533,6 +574,8 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
533 | # | 574 | # |
534 | # CONFIG_WATCHDOG is not set | 575 | # CONFIG_WATCHDOG is not set |
535 | # CONFIG_RTC is not set | 576 | # CONFIG_RTC is not set |
577 | CONFIG_GEN_RTC=y | ||
578 | # CONFIG_GEN_RTC_X is not set | ||
536 | # CONFIG_DTLK is not set | 579 | # CONFIG_DTLK is not set |
537 | # CONFIG_R3964 is not set | 580 | # CONFIG_R3964 is not set |
538 | # CONFIG_APPLICOM is not set | 581 | # CONFIG_APPLICOM is not set |
@@ -549,6 +592,7 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
549 | # TPM devices | 592 | # TPM devices |
550 | # | 593 | # |
551 | # CONFIG_TCG_TPM is not set | 594 | # CONFIG_TCG_TPM is not set |
595 | # CONFIG_TELCLOCK is not set | ||
552 | 596 | ||
553 | # | 597 | # |
554 | # I2C support | 598 | # I2C support |
@@ -599,6 +643,7 @@ CONFIG_I2C_AMD8111=y | |||
599 | # CONFIG_SENSORS_PCF8591 is not set | 643 | # CONFIG_SENSORS_PCF8591 is not set |
600 | # CONFIG_SENSORS_RTC8564 is not set | 644 | # CONFIG_SENSORS_RTC8564 is not set |
601 | # CONFIG_SENSORS_MAX6875 is not set | 645 | # CONFIG_SENSORS_MAX6875 is not set |
646 | # CONFIG_RTC_X1205_I2C is not set | ||
602 | # CONFIG_I2C_DEBUG_CORE is not set | 647 | # CONFIG_I2C_DEBUG_CORE is not set |
603 | # CONFIG_I2C_DEBUG_ALGO is not set | 648 | # CONFIG_I2C_DEBUG_ALGO is not set |
604 | # CONFIG_I2C_DEBUG_BUS is not set | 649 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -681,12 +726,15 @@ CONFIG_USB_UHCI_HCD=y | |||
681 | # | 726 | # |
682 | # USB Device Class drivers | 727 | # USB Device Class drivers |
683 | # | 728 | # |
684 | # CONFIG_USB_BLUETOOTH_TTY is not set | ||
685 | # CONFIG_USB_ACM is not set | 729 | # CONFIG_USB_ACM is not set |
686 | # CONFIG_USB_PRINTER is not set | 730 | # CONFIG_USB_PRINTER is not set |
687 | 731 | ||
688 | # | 732 | # |
689 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information | 733 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' |
734 | # | ||
735 | |||
736 | # | ||
737 | # may also be needed; see USB_STORAGE Help for more information | ||
690 | # | 738 | # |
691 | # CONFIG_USB_STORAGE is not set | 739 | # CONFIG_USB_STORAGE is not set |
692 | 740 | ||
@@ -776,6 +824,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y | |||
776 | # CONFIG_USB_SERIAL_KLSI is not set | 824 | # CONFIG_USB_SERIAL_KLSI is not set |
777 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set | 825 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set |
778 | # CONFIG_USB_SERIAL_MCT_U232 is not set | 826 | # CONFIG_USB_SERIAL_MCT_U232 is not set |
827 | # CONFIG_USB_SERIAL_NOKIA_DKU2 is not set | ||
779 | # CONFIG_USB_SERIAL_PL2303 is not set | 828 | # CONFIG_USB_SERIAL_PL2303 is not set |
780 | # CONFIG_USB_SERIAL_HP4X is not set | 829 | # CONFIG_USB_SERIAL_HP4X is not set |
781 | # CONFIG_USB_SERIAL_SAFE is not set | 830 | # CONFIG_USB_SERIAL_SAFE is not set |
@@ -985,9 +1034,19 @@ CONFIG_NLS_DEFAULT="utf-8" | |||
985 | CONFIG_NLS_UTF8=y | 1034 | CONFIG_NLS_UTF8=y |
986 | 1035 | ||
987 | # | 1036 | # |
988 | # Profiling support | 1037 | # Library routines |
1038 | # | ||
1039 | CONFIG_CRC_CCITT=y | ||
1040 | # CONFIG_CRC16 is not set | ||
1041 | CONFIG_CRC32=y | ||
1042 | # CONFIG_LIBCRC32C is not set | ||
1043 | CONFIG_ZLIB_INFLATE=y | ||
1044 | |||
1045 | # | ||
1046 | # Instrumentation Support | ||
989 | # | 1047 | # |
990 | # CONFIG_PROFILING is not set | 1048 | # CONFIG_PROFILING is not set |
1049 | # CONFIG_KPROBES is not set | ||
991 | 1050 | ||
992 | # | 1051 | # |
993 | # Kernel hacking | 1052 | # Kernel hacking |
@@ -1004,14 +1063,15 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y | |||
1004 | # CONFIG_DEBUG_KOBJECT is not set | 1063 | # CONFIG_DEBUG_KOBJECT is not set |
1005 | # CONFIG_DEBUG_INFO is not set | 1064 | # CONFIG_DEBUG_INFO is not set |
1006 | CONFIG_DEBUG_FS=y | 1065 | CONFIG_DEBUG_FS=y |
1066 | # CONFIG_DEBUG_VM is not set | ||
1067 | # CONFIG_RCU_TORTURE_TEST is not set | ||
1007 | CONFIG_DEBUG_STACKOVERFLOW=y | 1068 | CONFIG_DEBUG_STACKOVERFLOW=y |
1008 | # CONFIG_KPROBES is not set | ||
1009 | CONFIG_DEBUG_STACK_USAGE=y | 1069 | CONFIG_DEBUG_STACK_USAGE=y |
1010 | CONFIG_DEBUGGER=y | 1070 | CONFIG_DEBUGGER=y |
1011 | CONFIG_XMON=y | 1071 | CONFIG_XMON=y |
1012 | CONFIG_XMON_DEFAULT=y | 1072 | CONFIG_XMON_DEFAULT=y |
1013 | # CONFIG_PPCDBG is not set | ||
1014 | # CONFIG_IRQSTACKS is not set | 1073 | # CONFIG_IRQSTACKS is not set |
1074 | CONFIG_BOOTX_TEXT=y | ||
1015 | 1075 | ||
1016 | # | 1076 | # |
1017 | # Security options | 1077 | # Security options |
@@ -1051,12 +1111,3 @@ CONFIG_CRYPTO_DES=y | |||
1051 | # | 1111 | # |
1052 | # Hardware crypto devices | 1112 | # Hardware crypto devices |
1053 | # | 1113 | # |
1054 | |||
1055 | # | ||
1056 | # Library routines | ||
1057 | # | ||
1058 | CONFIG_CRC_CCITT=y | ||
1059 | # CONFIG_CRC16 is not set | ||
1060 | CONFIG_CRC32=y | ||
1061 | # CONFIG_LIBCRC32C is not set | ||
1062 | CONFIG_ZLIB_INFLATE=y | ||
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig new file mode 100644 index 000000000000..b5ba3bbd96fb --- /dev/null +++ b/arch/powerpc/configs/ppc64_defconfig | |||
@@ -0,0 +1,1579 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.15-rc1 | ||
4 | # Fri Nov 18 16:23:24 2005 | ||
5 | # | ||
6 | CONFIG_PPC64=y | ||
7 | CONFIG_64BIT=y | ||
8 | CONFIG_PPC_MERGE=y | ||
9 | CONFIG_MMU=y | ||
10 | CONFIG_GENERIC_HARDIRQS=y | ||
11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | ||
12 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
13 | CONFIG_PPC=y | ||
14 | CONFIG_EARLY_PRINTK=y | ||
15 | CONFIG_COMPAT=y | ||
16 | CONFIG_SYSVIPC_COMPAT=y | ||
17 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | ||
18 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | ||
19 | |||
20 | # | ||
21 | # Processor support | ||
22 | # | ||
23 | # CONFIG_POWER4_ONLY is not set | ||
24 | CONFIG_POWER3=y | ||
25 | CONFIG_POWER4=y | ||
26 | CONFIG_PPC_FPU=y | ||
27 | CONFIG_ALTIVEC=y | ||
28 | CONFIG_PPC_STD_MMU=y | ||
29 | CONFIG_SMP=y | ||
30 | CONFIG_NR_CPUS=32 | ||
31 | |||
32 | # | ||
33 | # Code maturity level options | ||
34 | # | ||
35 | CONFIG_EXPERIMENTAL=y | ||
36 | CONFIG_CLEAN_COMPILE=y | ||
37 | CONFIG_LOCK_KERNEL=y | ||
38 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
39 | |||
40 | # | ||
41 | # General setup | ||
42 | # | ||
43 | CONFIG_LOCALVERSION="" | ||
44 | CONFIG_LOCALVERSION_AUTO=y | ||
45 | CONFIG_SWAP=y | ||
46 | CONFIG_SYSVIPC=y | ||
47 | CONFIG_POSIX_MQUEUE=y | ||
48 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
49 | CONFIG_SYSCTL=y | ||
50 | # CONFIG_AUDIT is not set | ||
51 | CONFIG_HOTPLUG=y | ||
52 | CONFIG_KOBJECT_UEVENT=y | ||
53 | CONFIG_IKCONFIG=y | ||
54 | CONFIG_IKCONFIG_PROC=y | ||
55 | CONFIG_CPUSETS=y | ||
56 | CONFIG_INITRAMFS_SOURCE="" | ||
57 | # CONFIG_EMBEDDED is not set | ||
58 | CONFIG_KALLSYMS=y | ||
59 | CONFIG_KALLSYMS_ALL=y | ||
60 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
61 | CONFIG_PRINTK=y | ||
62 | CONFIG_BUG=y | ||
63 | CONFIG_BASE_FULL=y | ||
64 | CONFIG_FUTEX=y | ||
65 | CONFIG_EPOLL=y | ||
66 | CONFIG_SHMEM=y | ||
67 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
68 | CONFIG_CC_ALIGN_LABELS=0 | ||
69 | CONFIG_CC_ALIGN_LOOPS=0 | ||
70 | CONFIG_CC_ALIGN_JUMPS=0 | ||
71 | # CONFIG_TINY_SHMEM is not set | ||
72 | CONFIG_BASE_SMALL=0 | ||
73 | |||
74 | # | ||
75 | # Loadable module support | ||
76 | # | ||
77 | CONFIG_MODULES=y | ||
78 | CONFIG_MODULE_UNLOAD=y | ||
79 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
80 | CONFIG_OBSOLETE_MODPARM=y | ||
81 | CONFIG_MODVERSIONS=y | ||
82 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
83 | CONFIG_KMOD=y | ||
84 | CONFIG_STOP_MACHINE=y | ||
85 | |||
86 | # | ||
87 | # Block layer | ||
88 | # | ||
89 | |||
90 | # | ||
91 | # IO Schedulers | ||
92 | # | ||
93 | CONFIG_IOSCHED_NOOP=y | ||
94 | CONFIG_IOSCHED_AS=y | ||
95 | CONFIG_IOSCHED_DEADLINE=y | ||
96 | CONFIG_IOSCHED_CFQ=y | ||
97 | CONFIG_DEFAULT_AS=y | ||
98 | # CONFIG_DEFAULT_DEADLINE is not set | ||
99 | # CONFIG_DEFAULT_CFQ is not set | ||
100 | # CONFIG_DEFAULT_NOOP is not set | ||
101 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
102 | |||
103 | # | ||
104 | # Platform support | ||
105 | # | ||
106 | CONFIG_PPC_MULTIPLATFORM=y | ||
107 | # CONFIG_PPC_ISERIES is not set | ||
108 | # CONFIG_EMBEDDED6xx is not set | ||
109 | # CONFIG_APUS is not set | ||
110 | CONFIG_PPC_PSERIES=y | ||
111 | CONFIG_PPC_PMAC=y | ||
112 | CONFIG_PPC_PMAC64=y | ||
113 | CONFIG_PPC_MAPLE=y | ||
114 | # CONFIG_PPC_CELL is not set | ||
115 | CONFIG_PPC_OF=y | ||
116 | CONFIG_XICS=y | ||
117 | CONFIG_U3_DART=y | ||
118 | CONFIG_MPIC=y | ||
119 | CONFIG_PPC_RTAS=y | ||
120 | CONFIG_RTAS_ERROR_LOGGING=y | ||
121 | CONFIG_RTAS_PROC=y | ||
122 | CONFIG_RTAS_FLASH=m | ||
123 | # CONFIG_MMIO_NVRAM is not set | ||
124 | CONFIG_MPIC_BROKEN_U3=y | ||
125 | CONFIG_IBMVIO=y | ||
126 | # CONFIG_PPC_MPC106 is not set | ||
127 | CONFIG_GENERIC_TBSYNC=y | ||
128 | CONFIG_CPU_FREQ=y | ||
129 | CONFIG_CPU_FREQ_TABLE=y | ||
130 | # CONFIG_CPU_FREQ_DEBUG is not set | ||
131 | CONFIG_CPU_FREQ_STAT=y | ||
132 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set | ||
133 | CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y | ||
134 | # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set | ||
135 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y | ||
136 | CONFIG_CPU_FREQ_GOV_POWERSAVE=y | ||
137 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | ||
138 | # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set | ||
139 | # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set | ||
140 | CONFIG_CPU_FREQ_PMAC64=y | ||
141 | # CONFIG_WANT_EARLY_SERIAL is not set | ||
142 | |||
143 | # | ||
144 | # Kernel options | ||
145 | # | ||
146 | # CONFIG_HZ_100 is not set | ||
147 | CONFIG_HZ_250=y | ||
148 | # CONFIG_HZ_1000 is not set | ||
149 | CONFIG_HZ=250 | ||
150 | CONFIG_PREEMPT_NONE=y | ||
151 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
152 | # CONFIG_PREEMPT is not set | ||
153 | # CONFIG_PREEMPT_BKL is not set | ||
154 | CONFIG_BINFMT_ELF=y | ||
155 | CONFIG_BINFMT_MISC=m | ||
156 | CONFIG_FORCE_MAX_ZONEORDER=13 | ||
157 | CONFIG_IOMMU_VMERGE=y | ||
158 | CONFIG_HOTPLUG_CPU=y | ||
159 | CONFIG_KEXEC=y | ||
160 | CONFIG_IRQ_ALL_CPUS=y | ||
161 | CONFIG_PPC_SPLPAR=y | ||
162 | CONFIG_EEH=y | ||
163 | CONFIG_SCANLOG=m | ||
164 | CONFIG_LPARCFG=y | ||
165 | # CONFIG_NUMA is not set | ||
166 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y | ||
167 | CONFIG_ARCH_FLATMEM_ENABLE=y | ||
168 | CONFIG_ARCH_SPARSEMEM_ENABLE=y | ||
169 | CONFIG_ARCH_SPARSEMEM_DEFAULT=y | ||
170 | CONFIG_SELECT_MEMORY_MODEL=y | ||
171 | # CONFIG_FLATMEM_MANUAL is not set | ||
172 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
173 | CONFIG_SPARSEMEM_MANUAL=y | ||
174 | CONFIG_SPARSEMEM=y | ||
175 | CONFIG_HAVE_MEMORY_PRESENT=y | ||
176 | # CONFIG_SPARSEMEM_STATIC is not set | ||
177 | CONFIG_SPARSEMEM_EXTREME=y | ||
178 | # CONFIG_MEMORY_HOTPLUG is not set | ||
179 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
180 | # CONFIG_PPC_64K_PAGES is not set | ||
181 | # CONFIG_SCHED_SMT is not set | ||
182 | CONFIG_PROC_DEVICETREE=y | ||
183 | # CONFIG_CMDLINE_BOOL is not set | ||
184 | # CONFIG_PM is not set | ||
185 | CONFIG_SECCOMP=y | ||
186 | CONFIG_ISA_DMA_API=y | ||
187 | |||
188 | # | ||
189 | # Bus options | ||
190 | # | ||
191 | CONFIG_GENERIC_ISA_DMA=y | ||
192 | CONFIG_PPC_I8259=y | ||
193 | # CONFIG_PPC_INDIRECT_PCI is not set | ||
194 | CONFIG_PCI=y | ||
195 | CONFIG_PCI_DOMAINS=y | ||
196 | # CONFIG_PCI_LEGACY_PROC is not set | ||
197 | # CONFIG_PCI_DEBUG is not set | ||
198 | |||
199 | # | ||
200 | # PCCARD (PCMCIA/CardBus) support | ||
201 | # | ||
202 | # CONFIG_PCCARD is not set | ||
203 | |||
204 | # | ||
205 | # PCI Hotplug Support | ||
206 | # | ||
207 | CONFIG_HOTPLUG_PCI=m | ||
208 | # CONFIG_HOTPLUG_PCI_FAKE is not set | ||
209 | # CONFIG_HOTPLUG_PCI_CPCI is not set | ||
210 | # CONFIG_HOTPLUG_PCI_SHPC is not set | ||
211 | CONFIG_HOTPLUG_PCI_RPA=m | ||
212 | CONFIG_HOTPLUG_PCI_RPA_DLPAR=m | ||
213 | CONFIG_KERNEL_START=0xc000000000000000 | ||
214 | |||
215 | # | ||
216 | # Networking | ||
217 | # | ||
218 | CONFIG_NET=y | ||
219 | |||
220 | # | ||
221 | # Networking options | ||
222 | # | ||
223 | CONFIG_PACKET=y | ||
224 | # CONFIG_PACKET_MMAP is not set | ||
225 | CONFIG_UNIX=y | ||
226 | CONFIG_XFRM=y | ||
227 | CONFIG_XFRM_USER=m | ||
228 | CONFIG_NET_KEY=m | ||
229 | CONFIG_INET=y | ||
230 | CONFIG_IP_MULTICAST=y | ||
231 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
232 | CONFIG_IP_FIB_HASH=y | ||
233 | # CONFIG_IP_PNP is not set | ||
234 | CONFIG_NET_IPIP=y | ||
235 | # CONFIG_NET_IPGRE is not set | ||
236 | # CONFIG_IP_MROUTE is not set | ||
237 | # CONFIG_ARPD is not set | ||
238 | CONFIG_SYN_COOKIES=y | ||
239 | CONFIG_INET_AH=m | ||
240 | CONFIG_INET_ESP=m | ||
241 | CONFIG_INET_IPCOMP=m | ||
242 | CONFIG_INET_TUNNEL=y | ||
243 | CONFIG_INET_DIAG=y | ||
244 | CONFIG_INET_TCP_DIAG=y | ||
245 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
246 | CONFIG_TCP_CONG_BIC=y | ||
247 | |||
248 | # | ||
249 | # IP: Virtual Server Configuration | ||
250 | # | ||
251 | # CONFIG_IP_VS is not set | ||
252 | # CONFIG_IPV6 is not set | ||
253 | CONFIG_NETFILTER=y | ||
254 | # CONFIG_NETFILTER_DEBUG is not set | ||
255 | |||
256 | # | ||
257 | # Core Netfilter Configuration | ||
258 | # | ||
259 | CONFIG_NETFILTER_NETLINK=y | ||
260 | CONFIG_NETFILTER_NETLINK_QUEUE=m | ||
261 | CONFIG_NETFILTER_NETLINK_LOG=m | ||
262 | |||
263 | # | ||
264 | # IP: Netfilter Configuration | ||
265 | # | ||
266 | CONFIG_IP_NF_CONNTRACK=m | ||
267 | CONFIG_IP_NF_CT_ACCT=y | ||
268 | CONFIG_IP_NF_CONNTRACK_MARK=y | ||
269 | CONFIG_IP_NF_CONNTRACK_EVENTS=y | ||
270 | CONFIG_IP_NF_CONNTRACK_NETLINK=m | ||
271 | CONFIG_IP_NF_CT_PROTO_SCTP=m | ||
272 | CONFIG_IP_NF_FTP=m | ||
273 | CONFIG_IP_NF_IRC=m | ||
274 | # CONFIG_IP_NF_NETBIOS_NS is not set | ||
275 | CONFIG_IP_NF_TFTP=m | ||
276 | CONFIG_IP_NF_AMANDA=m | ||
277 | # CONFIG_IP_NF_PPTP is not set | ||
278 | CONFIG_IP_NF_QUEUE=m | ||
279 | CONFIG_IP_NF_IPTABLES=m | ||
280 | CONFIG_IP_NF_MATCH_LIMIT=m | ||
281 | CONFIG_IP_NF_MATCH_IPRANGE=m | ||
282 | CONFIG_IP_NF_MATCH_MAC=m | ||
283 | CONFIG_IP_NF_MATCH_PKTTYPE=m | ||
284 | CONFIG_IP_NF_MATCH_MARK=m | ||
285 | CONFIG_IP_NF_MATCH_MULTIPORT=m | ||
286 | CONFIG_IP_NF_MATCH_TOS=m | ||
287 | CONFIG_IP_NF_MATCH_RECENT=m | ||
288 | CONFIG_IP_NF_MATCH_ECN=m | ||
289 | CONFIG_IP_NF_MATCH_DSCP=m | ||
290 | CONFIG_IP_NF_MATCH_AH_ESP=m | ||
291 | CONFIG_IP_NF_MATCH_LENGTH=m | ||
292 | CONFIG_IP_NF_MATCH_TTL=m | ||
293 | CONFIG_IP_NF_MATCH_TCPMSS=m | ||
294 | CONFIG_IP_NF_MATCH_HELPER=m | ||
295 | CONFIG_IP_NF_MATCH_STATE=m | ||
296 | CONFIG_IP_NF_MATCH_CONNTRACK=m | ||
297 | CONFIG_IP_NF_MATCH_OWNER=m | ||
298 | CONFIG_IP_NF_MATCH_ADDRTYPE=m | ||
299 | CONFIG_IP_NF_MATCH_REALM=m | ||
300 | CONFIG_IP_NF_MATCH_SCTP=m | ||
301 | CONFIG_IP_NF_MATCH_DCCP=m | ||
302 | CONFIG_IP_NF_MATCH_COMMENT=m | ||
303 | CONFIG_IP_NF_MATCH_CONNMARK=m | ||
304 | CONFIG_IP_NF_MATCH_CONNBYTES=m | ||
305 | CONFIG_IP_NF_MATCH_HASHLIMIT=m | ||
306 | CONFIG_IP_NF_MATCH_STRING=m | ||
307 | CONFIG_IP_NF_FILTER=m | ||
308 | CONFIG_IP_NF_TARGET_REJECT=m | ||
309 | CONFIG_IP_NF_TARGET_LOG=m | ||
310 | CONFIG_IP_NF_TARGET_ULOG=m | ||
311 | CONFIG_IP_NF_TARGET_TCPMSS=m | ||
312 | CONFIG_IP_NF_TARGET_NFQUEUE=m | ||
313 | CONFIG_IP_NF_NAT=m | ||
314 | CONFIG_IP_NF_NAT_NEEDED=y | ||
315 | CONFIG_IP_NF_TARGET_MASQUERADE=m | ||
316 | CONFIG_IP_NF_TARGET_REDIRECT=m | ||
317 | CONFIG_IP_NF_TARGET_NETMAP=m | ||
318 | CONFIG_IP_NF_TARGET_SAME=m | ||
319 | CONFIG_IP_NF_NAT_SNMP_BASIC=m | ||
320 | CONFIG_IP_NF_NAT_IRC=m | ||
321 | CONFIG_IP_NF_NAT_FTP=m | ||
322 | CONFIG_IP_NF_NAT_TFTP=m | ||
323 | CONFIG_IP_NF_NAT_AMANDA=m | ||
324 | CONFIG_IP_NF_MANGLE=m | ||
325 | CONFIG_IP_NF_TARGET_TOS=m | ||
326 | CONFIG_IP_NF_TARGET_ECN=m | ||
327 | CONFIG_IP_NF_TARGET_DSCP=m | ||
328 | CONFIG_IP_NF_TARGET_MARK=m | ||
329 | CONFIG_IP_NF_TARGET_CLASSIFY=m | ||
330 | CONFIG_IP_NF_TARGET_TTL=m | ||
331 | CONFIG_IP_NF_TARGET_CONNMARK=m | ||
332 | CONFIG_IP_NF_TARGET_CLUSTERIP=m | ||
333 | CONFIG_IP_NF_RAW=m | ||
334 | CONFIG_IP_NF_TARGET_NOTRACK=m | ||
335 | CONFIG_IP_NF_ARPTABLES=m | ||
336 | CONFIG_IP_NF_ARPFILTER=m | ||
337 | CONFIG_IP_NF_ARP_MANGLE=m | ||
338 | |||
339 | # | ||
340 | # DCCP Configuration (EXPERIMENTAL) | ||
341 | # | ||
342 | # CONFIG_IP_DCCP is not set | ||
343 | |||
344 | # | ||
345 | # SCTP Configuration (EXPERIMENTAL) | ||
346 | # | ||
347 | # CONFIG_IP_SCTP is not set | ||
348 | # CONFIG_ATM is not set | ||
349 | # CONFIG_BRIDGE is not set | ||
350 | # CONFIG_VLAN_8021Q is not set | ||
351 | # CONFIG_DECNET is not set | ||
352 | CONFIG_LLC=y | ||
353 | # CONFIG_LLC2 is not set | ||
354 | # CONFIG_IPX is not set | ||
355 | # CONFIG_ATALK is not set | ||
356 | # CONFIG_X25 is not set | ||
357 | # CONFIG_LAPB is not set | ||
358 | # CONFIG_NET_DIVERT is not set | ||
359 | # CONFIG_ECONET is not set | ||
360 | # CONFIG_WAN_ROUTER is not set | ||
361 | |||
362 | # | ||
363 | # QoS and/or fair queueing | ||
364 | # | ||
365 | # CONFIG_NET_SCHED is not set | ||
366 | CONFIG_NET_CLS_ROUTE=y | ||
367 | |||
368 | # | ||
369 | # Network testing | ||
370 | # | ||
371 | # CONFIG_NET_PKTGEN is not set | ||
372 | # CONFIG_HAMRADIO is not set | ||
373 | # CONFIG_IRDA is not set | ||
374 | # CONFIG_BT is not set | ||
375 | # CONFIG_IEEE80211 is not set | ||
376 | |||
377 | # | ||
378 | # Device Drivers | ||
379 | # | ||
380 | |||
381 | # | ||
382 | # Generic Driver Options | ||
383 | # | ||
384 | CONFIG_STANDALONE=y | ||
385 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
386 | CONFIG_FW_LOADER=y | ||
387 | # CONFIG_DEBUG_DRIVER is not set | ||
388 | |||
389 | # | ||
390 | # Connector - unified userspace <-> kernelspace linker | ||
391 | # | ||
392 | # CONFIG_CONNECTOR is not set | ||
393 | |||
394 | # | ||
395 | # Memory Technology Devices (MTD) | ||
396 | # | ||
397 | # CONFIG_MTD is not set | ||
398 | |||
399 | # | ||
400 | # Parallel port support | ||
401 | # | ||
402 | # CONFIG_PARPORT is not set | ||
403 | |||
404 | # | ||
405 | # Plug and Play support | ||
406 | # | ||
407 | |||
408 | # | ||
409 | # Block devices | ||
410 | # | ||
411 | CONFIG_BLK_DEV_FD=y | ||
412 | # CONFIG_BLK_CPQ_DA is not set | ||
413 | # CONFIG_BLK_CPQ_CISS_DA is not set | ||
414 | # CONFIG_BLK_DEV_DAC960 is not set | ||
415 | # CONFIG_BLK_DEV_UMEM is not set | ||
416 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
417 | CONFIG_BLK_DEV_LOOP=y | ||
418 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
419 | CONFIG_BLK_DEV_NBD=m | ||
420 | # CONFIG_BLK_DEV_SX8 is not set | ||
421 | # CONFIG_BLK_DEV_UB is not set | ||
422 | CONFIG_BLK_DEV_RAM=y | ||
423 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
424 | CONFIG_BLK_DEV_RAM_SIZE=65536 | ||
425 | CONFIG_BLK_DEV_INITRD=y | ||
426 | # CONFIG_CDROM_PKTCDVD is not set | ||
427 | # CONFIG_ATA_OVER_ETH is not set | ||
428 | |||
429 | # | ||
430 | # ATA/ATAPI/MFM/RLL support | ||
431 | # | ||
432 | CONFIG_IDE=y | ||
433 | CONFIG_BLK_DEV_IDE=y | ||
434 | |||
435 | # | ||
436 | # Please see Documentation/ide.txt for help/info on IDE drives | ||
437 | # | ||
438 | # CONFIG_BLK_DEV_IDE_SATA is not set | ||
439 | CONFIG_BLK_DEV_IDEDISK=y | ||
440 | # CONFIG_IDEDISK_MULTI_MODE is not set | ||
441 | CONFIG_BLK_DEV_IDECD=y | ||
442 | # CONFIG_BLK_DEV_IDETAPE is not set | ||
443 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | ||
444 | # CONFIG_BLK_DEV_IDESCSI is not set | ||
445 | # CONFIG_IDE_TASK_IOCTL is not set | ||
446 | |||
447 | # | ||
448 | # IDE chipset support/bugfixes | ||
449 | # | ||
450 | CONFIG_IDE_GENERIC=y | ||
451 | CONFIG_BLK_DEV_IDEPCI=y | ||
452 | CONFIG_IDEPCI_SHARE_IRQ=y | ||
453 | # CONFIG_BLK_DEV_OFFBOARD is not set | ||
454 | CONFIG_BLK_DEV_GENERIC=y | ||
455 | # CONFIG_BLK_DEV_OPTI621 is not set | ||
456 | # CONFIG_BLK_DEV_SL82C105 is not set | ||
457 | CONFIG_BLK_DEV_IDEDMA_PCI=y | ||
458 | # CONFIG_BLK_DEV_IDEDMA_FORCED is not set | ||
459 | CONFIG_IDEDMA_PCI_AUTO=y | ||
460 | # CONFIG_IDEDMA_ONLYDISK is not set | ||
461 | # CONFIG_BLK_DEV_AEC62XX is not set | ||
462 | # CONFIG_BLK_DEV_ALI15X3 is not set | ||
463 | CONFIG_BLK_DEV_AMD74XX=y | ||
464 | # CONFIG_BLK_DEV_CMD64X is not set | ||
465 | # CONFIG_BLK_DEV_TRIFLEX is not set | ||
466 | # CONFIG_BLK_DEV_CY82C693 is not set | ||
467 | # CONFIG_BLK_DEV_CS5520 is not set | ||
468 | # CONFIG_BLK_DEV_CS5530 is not set | ||
469 | # CONFIG_BLK_DEV_HPT34X is not set | ||
470 | # CONFIG_BLK_DEV_HPT366 is not set | ||
471 | # CONFIG_BLK_DEV_SC1200 is not set | ||
472 | # CONFIG_BLK_DEV_PIIX is not set | ||
473 | # CONFIG_BLK_DEV_IT821X is not set | ||
474 | # CONFIG_BLK_DEV_NS87415 is not set | ||
475 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | ||
476 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set | ||
477 | # CONFIG_BLK_DEV_SVWKS is not set | ||
478 | # CONFIG_BLK_DEV_SIIMAGE is not set | ||
479 | # CONFIG_BLK_DEV_SLC90E66 is not set | ||
480 | # CONFIG_BLK_DEV_TRM290 is not set | ||
481 | # CONFIG_BLK_DEV_VIA82CXXX is not set | ||
482 | CONFIG_BLK_DEV_IDE_PMAC=y | ||
483 | CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y | ||
484 | CONFIG_BLK_DEV_IDEDMA_PMAC=y | ||
485 | # CONFIG_BLK_DEV_IDE_PMAC_BLINK is not set | ||
486 | # CONFIG_IDE_ARM is not set | ||
487 | CONFIG_BLK_DEV_IDEDMA=y | ||
488 | # CONFIG_IDEDMA_IVB is not set | ||
489 | CONFIG_IDEDMA_AUTO=y | ||
490 | # CONFIG_BLK_DEV_HD is not set | ||
491 | |||
492 | # | ||
493 | # SCSI device support | ||
494 | # | ||
495 | # CONFIG_RAID_ATTRS is not set | ||
496 | CONFIG_SCSI=y | ||
497 | CONFIG_SCSI_PROC_FS=y | ||
498 | |||
499 | # | ||
500 | # SCSI support type (disk, tape, CD-ROM) | ||
501 | # | ||
502 | CONFIG_BLK_DEV_SD=y | ||
503 | CONFIG_CHR_DEV_ST=y | ||
504 | # CONFIG_CHR_DEV_OSST is not set | ||
505 | CONFIG_BLK_DEV_SR=y | ||
506 | CONFIG_BLK_DEV_SR_VENDOR=y | ||
507 | CONFIG_CHR_DEV_SG=y | ||
508 | # CONFIG_CHR_DEV_SCH is not set | ||
509 | |||
510 | # | ||
511 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
512 | # | ||
513 | CONFIG_SCSI_MULTI_LUN=y | ||
514 | CONFIG_SCSI_CONSTANTS=y | ||
515 | # CONFIG_SCSI_LOGGING is not set | ||
516 | |||
517 | # | ||
518 | # SCSI Transport Attributes | ||
519 | # | ||
520 | CONFIG_SCSI_SPI_ATTRS=y | ||
521 | CONFIG_SCSI_FC_ATTRS=y | ||
522 | CONFIG_SCSI_ISCSI_ATTRS=m | ||
523 | # CONFIG_SCSI_SAS_ATTRS is not set | ||
524 | |||
525 | # | ||
526 | # SCSI low-level drivers | ||
527 | # | ||
528 | # CONFIG_ISCSI_TCP is not set | ||
529 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | ||
530 | # CONFIG_SCSI_3W_9XXX is not set | ||
531 | # CONFIG_SCSI_ACARD is not set | ||
532 | # CONFIG_SCSI_AACRAID is not set | ||
533 | # CONFIG_SCSI_AIC7XXX is not set | ||
534 | # CONFIG_SCSI_AIC7XXX_OLD is not set | ||
535 | # CONFIG_SCSI_AIC79XX is not set | ||
536 | # CONFIG_MEGARAID_NEWGEN is not set | ||
537 | # CONFIG_MEGARAID_LEGACY is not set | ||
538 | # CONFIG_MEGARAID_SAS is not set | ||
539 | CONFIG_SCSI_SATA=y | ||
540 | # CONFIG_SCSI_SATA_AHCI is not set | ||
541 | CONFIG_SCSI_SATA_SVW=y | ||
542 | # CONFIG_SCSI_ATA_PIIX is not set | ||
543 | # CONFIG_SCSI_SATA_MV is not set | ||
544 | # CONFIG_SCSI_SATA_NV is not set | ||
545 | # CONFIG_SCSI_PDC_ADMA is not set | ||
546 | # CONFIG_SCSI_SATA_QSTOR is not set | ||
547 | # CONFIG_SCSI_SATA_PROMISE is not set | ||
548 | # CONFIG_SCSI_SATA_SX4 is not set | ||
549 | # CONFIG_SCSI_SATA_SIL is not set | ||
550 | # CONFIG_SCSI_SATA_SIL24 is not set | ||
551 | # CONFIG_SCSI_SATA_SIS is not set | ||
552 | # CONFIG_SCSI_SATA_ULI is not set | ||
553 | # CONFIG_SCSI_SATA_VIA is not set | ||
554 | # CONFIG_SCSI_SATA_VITESSE is not set | ||
555 | # CONFIG_SCSI_BUSLOGIC is not set | ||
556 | # CONFIG_SCSI_DMX3191D is not set | ||
557 | # CONFIG_SCSI_EATA is not set | ||
558 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | ||
559 | # CONFIG_SCSI_GDTH is not set | ||
560 | # CONFIG_SCSI_IPS is not set | ||
561 | CONFIG_SCSI_IBMVSCSI=y | ||
562 | # CONFIG_SCSI_INITIO is not set | ||
563 | # CONFIG_SCSI_INIA100 is not set | ||
564 | CONFIG_SCSI_SYM53C8XX_2=y | ||
565 | CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 | ||
566 | CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 | ||
567 | CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 | ||
568 | # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set | ||
569 | CONFIG_SCSI_IPR=y | ||
570 | CONFIG_SCSI_IPR_TRACE=y | ||
571 | CONFIG_SCSI_IPR_DUMP=y | ||
572 | # CONFIG_SCSI_QLOGIC_FC is not set | ||
573 | # CONFIG_SCSI_QLOGIC_1280 is not set | ||
574 | CONFIG_SCSI_QLA2XXX=y | ||
575 | CONFIG_SCSI_QLA21XX=m | ||
576 | CONFIG_SCSI_QLA22XX=m | ||
577 | CONFIG_SCSI_QLA2300=m | ||
578 | CONFIG_SCSI_QLA2322=m | ||
579 | CONFIG_SCSI_QLA6312=m | ||
580 | CONFIG_SCSI_QLA24XX=m | ||
581 | CONFIG_SCSI_LPFC=m | ||
582 | # CONFIG_SCSI_DC395x is not set | ||
583 | # CONFIG_SCSI_DC390T is not set | ||
584 | CONFIG_SCSI_DEBUG=m | ||
585 | |||
586 | # | ||
587 | # Multi-device support (RAID and LVM) | ||
588 | # | ||
589 | CONFIG_MD=y | ||
590 | CONFIG_BLK_DEV_MD=y | ||
591 | CONFIG_MD_LINEAR=y | ||
592 | CONFIG_MD_RAID0=y | ||
593 | CONFIG_MD_RAID1=y | ||
594 | CONFIG_MD_RAID10=y | ||
595 | CONFIG_MD_RAID5=y | ||
596 | CONFIG_MD_RAID6=m | ||
597 | CONFIG_MD_MULTIPATH=m | ||
598 | CONFIG_MD_FAULTY=m | ||
599 | CONFIG_BLK_DEV_DM=y | ||
600 | CONFIG_DM_CRYPT=m | ||
601 | CONFIG_DM_SNAPSHOT=m | ||
602 | CONFIG_DM_MIRROR=m | ||
603 | CONFIG_DM_ZERO=m | ||
604 | CONFIG_DM_MULTIPATH=m | ||
605 | CONFIG_DM_MULTIPATH_EMC=m | ||
606 | |||
607 | # | ||
608 | # Fusion MPT device support | ||
609 | # | ||
610 | # CONFIG_FUSION is not set | ||
611 | # CONFIG_FUSION_SPI is not set | ||
612 | # CONFIG_FUSION_FC is not set | ||
613 | # CONFIG_FUSION_SAS is not set | ||
614 | |||
615 | # | ||
616 | # IEEE 1394 (FireWire) support | ||
617 | # | ||
618 | CONFIG_IEEE1394=y | ||
619 | |||
620 | # | ||
621 | # Subsystem Options | ||
622 | # | ||
623 | # CONFIG_IEEE1394_VERBOSEDEBUG is not set | ||
624 | # CONFIG_IEEE1394_OUI_DB is not set | ||
625 | CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y | ||
626 | CONFIG_IEEE1394_CONFIG_ROM_IP1394=y | ||
627 | # CONFIG_IEEE1394_EXPORT_FULL_API is not set | ||
628 | |||
629 | # | ||
630 | # Device Drivers | ||
631 | # | ||
632 | # CONFIG_IEEE1394_PCILYNX is not set | ||
633 | CONFIG_IEEE1394_OHCI1394=y | ||
634 | |||
635 | # | ||
636 | # Protocol Drivers | ||
637 | # | ||
638 | CONFIG_IEEE1394_VIDEO1394=m | ||
639 | CONFIG_IEEE1394_SBP2=m | ||
640 | # CONFIG_IEEE1394_SBP2_PHYS_DMA is not set | ||
641 | CONFIG_IEEE1394_ETH1394=m | ||
642 | CONFIG_IEEE1394_DV1394=m | ||
643 | CONFIG_IEEE1394_RAWIO=y | ||
644 | CONFIG_IEEE1394_CMP=m | ||
645 | CONFIG_IEEE1394_AMDTP=m | ||
646 | |||
647 | # | ||
648 | # I2O device support | ||
649 | # | ||
650 | # CONFIG_I2O is not set | ||
651 | |||
652 | # | ||
653 | # Macintosh device drivers | ||
654 | # | ||
655 | CONFIG_ADB_PMU=y | ||
656 | CONFIG_PMAC_SMU=y | ||
657 | CONFIG_THERM_PM72=y | ||
658 | CONFIG_WINDFARM=y | ||
659 | CONFIG_WINDFARM_PM81=y | ||
660 | CONFIG_WINDFARM_PM91=y | ||
661 | |||
662 | # | ||
663 | # Network device support | ||
664 | # | ||
665 | CONFIG_NETDEVICES=y | ||
666 | CONFIG_DUMMY=m | ||
667 | CONFIG_BONDING=m | ||
668 | # CONFIG_EQUALIZER is not set | ||
669 | CONFIG_TUN=m | ||
670 | |||
671 | # | ||
672 | # ARCnet devices | ||
673 | # | ||
674 | # CONFIG_ARCNET is not set | ||
675 | |||
676 | # | ||
677 | # PHY device support | ||
678 | # | ||
679 | # CONFIG_PHYLIB is not set | ||
680 | |||
681 | # | ||
682 | # Ethernet (10 or 100Mbit) | ||
683 | # | ||
684 | CONFIG_NET_ETHERNET=y | ||
685 | CONFIG_MII=y | ||
686 | # CONFIG_HAPPYMEAL is not set | ||
687 | CONFIG_SUNGEM=y | ||
688 | # CONFIG_CASSINI is not set | ||
689 | CONFIG_NET_VENDOR_3COM=y | ||
690 | CONFIG_VORTEX=y | ||
691 | # CONFIG_TYPHOON is not set | ||
692 | |||
693 | # | ||
694 | # Tulip family network device support | ||
695 | # | ||
696 | # CONFIG_NET_TULIP is not set | ||
697 | # CONFIG_HP100 is not set | ||
698 | CONFIG_IBMVETH=m | ||
699 | CONFIG_NET_PCI=y | ||
700 | CONFIG_PCNET32=y | ||
701 | # CONFIG_AMD8111_ETH is not set | ||
702 | # CONFIG_ADAPTEC_STARFIRE is not set | ||
703 | # CONFIG_B44 is not set | ||
704 | # CONFIG_FORCEDETH is not set | ||
705 | # CONFIG_DGRS is not set | ||
706 | # CONFIG_EEPRO100 is not set | ||
707 | CONFIG_E100=y | ||
708 | # CONFIG_FEALNX is not set | ||
709 | # CONFIG_NATSEMI is not set | ||
710 | # CONFIG_NE2K_PCI is not set | ||
711 | # CONFIG_8139CP is not set | ||
712 | # CONFIG_8139TOO is not set | ||
713 | # CONFIG_SIS900 is not set | ||
714 | # CONFIG_EPIC100 is not set | ||
715 | # CONFIG_SUNDANCE is not set | ||
716 | # CONFIG_VIA_RHINE is not set | ||
717 | |||
718 | # | ||
719 | # Ethernet (1000 Mbit) | ||
720 | # | ||
721 | CONFIG_ACENIC=y | ||
722 | CONFIG_ACENIC_OMIT_TIGON_I=y | ||
723 | # CONFIG_DL2K is not set | ||
724 | CONFIG_E1000=y | ||
725 | # CONFIG_E1000_NAPI is not set | ||
726 | # CONFIG_NS83820 is not set | ||
727 | # CONFIG_HAMACHI is not set | ||
728 | # CONFIG_YELLOWFIN is not set | ||
729 | # CONFIG_R8169 is not set | ||
730 | # CONFIG_SIS190 is not set | ||
731 | # CONFIG_SKGE is not set | ||
732 | # CONFIG_SK98LIN is not set | ||
733 | # CONFIG_VIA_VELOCITY is not set | ||
734 | CONFIG_TIGON3=y | ||
735 | # CONFIG_BNX2 is not set | ||
736 | # CONFIG_MV643XX_ETH is not set | ||
737 | |||
738 | # | ||
739 | # Ethernet (10000 Mbit) | ||
740 | # | ||
741 | # CONFIG_CHELSIO_T1 is not set | ||
742 | CONFIG_IXGB=m | ||
743 | # CONFIG_IXGB_NAPI is not set | ||
744 | # CONFIG_S2IO is not set | ||
745 | |||
746 | # | ||
747 | # Token Ring devices | ||
748 | # | ||
749 | CONFIG_TR=y | ||
750 | CONFIG_IBMOL=y | ||
751 | # CONFIG_3C359 is not set | ||
752 | # CONFIG_TMS380TR is not set | ||
753 | |||
754 | # | ||
755 | # Wireless LAN (non-hamradio) | ||
756 | # | ||
757 | # CONFIG_NET_RADIO is not set | ||
758 | |||
759 | # | ||
760 | # Wan interfaces | ||
761 | # | ||
762 | # CONFIG_WAN is not set | ||
763 | # CONFIG_FDDI is not set | ||
764 | # CONFIG_HIPPI is not set | ||
765 | CONFIG_PPP=m | ||
766 | # CONFIG_PPP_MULTILINK is not set | ||
767 | # CONFIG_PPP_FILTER is not set | ||
768 | CONFIG_PPP_ASYNC=m | ||
769 | CONFIG_PPP_SYNC_TTY=m | ||
770 | CONFIG_PPP_DEFLATE=m | ||
771 | CONFIG_PPP_BSDCOMP=m | ||
772 | # CONFIG_PPP_MPPE is not set | ||
773 | CONFIG_PPPOE=m | ||
774 | # CONFIG_SLIP is not set | ||
775 | # CONFIG_NET_FC is not set | ||
776 | # CONFIG_SHAPER is not set | ||
777 | CONFIG_NETCONSOLE=y | ||
778 | CONFIG_NETPOLL=y | ||
779 | CONFIG_NETPOLL_RX=y | ||
780 | CONFIG_NETPOLL_TRAP=y | ||
781 | CONFIG_NET_POLL_CONTROLLER=y | ||
782 | |||
783 | # | ||
784 | # ISDN subsystem | ||
785 | # | ||
786 | # CONFIG_ISDN is not set | ||
787 | |||
788 | # | ||
789 | # Telephony Support | ||
790 | # | ||
791 | # CONFIG_PHONE is not set | ||
792 | |||
793 | # | ||
794 | # Input device support | ||
795 | # | ||
796 | CONFIG_INPUT=y | ||
797 | |||
798 | # | ||
799 | # Userland interfaces | ||
800 | # | ||
801 | CONFIG_INPUT_MOUSEDEV=y | ||
802 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
803 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
804 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
805 | # CONFIG_INPUT_JOYDEV is not set | ||
806 | # CONFIG_INPUT_TSDEV is not set | ||
807 | CONFIG_INPUT_EVDEV=m | ||
808 | # CONFIG_INPUT_EVBUG is not set | ||
809 | |||
810 | # | ||
811 | # Input Device Drivers | ||
812 | # | ||
813 | CONFIG_INPUT_KEYBOARD=y | ||
814 | CONFIG_KEYBOARD_ATKBD=y | ||
815 | # CONFIG_KEYBOARD_SUNKBD is not set | ||
816 | # CONFIG_KEYBOARD_LKKBD is not set | ||
817 | # CONFIG_KEYBOARD_XTKBD is not set | ||
818 | # CONFIG_KEYBOARD_NEWTON is not set | ||
819 | CONFIG_INPUT_MOUSE=y | ||
820 | CONFIG_MOUSE_PS2=y | ||
821 | # CONFIG_MOUSE_SERIAL is not set | ||
822 | # CONFIG_MOUSE_VSXXXAA is not set | ||
823 | # CONFIG_INPUT_JOYSTICK is not set | ||
824 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
825 | CONFIG_INPUT_MISC=y | ||
826 | CONFIG_INPUT_PCSPKR=m | ||
827 | # CONFIG_INPUT_UINPUT is not set | ||
828 | |||
829 | # | ||
830 | # Hardware I/O ports | ||
831 | # | ||
832 | CONFIG_SERIO=y | ||
833 | CONFIG_SERIO_I8042=y | ||
834 | # CONFIG_SERIO_SERPORT is not set | ||
835 | # CONFIG_SERIO_PCIPS2 is not set | ||
836 | CONFIG_SERIO_LIBPS2=y | ||
837 | # CONFIG_SERIO_RAW is not set | ||
838 | # CONFIG_GAMEPORT is not set | ||
839 | |||
840 | # | ||
841 | # Character devices | ||
842 | # | ||
843 | CONFIG_VT=y | ||
844 | CONFIG_VT_CONSOLE=y | ||
845 | CONFIG_HW_CONSOLE=y | ||
846 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
847 | |||
848 | # | ||
849 | # Serial drivers | ||
850 | # | ||
851 | CONFIG_SERIAL_8250=y | ||
852 | CONFIG_SERIAL_8250_CONSOLE=y | ||
853 | CONFIG_SERIAL_8250_NR_UARTS=4 | ||
854 | # CONFIG_SERIAL_8250_EXTENDED is not set | ||
855 | |||
856 | # | ||
857 | # Non-8250 serial port support | ||
858 | # | ||
859 | CONFIG_SERIAL_CORE=y | ||
860 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
861 | # CONFIG_SERIAL_PMACZILOG is not set | ||
862 | CONFIG_SERIAL_ICOM=m | ||
863 | CONFIG_SERIAL_JSM=m | ||
864 | CONFIG_UNIX98_PTYS=y | ||
865 | CONFIG_LEGACY_PTYS=y | ||
866 | CONFIG_LEGACY_PTY_COUNT=256 | ||
867 | CONFIG_HVC_CONSOLE=y | ||
868 | CONFIG_HVCS=m | ||
869 | |||
870 | # | ||
871 | # IPMI | ||
872 | # | ||
873 | # CONFIG_IPMI_HANDLER is not set | ||
874 | |||
875 | # | ||
876 | # Watchdog Cards | ||
877 | # | ||
878 | # CONFIG_WATCHDOG is not set | ||
879 | # CONFIG_RTC is not set | ||
880 | # CONFIG_GEN_RTC is not set | ||
881 | # CONFIG_DTLK is not set | ||
882 | # CONFIG_R3964 is not set | ||
883 | # CONFIG_APPLICOM is not set | ||
884 | |||
885 | # | ||
886 | # Ftape, the floppy tape device driver | ||
887 | # | ||
888 | # CONFIG_AGP is not set | ||
889 | # CONFIG_DRM is not set | ||
890 | CONFIG_RAW_DRIVER=y | ||
891 | CONFIG_MAX_RAW_DEVS=256 | ||
892 | # CONFIG_HANGCHECK_TIMER is not set | ||
893 | |||
894 | # | ||
895 | # TPM devices | ||
896 | # | ||
897 | # CONFIG_TCG_TPM is not set | ||
898 | # CONFIG_TELCLOCK is not set | ||
899 | |||
900 | # | ||
901 | # I2C support | ||
902 | # | ||
903 | CONFIG_I2C=y | ||
904 | CONFIG_I2C_CHARDEV=y | ||
905 | |||
906 | # | ||
907 | # I2C Algorithms | ||
908 | # | ||
909 | CONFIG_I2C_ALGOBIT=y | ||
910 | # CONFIG_I2C_ALGOPCF is not set | ||
911 | # CONFIG_I2C_ALGOPCA is not set | ||
912 | |||
913 | # | ||
914 | # I2C Hardware Bus support | ||
915 | # | ||
916 | # CONFIG_I2C_ALI1535 is not set | ||
917 | # CONFIG_I2C_ALI1563 is not set | ||
918 | # CONFIG_I2C_ALI15X3 is not set | ||
919 | # CONFIG_I2C_AMD756 is not set | ||
920 | CONFIG_I2C_AMD8111=y | ||
921 | # CONFIG_I2C_I801 is not set | ||
922 | # CONFIG_I2C_I810 is not set | ||
923 | # CONFIG_I2C_PIIX4 is not set | ||
924 | CONFIG_I2C_KEYWEST=y | ||
925 | CONFIG_I2C_PMAC_SMU=y | ||
926 | # CONFIG_I2C_NFORCE2 is not set | ||
927 | # CONFIG_I2C_PARPORT_LIGHT is not set | ||
928 | # CONFIG_I2C_PROSAVAGE is not set | ||
929 | # CONFIG_I2C_SAVAGE4 is not set | ||
930 | # CONFIG_SCx200_ACB is not set | ||
931 | # CONFIG_I2C_SIS5595 is not set | ||
932 | # CONFIG_I2C_SIS630 is not set | ||
933 | # CONFIG_I2C_SIS96X is not set | ||
934 | # CONFIG_I2C_STUB is not set | ||
935 | # CONFIG_I2C_VIA is not set | ||
936 | # CONFIG_I2C_VIAPRO is not set | ||
937 | # CONFIG_I2C_VOODOO3 is not set | ||
938 | # CONFIG_I2C_PCA_ISA is not set | ||
939 | |||
940 | # | ||
941 | # Miscellaneous I2C Chip support | ||
942 | # | ||
943 | # CONFIG_SENSORS_DS1337 is not set | ||
944 | # CONFIG_SENSORS_DS1374 is not set | ||
945 | # CONFIG_SENSORS_EEPROM is not set | ||
946 | # CONFIG_SENSORS_PCF8574 is not set | ||
947 | # CONFIG_SENSORS_PCA9539 is not set | ||
948 | # CONFIG_SENSORS_PCF8591 is not set | ||
949 | # CONFIG_SENSORS_RTC8564 is not set | ||
950 | # CONFIG_SENSORS_MAX6875 is not set | ||
951 | # CONFIG_RTC_X1205_I2C is not set | ||
952 | # CONFIG_I2C_DEBUG_CORE is not set | ||
953 | # CONFIG_I2C_DEBUG_ALGO is not set | ||
954 | # CONFIG_I2C_DEBUG_BUS is not set | ||
955 | # CONFIG_I2C_DEBUG_CHIP is not set | ||
956 | |||
957 | # | ||
958 | # Dallas's 1-wire bus | ||
959 | # | ||
960 | # CONFIG_W1 is not set | ||
961 | |||
962 | # | ||
963 | # Hardware Monitoring support | ||
964 | # | ||
965 | # CONFIG_HWMON is not set | ||
966 | # CONFIG_HWMON_VID is not set | ||
967 | |||
968 | # | ||
969 | # Misc devices | ||
970 | # | ||
971 | |||
972 | # | ||
973 | # Multimedia Capabilities Port drivers | ||
974 | # | ||
975 | |||
976 | # | ||
977 | # Multimedia devices | ||
978 | # | ||
979 | # CONFIG_VIDEO_DEV is not set | ||
980 | |||
981 | # | ||
982 | # Digital Video Broadcasting Devices | ||
983 | # | ||
984 | # CONFIG_DVB is not set | ||
985 | |||
986 | # | ||
987 | # Graphics support | ||
988 | # | ||
989 | CONFIG_FB=y | ||
990 | CONFIG_FB_CFB_FILLRECT=y | ||
991 | CONFIG_FB_CFB_COPYAREA=y | ||
992 | CONFIG_FB_CFB_IMAGEBLIT=y | ||
993 | CONFIG_FB_MACMODES=y | ||
994 | CONFIG_FB_MODE_HELPERS=y | ||
995 | CONFIG_FB_TILEBLITTING=y | ||
996 | # CONFIG_FB_CIRRUS is not set | ||
997 | # CONFIG_FB_PM2 is not set | ||
998 | # CONFIG_FB_CYBER2000 is not set | ||
999 | CONFIG_FB_OF=y | ||
1000 | # CONFIG_FB_CONTROL is not set | ||
1001 | # CONFIG_FB_PLATINUM is not set | ||
1002 | # CONFIG_FB_VALKYRIE is not set | ||
1003 | # CONFIG_FB_CT65550 is not set | ||
1004 | # CONFIG_FB_ASILIANT is not set | ||
1005 | # CONFIG_FB_IMSTT is not set | ||
1006 | # CONFIG_FB_VGA16 is not set | ||
1007 | # CONFIG_FB_S1D13XXX is not set | ||
1008 | # CONFIG_FB_NVIDIA is not set | ||
1009 | # CONFIG_FB_RIVA is not set | ||
1010 | CONFIG_FB_MATROX=y | ||
1011 | CONFIG_FB_MATROX_MILLENIUM=y | ||
1012 | CONFIG_FB_MATROX_MYSTIQUE=y | ||
1013 | CONFIG_FB_MATROX_G=y | ||
1014 | CONFIG_FB_MATROX_I2C=m | ||
1015 | CONFIG_FB_MATROX_MAVEN=m | ||
1016 | CONFIG_FB_MATROX_MULTIHEAD=y | ||
1017 | # CONFIG_FB_RADEON_OLD is not set | ||
1018 | CONFIG_FB_RADEON=y | ||
1019 | CONFIG_FB_RADEON_I2C=y | ||
1020 | # CONFIG_FB_RADEON_DEBUG is not set | ||
1021 | # CONFIG_FB_ATY128 is not set | ||
1022 | # CONFIG_FB_ATY is not set | ||
1023 | # CONFIG_FB_SAVAGE is not set | ||
1024 | # CONFIG_FB_SIS is not set | ||
1025 | # CONFIG_FB_NEOMAGIC is not set | ||
1026 | # CONFIG_FB_KYRO is not set | ||
1027 | # CONFIG_FB_3DFX is not set | ||
1028 | # CONFIG_FB_VOODOO1 is not set | ||
1029 | # CONFIG_FB_CYBLA is not set | ||
1030 | # CONFIG_FB_TRIDENT is not set | ||
1031 | # CONFIG_FB_VIRTUAL is not set | ||
1032 | |||
1033 | # | ||
1034 | # Console display driver support | ||
1035 | # | ||
1036 | # CONFIG_VGA_CONSOLE is not set | ||
1037 | CONFIG_DUMMY_CONSOLE=y | ||
1038 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
1039 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | ||
1040 | # CONFIG_FONTS is not set | ||
1041 | CONFIG_FONT_8x8=y | ||
1042 | CONFIG_FONT_8x16=y | ||
1043 | |||
1044 | # | ||
1045 | # Logo configuration | ||
1046 | # | ||
1047 | CONFIG_LOGO=y | ||
1048 | CONFIG_LOGO_LINUX_MONO=y | ||
1049 | CONFIG_LOGO_LINUX_VGA16=y | ||
1050 | CONFIG_LOGO_LINUX_CLUT224=y | ||
1051 | CONFIG_BACKLIGHT_LCD_SUPPORT=y | ||
1052 | CONFIG_BACKLIGHT_CLASS_DEVICE=y | ||
1053 | CONFIG_BACKLIGHT_DEVICE=y | ||
1054 | CONFIG_LCD_CLASS_DEVICE=y | ||
1055 | CONFIG_LCD_DEVICE=y | ||
1056 | |||
1057 | # | ||
1058 | # Sound | ||
1059 | # | ||
1060 | CONFIG_SOUND=m | ||
1061 | |||
1062 | # | ||
1063 | # Advanced Linux Sound Architecture | ||
1064 | # | ||
1065 | CONFIG_SND=m | ||
1066 | CONFIG_SND_TIMER=m | ||
1067 | CONFIG_SND_PCM=m | ||
1068 | CONFIG_SND_SEQUENCER=m | ||
1069 | CONFIG_SND_SEQ_DUMMY=m | ||
1070 | CONFIG_SND_OSSEMUL=y | ||
1071 | CONFIG_SND_MIXER_OSS=m | ||
1072 | CONFIG_SND_PCM_OSS=m | ||
1073 | CONFIG_SND_SEQUENCER_OSS=y | ||
1074 | # CONFIG_SND_VERBOSE_PRINTK is not set | ||
1075 | # CONFIG_SND_DEBUG is not set | ||
1076 | CONFIG_SND_GENERIC_DRIVER=y | ||
1077 | |||
1078 | # | ||
1079 | # Generic devices | ||
1080 | # | ||
1081 | # CONFIG_SND_DUMMY is not set | ||
1082 | # CONFIG_SND_VIRMIDI is not set | ||
1083 | # CONFIG_SND_MTPAV is not set | ||
1084 | # CONFIG_SND_SERIAL_U16550 is not set | ||
1085 | # CONFIG_SND_MPU401 is not set | ||
1086 | |||
1087 | # | ||
1088 | # PCI devices | ||
1089 | # | ||
1090 | # CONFIG_SND_ALI5451 is not set | ||
1091 | # CONFIG_SND_ATIIXP is not set | ||
1092 | # CONFIG_SND_ATIIXP_MODEM is not set | ||
1093 | # CONFIG_SND_AU8810 is not set | ||
1094 | # CONFIG_SND_AU8820 is not set | ||
1095 | # CONFIG_SND_AU8830 is not set | ||
1096 | # CONFIG_SND_AZT3328 is not set | ||
1097 | # CONFIG_SND_BT87X is not set | ||
1098 | # CONFIG_SND_CS46XX is not set | ||
1099 | # CONFIG_SND_CS4281 is not set | ||
1100 | # CONFIG_SND_EMU10K1 is not set | ||
1101 | # CONFIG_SND_EMU10K1X is not set | ||
1102 | # CONFIG_SND_CA0106 is not set | ||
1103 | # CONFIG_SND_KORG1212 is not set | ||
1104 | # CONFIG_SND_MIXART is not set | ||
1105 | # CONFIG_SND_NM256 is not set | ||
1106 | # CONFIG_SND_RME32 is not set | ||
1107 | # CONFIG_SND_RME96 is not set | ||
1108 | # CONFIG_SND_RME9652 is not set | ||
1109 | # CONFIG_SND_HDSP is not set | ||
1110 | # CONFIG_SND_HDSPM is not set | ||
1111 | # CONFIG_SND_TRIDENT is not set | ||
1112 | # CONFIG_SND_YMFPCI is not set | ||
1113 | # CONFIG_SND_AD1889 is not set | ||
1114 | # CONFIG_SND_ALS4000 is not set | ||
1115 | # CONFIG_SND_CMIPCI is not set | ||
1116 | # CONFIG_SND_ENS1370 is not set | ||
1117 | # CONFIG_SND_ENS1371 is not set | ||
1118 | # CONFIG_SND_ES1938 is not set | ||
1119 | # CONFIG_SND_ES1968 is not set | ||
1120 | # CONFIG_SND_MAESTRO3 is not set | ||
1121 | # CONFIG_SND_FM801 is not set | ||
1122 | # CONFIG_SND_ICE1712 is not set | ||
1123 | # CONFIG_SND_ICE1724 is not set | ||
1124 | # CONFIG_SND_INTEL8X0 is not set | ||
1125 | # CONFIG_SND_INTEL8X0M is not set | ||
1126 | # CONFIG_SND_SONICVIBES is not set | ||
1127 | # CONFIG_SND_VIA82XX is not set | ||
1128 | # CONFIG_SND_VIA82XX_MODEM is not set | ||
1129 | # CONFIG_SND_VX222 is not set | ||
1130 | # CONFIG_SND_HDA_INTEL is not set | ||
1131 | |||
1132 | # | ||
1133 | # ALSA PowerMac devices | ||
1134 | # | ||
1135 | CONFIG_SND_POWERMAC=m | ||
1136 | CONFIG_SND_POWERMAC_AUTO_DRC=y | ||
1137 | |||
1138 | # | ||
1139 | # USB devices | ||
1140 | # | ||
1141 | # CONFIG_SND_USB_AUDIO is not set | ||
1142 | # CONFIG_SND_USB_USX2Y is not set | ||
1143 | |||
1144 | # | ||
1145 | # Open Sound System | ||
1146 | # | ||
1147 | # CONFIG_SOUND_PRIME is not set | ||
1148 | |||
1149 | # | ||
1150 | # USB support | ||
1151 | # | ||
1152 | CONFIG_USB_ARCH_HAS_HCD=y | ||
1153 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
1154 | CONFIG_USB=y | ||
1155 | # CONFIG_USB_DEBUG is not set | ||
1156 | |||
1157 | # | ||
1158 | # Miscellaneous USB options | ||
1159 | # | ||
1160 | CONFIG_USB_DEVICEFS=y | ||
1161 | # CONFIG_USB_BANDWIDTH is not set | ||
1162 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
1163 | # CONFIG_USB_OTG is not set | ||
1164 | |||
1165 | # | ||
1166 | # USB Host Controller Drivers | ||
1167 | # | ||
1168 | CONFIG_USB_EHCI_HCD=y | ||
1169 | # CONFIG_USB_EHCI_SPLIT_ISO is not set | ||
1170 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | ||
1171 | # CONFIG_USB_ISP116X_HCD is not set | ||
1172 | CONFIG_USB_OHCI_HCD=y | ||
1173 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set | ||
1174 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
1175 | # CONFIG_USB_UHCI_HCD is not set | ||
1176 | # CONFIG_USB_SL811_HCD is not set | ||
1177 | |||
1178 | # | ||
1179 | # USB Device Class drivers | ||
1180 | # | ||
1181 | # CONFIG_OBSOLETE_OSS_USB_DRIVER is not set | ||
1182 | # CONFIG_USB_ACM is not set | ||
1183 | # CONFIG_USB_PRINTER is not set | ||
1184 | |||
1185 | # | ||
1186 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
1187 | # | ||
1188 | |||
1189 | # | ||
1190 | # may also be needed; see USB_STORAGE Help for more information | ||
1191 | # | ||
1192 | CONFIG_USB_STORAGE=m | ||
1193 | # CONFIG_USB_STORAGE_DEBUG is not set | ||
1194 | # CONFIG_USB_STORAGE_DATAFAB is not set | ||
1195 | # CONFIG_USB_STORAGE_FREECOM is not set | ||
1196 | # CONFIG_USB_STORAGE_ISD200 is not set | ||
1197 | # CONFIG_USB_STORAGE_DPCM is not set | ||
1198 | # CONFIG_USB_STORAGE_USBAT is not set | ||
1199 | # CONFIG_USB_STORAGE_SDDR09 is not set | ||
1200 | # CONFIG_USB_STORAGE_SDDR55 is not set | ||
1201 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | ||
1202 | # CONFIG_USB_STORAGE_ONETOUCH is not set | ||
1203 | |||
1204 | # | ||
1205 | # USB Input Devices | ||
1206 | # | ||
1207 | CONFIG_USB_HID=y | ||
1208 | CONFIG_USB_HIDINPUT=y | ||
1209 | # CONFIG_HID_FF is not set | ||
1210 | CONFIG_USB_HIDDEV=y | ||
1211 | # CONFIG_USB_AIPTEK is not set | ||
1212 | # CONFIG_USB_WACOM is not set | ||
1213 | # CONFIG_USB_ACECAD is not set | ||
1214 | # CONFIG_USB_KBTAB is not set | ||
1215 | # CONFIG_USB_POWERMATE is not set | ||
1216 | # CONFIG_USB_MTOUCH is not set | ||
1217 | # CONFIG_USB_ITMTOUCH is not set | ||
1218 | # CONFIG_USB_EGALAX is not set | ||
1219 | # CONFIG_USB_YEALINK is not set | ||
1220 | # CONFIG_USB_XPAD is not set | ||
1221 | # CONFIG_USB_ATI_REMOTE is not set | ||
1222 | # CONFIG_USB_KEYSPAN_REMOTE is not set | ||
1223 | # CONFIG_USB_APPLETOUCH is not set | ||
1224 | |||
1225 | # | ||
1226 | # USB Imaging devices | ||
1227 | # | ||
1228 | # CONFIG_USB_MDC800 is not set | ||
1229 | # CONFIG_USB_MICROTEK is not set | ||
1230 | |||
1231 | # | ||
1232 | # USB Multimedia devices | ||
1233 | # | ||
1234 | # CONFIG_USB_DABUSB is not set | ||
1235 | |||
1236 | # | ||
1237 | # Video4Linux support is needed for USB Multimedia device support | ||
1238 | # | ||
1239 | |||
1240 | # | ||
1241 | # USB Network Adapters | ||
1242 | # | ||
1243 | # CONFIG_USB_CATC is not set | ||
1244 | # CONFIG_USB_KAWETH is not set | ||
1245 | # CONFIG_USB_PEGASUS is not set | ||
1246 | # CONFIG_USB_RTL8150 is not set | ||
1247 | # CONFIG_USB_USBNET is not set | ||
1248 | # CONFIG_USB_MON is not set | ||
1249 | |||
1250 | # | ||
1251 | # USB port drivers | ||
1252 | # | ||
1253 | |||
1254 | # | ||
1255 | # USB Serial Converter support | ||
1256 | # | ||
1257 | # CONFIG_USB_SERIAL is not set | ||
1258 | |||
1259 | # | ||
1260 | # USB Miscellaneous drivers | ||
1261 | # | ||
1262 | # CONFIG_USB_EMI62 is not set | ||
1263 | # CONFIG_USB_EMI26 is not set | ||
1264 | # CONFIG_USB_AUERSWALD is not set | ||
1265 | # CONFIG_USB_RIO500 is not set | ||
1266 | # CONFIG_USB_LEGOTOWER is not set | ||
1267 | # CONFIG_USB_LCD is not set | ||
1268 | # CONFIG_USB_LED is not set | ||
1269 | # CONFIG_USB_CYTHERM is not set | ||
1270 | # CONFIG_USB_PHIDGETKIT is not set | ||
1271 | # CONFIG_USB_PHIDGETSERVO is not set | ||
1272 | # CONFIG_USB_IDMOUSE is not set | ||
1273 | # CONFIG_USB_SISUSBVGA is not set | ||
1274 | # CONFIG_USB_LD is not set | ||
1275 | # CONFIG_USB_TEST is not set | ||
1276 | |||
1277 | # | ||
1278 | # USB DSL modem support | ||
1279 | # | ||
1280 | |||
1281 | # | ||
1282 | # USB Gadget Support | ||
1283 | # | ||
1284 | # CONFIG_USB_GADGET is not set | ||
1285 | |||
1286 | # | ||
1287 | # MMC/SD Card support | ||
1288 | # | ||
1289 | # CONFIG_MMC is not set | ||
1290 | |||
1291 | # | ||
1292 | # InfiniBand support | ||
1293 | # | ||
1294 | CONFIG_INFINIBAND=m | ||
1295 | # CONFIG_INFINIBAND_USER_MAD is not set | ||
1296 | # CONFIG_INFINIBAND_USER_ACCESS is not set | ||
1297 | CONFIG_INFINIBAND_MTHCA=m | ||
1298 | # CONFIG_INFINIBAND_MTHCA_DEBUG is not set | ||
1299 | CONFIG_INFINIBAND_IPOIB=m | ||
1300 | # CONFIG_INFINIBAND_IPOIB_DEBUG is not set | ||
1301 | # CONFIG_INFINIBAND_SRP is not set | ||
1302 | |||
1303 | # | ||
1304 | # SN Devices | ||
1305 | # | ||
1306 | |||
1307 | # | ||
1308 | # File systems | ||
1309 | # | ||
1310 | CONFIG_EXT2_FS=y | ||
1311 | CONFIG_EXT2_FS_XATTR=y | ||
1312 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
1313 | CONFIG_EXT2_FS_SECURITY=y | ||
1314 | CONFIG_EXT2_FS_XIP=y | ||
1315 | CONFIG_FS_XIP=y | ||
1316 | CONFIG_EXT3_FS=y | ||
1317 | CONFIG_EXT3_FS_XATTR=y | ||
1318 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
1319 | CONFIG_EXT3_FS_SECURITY=y | ||
1320 | CONFIG_JBD=y | ||
1321 | # CONFIG_JBD_DEBUG is not set | ||
1322 | CONFIG_FS_MBCACHE=y | ||
1323 | CONFIG_REISERFS_FS=y | ||
1324 | # CONFIG_REISERFS_CHECK is not set | ||
1325 | # CONFIG_REISERFS_PROC_INFO is not set | ||
1326 | CONFIG_REISERFS_FS_XATTR=y | ||
1327 | CONFIG_REISERFS_FS_POSIX_ACL=y | ||
1328 | CONFIG_REISERFS_FS_SECURITY=y | ||
1329 | CONFIG_JFS_FS=y | ||
1330 | CONFIG_JFS_POSIX_ACL=y | ||
1331 | CONFIG_JFS_SECURITY=y | ||
1332 | # CONFIG_JFS_DEBUG is not set | ||
1333 | # CONFIG_JFS_STATISTICS is not set | ||
1334 | CONFIG_FS_POSIX_ACL=y | ||
1335 | CONFIG_XFS_FS=m | ||
1336 | CONFIG_XFS_EXPORT=y | ||
1337 | # CONFIG_XFS_QUOTA is not set | ||
1338 | CONFIG_XFS_SECURITY=y | ||
1339 | CONFIG_XFS_POSIX_ACL=y | ||
1340 | # CONFIG_XFS_RT is not set | ||
1341 | # CONFIG_MINIX_FS is not set | ||
1342 | # CONFIG_ROMFS_FS is not set | ||
1343 | CONFIG_INOTIFY=y | ||
1344 | # CONFIG_QUOTA is not set | ||
1345 | CONFIG_DNOTIFY=y | ||
1346 | CONFIG_AUTOFS_FS=y | ||
1347 | # CONFIG_AUTOFS4_FS is not set | ||
1348 | # CONFIG_FUSE_FS is not set | ||
1349 | |||
1350 | # | ||
1351 | # CD-ROM/DVD Filesystems | ||
1352 | # | ||
1353 | CONFIG_ISO9660_FS=y | ||
1354 | # CONFIG_JOLIET is not set | ||
1355 | # CONFIG_ZISOFS is not set | ||
1356 | CONFIG_UDF_FS=m | ||
1357 | CONFIG_UDF_NLS=y | ||
1358 | |||
1359 | # | ||
1360 | # DOS/FAT/NT Filesystems | ||
1361 | # | ||
1362 | CONFIG_FAT_FS=y | ||
1363 | CONFIG_MSDOS_FS=y | ||
1364 | CONFIG_VFAT_FS=y | ||
1365 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
1366 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
1367 | # CONFIG_NTFS_FS is not set | ||
1368 | |||
1369 | # | ||
1370 | # Pseudo filesystems | ||
1371 | # | ||
1372 | CONFIG_PROC_FS=y | ||
1373 | CONFIG_PROC_KCORE=y | ||
1374 | CONFIG_SYSFS=y | ||
1375 | CONFIG_TMPFS=y | ||
1376 | CONFIG_HUGETLBFS=y | ||
1377 | CONFIG_HUGETLB_PAGE=y | ||
1378 | CONFIG_RAMFS=y | ||
1379 | # CONFIG_RELAYFS_FS is not set | ||
1380 | |||
1381 | # | ||
1382 | # Miscellaneous filesystems | ||
1383 | # | ||
1384 | # CONFIG_ADFS_FS is not set | ||
1385 | # CONFIG_AFFS_FS is not set | ||
1386 | CONFIG_HFS_FS=m | ||
1387 | CONFIG_HFSPLUS_FS=m | ||
1388 | # CONFIG_BEFS_FS is not set | ||
1389 | # CONFIG_BFS_FS is not set | ||
1390 | # CONFIG_EFS_FS is not set | ||
1391 | CONFIG_CRAMFS=y | ||
1392 | # CONFIG_VXFS_FS is not set | ||
1393 | # CONFIG_HPFS_FS is not set | ||
1394 | # CONFIG_QNX4FS_FS is not set | ||
1395 | # CONFIG_SYSV_FS is not set | ||
1396 | # CONFIG_UFS_FS is not set | ||
1397 | |||
1398 | # | ||
1399 | # Network File Systems | ||
1400 | # | ||
1401 | CONFIG_NFS_FS=y | ||
1402 | CONFIG_NFS_V3=y | ||
1403 | CONFIG_NFS_V3_ACL=y | ||
1404 | CONFIG_NFS_V4=y | ||
1405 | # CONFIG_NFS_DIRECTIO is not set | ||
1406 | CONFIG_NFSD=m | ||
1407 | CONFIG_NFSD_V2_ACL=y | ||
1408 | CONFIG_NFSD_V3=y | ||
1409 | CONFIG_NFSD_V3_ACL=y | ||
1410 | CONFIG_NFSD_V4=y | ||
1411 | CONFIG_NFSD_TCP=y | ||
1412 | CONFIG_LOCKD=y | ||
1413 | CONFIG_LOCKD_V4=y | ||
1414 | CONFIG_EXPORTFS=m | ||
1415 | CONFIG_NFS_ACL_SUPPORT=y | ||
1416 | CONFIG_NFS_COMMON=y | ||
1417 | CONFIG_SUNRPC=y | ||
1418 | CONFIG_SUNRPC_GSS=y | ||
1419 | CONFIG_RPCSEC_GSS_KRB5=y | ||
1420 | CONFIG_RPCSEC_GSS_SPKM3=m | ||
1421 | # CONFIG_SMB_FS is not set | ||
1422 | CONFIG_CIFS=m | ||
1423 | # CONFIG_CIFS_STATS is not set | ||
1424 | CONFIG_CIFS_XATTR=y | ||
1425 | CONFIG_CIFS_POSIX=y | ||
1426 | # CONFIG_CIFS_EXPERIMENTAL is not set | ||
1427 | # CONFIG_NCP_FS is not set | ||
1428 | # CONFIG_CODA_FS is not set | ||
1429 | # CONFIG_AFS_FS is not set | ||
1430 | # CONFIG_9P_FS is not set | ||
1431 | |||
1432 | # | ||
1433 | # Partition Types | ||
1434 | # | ||
1435 | CONFIG_PARTITION_ADVANCED=y | ||
1436 | # CONFIG_ACORN_PARTITION is not set | ||
1437 | # CONFIG_OSF_PARTITION is not set | ||
1438 | # CONFIG_AMIGA_PARTITION is not set | ||
1439 | # CONFIG_ATARI_PARTITION is not set | ||
1440 | CONFIG_MAC_PARTITION=y | ||
1441 | CONFIG_MSDOS_PARTITION=y | ||
1442 | # CONFIG_BSD_DISKLABEL is not set | ||
1443 | # CONFIG_MINIX_SUBPARTITION is not set | ||
1444 | # CONFIG_SOLARIS_X86_PARTITION is not set | ||
1445 | # CONFIG_UNIXWARE_DISKLABEL is not set | ||
1446 | # CONFIG_LDM_PARTITION is not set | ||
1447 | # CONFIG_SGI_PARTITION is not set | ||
1448 | # CONFIG_ULTRIX_PARTITION is not set | ||
1449 | # CONFIG_SUN_PARTITION is not set | ||
1450 | # CONFIG_EFI_PARTITION is not set | ||
1451 | |||
1452 | # | ||
1453 | # Native Language Support | ||
1454 | # | ||
1455 | CONFIG_NLS=y | ||
1456 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
1457 | CONFIG_NLS_CODEPAGE_437=y | ||
1458 | CONFIG_NLS_CODEPAGE_737=m | ||
1459 | CONFIG_NLS_CODEPAGE_775=m | ||
1460 | CONFIG_NLS_CODEPAGE_850=m | ||
1461 | CONFIG_NLS_CODEPAGE_852=m | ||
1462 | CONFIG_NLS_CODEPAGE_855=m | ||
1463 | CONFIG_NLS_CODEPAGE_857=m | ||
1464 | CONFIG_NLS_CODEPAGE_860=m | ||
1465 | CONFIG_NLS_CODEPAGE_861=m | ||
1466 | CONFIG_NLS_CODEPAGE_862=m | ||
1467 | CONFIG_NLS_CODEPAGE_863=m | ||
1468 | CONFIG_NLS_CODEPAGE_864=m | ||
1469 | CONFIG_NLS_CODEPAGE_865=m | ||
1470 | CONFIG_NLS_CODEPAGE_866=m | ||
1471 | CONFIG_NLS_CODEPAGE_869=m | ||
1472 | CONFIG_NLS_CODEPAGE_936=m | ||
1473 | CONFIG_NLS_CODEPAGE_950=m | ||
1474 | CONFIG_NLS_CODEPAGE_932=m | ||
1475 | CONFIG_NLS_CODEPAGE_949=m | ||
1476 | CONFIG_NLS_CODEPAGE_874=m | ||
1477 | CONFIG_NLS_ISO8859_8=m | ||
1478 | CONFIG_NLS_CODEPAGE_1250=m | ||
1479 | CONFIG_NLS_CODEPAGE_1251=m | ||
1480 | CONFIG_NLS_ASCII=m | ||
1481 | CONFIG_NLS_ISO8859_1=y | ||
1482 | CONFIG_NLS_ISO8859_2=m | ||
1483 | CONFIG_NLS_ISO8859_3=m | ||
1484 | CONFIG_NLS_ISO8859_4=m | ||
1485 | CONFIG_NLS_ISO8859_5=m | ||
1486 | CONFIG_NLS_ISO8859_6=m | ||
1487 | CONFIG_NLS_ISO8859_7=m | ||
1488 | CONFIG_NLS_ISO8859_9=m | ||
1489 | CONFIG_NLS_ISO8859_13=m | ||
1490 | CONFIG_NLS_ISO8859_14=m | ||
1491 | CONFIG_NLS_ISO8859_15=m | ||
1492 | CONFIG_NLS_KOI8_R=m | ||
1493 | CONFIG_NLS_KOI8_U=m | ||
1494 | CONFIG_NLS_UTF8=m | ||
1495 | |||
1496 | # | ||
1497 | # Library routines | ||
1498 | # | ||
1499 | CONFIG_CRC_CCITT=m | ||
1500 | # CONFIG_CRC16 is not set | ||
1501 | CONFIG_CRC32=y | ||
1502 | CONFIG_LIBCRC32C=m | ||
1503 | CONFIG_ZLIB_INFLATE=y | ||
1504 | CONFIG_ZLIB_DEFLATE=m | ||
1505 | CONFIG_TEXTSEARCH=y | ||
1506 | CONFIG_TEXTSEARCH_KMP=m | ||
1507 | CONFIG_TEXTSEARCH_BM=m | ||
1508 | CONFIG_TEXTSEARCH_FSM=m | ||
1509 | |||
1510 | # | ||
1511 | # Instrumentation Support | ||
1512 | # | ||
1513 | CONFIG_PROFILING=y | ||
1514 | CONFIG_OPROFILE=y | ||
1515 | # CONFIG_KPROBES is not set | ||
1516 | |||
1517 | # | ||
1518 | # Kernel hacking | ||
1519 | # | ||
1520 | # CONFIG_PRINTK_TIME is not set | ||
1521 | CONFIG_DEBUG_KERNEL=y | ||
1522 | CONFIG_MAGIC_SYSRQ=y | ||
1523 | CONFIG_LOG_BUF_SHIFT=17 | ||
1524 | CONFIG_DETECT_SOFTLOCKUP=y | ||
1525 | # CONFIG_SCHEDSTATS is not set | ||
1526 | # CONFIG_DEBUG_SLAB is not set | ||
1527 | # CONFIG_DEBUG_SPINLOCK is not set | ||
1528 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
1529 | # CONFIG_DEBUG_KOBJECT is not set | ||
1530 | # CONFIG_DEBUG_INFO is not set | ||
1531 | CONFIG_DEBUG_FS=y | ||
1532 | # CONFIG_DEBUG_VM is not set | ||
1533 | # CONFIG_RCU_TORTURE_TEST is not set | ||
1534 | CONFIG_DEBUG_STACKOVERFLOW=y | ||
1535 | CONFIG_DEBUG_STACK_USAGE=y | ||
1536 | CONFIG_DEBUGGER=y | ||
1537 | CONFIG_XMON=y | ||
1538 | # CONFIG_XMON_DEFAULT is not set | ||
1539 | CONFIG_IRQSTACKS=y | ||
1540 | CONFIG_BOOTX_TEXT=y | ||
1541 | |||
1542 | # | ||
1543 | # Security options | ||
1544 | # | ||
1545 | # CONFIG_KEYS is not set | ||
1546 | # CONFIG_SECURITY is not set | ||
1547 | |||
1548 | # | ||
1549 | # Cryptographic options | ||
1550 | # | ||
1551 | CONFIG_CRYPTO=y | ||
1552 | CONFIG_CRYPTO_HMAC=y | ||
1553 | CONFIG_CRYPTO_NULL=m | ||
1554 | CONFIG_CRYPTO_MD4=m | ||
1555 | CONFIG_CRYPTO_MD5=y | ||
1556 | CONFIG_CRYPTO_SHA1=m | ||
1557 | CONFIG_CRYPTO_SHA256=m | ||
1558 | CONFIG_CRYPTO_SHA512=m | ||
1559 | CONFIG_CRYPTO_WP512=m | ||
1560 | CONFIG_CRYPTO_TGR192=m | ||
1561 | CONFIG_CRYPTO_DES=y | ||
1562 | CONFIG_CRYPTO_BLOWFISH=m | ||
1563 | CONFIG_CRYPTO_TWOFISH=m | ||
1564 | CONFIG_CRYPTO_SERPENT=m | ||
1565 | CONFIG_CRYPTO_AES=m | ||
1566 | CONFIG_CRYPTO_CAST5=m | ||
1567 | CONFIG_CRYPTO_CAST6=m | ||
1568 | CONFIG_CRYPTO_TEA=m | ||
1569 | CONFIG_CRYPTO_ARC4=m | ||
1570 | CONFIG_CRYPTO_KHAZAD=m | ||
1571 | CONFIG_CRYPTO_ANUBIS=m | ||
1572 | CONFIG_CRYPTO_DEFLATE=m | ||
1573 | CONFIG_CRYPTO_MICHAEL_MIC=m | ||
1574 | CONFIG_CRYPTO_CRC32C=m | ||
1575 | CONFIG_CRYPTO_TEST=m | ||
1576 | |||
1577 | # | ||
1578 | # Hardware crypto devices | ||
1579 | # | ||
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 9f09dff9e11a..b589b196eb3f 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig | |||
@@ -1,18 +1,33 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.14-rc4 | 3 | # Linux kernel version: 2.6.15-rc1 |
4 | # Thu Oct 20 08:32:17 2005 | 4 | # Tue Nov 15 14:36:55 2005 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | ||
6 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
8 | CONFIG_PPC_MERGE=y | ||
7 | CONFIG_MMU=y | 9 | CONFIG_MMU=y |
10 | CONFIG_GENERIC_HARDIRQS=y | ||
8 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
9 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 12 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
10 | CONFIG_GENERIC_ISA_DMA=y | 13 | CONFIG_PPC=y |
11 | CONFIG_EARLY_PRINTK=y | 14 | CONFIG_EARLY_PRINTK=y |
12 | CONFIG_COMPAT=y | 15 | CONFIG_COMPAT=y |
16 | CONFIG_SYSVIPC_COMPAT=y | ||
13 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | 17 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y |
14 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | 18 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y |
15 | CONFIG_FORCE_MAX_ZONEORDER=13 | 19 | |
20 | # | ||
21 | # Processor support | ||
22 | # | ||
23 | # CONFIG_POWER4_ONLY is not set | ||
24 | CONFIG_POWER3=y | ||
25 | CONFIG_POWER4=y | ||
26 | CONFIG_PPC_FPU=y | ||
27 | CONFIG_ALTIVEC=y | ||
28 | CONFIG_PPC_STD_MMU=y | ||
29 | CONFIG_SMP=y | ||
30 | CONFIG_NR_CPUS=128 | ||
16 | 31 | ||
17 | # | 32 | # |
18 | # Code maturity level options | 33 | # Code maturity level options |
@@ -68,75 +83,102 @@ CONFIG_MODVERSIONS=y | |||
68 | CONFIG_MODULE_SRCVERSION_ALL=y | 83 | CONFIG_MODULE_SRCVERSION_ALL=y |
69 | CONFIG_KMOD=y | 84 | CONFIG_KMOD=y |
70 | CONFIG_STOP_MACHINE=y | 85 | CONFIG_STOP_MACHINE=y |
71 | CONFIG_SYSVIPC_COMPAT=y | 86 | |
87 | # | ||
88 | # Block layer | ||
89 | # | ||
90 | |||
91 | # | ||
92 | # IO Schedulers | ||
93 | # | ||
94 | CONFIG_IOSCHED_NOOP=y | ||
95 | CONFIG_IOSCHED_AS=y | ||
96 | CONFIG_IOSCHED_DEADLINE=y | ||
97 | CONFIG_IOSCHED_CFQ=y | ||
98 | CONFIG_DEFAULT_AS=y | ||
99 | # CONFIG_DEFAULT_DEADLINE is not set | ||
100 | # CONFIG_DEFAULT_CFQ is not set | ||
101 | # CONFIG_DEFAULT_NOOP is not set | ||
102 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
72 | 103 | ||
73 | # | 104 | # |
74 | # Platform support | 105 | # Platform support |
75 | # | 106 | # |
76 | # CONFIG_PPC_ISERIES is not set | ||
77 | CONFIG_PPC_MULTIPLATFORM=y | 107 | CONFIG_PPC_MULTIPLATFORM=y |
108 | # CONFIG_PPC_ISERIES is not set | ||
109 | # CONFIG_EMBEDDED6xx is not set | ||
110 | # CONFIG_APUS is not set | ||
78 | CONFIG_PPC_PSERIES=y | 111 | CONFIG_PPC_PSERIES=y |
79 | # CONFIG_PPC_BPA is not set | ||
80 | # CONFIG_PPC_PMAC is not set | 112 | # CONFIG_PPC_PMAC is not set |
81 | # CONFIG_PPC_MAPLE is not set | 113 | # CONFIG_PPC_MAPLE is not set |
82 | CONFIG_PPC=y | 114 | # CONFIG_PPC_CELL is not set |
83 | CONFIG_PPC64=y | ||
84 | CONFIG_PPC_OF=y | 115 | CONFIG_PPC_OF=y |
85 | CONFIG_XICS=y | 116 | CONFIG_XICS=y |
117 | # CONFIG_U3_DART is not set | ||
86 | CONFIG_MPIC=y | 118 | CONFIG_MPIC=y |
87 | CONFIG_ALTIVEC=y | 119 | CONFIG_PPC_RTAS=y |
88 | CONFIG_PPC_SPLPAR=y | 120 | CONFIG_RTAS_ERROR_LOGGING=y |
89 | CONFIG_KEXEC=y | 121 | CONFIG_RTAS_PROC=y |
122 | CONFIG_RTAS_FLASH=m | ||
123 | # CONFIG_MMIO_NVRAM is not set | ||
90 | CONFIG_IBMVIO=y | 124 | CONFIG_IBMVIO=y |
91 | # CONFIG_U3_DART is not set | 125 | # CONFIG_PPC_MPC106 is not set |
92 | # CONFIG_BOOTX_TEXT is not set | 126 | # CONFIG_GENERIC_TBSYNC is not set |
93 | # CONFIG_POWER4_ONLY is not set | 127 | # CONFIG_CPU_FREQ is not set |
128 | # CONFIG_WANT_EARLY_SERIAL is not set | ||
129 | |||
130 | # | ||
131 | # Kernel options | ||
132 | # | ||
133 | # CONFIG_HZ_100 is not set | ||
134 | CONFIG_HZ_250=y | ||
135 | # CONFIG_HZ_1000 is not set | ||
136 | CONFIG_HZ=250 | ||
137 | CONFIG_PREEMPT_NONE=y | ||
138 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
139 | # CONFIG_PREEMPT is not set | ||
140 | # CONFIG_PREEMPT_BKL is not set | ||
141 | CONFIG_BINFMT_ELF=y | ||
142 | # CONFIG_BINFMT_MISC is not set | ||
143 | CONFIG_FORCE_MAX_ZONEORDER=13 | ||
94 | CONFIG_IOMMU_VMERGE=y | 144 | CONFIG_IOMMU_VMERGE=y |
95 | CONFIG_SMP=y | 145 | CONFIG_HOTPLUG_CPU=y |
96 | CONFIG_NR_CPUS=128 | 146 | CONFIG_KEXEC=y |
147 | CONFIG_IRQ_ALL_CPUS=y | ||
148 | CONFIG_PPC_SPLPAR=y | ||
149 | CONFIG_EEH=y | ||
150 | CONFIG_SCANLOG=m | ||
151 | CONFIG_LPARCFG=y | ||
152 | CONFIG_NUMA=y | ||
97 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y | 153 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y |
98 | CONFIG_ARCH_FLATMEM_ENABLE=y | ||
99 | CONFIG_ARCH_DISCONTIGMEM_ENABLE=y | ||
100 | CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y | ||
101 | CONFIG_ARCH_SPARSEMEM_ENABLE=y | 154 | CONFIG_ARCH_SPARSEMEM_ENABLE=y |
155 | CONFIG_ARCH_SPARSEMEM_DEFAULT=y | ||
102 | CONFIG_SELECT_MEMORY_MODEL=y | 156 | CONFIG_SELECT_MEMORY_MODEL=y |
103 | # CONFIG_FLATMEM_MANUAL is not set | 157 | # CONFIG_FLATMEM_MANUAL is not set |
104 | CONFIG_DISCONTIGMEM_MANUAL=y | 158 | # CONFIG_DISCONTIGMEM_MANUAL is not set |
105 | # CONFIG_SPARSEMEM_MANUAL is not set | 159 | CONFIG_SPARSEMEM_MANUAL=y |
106 | CONFIG_DISCONTIGMEM=y | 160 | CONFIG_SPARSEMEM=y |
107 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
108 | CONFIG_NEED_MULTIPLE_NODES=y | 161 | CONFIG_NEED_MULTIPLE_NODES=y |
162 | CONFIG_HAVE_MEMORY_PRESENT=y | ||
109 | # CONFIG_SPARSEMEM_STATIC is not set | 163 | # CONFIG_SPARSEMEM_STATIC is not set |
164 | CONFIG_SPARSEMEM_EXTREME=y | ||
165 | # CONFIG_MEMORY_HOTPLUG is not set | ||
166 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
110 | CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y | 167 | CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y |
111 | CONFIG_NODES_SPAN_OTHER_NODES=y | 168 | # CONFIG_PPC_64K_PAGES is not set |
112 | CONFIG_NUMA=y | ||
113 | CONFIG_SCHED_SMT=y | 169 | CONFIG_SCHED_SMT=y |
114 | CONFIG_PREEMPT_NONE=y | ||
115 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
116 | # CONFIG_PREEMPT is not set | ||
117 | # CONFIG_PREEMPT_BKL is not set | ||
118 | # CONFIG_HZ_100 is not set | ||
119 | CONFIG_HZ_250=y | ||
120 | # CONFIG_HZ_1000 is not set | ||
121 | CONFIG_HZ=250 | ||
122 | CONFIG_EEH=y | ||
123 | CONFIG_GENERIC_HARDIRQS=y | ||
124 | CONFIG_PPC_RTAS=y | ||
125 | CONFIG_RTAS_PROC=y | ||
126 | CONFIG_RTAS_FLASH=m | ||
127 | CONFIG_SCANLOG=m | ||
128 | CONFIG_LPARCFG=y | ||
129 | CONFIG_SECCOMP=y | ||
130 | CONFIG_BINFMT_ELF=y | ||
131 | # CONFIG_BINFMT_MISC is not set | ||
132 | CONFIG_HOTPLUG_CPU=y | ||
133 | CONFIG_PROC_DEVICETREE=y | 170 | CONFIG_PROC_DEVICETREE=y |
134 | # CONFIG_CMDLINE_BOOL is not set | 171 | # CONFIG_CMDLINE_BOOL is not set |
172 | # CONFIG_PM is not set | ||
173 | CONFIG_SECCOMP=y | ||
135 | CONFIG_ISA_DMA_API=y | 174 | CONFIG_ISA_DMA_API=y |
136 | 175 | ||
137 | # | 176 | # |
138 | # Bus Options | 177 | # Bus options |
139 | # | 178 | # |
179 | CONFIG_GENERIC_ISA_DMA=y | ||
180 | CONFIG_PPC_I8259=y | ||
181 | # CONFIG_PPC_INDIRECT_PCI is not set | ||
140 | CONFIG_PCI=y | 182 | CONFIG_PCI=y |
141 | CONFIG_PCI_DOMAINS=y | 183 | CONFIG_PCI_DOMAINS=y |
142 | CONFIG_PCI_LEGACY_PROC=y | 184 | CONFIG_PCI_LEGACY_PROC=y |
@@ -156,6 +198,7 @@ CONFIG_HOTPLUG_PCI=m | |||
156 | # CONFIG_HOTPLUG_PCI_SHPC is not set | 198 | # CONFIG_HOTPLUG_PCI_SHPC is not set |
157 | CONFIG_HOTPLUG_PCI_RPA=m | 199 | CONFIG_HOTPLUG_PCI_RPA=m |
158 | CONFIG_HOTPLUG_PCI_RPA_DLPAR=m | 200 | CONFIG_HOTPLUG_PCI_RPA_DLPAR=m |
201 | CONFIG_KERNEL_START=0xc000000000000000 | ||
159 | 202 | ||
160 | # | 203 | # |
161 | # Networking | 204 | # Networking |
@@ -197,6 +240,10 @@ CONFIG_TCP_CONG_BIC=y | |||
197 | # CONFIG_IPV6 is not set | 240 | # CONFIG_IPV6 is not set |
198 | CONFIG_NETFILTER=y | 241 | CONFIG_NETFILTER=y |
199 | # CONFIG_NETFILTER_DEBUG is not set | 242 | # CONFIG_NETFILTER_DEBUG is not set |
243 | |||
244 | # | ||
245 | # Core Netfilter Configuration | ||
246 | # | ||
200 | CONFIG_NETFILTER_NETLINK=y | 247 | CONFIG_NETFILTER_NETLINK=y |
201 | CONFIG_NETFILTER_NETLINK_QUEUE=m | 248 | CONFIG_NETFILTER_NETLINK_QUEUE=m |
202 | CONFIG_NETFILTER_NETLINK_LOG=m | 249 | CONFIG_NETFILTER_NETLINK_LOG=m |
@@ -299,6 +346,10 @@ CONFIG_LLC=y | |||
299 | # CONFIG_NET_DIVERT is not set | 346 | # CONFIG_NET_DIVERT is not set |
300 | # CONFIG_ECONET is not set | 347 | # CONFIG_ECONET is not set |
301 | # CONFIG_WAN_ROUTER is not set | 348 | # CONFIG_WAN_ROUTER is not set |
349 | |||
350 | # | ||
351 | # QoS and/or fair queueing | ||
352 | # | ||
302 | # CONFIG_NET_SCHED is not set | 353 | # CONFIG_NET_SCHED is not set |
303 | CONFIG_NET_CLS_ROUTE=y | 354 | CONFIG_NET_CLS_ROUTE=y |
304 | 355 | ||
@@ -368,14 +419,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16 | |||
368 | CONFIG_BLK_DEV_RAM_SIZE=65536 | 419 | CONFIG_BLK_DEV_RAM_SIZE=65536 |
369 | CONFIG_BLK_DEV_INITRD=y | 420 | CONFIG_BLK_DEV_INITRD=y |
370 | # CONFIG_CDROM_PKTCDVD is not set | 421 | # CONFIG_CDROM_PKTCDVD is not set |
371 | |||
372 | # | ||
373 | # IO Schedulers | ||
374 | # | ||
375 | CONFIG_IOSCHED_NOOP=y | ||
376 | CONFIG_IOSCHED_AS=y | ||
377 | CONFIG_IOSCHED_DEADLINE=y | ||
378 | CONFIG_IOSCHED_CFQ=y | ||
379 | # CONFIG_ATA_OVER_ETH is not set | 422 | # CONFIG_ATA_OVER_ETH is not set |
380 | 423 | ||
381 | # | 424 | # |
@@ -473,6 +516,7 @@ CONFIG_SCSI_ISCSI_ATTRS=m | |||
473 | # | 516 | # |
474 | # SCSI low-level drivers | 517 | # SCSI low-level drivers |
475 | # | 518 | # |
519 | # CONFIG_ISCSI_TCP is not set | ||
476 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | 520 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
477 | # CONFIG_SCSI_3W_9XXX is not set | 521 | # CONFIG_SCSI_3W_9XXX is not set |
478 | # CONFIG_SCSI_ACARD is not set | 522 | # CONFIG_SCSI_ACARD is not set |
@@ -559,6 +603,7 @@ CONFIG_DM_MULTIPATH_EMC=m | |||
559 | # | 603 | # |
560 | # Macintosh device drivers | 604 | # Macintosh device drivers |
561 | # | 605 | # |
606 | # CONFIG_WINDFARM is not set | ||
562 | 607 | ||
563 | # | 608 | # |
564 | # Network device support | 609 | # Network device support |
@@ -645,7 +690,6 @@ CONFIG_IXGB=m | |||
645 | # CONFIG_IXGB_NAPI is not set | 690 | # CONFIG_IXGB_NAPI is not set |
646 | CONFIG_S2IO=m | 691 | CONFIG_S2IO=m |
647 | # CONFIG_S2IO_NAPI is not set | 692 | # CONFIG_S2IO_NAPI is not set |
648 | # CONFIG_2BUFF_MODE is not set | ||
649 | 693 | ||
650 | # | 694 | # |
651 | # Token Ring devices | 695 | # Token Ring devices |
@@ -674,6 +718,7 @@ CONFIG_PPP_ASYNC=m | |||
674 | CONFIG_PPP_SYNC_TTY=m | 718 | CONFIG_PPP_SYNC_TTY=m |
675 | CONFIG_PPP_DEFLATE=m | 719 | CONFIG_PPP_DEFLATE=m |
676 | CONFIG_PPP_BSDCOMP=m | 720 | CONFIG_PPP_BSDCOMP=m |
721 | # CONFIG_PPP_MPPE is not set | ||
677 | CONFIG_PPPOE=m | 722 | CONFIG_PPPOE=m |
678 | # CONFIG_SLIP is not set | 723 | # CONFIG_SLIP is not set |
679 | # CONFIG_NET_FC is not set | 724 | # CONFIG_NET_FC is not set |
@@ -784,6 +829,8 @@ CONFIG_HVCS=m | |||
784 | # | 829 | # |
785 | # CONFIG_WATCHDOG is not set | 830 | # CONFIG_WATCHDOG is not set |
786 | # CONFIG_RTC is not set | 831 | # CONFIG_RTC is not set |
832 | CONFIG_GEN_RTC=y | ||
833 | # CONFIG_GEN_RTC_X is not set | ||
787 | # CONFIG_DTLK is not set | 834 | # CONFIG_DTLK is not set |
788 | # CONFIG_R3964 is not set | 835 | # CONFIG_R3964 is not set |
789 | # CONFIG_APPLICOM is not set | 836 | # CONFIG_APPLICOM is not set |
@@ -801,6 +848,7 @@ CONFIG_MAX_RAW_DEVS=1024 | |||
801 | # TPM devices | 848 | # TPM devices |
802 | # | 849 | # |
803 | # CONFIG_TCG_TPM is not set | 850 | # CONFIG_TCG_TPM is not set |
851 | # CONFIG_TELCLOCK is not set | ||
804 | 852 | ||
805 | # | 853 | # |
806 | # I2C support | 854 | # I2C support |
@@ -852,6 +900,7 @@ CONFIG_I2C_ALGOBIT=y | |||
852 | # CONFIG_SENSORS_PCF8591 is not set | 900 | # CONFIG_SENSORS_PCF8591 is not set |
853 | # CONFIG_SENSORS_RTC8564 is not set | 901 | # CONFIG_SENSORS_RTC8564 is not set |
854 | # CONFIG_SENSORS_MAX6875 is not set | 902 | # CONFIG_SENSORS_MAX6875 is not set |
903 | # CONFIG_RTC_X1205_I2C is not set | ||
855 | # CONFIG_I2C_DEBUG_CORE is not set | 904 | # CONFIG_I2C_DEBUG_CORE is not set |
856 | # CONFIG_I2C_DEBUG_ALGO is not set | 905 | # CONFIG_I2C_DEBUG_ALGO is not set |
857 | # CONFIG_I2C_DEBUG_BUS is not set | 906 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -893,7 +942,6 @@ CONFIG_FB=y | |||
893 | CONFIG_FB_CFB_FILLRECT=y | 942 | CONFIG_FB_CFB_FILLRECT=y |
894 | CONFIG_FB_CFB_COPYAREA=y | 943 | CONFIG_FB_CFB_COPYAREA=y |
895 | CONFIG_FB_CFB_IMAGEBLIT=y | 944 | CONFIG_FB_CFB_IMAGEBLIT=y |
896 | CONFIG_FB_SOFT_CURSOR=y | ||
897 | CONFIG_FB_MACMODES=y | 945 | CONFIG_FB_MACMODES=y |
898 | CONFIG_FB_MODE_HELPERS=y | 946 | CONFIG_FB_MODE_HELPERS=y |
899 | CONFIG_FB_TILEBLITTING=y | 947 | CONFIG_FB_TILEBLITTING=y |
@@ -905,6 +953,7 @@ CONFIG_FB_OF=y | |||
905 | # CONFIG_FB_ASILIANT is not set | 953 | # CONFIG_FB_ASILIANT is not set |
906 | # CONFIG_FB_IMSTT is not set | 954 | # CONFIG_FB_IMSTT is not set |
907 | # CONFIG_FB_VGA16 is not set | 955 | # CONFIG_FB_VGA16 is not set |
956 | # CONFIG_FB_S1D13XXX is not set | ||
908 | # CONFIG_FB_NVIDIA is not set | 957 | # CONFIG_FB_NVIDIA is not set |
909 | # CONFIG_FB_RIVA is not set | 958 | # CONFIG_FB_RIVA is not set |
910 | CONFIG_FB_MATROX=y | 959 | CONFIG_FB_MATROX=y |
@@ -927,7 +976,6 @@ CONFIG_FB_RADEON_I2C=y | |||
927 | # CONFIG_FB_VOODOO1 is not set | 976 | # CONFIG_FB_VOODOO1 is not set |
928 | # CONFIG_FB_CYBLA is not set | 977 | # CONFIG_FB_CYBLA is not set |
929 | # CONFIG_FB_TRIDENT is not set | 978 | # CONFIG_FB_TRIDENT is not set |
930 | # CONFIG_FB_S1D13XXX is not set | ||
931 | # CONFIG_FB_VIRTUAL is not set | 979 | # CONFIG_FB_VIRTUAL is not set |
932 | 980 | ||
933 | # | 981 | # |
@@ -936,6 +984,7 @@ CONFIG_FB_RADEON_I2C=y | |||
936 | # CONFIG_VGA_CONSOLE is not set | 984 | # CONFIG_VGA_CONSOLE is not set |
937 | CONFIG_DUMMY_CONSOLE=y | 985 | CONFIG_DUMMY_CONSOLE=y |
938 | CONFIG_FRAMEBUFFER_CONSOLE=y | 986 | CONFIG_FRAMEBUFFER_CONSOLE=y |
987 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | ||
939 | # CONFIG_FONTS is not set | 988 | # CONFIG_FONTS is not set |
940 | CONFIG_FONT_8x8=y | 989 | CONFIG_FONT_8x8=y |
941 | CONFIG_FONT_8x16=y | 990 | CONFIG_FONT_8x16=y |
@@ -990,12 +1039,15 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y | |||
990 | # | 1039 | # |
991 | # USB Device Class drivers | 1040 | # USB Device Class drivers |
992 | # | 1041 | # |
993 | # CONFIG_USB_BLUETOOTH_TTY is not set | ||
994 | # CONFIG_USB_ACM is not set | 1042 | # CONFIG_USB_ACM is not set |
995 | # CONFIG_USB_PRINTER is not set | 1043 | # CONFIG_USB_PRINTER is not set |
996 | 1044 | ||
997 | # | 1045 | # |
998 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information | 1046 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' |
1047 | # | ||
1048 | |||
1049 | # | ||
1050 | # may also be needed; see USB_STORAGE Help for more information | ||
999 | # | 1051 | # |
1000 | CONFIG_USB_STORAGE=y | 1052 | CONFIG_USB_STORAGE=y |
1001 | # CONFIG_USB_STORAGE_DEBUG is not set | 1053 | # CONFIG_USB_STORAGE_DEBUG is not set |
@@ -1106,6 +1158,7 @@ CONFIG_INFINIBAND_MTHCA=m | |||
1106 | # CONFIG_INFINIBAND_MTHCA_DEBUG is not set | 1158 | # CONFIG_INFINIBAND_MTHCA_DEBUG is not set |
1107 | CONFIG_INFINIBAND_IPOIB=m | 1159 | CONFIG_INFINIBAND_IPOIB=m |
1108 | # CONFIG_INFINIBAND_IPOIB_DEBUG is not set | 1160 | # CONFIG_INFINIBAND_IPOIB_DEBUG is not set |
1161 | # CONFIG_INFINIBAND_SRP is not set | ||
1109 | 1162 | ||
1110 | # | 1163 | # |
1111 | # SN Devices | 1164 | # SN Devices |
@@ -1288,10 +1341,25 @@ CONFIG_NLS_ISO8859_1=y | |||
1288 | # CONFIG_NLS_UTF8 is not set | 1341 | # CONFIG_NLS_UTF8 is not set |
1289 | 1342 | ||
1290 | # | 1343 | # |
1291 | # Profiling support | 1344 | # Library routines |
1345 | # | ||
1346 | CONFIG_CRC_CCITT=m | ||
1347 | # CONFIG_CRC16 is not set | ||
1348 | CONFIG_CRC32=y | ||
1349 | CONFIG_LIBCRC32C=m | ||
1350 | CONFIG_ZLIB_INFLATE=y | ||
1351 | CONFIG_ZLIB_DEFLATE=m | ||
1352 | CONFIG_TEXTSEARCH=y | ||
1353 | CONFIG_TEXTSEARCH_KMP=m | ||
1354 | CONFIG_TEXTSEARCH_BM=m | ||
1355 | CONFIG_TEXTSEARCH_FSM=m | ||
1356 | |||
1357 | # | ||
1358 | # Instrumentation Support | ||
1292 | # | 1359 | # |
1293 | CONFIG_PROFILING=y | 1360 | CONFIG_PROFILING=y |
1294 | CONFIG_OPROFILE=y | 1361 | CONFIG_OPROFILE=y |
1362 | # CONFIG_KPROBES is not set | ||
1295 | 1363 | ||
1296 | # | 1364 | # |
1297 | # Kernel hacking | 1365 | # Kernel hacking |
@@ -1308,14 +1376,15 @@ CONFIG_DETECT_SOFTLOCKUP=y | |||
1308 | # CONFIG_DEBUG_KOBJECT is not set | 1376 | # CONFIG_DEBUG_KOBJECT is not set |
1309 | # CONFIG_DEBUG_INFO is not set | 1377 | # CONFIG_DEBUG_INFO is not set |
1310 | CONFIG_DEBUG_FS=y | 1378 | CONFIG_DEBUG_FS=y |
1379 | # CONFIG_DEBUG_VM is not set | ||
1380 | # CONFIG_RCU_TORTURE_TEST is not set | ||
1311 | CONFIG_DEBUG_STACKOVERFLOW=y | 1381 | CONFIG_DEBUG_STACKOVERFLOW=y |
1312 | # CONFIG_KPROBES is not set | ||
1313 | CONFIG_DEBUG_STACK_USAGE=y | 1382 | CONFIG_DEBUG_STACK_USAGE=y |
1314 | CONFIG_DEBUGGER=y | 1383 | CONFIG_DEBUGGER=y |
1315 | CONFIG_XMON=y | 1384 | CONFIG_XMON=y |
1316 | CONFIG_XMON_DEFAULT=y | 1385 | CONFIG_XMON_DEFAULT=y |
1317 | # CONFIG_PPCDBG is not set | ||
1318 | CONFIG_IRQSTACKS=y | 1386 | CONFIG_IRQSTACKS=y |
1387 | # CONFIG_BOOTX_TEXT is not set | ||
1319 | 1388 | ||
1320 | # | 1389 | # |
1321 | # Security options | 1390 | # Security options |
@@ -1355,17 +1424,3 @@ CONFIG_CRYPTO_TEST=m | |||
1355 | # | 1424 | # |
1356 | # Hardware crypto devices | 1425 | # Hardware crypto devices |
1357 | # | 1426 | # |
1358 | |||
1359 | # | ||
1360 | # Library routines | ||
1361 | # | ||
1362 | CONFIG_CRC_CCITT=m | ||
1363 | # CONFIG_CRC16 is not set | ||
1364 | CONFIG_CRC32=y | ||
1365 | CONFIG_LIBCRC32C=m | ||
1366 | CONFIG_ZLIB_INFLATE=y | ||
1367 | CONFIG_ZLIB_DEFLATE=m | ||
1368 | CONFIG_TEXTSEARCH=y | ||
1369 | CONFIG_TEXTSEARCH_KMP=m | ||
1370 | CONFIG_TEXTSEARCH_BM=m | ||
1371 | CONFIG_TEXTSEARCH_FSM=m | ||
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 9a74b7ab03a4..9ed551b6c172 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -12,12 +12,12 @@ CFLAGS_btext.o += -fPIC | |||
12 | endif | 12 | endif |
13 | 13 | ||
14 | obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ | 14 | obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ |
15 | irq.o signal_32.o pmc.o vdso.o | 15 | irq.o align.o signal_32.o pmc.o vdso.o |
16 | obj-y += vdso32/ | 16 | obj-y += vdso32/ |
17 | obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ | 17 | obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ |
18 | signal_64.o ptrace32.o systbl.o \ | 18 | signal_64.o ptrace32.o systbl.o \ |
19 | paca.o ioctl32.o cpu_setup_power4.o \ | 19 | paca.o ioctl32.o cpu_setup_power4.o \ |
20 | firmware.o sysfs.o udbg.o | 20 | firmware.o sysfs.o udbg.o idle_64.o |
21 | obj-$(CONFIG_PPC64) += vdso64/ | 21 | obj-$(CONFIG_PPC64) += vdso64/ |
22 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 22 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
23 | obj-$(CONFIG_POWER4) += idle_power4.o | 23 | obj-$(CONFIG_POWER4) += idle_power4.o |
@@ -25,7 +25,7 @@ obj-$(CONFIG_PPC_OF) += of_device.o | |||
25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o | 25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o |
26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) | 26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) |
27 | rtaspci-$(CONFIG_PPC64) := rtas_pci.o | 27 | rtaspci-$(CONFIG_PPC64) := rtas_pci.o |
28 | obj-$(CONFIG_PPC_RTAS) += rtas.o $(rtaspci-y) | 28 | obj-$(CONFIG_PPC_RTAS) += rtas.o rtas-rtc.o $(rtaspci-y) |
29 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o | 29 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o |
30 | obj-$(CONFIG_RTAS_PROC) += rtas-proc.o | 30 | obj-$(CONFIG_RTAS_PROC) += rtas-proc.o |
31 | obj-$(CONFIG_LPARCFG) += lparcfg.o | 31 | obj-$(CONFIG_LPARCFG) += lparcfg.o |
@@ -35,6 +35,7 @@ obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o | |||
35 | obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o | 35 | obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o |
36 | udbgscc-$(CONFIG_PPC64) := udbg_scc.o | 36 | udbgscc-$(CONFIG_PPC64) := udbg_scc.o |
37 | obj-$(CONFIG_PPC_PMAC) += $(udbgscc-y) | 37 | obj-$(CONFIG_PPC_PMAC) += $(udbgscc-y) |
38 | obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o | ||
38 | 39 | ||
39 | ifeq ($(CONFIG_PPC_MERGE),y) | 40 | ifeq ($(CONFIG_PPC_MERGE),y) |
40 | 41 | ||
@@ -49,12 +50,23 @@ extra-y += vmlinux.lds | |||
49 | obj-y += process.o init_task.o time.o \ | 50 | obj-y += process.o init_task.o time.o \ |
50 | prom.o traps.o setup-common.o | 51 | prom.o traps.o setup-common.o |
51 | obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o | 52 | obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o |
52 | obj-$(CONFIG_PPC64) += misc_64.o | 53 | obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o |
53 | obj-$(CONFIG_PPC_OF) += prom_init.o | 54 | obj-$(CONFIG_PPC_OF) += prom_init.o |
54 | obj-$(CONFIG_MODULES) += ppc_ksyms.o | 55 | obj-$(CONFIG_MODULES) += ppc_ksyms.o |
55 | obj-$(CONFIG_BOOTX_TEXT) += btext.o | 56 | obj-$(CONFIG_BOOTX_TEXT) += btext.o |
56 | obj-$(CONFIG_6xx) += idle_6xx.o | 57 | obj-$(CONFIG_6xx) += idle_6xx.o |
57 | obj-$(CONFIG_SMP) += smp.o | 58 | obj-$(CONFIG_SMP) += smp.o |
59 | obj-$(CONFIG_KPROBES) += kprobes.o | ||
60 | |||
61 | module-$(CONFIG_PPC64) += module_64.o | ||
62 | obj-$(CONFIG_MODULES) += $(module-y) | ||
63 | |||
64 | pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \ | ||
65 | pci_direct_iommu.o iomap.o | ||
66 | obj-$(CONFIG_PCI) += $(pci64-y) | ||
67 | |||
68 | kexec64-$(CONFIG_PPC64) += machine_kexec_64.o | ||
69 | obj-$(CONFIG_KEXEC) += $(kexec64-y) | ||
58 | 70 | ||
59 | ifeq ($(CONFIG_PPC_ISERIES),y) | 71 | ifeq ($(CONFIG_PPC_ISERIES),y) |
60 | $(obj)/head_64.o: $(obj)/lparmap.s | 72 | $(obj)/head_64.o: $(obj)/lparmap.s |
@@ -62,13 +74,12 @@ AFLAGS_head_64.o += -I$(obj) | |||
62 | endif | 74 | endif |
63 | 75 | ||
64 | else | 76 | else |
65 | # stuff used from here for ARCH=ppc or ARCH=ppc64 | 77 | # stuff used from here for ARCH=ppc |
66 | smpobj-$(CONFIG_SMP) += smp.o | 78 | smpobj-$(CONFIG_SMP) += smp.o |
67 | obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o \ | ||
68 | setup-common.o $(smpobj-y) | ||
69 | |||
70 | 79 | ||
71 | endif | 80 | endif |
72 | 81 | ||
82 | obj-$(CONFIG_PPC64) += $(obj64-y) | ||
83 | |||
73 | extra-$(CONFIG_PPC_FPU) += fpu.o | 84 | extra-$(CONFIG_PPC_FPU) += fpu.o |
74 | extra-$(CONFIG_PPC64) += entry_64.o | 85 | extra-$(CONFIG_PPC64) += entry_64.o |
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c new file mode 100644 index 000000000000..faaec9c6f78f --- /dev/null +++ b/arch/powerpc/kernel/align.c | |||
@@ -0,0 +1,530 @@ | |||
1 | /* align.c - handle alignment exceptions for the Power PC. | ||
2 | * | ||
3 | * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au> | ||
4 | * Copyright (c) 1998-1999 TiVo, Inc. | ||
5 | * PowerPC 403GCX modifications. | ||
6 | * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> | ||
7 | * PowerPC 403GCX/405GP modifications. | ||
8 | * Copyright (c) 2001-2002 PPC64 team, IBM Corp | ||
9 | * 64-bit and Power4 support | ||
10 | * Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp | ||
11 | * <benh@kernel.crashing.org> | ||
12 | * Merge ppc32 and ppc64 implementations | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version | ||
17 | * 2 of the License, or (at your option) any later version. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/mm.h> | ||
22 | #include <asm/processor.h> | ||
23 | #include <asm/uaccess.h> | ||
24 | #include <asm/system.h> | ||
25 | #include <asm/cache.h> | ||
26 | #include <asm/cputable.h> | ||
27 | |||
28 | struct aligninfo { | ||
29 | unsigned char len; | ||
30 | unsigned char flags; | ||
31 | }; | ||
32 | |||
33 | #define IS_XFORM(inst) (((inst) >> 26) == 31) | ||
34 | #define IS_DSFORM(inst) (((inst) >> 26) >= 56) | ||
35 | |||
36 | #define INVALID { 0, 0 } | ||
37 | |||
38 | #define LD 1 /* load */ | ||
39 | #define ST 2 /* store */ | ||
40 | #define SE 4 /* sign-extend value */ | ||
41 | #define F 8 /* to/from fp regs */ | ||
42 | #define U 0x10 /* update index register */ | ||
43 | #define M 0x20 /* multiple load/store */ | ||
44 | #define SW 0x40 /* byte swap int or ... */ | ||
45 | #define S 0x40 /* ... single-precision fp */ | ||
46 | #define SX 0x40 /* byte count in XER */ | ||
47 | #define HARD 0x80 /* string, stwcx. */ | ||
48 | |||
49 | #define DCBZ 0x5f /* 8xx/82xx dcbz faults when cache not enabled */ | ||
50 | |||
51 | #define SWAP(a, b) (t = (a), (a) = (b), (b) = t) | ||
52 | |||
53 | /* | ||
54 | * The PowerPC stores certain bits of the instruction that caused the | ||
55 | * alignment exception in the DSISR register. This array maps those | ||
56 | * bits to information about the operand length and what the | ||
57 | * instruction would do. | ||
58 | */ | ||
59 | static struct aligninfo aligninfo[128] = { | ||
60 | { 4, LD }, /* 00 0 0000: lwz / lwarx */ | ||
61 | INVALID, /* 00 0 0001 */ | ||
62 | { 4, ST }, /* 00 0 0010: stw */ | ||
63 | INVALID, /* 00 0 0011 */ | ||
64 | { 2, LD }, /* 00 0 0100: lhz */ | ||
65 | { 2, LD+SE }, /* 00 0 0101: lha */ | ||
66 | { 2, ST }, /* 00 0 0110: sth */ | ||
67 | { 4, LD+M }, /* 00 0 0111: lmw */ | ||
68 | { 4, LD+F+S }, /* 00 0 1000: lfs */ | ||
69 | { 8, LD+F }, /* 00 0 1001: lfd */ | ||
70 | { 4, ST+F+S }, /* 00 0 1010: stfs */ | ||
71 | { 8, ST+F }, /* 00 0 1011: stfd */ | ||
72 | INVALID, /* 00 0 1100 */ | ||
73 | { 8, LD }, /* 00 0 1101: ld/ldu/lwa */ | ||
74 | INVALID, /* 00 0 1110 */ | ||
75 | { 8, ST }, /* 00 0 1111: std/stdu */ | ||
76 | { 4, LD+U }, /* 00 1 0000: lwzu */ | ||
77 | INVALID, /* 00 1 0001 */ | ||
78 | { 4, ST+U }, /* 00 1 0010: stwu */ | ||
79 | INVALID, /* 00 1 0011 */ | ||
80 | { 2, LD+U }, /* 00 1 0100: lhzu */ | ||
81 | { 2, LD+SE+U }, /* 00 1 0101: lhau */ | ||
82 | { 2, ST+U }, /* 00 1 0110: sthu */ | ||
83 | { 4, ST+M }, /* 00 1 0111: stmw */ | ||
84 | { 4, LD+F+S+U }, /* 00 1 1000: lfsu */ | ||
85 | { 8, LD+F+U }, /* 00 1 1001: lfdu */ | ||
86 | { 4, ST+F+S+U }, /* 00 1 1010: stfsu */ | ||
87 | { 8, ST+F+U }, /* 00 1 1011: stfdu */ | ||
88 | INVALID, /* 00 1 1100 */ | ||
89 | INVALID, /* 00 1 1101 */ | ||
90 | INVALID, /* 00 1 1110 */ | ||
91 | INVALID, /* 00 1 1111 */ | ||
92 | { 8, LD }, /* 01 0 0000: ldx */ | ||
93 | INVALID, /* 01 0 0001 */ | ||
94 | { 8, ST }, /* 01 0 0010: stdx */ | ||
95 | INVALID, /* 01 0 0011 */ | ||
96 | INVALID, /* 01 0 0100 */ | ||
97 | { 4, LD+SE }, /* 01 0 0101: lwax */ | ||
98 | INVALID, /* 01 0 0110 */ | ||
99 | INVALID, /* 01 0 0111 */ | ||
100 | { 4, LD+M+HARD+SX }, /* 01 0 1000: lswx */ | ||
101 | { 4, LD+M+HARD }, /* 01 0 1001: lswi */ | ||
102 | { 4, ST+M+HARD+SX }, /* 01 0 1010: stswx */ | ||
103 | { 4, ST+M+HARD }, /* 01 0 1011: stswi */ | ||
104 | INVALID, /* 01 0 1100 */ | ||
105 | { 8, LD+U }, /* 01 0 1101: ldu */ | ||
106 | INVALID, /* 01 0 1110 */ | ||
107 | { 8, ST+U }, /* 01 0 1111: stdu */ | ||
108 | { 8, LD+U }, /* 01 1 0000: ldux */ | ||
109 | INVALID, /* 01 1 0001 */ | ||
110 | { 8, ST+U }, /* 01 1 0010: stdux */ | ||
111 | INVALID, /* 01 1 0011 */ | ||
112 | INVALID, /* 01 1 0100 */ | ||
113 | { 4, LD+SE+U }, /* 01 1 0101: lwaux */ | ||
114 | INVALID, /* 01 1 0110 */ | ||
115 | INVALID, /* 01 1 0111 */ | ||
116 | INVALID, /* 01 1 1000 */ | ||
117 | INVALID, /* 01 1 1001 */ | ||
118 | INVALID, /* 01 1 1010 */ | ||
119 | INVALID, /* 01 1 1011 */ | ||
120 | INVALID, /* 01 1 1100 */ | ||
121 | INVALID, /* 01 1 1101 */ | ||
122 | INVALID, /* 01 1 1110 */ | ||
123 | INVALID, /* 01 1 1111 */ | ||
124 | INVALID, /* 10 0 0000 */ | ||
125 | INVALID, /* 10 0 0001 */ | ||
126 | INVALID, /* 10 0 0010: stwcx. */ | ||
127 | INVALID, /* 10 0 0011 */ | ||
128 | INVALID, /* 10 0 0100 */ | ||
129 | INVALID, /* 10 0 0101 */ | ||
130 | INVALID, /* 10 0 0110 */ | ||
131 | INVALID, /* 10 0 0111 */ | ||
132 | { 4, LD+SW }, /* 10 0 1000: lwbrx */ | ||
133 | INVALID, /* 10 0 1001 */ | ||
134 | { 4, ST+SW }, /* 10 0 1010: stwbrx */ | ||
135 | INVALID, /* 10 0 1011 */ | ||
136 | { 2, LD+SW }, /* 10 0 1100: lhbrx */ | ||
137 | { 4, LD+SE }, /* 10 0 1101 lwa */ | ||
138 | { 2, ST+SW }, /* 10 0 1110: sthbrx */ | ||
139 | INVALID, /* 10 0 1111 */ | ||
140 | INVALID, /* 10 1 0000 */ | ||
141 | INVALID, /* 10 1 0001 */ | ||
142 | INVALID, /* 10 1 0010 */ | ||
143 | INVALID, /* 10 1 0011 */ | ||
144 | INVALID, /* 10 1 0100 */ | ||
145 | INVALID, /* 10 1 0101 */ | ||
146 | INVALID, /* 10 1 0110 */ | ||
147 | INVALID, /* 10 1 0111 */ | ||
148 | INVALID, /* 10 1 1000 */ | ||
149 | INVALID, /* 10 1 1001 */ | ||
150 | INVALID, /* 10 1 1010 */ | ||
151 | INVALID, /* 10 1 1011 */ | ||
152 | INVALID, /* 10 1 1100 */ | ||
153 | INVALID, /* 10 1 1101 */ | ||
154 | INVALID, /* 10 1 1110 */ | ||
155 | { 0, ST+HARD }, /* 10 1 1111: dcbz */ | ||
156 | { 4, LD }, /* 11 0 0000: lwzx */ | ||
157 | INVALID, /* 11 0 0001 */ | ||
158 | { 4, ST }, /* 11 0 0010: stwx */ | ||
159 | INVALID, /* 11 0 0011 */ | ||
160 | { 2, LD }, /* 11 0 0100: lhzx */ | ||
161 | { 2, LD+SE }, /* 11 0 0101: lhax */ | ||
162 | { 2, ST }, /* 11 0 0110: sthx */ | ||
163 | INVALID, /* 11 0 0111 */ | ||
164 | { 4, LD+F+S }, /* 11 0 1000: lfsx */ | ||
165 | { 8, LD+F }, /* 11 0 1001: lfdx */ | ||
166 | { 4, ST+F+S }, /* 11 0 1010: stfsx */ | ||
167 | { 8, ST+F }, /* 11 0 1011: stfdx */ | ||
168 | INVALID, /* 11 0 1100 */ | ||
169 | { 8, LD+M }, /* 11 0 1101: lmd */ | ||
170 | INVALID, /* 11 0 1110 */ | ||
171 | { 8, ST+M }, /* 11 0 1111: stmd */ | ||
172 | { 4, LD+U }, /* 11 1 0000: lwzux */ | ||
173 | INVALID, /* 11 1 0001 */ | ||
174 | { 4, ST+U }, /* 11 1 0010: stwux */ | ||
175 | INVALID, /* 11 1 0011 */ | ||
176 | { 2, LD+U }, /* 11 1 0100: lhzux */ | ||
177 | { 2, LD+SE+U }, /* 11 1 0101: lhaux */ | ||
178 | { 2, ST+U }, /* 11 1 0110: sthux */ | ||
179 | INVALID, /* 11 1 0111 */ | ||
180 | { 4, LD+F+S+U }, /* 11 1 1000: lfsux */ | ||
181 | { 8, LD+F+U }, /* 11 1 1001: lfdux */ | ||
182 | { 4, ST+F+S+U }, /* 11 1 1010: stfsux */ | ||
183 | { 8, ST+F+U }, /* 11 1 1011: stfdux */ | ||
184 | INVALID, /* 11 1 1100 */ | ||
185 | INVALID, /* 11 1 1101 */ | ||
186 | INVALID, /* 11 1 1110 */ | ||
187 | INVALID, /* 11 1 1111 */ | ||
188 | }; | ||
189 | |||
190 | /* | ||
191 | * Create a DSISR value from the instruction | ||
192 | */ | ||
193 | static inline unsigned make_dsisr(unsigned instr) | ||
194 | { | ||
195 | unsigned dsisr; | ||
196 | |||
197 | |||
198 | /* bits 6:15 --> 22:31 */ | ||
199 | dsisr = (instr & 0x03ff0000) >> 16; | ||
200 | |||
201 | if (IS_XFORM(instr)) { | ||
202 | /* bits 29:30 --> 15:16 */ | ||
203 | dsisr |= (instr & 0x00000006) << 14; | ||
204 | /* bit 25 --> 17 */ | ||
205 | dsisr |= (instr & 0x00000040) << 8; | ||
206 | /* bits 21:24 --> 18:21 */ | ||
207 | dsisr |= (instr & 0x00000780) << 3; | ||
208 | } else { | ||
209 | /* bit 5 --> 17 */ | ||
210 | dsisr |= (instr & 0x04000000) >> 12; | ||
211 | /* bits 1: 4 --> 18:21 */ | ||
212 | dsisr |= (instr & 0x78000000) >> 17; | ||
213 | /* bits 30:31 --> 12:13 */ | ||
214 | if (IS_DSFORM(instr)) | ||
215 | dsisr |= (instr & 0x00000003) << 18; | ||
216 | } | ||
217 | |||
218 | return dsisr; | ||
219 | } | ||
220 | |||
221 | /* | ||
222 | * The dcbz (data cache block zero) instruction | ||
223 | * gives an alignment fault if used on non-cacheable | ||
224 | * memory. We handle the fault mainly for the | ||
225 | * case when we are running with the cache disabled | ||
226 | * for debugging. | ||
227 | */ | ||
228 | static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr) | ||
229 | { | ||
230 | long __user *p; | ||
231 | int i, size; | ||
232 | |||
233 | #ifdef __powerpc64__ | ||
234 | size = ppc64_caches.dline_size; | ||
235 | #else | ||
236 | size = L1_CACHE_BYTES; | ||
237 | #endif | ||
238 | p = (long __user *) (regs->dar & -size); | ||
239 | if (user_mode(regs) && !access_ok(VERIFY_WRITE, p, size)) | ||
240 | return -EFAULT; | ||
241 | for (i = 0; i < size / sizeof(long); ++i) | ||
242 | if (__put_user(0, p+i)) | ||
243 | return -EFAULT; | ||
244 | return 1; | ||
245 | } | ||
246 | |||
247 | /* | ||
248 | * Emulate load & store multiple instructions | ||
249 | * On 64-bit machines, these instructions only affect/use the | ||
250 | * bottom 4 bytes of each register, and the loads clear the | ||
251 | * top 4 bytes of the affected register. | ||
252 | */ | ||
253 | #ifdef CONFIG_PPC64 | ||
254 | #define REG_BYTE(rp, i) *((u8 *)((rp) + ((i) >> 2)) + ((i) & 3) + 4) | ||
255 | #else | ||
256 | #define REG_BYTE(rp, i) *((u8 *)(rp) + (i)) | ||
257 | #endif | ||
258 | |||
259 | static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, | ||
260 | unsigned int reg, unsigned int nb, | ||
261 | unsigned int flags, unsigned int instr) | ||
262 | { | ||
263 | unsigned long *rptr; | ||
264 | unsigned int nb0, i; | ||
265 | |||
266 | /* | ||
267 | * We do not try to emulate 8 bytes multiple as they aren't really | ||
268 | * available in our operating environments and we don't try to | ||
269 | * emulate multiples operations in kernel land as they should never | ||
270 | * be used/generated there at least not on unaligned boundaries | ||
271 | */ | ||
272 | if (unlikely((nb > 4) || !user_mode(regs))) | ||
273 | return 0; | ||
274 | |||
275 | /* lmw, stmw, lswi/x, stswi/x */ | ||
276 | nb0 = 0; | ||
277 | if (flags & HARD) { | ||
278 | if (flags & SX) { | ||
279 | nb = regs->xer & 127; | ||
280 | if (nb == 0) | ||
281 | return 1; | ||
282 | } else { | ||
283 | if (__get_user(instr, | ||
284 | (unsigned int __user *)regs->nip)) | ||
285 | return -EFAULT; | ||
286 | nb = (instr >> 11) & 0x1f; | ||
287 | if (nb == 0) | ||
288 | nb = 32; | ||
289 | } | ||
290 | if (nb + reg * 4 > 128) { | ||
291 | nb0 = nb + reg * 4 - 128; | ||
292 | nb = 128 - reg * 4; | ||
293 | } | ||
294 | } else { | ||
295 | /* lwm, stmw */ | ||
296 | nb = (32 - reg) * 4; | ||
297 | } | ||
298 | |||
299 | if (!access_ok((flags & ST ? VERIFY_WRITE: VERIFY_READ), addr, nb+nb0)) | ||
300 | return -EFAULT; /* bad address */ | ||
301 | |||
302 | rptr = ®s->gpr[reg]; | ||
303 | if (flags & LD) { | ||
304 | /* | ||
305 | * This zeroes the top 4 bytes of the affected registers | ||
306 | * in 64-bit mode, and also zeroes out any remaining | ||
307 | * bytes of the last register for lsw*. | ||
308 | */ | ||
309 | memset(rptr, 0, ((nb + 3) / 4) * sizeof(unsigned long)); | ||
310 | if (nb0 > 0) | ||
311 | memset(®s->gpr[0], 0, | ||
312 | ((nb0 + 3) / 4) * sizeof(unsigned long)); | ||
313 | |||
314 | for (i = 0; i < nb; ++i) | ||
315 | if (__get_user(REG_BYTE(rptr, i), addr + i)) | ||
316 | return -EFAULT; | ||
317 | if (nb0 > 0) { | ||
318 | rptr = ®s->gpr[0]; | ||
319 | addr += nb; | ||
320 | for (i = 0; i < nb0; ++i) | ||
321 | if (__get_user(REG_BYTE(rptr, i), addr + i)) | ||
322 | return -EFAULT; | ||
323 | } | ||
324 | |||
325 | } else { | ||
326 | for (i = 0; i < nb; ++i) | ||
327 | if (__put_user(REG_BYTE(rptr, i), addr + i)) | ||
328 | return -EFAULT; | ||
329 | if (nb0 > 0) { | ||
330 | rptr = ®s->gpr[0]; | ||
331 | addr += nb; | ||
332 | for (i = 0; i < nb0; ++i) | ||
333 | if (__put_user(REG_BYTE(rptr, i), addr + i)) | ||
334 | return -EFAULT; | ||
335 | } | ||
336 | } | ||
337 | return 1; | ||
338 | } | ||
339 | |||
340 | |||
341 | /* | ||
342 | * Called on alignment exception. Attempts to fixup | ||
343 | * | ||
344 | * Return 1 on success | ||
345 | * Return 0 if unable to handle the interrupt | ||
346 | * Return -EFAULT if data address is bad | ||
347 | */ | ||
348 | |||
349 | int fix_alignment(struct pt_regs *regs) | ||
350 | { | ||
351 | unsigned int instr, nb, flags; | ||
352 | unsigned int reg, areg; | ||
353 | unsigned int dsisr; | ||
354 | unsigned char __user *addr; | ||
355 | unsigned char __user *p; | ||
356 | int ret, t; | ||
357 | union { | ||
358 | u64 ll; | ||
359 | double dd; | ||
360 | unsigned char v[8]; | ||
361 | struct { | ||
362 | unsigned hi32; | ||
363 | int low32; | ||
364 | } x32; | ||
365 | struct { | ||
366 | unsigned char hi48[6]; | ||
367 | short low16; | ||
368 | } x16; | ||
369 | } data; | ||
370 | |||
371 | /* | ||
372 | * We require a complete register set, if not, then our assembly | ||
373 | * is broken | ||
374 | */ | ||
375 | CHECK_FULL_REGS(regs); | ||
376 | |||
377 | dsisr = regs->dsisr; | ||
378 | |||
379 | /* Some processors don't provide us with a DSISR we can use here, | ||
380 | * let's make one up from the instruction | ||
381 | */ | ||
382 | if (cpu_has_feature(CPU_FTR_NODSISRALIGN)) { | ||
383 | unsigned int real_instr; | ||
384 | if (unlikely(__get_user(real_instr, | ||
385 | (unsigned int __user *)regs->nip))) | ||
386 | return -EFAULT; | ||
387 | dsisr = make_dsisr(real_instr); | ||
388 | } | ||
389 | |||
390 | /* extract the operation and registers from the dsisr */ | ||
391 | reg = (dsisr >> 5) & 0x1f; /* source/dest register */ | ||
392 | areg = dsisr & 0x1f; /* register to update */ | ||
393 | instr = (dsisr >> 10) & 0x7f; | ||
394 | instr |= (dsisr >> 13) & 0x60; | ||
395 | |||
396 | /* Lookup the operation in our table */ | ||
397 | nb = aligninfo[instr].len; | ||
398 | flags = aligninfo[instr].flags; | ||
399 | |||
400 | /* DAR has the operand effective address */ | ||
401 | addr = (unsigned char __user *)regs->dar; | ||
402 | |||
403 | /* A size of 0 indicates an instruction we don't support, with | ||
404 | * the exception of DCBZ which is handled as a special case here | ||
405 | */ | ||
406 | if (instr == DCBZ) | ||
407 | return emulate_dcbz(regs, addr); | ||
408 | if (unlikely(nb == 0)) | ||
409 | return 0; | ||
410 | |||
411 | /* Load/Store Multiple instructions are handled in their own | ||
412 | * function | ||
413 | */ | ||
414 | if (flags & M) | ||
415 | return emulate_multiple(regs, addr, reg, nb, flags, instr); | ||
416 | |||
417 | /* Verify the address of the operand */ | ||
418 | if (unlikely(user_mode(regs) && | ||
419 | !access_ok((flags & ST ? VERIFY_WRITE : VERIFY_READ), | ||
420 | addr, nb))) | ||
421 | return -EFAULT; | ||
422 | |||
423 | /* Force the fprs into the save area so we can reference them */ | ||
424 | if (flags & F) { | ||
425 | /* userland only */ | ||
426 | if (unlikely(!user_mode(regs))) | ||
427 | return 0; | ||
428 | flush_fp_to_thread(current); | ||
429 | } | ||
430 | |||
431 | /* If we are loading, get the data from user space, else | ||
432 | * get it from register values | ||
433 | */ | ||
434 | if (flags & LD) { | ||
435 | data.ll = 0; | ||
436 | ret = 0; | ||
437 | p = addr; | ||
438 | switch (nb) { | ||
439 | case 8: | ||
440 | ret |= __get_user(data.v[0], p++); | ||
441 | ret |= __get_user(data.v[1], p++); | ||
442 | ret |= __get_user(data.v[2], p++); | ||
443 | ret |= __get_user(data.v[3], p++); | ||
444 | case 4: | ||
445 | ret |= __get_user(data.v[4], p++); | ||
446 | ret |= __get_user(data.v[5], p++); | ||
447 | case 2: | ||
448 | ret |= __get_user(data.v[6], p++); | ||
449 | ret |= __get_user(data.v[7], p++); | ||
450 | if (unlikely(ret)) | ||
451 | return -EFAULT; | ||
452 | } | ||
453 | } else if (flags & F) | ||
454 | data.dd = current->thread.fpr[reg]; | ||
455 | else | ||
456 | data.ll = regs->gpr[reg]; | ||
457 | |||
458 | /* Perform other misc operations like sign extension, byteswap, | ||
459 | * or floating point single precision conversion | ||
460 | */ | ||
461 | switch (flags & ~U) { | ||
462 | case LD+SE: /* sign extend */ | ||
463 | if ( nb == 2 ) | ||
464 | data.ll = data.x16.low16; | ||
465 | else /* nb must be 4 */ | ||
466 | data.ll = data.x32.low32; | ||
467 | break; | ||
468 | case LD+S: /* byte-swap */ | ||
469 | case ST+S: | ||
470 | if (nb == 2) { | ||
471 | SWAP(data.v[6], data.v[7]); | ||
472 | } else { | ||
473 | SWAP(data.v[4], data.v[7]); | ||
474 | SWAP(data.v[5], data.v[6]); | ||
475 | } | ||
476 | break; | ||
477 | |||
478 | /* Single-precision FP load and store require conversions... */ | ||
479 | case LD+F+S: | ||
480 | #ifdef CONFIG_PPC_FPU | ||
481 | preempt_disable(); | ||
482 | enable_kernel_fp(); | ||
483 | cvt_fd((float *)&data.v[4], &data.dd, ¤t->thread); | ||
484 | preempt_enable(); | ||
485 | #else | ||
486 | return 0; | ||
487 | #endif | ||
488 | break; | ||
489 | case ST+F+S: | ||
490 | #ifdef CONFIG_PPC_FPU | ||
491 | preempt_disable(); | ||
492 | enable_kernel_fp(); | ||
493 | cvt_df(&data.dd, (float *)&data.v[4], ¤t->thread); | ||
494 | preempt_enable(); | ||
495 | #else | ||
496 | return 0; | ||
497 | #endif | ||
498 | break; | ||
499 | } | ||
500 | |||
501 | /* Store result to memory or update registers */ | ||
502 | if (flags & ST) { | ||
503 | ret = 0; | ||
504 | p = addr; | ||
505 | switch (nb) { | ||
506 | case 8: | ||
507 | ret |= __put_user(data.v[0], p++); | ||
508 | ret |= __put_user(data.v[1], p++); | ||
509 | ret |= __put_user(data.v[2], p++); | ||
510 | ret |= __put_user(data.v[3], p++); | ||
511 | case 4: | ||
512 | ret |= __put_user(data.v[4], p++); | ||
513 | ret |= __put_user(data.v[5], p++); | ||
514 | case 2: | ||
515 | ret |= __put_user(data.v[6], p++); | ||
516 | ret |= __put_user(data.v[7], p++); | ||
517 | } | ||
518 | if (unlikely(ret)) | ||
519 | return -EFAULT; | ||
520 | } else if (flags & F) | ||
521 | current->thread.fpr[reg] = data.dd; | ||
522 | else | ||
523 | regs->gpr[reg] = data.ll; | ||
524 | |||
525 | /* Update RA as needed */ | ||
526 | if (flags & U) | ||
527 | regs->gpr[areg] = regs->dar; | ||
528 | |||
529 | return 1; | ||
530 | } | ||
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 4550eb4f4fbd..91538d2445bf 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -270,13 +270,15 @@ int main(void) | |||
270 | DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec)); | 270 | DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec)); |
271 | DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec)); | 271 | DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec)); |
272 | DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec)); | 272 | DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec)); |
273 | DEFINE(TSPC64_TV_SEC, offsetof(struct timespec, tv_sec)); | ||
274 | DEFINE(TSPC64_TV_NSEC, offsetof(struct timespec, tv_nsec)); | ||
273 | DEFINE(TSPC32_TV_SEC, offsetof(struct compat_timespec, tv_sec)); | 275 | DEFINE(TSPC32_TV_SEC, offsetof(struct compat_timespec, tv_sec)); |
274 | DEFINE(TSPC32_TV_NSEC, offsetof(struct compat_timespec, tv_nsec)); | 276 | DEFINE(TSPC32_TV_NSEC, offsetof(struct compat_timespec, tv_nsec)); |
275 | #else | 277 | #else |
276 | DEFINE(TVAL32_TV_SEC, offsetof(struct timeval, tv_sec)); | 278 | DEFINE(TVAL32_TV_SEC, offsetof(struct timeval, tv_sec)); |
277 | DEFINE(TVAL32_TV_USEC, offsetof(struct timeval, tv_usec)); | 279 | DEFINE(TVAL32_TV_USEC, offsetof(struct timeval, tv_usec)); |
278 | DEFINE(TSPEC32_TV_SEC, offsetof(struct timespec, tv_sec)); | 280 | DEFINE(TSPC32_TV_SEC, offsetof(struct timespec, tv_sec)); |
279 | DEFINE(TSPEC32_TV_NSEC, offsetof(struct timespec, tv_nsec)); | 281 | DEFINE(TSPC32_TV_NSEC, offsetof(struct timespec, tv_nsec)); |
280 | #endif | 282 | #endif |
281 | /* timeval/timezone offsets for use by vdso */ | 283 | /* timeval/timezone offsets for use by vdso */ |
282 | DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); | 284 | DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); |
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c new file mode 100644 index 000000000000..7c3419656ccc --- /dev/null +++ b/arch/powerpc/kernel/dma_64.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 IBM Corporation | ||
3 | * | ||
4 | * Implements the generic device dma API for ppc64. Handles | ||
5 | * the pci and vio busses | ||
6 | */ | ||
7 | |||
8 | #include <linux/device.h> | ||
9 | #include <linux/dma-mapping.h> | ||
10 | /* Include the busses we support */ | ||
11 | #include <linux/pci.h> | ||
12 | #include <asm/vio.h> | ||
13 | #include <asm/scatterlist.h> | ||
14 | #include <asm/bug.h> | ||
15 | |||
16 | static struct dma_mapping_ops *get_dma_ops(struct device *dev) | ||
17 | { | ||
18 | #ifdef CONFIG_PCI | ||
19 | if (dev->bus == &pci_bus_type) | ||
20 | return &pci_dma_ops; | ||
21 | #endif | ||
22 | #ifdef CONFIG_IBMVIO | ||
23 | if (dev->bus == &vio_bus_type) | ||
24 | return &vio_dma_ops; | ||
25 | #endif | ||
26 | return NULL; | ||
27 | } | ||
28 | |||
29 | int dma_supported(struct device *dev, u64 mask) | ||
30 | { | ||
31 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
32 | |||
33 | if (dma_ops) | ||
34 | return dma_ops->dma_supported(dev, mask); | ||
35 | BUG(); | ||
36 | return 0; | ||
37 | } | ||
38 | EXPORT_SYMBOL(dma_supported); | ||
39 | |||
40 | int dma_set_mask(struct device *dev, u64 dma_mask) | ||
41 | { | ||
42 | #ifdef CONFIG_PCI | ||
43 | if (dev->bus == &pci_bus_type) | ||
44 | return pci_set_dma_mask(to_pci_dev(dev), dma_mask); | ||
45 | #endif | ||
46 | #ifdef CONFIG_IBMVIO | ||
47 | if (dev->bus == &vio_bus_type) | ||
48 | return -EIO; | ||
49 | #endif /* CONFIG_IBMVIO */ | ||
50 | BUG(); | ||
51 | return 0; | ||
52 | } | ||
53 | EXPORT_SYMBOL(dma_set_mask); | ||
54 | |||
55 | void *dma_alloc_coherent(struct device *dev, size_t size, | ||
56 | dma_addr_t *dma_handle, gfp_t flag) | ||
57 | { | ||
58 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
59 | |||
60 | if (dma_ops) | ||
61 | return dma_ops->alloc_coherent(dev, size, dma_handle, flag); | ||
62 | BUG(); | ||
63 | return NULL; | ||
64 | } | ||
65 | EXPORT_SYMBOL(dma_alloc_coherent); | ||
66 | |||
67 | void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, | ||
68 | dma_addr_t dma_handle) | ||
69 | { | ||
70 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
71 | |||
72 | if (dma_ops) | ||
73 | dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); | ||
74 | else | ||
75 | BUG(); | ||
76 | } | ||
77 | EXPORT_SYMBOL(dma_free_coherent); | ||
78 | |||
79 | dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size, | ||
80 | enum dma_data_direction direction) | ||
81 | { | ||
82 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
83 | |||
84 | if (dma_ops) | ||
85 | return dma_ops->map_single(dev, cpu_addr, size, direction); | ||
86 | BUG(); | ||
87 | return (dma_addr_t)0; | ||
88 | } | ||
89 | EXPORT_SYMBOL(dma_map_single); | ||
90 | |||
91 | void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, | ||
92 | enum dma_data_direction direction) | ||
93 | { | ||
94 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
95 | |||
96 | if (dma_ops) | ||
97 | dma_ops->unmap_single(dev, dma_addr, size, direction); | ||
98 | else | ||
99 | BUG(); | ||
100 | } | ||
101 | EXPORT_SYMBOL(dma_unmap_single); | ||
102 | |||
103 | dma_addr_t dma_map_page(struct device *dev, struct page *page, | ||
104 | unsigned long offset, size_t size, | ||
105 | enum dma_data_direction direction) | ||
106 | { | ||
107 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
108 | |||
109 | if (dma_ops) | ||
110 | return dma_ops->map_single(dev, | ||
111 | (page_address(page) + offset), size, direction); | ||
112 | BUG(); | ||
113 | return (dma_addr_t)0; | ||
114 | } | ||
115 | EXPORT_SYMBOL(dma_map_page); | ||
116 | |||
117 | void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, | ||
118 | enum dma_data_direction direction) | ||
119 | { | ||
120 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
121 | |||
122 | if (dma_ops) | ||
123 | dma_ops->unmap_single(dev, dma_address, size, direction); | ||
124 | else | ||
125 | BUG(); | ||
126 | } | ||
127 | EXPORT_SYMBOL(dma_unmap_page); | ||
128 | |||
129 | int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | ||
130 | enum dma_data_direction direction) | ||
131 | { | ||
132 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
133 | |||
134 | if (dma_ops) | ||
135 | return dma_ops->map_sg(dev, sg, nents, direction); | ||
136 | BUG(); | ||
137 | return 0; | ||
138 | } | ||
139 | EXPORT_SYMBOL(dma_map_sg); | ||
140 | |||
141 | void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, | ||
142 | enum dma_data_direction direction) | ||
143 | { | ||
144 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
145 | |||
146 | if (dma_ops) | ||
147 | dma_ops->unmap_sg(dev, sg, nhwentries, direction); | ||
148 | else | ||
149 | BUG(); | ||
150 | } | ||
151 | EXPORT_SYMBOL(dma_unmap_sg); | ||
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 5063c603fad4..8d60fa99fc4b 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
@@ -24,7 +24,7 @@ | |||
24 | * Copyright 2002-2004 MontaVista Software, Inc. | 24 | * Copyright 2002-2004 MontaVista Software, Inc. |
25 | * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org> | 25 | * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org> |
26 | * Copyright 2004 Freescale Semiconductor, Inc | 26 | * Copyright 2004 Freescale Semiconductor, Inc |
27 | * PowerPC e500 modifications, Kumar Gala <kumar.gala@freescale.com> | 27 | * PowerPC e500 modifications, Kumar Gala <galak@kernel.crashing.org> |
28 | * | 28 | * |
29 | * This program is free software; you can redistribute it and/or modify it | 29 | * This program is free software; you can redistribute it and/or modify it |
30 | * under the terms of the GNU General Public License as published by the | 30 | * under the terms of the GNU General Public License as published by the |
diff --git a/arch/powerpc/kernel/idle_64.c b/arch/powerpc/kernel/idle_64.c new file mode 100644 index 000000000000..b879d3057ef8 --- /dev/null +++ b/arch/powerpc/kernel/idle_64.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * Idle daemon for PowerPC. Idle daemon will handle any action | ||
3 | * that needs to be taken when the system becomes idle. | ||
4 | * | ||
5 | * Originally Written by Cort Dougan (cort@cs.nmt.edu) | ||
6 | * | ||
7 | * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com> | ||
8 | * | ||
9 | * Additional shared processor, SMT, and firmware support | ||
10 | * Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version | ||
15 | * 2 of the License, or (at your option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/config.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/smp.h> | ||
22 | #include <linux/cpu.h> | ||
23 | #include <linux/sysctl.h> | ||
24 | |||
25 | #include <asm/system.h> | ||
26 | #include <asm/processor.h> | ||
27 | #include <asm/cputable.h> | ||
28 | #include <asm/time.h> | ||
29 | #include <asm/machdep.h> | ||
30 | #include <asm/smp.h> | ||
31 | |||
32 | extern void power4_idle(void); | ||
33 | |||
34 | void default_idle(void) | ||
35 | { | ||
36 | unsigned int cpu = smp_processor_id(); | ||
37 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
38 | |||
39 | while (1) { | ||
40 | if (!need_resched()) { | ||
41 | while (!need_resched() && !cpu_is_offline(cpu)) { | ||
42 | ppc64_runlatch_off(); | ||
43 | |||
44 | /* | ||
45 | * Go into low thread priority and possibly | ||
46 | * low power mode. | ||
47 | */ | ||
48 | HMT_low(); | ||
49 | HMT_very_low(); | ||
50 | } | ||
51 | |||
52 | HMT_medium(); | ||
53 | } | ||
54 | |||
55 | ppc64_runlatch_on(); | ||
56 | preempt_enable_no_resched(); | ||
57 | schedule(); | ||
58 | preempt_disable(); | ||
59 | if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) | ||
60 | cpu_die(); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | void native_idle(void) | ||
65 | { | ||
66 | while (1) { | ||
67 | ppc64_runlatch_off(); | ||
68 | |||
69 | if (!need_resched()) | ||
70 | power4_idle(); | ||
71 | |||
72 | if (need_resched()) { | ||
73 | ppc64_runlatch_on(); | ||
74 | preempt_enable_no_resched(); | ||
75 | schedule(); | ||
76 | preempt_disable(); | ||
77 | } | ||
78 | |||
79 | if (cpu_is_offline(smp_processor_id()) && | ||
80 | system_state == SYSTEM_RUNNING) | ||
81 | cpu_die(); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | void cpu_idle(void) | ||
86 | { | ||
87 | BUG_ON(NULL == ppc_md.idle_loop); | ||
88 | ppc_md.idle_loop(); | ||
89 | } | ||
90 | |||
91 | int powersave_nap; | ||
92 | |||
93 | #ifdef CONFIG_SYSCTL | ||
94 | /* | ||
95 | * Register the sysctl to set/clear powersave_nap. | ||
96 | */ | ||
97 | static ctl_table powersave_nap_ctl_table[]={ | ||
98 | { | ||
99 | .ctl_name = KERN_PPC_POWERSAVE_NAP, | ||
100 | .procname = "powersave-nap", | ||
101 | .data = &powersave_nap, | ||
102 | .maxlen = sizeof(int), | ||
103 | .mode = 0644, | ||
104 | .proc_handler = &proc_dointvec, | ||
105 | }, | ||
106 | { 0, }, | ||
107 | }; | ||
108 | static ctl_table powersave_nap_sysctl_root[] = { | ||
109 | { 1, "kernel", NULL, 0, 0755, powersave_nap_ctl_table, }, | ||
110 | { 0,}, | ||
111 | }; | ||
112 | |||
113 | static int __init | ||
114 | register_powersave_nap_sysctl(void) | ||
115 | { | ||
116 | register_sysctl_table(powersave_nap_sysctl_root, 0); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | __initcall(register_powersave_nap_sysctl); | ||
121 | #endif | ||
diff --git a/arch/powerpc/kernel/ioctl32.c b/arch/powerpc/kernel/ioctl32.c index 3fa6a93adbd0..0fa3d27fef01 100644 --- a/arch/powerpc/kernel/ioctl32.c +++ b/arch/powerpc/kernel/ioctl32.c | |||
@@ -40,10 +40,6 @@ IOCTL_TABLE_START | |||
40 | #define DECLARES | 40 | #define DECLARES |
41 | #include "compat_ioctl.c" | 41 | #include "compat_ioctl.c" |
42 | 42 | ||
43 | /* Little p (/dev/rtc, /dev/envctrl, etc.) */ | ||
44 | COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */ | ||
45 | COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */ | ||
46 | |||
47 | IOCTL_TABLE_END | 43 | IOCTL_TABLE_END |
48 | 44 | ||
49 | int ioctl_table_size = ARRAY_SIZE(ioctl_start); | 45 | int ioctl_table_size = ARRAY_SIZE(ioctl_start); |
diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c new file mode 100644 index 000000000000..6160c8dbb7c5 --- /dev/null +++ b/arch/powerpc/kernel/iomap.c | |||
@@ -0,0 +1,146 @@ | |||
1 | /* | ||
2 | * arch/ppc64/kernel/iomap.c | ||
3 | * | ||
4 | * ppc64 "iomap" interface implementation. | ||
5 | * | ||
6 | * (C) Copyright 2004 Linus Torvalds | ||
7 | */ | ||
8 | #include <linux/init.h> | ||
9 | #include <linux/pci.h> | ||
10 | #include <linux/mm.h> | ||
11 | #include <asm/io.h> | ||
12 | |||
13 | /* | ||
14 | * Here comes the ppc64 implementation of the IOMAP | ||
15 | * interfaces. | ||
16 | */ | ||
17 | unsigned int fastcall ioread8(void __iomem *addr) | ||
18 | { | ||
19 | return readb(addr); | ||
20 | } | ||
21 | unsigned int fastcall ioread16(void __iomem *addr) | ||
22 | { | ||
23 | return readw(addr); | ||
24 | } | ||
25 | unsigned int fastcall ioread16be(void __iomem *addr) | ||
26 | { | ||
27 | return in_be16(addr); | ||
28 | } | ||
29 | unsigned int fastcall ioread32(void __iomem *addr) | ||
30 | { | ||
31 | return readl(addr); | ||
32 | } | ||
33 | unsigned int fastcall ioread32be(void __iomem *addr) | ||
34 | { | ||
35 | return in_be32(addr); | ||
36 | } | ||
37 | EXPORT_SYMBOL(ioread8); | ||
38 | EXPORT_SYMBOL(ioread16); | ||
39 | EXPORT_SYMBOL(ioread16be); | ||
40 | EXPORT_SYMBOL(ioread32); | ||
41 | EXPORT_SYMBOL(ioread32be); | ||
42 | |||
43 | void fastcall iowrite8(u8 val, void __iomem *addr) | ||
44 | { | ||
45 | writeb(val, addr); | ||
46 | } | ||
47 | void fastcall iowrite16(u16 val, void __iomem *addr) | ||
48 | { | ||
49 | writew(val, addr); | ||
50 | } | ||
51 | void fastcall iowrite16be(u16 val, void __iomem *addr) | ||
52 | { | ||
53 | out_be16(addr, val); | ||
54 | } | ||
55 | void fastcall iowrite32(u32 val, void __iomem *addr) | ||
56 | { | ||
57 | writel(val, addr); | ||
58 | } | ||
59 | void fastcall iowrite32be(u32 val, void __iomem *addr) | ||
60 | { | ||
61 | out_be32(addr, val); | ||
62 | } | ||
63 | EXPORT_SYMBOL(iowrite8); | ||
64 | EXPORT_SYMBOL(iowrite16); | ||
65 | EXPORT_SYMBOL(iowrite16be); | ||
66 | EXPORT_SYMBOL(iowrite32); | ||
67 | EXPORT_SYMBOL(iowrite32be); | ||
68 | |||
69 | /* | ||
70 | * These are the "repeat read/write" functions. Note the | ||
71 | * non-CPU byte order. We do things in "IO byteorder" | ||
72 | * here. | ||
73 | * | ||
74 | * FIXME! We could make these do EEH handling if we really | ||
75 | * wanted. Not clear if we do. | ||
76 | */ | ||
77 | void ioread8_rep(void __iomem *addr, void *dst, unsigned long count) | ||
78 | { | ||
79 | _insb((u8 __iomem *) addr, dst, count); | ||
80 | } | ||
81 | void ioread16_rep(void __iomem *addr, void *dst, unsigned long count) | ||
82 | { | ||
83 | _insw_ns((u16 __iomem *) addr, dst, count); | ||
84 | } | ||
85 | void ioread32_rep(void __iomem *addr, void *dst, unsigned long count) | ||
86 | { | ||
87 | _insl_ns((u32 __iomem *) addr, dst, count); | ||
88 | } | ||
89 | EXPORT_SYMBOL(ioread8_rep); | ||
90 | EXPORT_SYMBOL(ioread16_rep); | ||
91 | EXPORT_SYMBOL(ioread32_rep); | ||
92 | |||
93 | void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count) | ||
94 | { | ||
95 | _outsb((u8 __iomem *) addr, src, count); | ||
96 | } | ||
97 | void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count) | ||
98 | { | ||
99 | _outsw_ns((u16 __iomem *) addr, src, count); | ||
100 | } | ||
101 | void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count) | ||
102 | { | ||
103 | _outsl_ns((u32 __iomem *) addr, src, count); | ||
104 | } | ||
105 | EXPORT_SYMBOL(iowrite8_rep); | ||
106 | EXPORT_SYMBOL(iowrite16_rep); | ||
107 | EXPORT_SYMBOL(iowrite32_rep); | ||
108 | |||
109 | void __iomem *ioport_map(unsigned long port, unsigned int len) | ||
110 | { | ||
111 | if (!_IO_IS_VALID(port)) | ||
112 | return NULL; | ||
113 | return (void __iomem *) (port+pci_io_base); | ||
114 | } | ||
115 | |||
116 | void ioport_unmap(void __iomem *addr) | ||
117 | { | ||
118 | /* Nothing to do */ | ||
119 | } | ||
120 | EXPORT_SYMBOL(ioport_map); | ||
121 | EXPORT_SYMBOL(ioport_unmap); | ||
122 | |||
123 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) | ||
124 | { | ||
125 | unsigned long start = pci_resource_start(dev, bar); | ||
126 | unsigned long len = pci_resource_len(dev, bar); | ||
127 | unsigned long flags = pci_resource_flags(dev, bar); | ||
128 | |||
129 | if (!len) | ||
130 | return NULL; | ||
131 | if (max && len > max) | ||
132 | len = max; | ||
133 | if (flags & IORESOURCE_IO) | ||
134 | return ioport_map(start, len); | ||
135 | if (flags & IORESOURCE_MEM) | ||
136 | return ioremap(start, len); | ||
137 | /* What? */ | ||
138 | return NULL; | ||
139 | } | ||
140 | |||
141 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr) | ||
142 | { | ||
143 | /* Nothing to do */ | ||
144 | } | ||
145 | EXPORT_SYMBOL(pci_iomap); | ||
146 | EXPORT_SYMBOL(pci_iounmap); | ||
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c new file mode 100644 index 000000000000..4d9b4388918b --- /dev/null +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -0,0 +1,572 @@ | |||
1 | /* | ||
2 | * arch/ppc64/kernel/iommu.c | ||
3 | * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation | ||
4 | * | ||
5 | * Rewrite, cleanup, new allocation schemes, virtual merging: | ||
6 | * Copyright (C) 2004 Olof Johansson, IBM Corporation | ||
7 | * and Ben. Herrenschmidt, IBM Corporation | ||
8 | * | ||
9 | * Dynamic DMA mapping support, bus-independent parts. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | |||
27 | #include <linux/config.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/types.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/mm.h> | ||
32 | #include <linux/spinlock.h> | ||
33 | #include <linux/string.h> | ||
34 | #include <linux/dma-mapping.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/bitops.h> | ||
37 | #include <asm/io.h> | ||
38 | #include <asm/prom.h> | ||
39 | #include <asm/iommu.h> | ||
40 | #include <asm/pci-bridge.h> | ||
41 | #include <asm/machdep.h> | ||
42 | |||
43 | #define DBG(...) | ||
44 | |||
45 | #ifdef CONFIG_IOMMU_VMERGE | ||
46 | static int novmerge = 0; | ||
47 | #else | ||
48 | static int novmerge = 1; | ||
49 | #endif | ||
50 | |||
51 | static int __init setup_iommu(char *str) | ||
52 | { | ||
53 | if (!strcmp(str, "novmerge")) | ||
54 | novmerge = 1; | ||
55 | else if (!strcmp(str, "vmerge")) | ||
56 | novmerge = 0; | ||
57 | return 1; | ||
58 | } | ||
59 | |||
60 | __setup("iommu=", setup_iommu); | ||
61 | |||
62 | static unsigned long iommu_range_alloc(struct iommu_table *tbl, | ||
63 | unsigned long npages, | ||
64 | unsigned long *handle, | ||
65 | unsigned int align_order) | ||
66 | { | ||
67 | unsigned long n, end, i, start; | ||
68 | unsigned long limit; | ||
69 | int largealloc = npages > 15; | ||
70 | int pass = 0; | ||
71 | unsigned long align_mask; | ||
72 | |||
73 | align_mask = 0xffffffffffffffffl >> (64 - align_order); | ||
74 | |||
75 | /* This allocator was derived from x86_64's bit string search */ | ||
76 | |||
77 | /* Sanity check */ | ||
78 | if (unlikely(npages) == 0) { | ||
79 | if (printk_ratelimit()) | ||
80 | WARN_ON(1); | ||
81 | return DMA_ERROR_CODE; | ||
82 | } | ||
83 | |||
84 | if (handle && *handle) | ||
85 | start = *handle; | ||
86 | else | ||
87 | start = largealloc ? tbl->it_largehint : tbl->it_hint; | ||
88 | |||
89 | /* Use only half of the table for small allocs (15 pages or less) */ | ||
90 | limit = largealloc ? tbl->it_size : tbl->it_halfpoint; | ||
91 | |||
92 | if (largealloc && start < tbl->it_halfpoint) | ||
93 | start = tbl->it_halfpoint; | ||
94 | |||
95 | /* The case below can happen if we have a small segment appended | ||
96 | * to a large, or when the previous alloc was at the very end of | ||
97 | * the available space. If so, go back to the initial start. | ||
98 | */ | ||
99 | if (start >= limit) | ||
100 | start = largealloc ? tbl->it_largehint : tbl->it_hint; | ||
101 | |||
102 | again: | ||
103 | |||
104 | n = find_next_zero_bit(tbl->it_map, limit, start); | ||
105 | |||
106 | /* Align allocation */ | ||
107 | n = (n + align_mask) & ~align_mask; | ||
108 | |||
109 | end = n + npages; | ||
110 | |||
111 | if (unlikely(end >= limit)) { | ||
112 | if (likely(pass < 2)) { | ||
113 | /* First failure, just rescan the half of the table. | ||
114 | * Second failure, rescan the other half of the table. | ||
115 | */ | ||
116 | start = (largealloc ^ pass) ? tbl->it_halfpoint : 0; | ||
117 | limit = pass ? tbl->it_size : limit; | ||
118 | pass++; | ||
119 | goto again; | ||
120 | } else { | ||
121 | /* Third failure, give up */ | ||
122 | return DMA_ERROR_CODE; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | for (i = n; i < end; i++) | ||
127 | if (test_bit(i, tbl->it_map)) { | ||
128 | start = i+1; | ||
129 | goto again; | ||
130 | } | ||
131 | |||
132 | for (i = n; i < end; i++) | ||
133 | __set_bit(i, tbl->it_map); | ||
134 | |||
135 | /* Bump the hint to a new block for small allocs. */ | ||
136 | if (largealloc) { | ||
137 | /* Don't bump to new block to avoid fragmentation */ | ||
138 | tbl->it_largehint = end; | ||
139 | } else { | ||
140 | /* Overflow will be taken care of at the next allocation */ | ||
141 | tbl->it_hint = (end + tbl->it_blocksize - 1) & | ||
142 | ~(tbl->it_blocksize - 1); | ||
143 | } | ||
144 | |||
145 | /* Update handle for SG allocations */ | ||
146 | if (handle) | ||
147 | *handle = end; | ||
148 | |||
149 | return n; | ||
150 | } | ||
151 | |||
152 | static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page, | ||
153 | unsigned int npages, enum dma_data_direction direction, | ||
154 | unsigned int align_order) | ||
155 | { | ||
156 | unsigned long entry, flags; | ||
157 | dma_addr_t ret = DMA_ERROR_CODE; | ||
158 | |||
159 | spin_lock_irqsave(&(tbl->it_lock), flags); | ||
160 | |||
161 | entry = iommu_range_alloc(tbl, npages, NULL, align_order); | ||
162 | |||
163 | if (unlikely(entry == DMA_ERROR_CODE)) { | ||
164 | spin_unlock_irqrestore(&(tbl->it_lock), flags); | ||
165 | return DMA_ERROR_CODE; | ||
166 | } | ||
167 | |||
168 | entry += tbl->it_offset; /* Offset into real TCE table */ | ||
169 | ret = entry << PAGE_SHIFT; /* Set the return dma address */ | ||
170 | |||
171 | /* Put the TCEs in the HW table */ | ||
172 | ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & PAGE_MASK, | ||
173 | direction); | ||
174 | |||
175 | |||
176 | /* Flush/invalidate TLB caches if necessary */ | ||
177 | if (ppc_md.tce_flush) | ||
178 | ppc_md.tce_flush(tbl); | ||
179 | |||
180 | spin_unlock_irqrestore(&(tbl->it_lock), flags); | ||
181 | |||
182 | /* Make sure updates are seen by hardware */ | ||
183 | mb(); | ||
184 | |||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, | ||
189 | unsigned int npages) | ||
190 | { | ||
191 | unsigned long entry, free_entry; | ||
192 | unsigned long i; | ||
193 | |||
194 | entry = dma_addr >> PAGE_SHIFT; | ||
195 | free_entry = entry - tbl->it_offset; | ||
196 | |||
197 | if (((free_entry + npages) > tbl->it_size) || | ||
198 | (entry < tbl->it_offset)) { | ||
199 | if (printk_ratelimit()) { | ||
200 | printk(KERN_INFO "iommu_free: invalid entry\n"); | ||
201 | printk(KERN_INFO "\tentry = 0x%lx\n", entry); | ||
202 | printk(KERN_INFO "\tdma_addr = 0x%lx\n", (u64)dma_addr); | ||
203 | printk(KERN_INFO "\tTable = 0x%lx\n", (u64)tbl); | ||
204 | printk(KERN_INFO "\tbus# = 0x%lx\n", (u64)tbl->it_busno); | ||
205 | printk(KERN_INFO "\tsize = 0x%lx\n", (u64)tbl->it_size); | ||
206 | printk(KERN_INFO "\tstartOff = 0x%lx\n", (u64)tbl->it_offset); | ||
207 | printk(KERN_INFO "\tindex = 0x%lx\n", (u64)tbl->it_index); | ||
208 | WARN_ON(1); | ||
209 | } | ||
210 | return; | ||
211 | } | ||
212 | |||
213 | ppc_md.tce_free(tbl, entry, npages); | ||
214 | |||
215 | for (i = 0; i < npages; i++) | ||
216 | __clear_bit(free_entry+i, tbl->it_map); | ||
217 | } | ||
218 | |||
219 | static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, | ||
220 | unsigned int npages) | ||
221 | { | ||
222 | unsigned long flags; | ||
223 | |||
224 | spin_lock_irqsave(&(tbl->it_lock), flags); | ||
225 | |||
226 | __iommu_free(tbl, dma_addr, npages); | ||
227 | |||
228 | /* Make sure TLB cache is flushed if the HW needs it. We do | ||
229 | * not do an mb() here on purpose, it is not needed on any of | ||
230 | * the current platforms. | ||
231 | */ | ||
232 | if (ppc_md.tce_flush) | ||
233 | ppc_md.tce_flush(tbl); | ||
234 | |||
235 | spin_unlock_irqrestore(&(tbl->it_lock), flags); | ||
236 | } | ||
237 | |||
238 | int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | ||
239 | struct scatterlist *sglist, int nelems, | ||
240 | enum dma_data_direction direction) | ||
241 | { | ||
242 | dma_addr_t dma_next = 0, dma_addr; | ||
243 | unsigned long flags; | ||
244 | struct scatterlist *s, *outs, *segstart; | ||
245 | int outcount, incount; | ||
246 | unsigned long handle; | ||
247 | |||
248 | BUG_ON(direction == DMA_NONE); | ||
249 | |||
250 | if ((nelems == 0) || !tbl) | ||
251 | return 0; | ||
252 | |||
253 | outs = s = segstart = &sglist[0]; | ||
254 | outcount = 1; | ||
255 | incount = nelems; | ||
256 | handle = 0; | ||
257 | |||
258 | /* Init first segment length for backout at failure */ | ||
259 | outs->dma_length = 0; | ||
260 | |||
261 | DBG("mapping %d elements:\n", nelems); | ||
262 | |||
263 | spin_lock_irqsave(&(tbl->it_lock), flags); | ||
264 | |||
265 | for (s = outs; nelems; nelems--, s++) { | ||
266 | unsigned long vaddr, npages, entry, slen; | ||
267 | |||
268 | slen = s->length; | ||
269 | /* Sanity check */ | ||
270 | if (slen == 0) { | ||
271 | dma_next = 0; | ||
272 | continue; | ||
273 | } | ||
274 | /* Allocate iommu entries for that segment */ | ||
275 | vaddr = (unsigned long)page_address(s->page) + s->offset; | ||
276 | npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK); | ||
277 | npages >>= PAGE_SHIFT; | ||
278 | entry = iommu_range_alloc(tbl, npages, &handle, 0); | ||
279 | |||
280 | DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); | ||
281 | |||
282 | /* Handle failure */ | ||
283 | if (unlikely(entry == DMA_ERROR_CODE)) { | ||
284 | if (printk_ratelimit()) | ||
285 | printk(KERN_INFO "iommu_alloc failed, tbl %p vaddr %lx" | ||
286 | " npages %lx\n", tbl, vaddr, npages); | ||
287 | goto failure; | ||
288 | } | ||
289 | |||
290 | /* Convert entry to a dma_addr_t */ | ||
291 | entry += tbl->it_offset; | ||
292 | dma_addr = entry << PAGE_SHIFT; | ||
293 | dma_addr |= s->offset; | ||
294 | |||
295 | DBG(" - %lx pages, entry: %lx, dma_addr: %lx\n", | ||
296 | npages, entry, dma_addr); | ||
297 | |||
298 | /* Insert into HW table */ | ||
299 | ppc_md.tce_build(tbl, entry, npages, vaddr & PAGE_MASK, direction); | ||
300 | |||
301 | /* If we are in an open segment, try merging */ | ||
302 | if (segstart != s) { | ||
303 | DBG(" - trying merge...\n"); | ||
304 | /* We cannot merge if: | ||
305 | * - allocated dma_addr isn't contiguous to previous allocation | ||
306 | */ | ||
307 | if (novmerge || (dma_addr != dma_next)) { | ||
308 | /* Can't merge: create a new segment */ | ||
309 | segstart = s; | ||
310 | outcount++; outs++; | ||
311 | DBG(" can't merge, new segment.\n"); | ||
312 | } else { | ||
313 | outs->dma_length += s->length; | ||
314 | DBG(" merged, new len: %lx\n", outs->dma_length); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | if (segstart == s) { | ||
319 | /* This is a new segment, fill entries */ | ||
320 | DBG(" - filling new segment.\n"); | ||
321 | outs->dma_address = dma_addr; | ||
322 | outs->dma_length = slen; | ||
323 | } | ||
324 | |||
325 | /* Calculate next page pointer for contiguous check */ | ||
326 | dma_next = dma_addr + slen; | ||
327 | |||
328 | DBG(" - dma next is: %lx\n", dma_next); | ||
329 | } | ||
330 | |||
331 | /* Flush/invalidate TLB caches if necessary */ | ||
332 | if (ppc_md.tce_flush) | ||
333 | ppc_md.tce_flush(tbl); | ||
334 | |||
335 | spin_unlock_irqrestore(&(tbl->it_lock), flags); | ||
336 | |||
337 | /* Make sure updates are seen by hardware */ | ||
338 | mb(); | ||
339 | |||
340 | DBG("mapped %d elements:\n", outcount); | ||
341 | |||
342 | /* For the sake of iommu_unmap_sg, we clear out the length in the | ||
343 | * next entry of the sglist if we didn't fill the list completely | ||
344 | */ | ||
345 | if (outcount < incount) { | ||
346 | outs++; | ||
347 | outs->dma_address = DMA_ERROR_CODE; | ||
348 | outs->dma_length = 0; | ||
349 | } | ||
350 | return outcount; | ||
351 | |||
352 | failure: | ||
353 | for (s = &sglist[0]; s <= outs; s++) { | ||
354 | if (s->dma_length != 0) { | ||
355 | unsigned long vaddr, npages; | ||
356 | |||
357 | vaddr = s->dma_address & PAGE_MASK; | ||
358 | npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr) | ||
359 | >> PAGE_SHIFT; | ||
360 | __iommu_free(tbl, vaddr, npages); | ||
361 | } | ||
362 | } | ||
363 | spin_unlock_irqrestore(&(tbl->it_lock), flags); | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | |||
368 | void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, | ||
369 | int nelems, enum dma_data_direction direction) | ||
370 | { | ||
371 | unsigned long flags; | ||
372 | |||
373 | BUG_ON(direction == DMA_NONE); | ||
374 | |||
375 | if (!tbl) | ||
376 | return; | ||
377 | |||
378 | spin_lock_irqsave(&(tbl->it_lock), flags); | ||
379 | |||
380 | while (nelems--) { | ||
381 | unsigned int npages; | ||
382 | dma_addr_t dma_handle = sglist->dma_address; | ||
383 | |||
384 | if (sglist->dma_length == 0) | ||
385 | break; | ||
386 | npages = (PAGE_ALIGN(dma_handle + sglist->dma_length) | ||
387 | - (dma_handle & PAGE_MASK)) >> PAGE_SHIFT; | ||
388 | __iommu_free(tbl, dma_handle, npages); | ||
389 | sglist++; | ||
390 | } | ||
391 | |||
392 | /* Flush/invalidate TLBs if necessary. As for iommu_free(), we | ||
393 | * do not do an mb() here, the affected platforms do not need it | ||
394 | * when freeing. | ||
395 | */ | ||
396 | if (ppc_md.tce_flush) | ||
397 | ppc_md.tce_flush(tbl); | ||
398 | |||
399 | spin_unlock_irqrestore(&(tbl->it_lock), flags); | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | * Build a iommu_table structure. This contains a bit map which | ||
404 | * is used to manage allocation of the tce space. | ||
405 | */ | ||
406 | struct iommu_table *iommu_init_table(struct iommu_table *tbl) | ||
407 | { | ||
408 | unsigned long sz; | ||
409 | static int welcomed = 0; | ||
410 | |||
411 | /* Set aside 1/4 of the table for large allocations. */ | ||
412 | tbl->it_halfpoint = tbl->it_size * 3 / 4; | ||
413 | |||
414 | /* number of bytes needed for the bitmap */ | ||
415 | sz = (tbl->it_size + 7) >> 3; | ||
416 | |||
417 | tbl->it_map = (unsigned long *)__get_free_pages(GFP_ATOMIC, get_order(sz)); | ||
418 | if (!tbl->it_map) | ||
419 | panic("iommu_init_table: Can't allocate %ld bytes\n", sz); | ||
420 | |||
421 | memset(tbl->it_map, 0, sz); | ||
422 | |||
423 | tbl->it_hint = 0; | ||
424 | tbl->it_largehint = tbl->it_halfpoint; | ||
425 | spin_lock_init(&tbl->it_lock); | ||
426 | |||
427 | /* Clear the hardware table in case firmware left allocations in it */ | ||
428 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); | ||
429 | |||
430 | if (!welcomed) { | ||
431 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", | ||
432 | novmerge ? "disabled" : "enabled"); | ||
433 | welcomed = 1; | ||
434 | } | ||
435 | |||
436 | return tbl; | ||
437 | } | ||
438 | |||
439 | void iommu_free_table(struct device_node *dn) | ||
440 | { | ||
441 | struct pci_dn *pdn = dn->data; | ||
442 | struct iommu_table *tbl = pdn->iommu_table; | ||
443 | unsigned long bitmap_sz, i; | ||
444 | unsigned int order; | ||
445 | |||
446 | if (!tbl || !tbl->it_map) { | ||
447 | printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__, | ||
448 | dn->full_name); | ||
449 | return; | ||
450 | } | ||
451 | |||
452 | /* verify that table contains no entries */ | ||
453 | /* it_size is in entries, and we're examining 64 at a time */ | ||
454 | for (i = 0; i < (tbl->it_size/64); i++) { | ||
455 | if (tbl->it_map[i] != 0) { | ||
456 | printk(KERN_WARNING "%s: Unexpected TCEs for %s\n", | ||
457 | __FUNCTION__, dn->full_name); | ||
458 | break; | ||
459 | } | ||
460 | } | ||
461 | |||
462 | /* calculate bitmap size in bytes */ | ||
463 | bitmap_sz = (tbl->it_size + 7) / 8; | ||
464 | |||
465 | /* free bitmap */ | ||
466 | order = get_order(bitmap_sz); | ||
467 | free_pages((unsigned long) tbl->it_map, order); | ||
468 | |||
469 | /* free table */ | ||
470 | kfree(tbl); | ||
471 | } | ||
472 | |||
473 | /* Creates TCEs for a user provided buffer. The user buffer must be | ||
474 | * contiguous real kernel storage (not vmalloc). The address of the buffer | ||
475 | * passed here is the kernel (virtual) address of the buffer. The buffer | ||
476 | * need not be page aligned, the dma_addr_t returned will point to the same | ||
477 | * byte within the page as vaddr. | ||
478 | */ | ||
479 | dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, | ||
480 | size_t size, enum dma_data_direction direction) | ||
481 | { | ||
482 | dma_addr_t dma_handle = DMA_ERROR_CODE; | ||
483 | unsigned long uaddr; | ||
484 | unsigned int npages; | ||
485 | |||
486 | BUG_ON(direction == DMA_NONE); | ||
487 | |||
488 | uaddr = (unsigned long)vaddr; | ||
489 | npages = PAGE_ALIGN(uaddr + size) - (uaddr & PAGE_MASK); | ||
490 | npages >>= PAGE_SHIFT; | ||
491 | |||
492 | if (tbl) { | ||
493 | dma_handle = iommu_alloc(tbl, vaddr, npages, direction, 0); | ||
494 | if (dma_handle == DMA_ERROR_CODE) { | ||
495 | if (printk_ratelimit()) { | ||
496 | printk(KERN_INFO "iommu_alloc failed, " | ||
497 | "tbl %p vaddr %p npages %d\n", | ||
498 | tbl, vaddr, npages); | ||
499 | } | ||
500 | } else | ||
501 | dma_handle |= (uaddr & ~PAGE_MASK); | ||
502 | } | ||
503 | |||
504 | return dma_handle; | ||
505 | } | ||
506 | |||
507 | void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, | ||
508 | size_t size, enum dma_data_direction direction) | ||
509 | { | ||
510 | BUG_ON(direction == DMA_NONE); | ||
511 | |||
512 | if (tbl) | ||
513 | iommu_free(tbl, dma_handle, (PAGE_ALIGN(dma_handle + size) - | ||
514 | (dma_handle & PAGE_MASK)) >> PAGE_SHIFT); | ||
515 | } | ||
516 | |||
517 | /* Allocates a contiguous real buffer and creates mappings over it. | ||
518 | * Returns the virtual address of the buffer and sets dma_handle | ||
519 | * to the dma address (mapping) of the first page. | ||
520 | */ | ||
521 | void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, | ||
522 | dma_addr_t *dma_handle, gfp_t flag) | ||
523 | { | ||
524 | void *ret = NULL; | ||
525 | dma_addr_t mapping; | ||
526 | unsigned int npages, order; | ||
527 | |||
528 | size = PAGE_ALIGN(size); | ||
529 | npages = size >> PAGE_SHIFT; | ||
530 | order = get_order(size); | ||
531 | |||
532 | /* | ||
533 | * Client asked for way too much space. This is checked later | ||
534 | * anyway. It is easier to debug here for the drivers than in | ||
535 | * the tce tables. | ||
536 | */ | ||
537 | if (order >= IOMAP_MAX_ORDER) { | ||
538 | printk("iommu_alloc_consistent size too large: 0x%lx\n", size); | ||
539 | return NULL; | ||
540 | } | ||
541 | |||
542 | if (!tbl) | ||
543 | return NULL; | ||
544 | |||
545 | /* Alloc enough pages (and possibly more) */ | ||
546 | ret = (void *)__get_free_pages(flag, order); | ||
547 | if (!ret) | ||
548 | return NULL; | ||
549 | memset(ret, 0, size); | ||
550 | |||
551 | /* Set up tces to cover the allocated range */ | ||
552 | mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL, order); | ||
553 | if (mapping == DMA_ERROR_CODE) { | ||
554 | free_pages((unsigned long)ret, order); | ||
555 | ret = NULL; | ||
556 | } else | ||
557 | *dma_handle = mapping; | ||
558 | return ret; | ||
559 | } | ||
560 | |||
561 | void iommu_free_coherent(struct iommu_table *tbl, size_t size, | ||
562 | void *vaddr, dma_addr_t dma_handle) | ||
563 | { | ||
564 | unsigned int npages; | ||
565 | |||
566 | if (tbl) { | ||
567 | size = PAGE_ALIGN(size); | ||
568 | npages = size >> PAGE_SHIFT; | ||
569 | iommu_free(tbl, dma_handle, npages); | ||
570 | free_pages((unsigned long)vaddr, get_order(size)); | ||
571 | } | ||
572 | } | ||
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 4b7940693f3d..5a71ed9612fe 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -71,6 +71,11 @@ | |||
71 | #include <asm/paca.h> | 71 | #include <asm/paca.h> |
72 | #endif | 72 | #endif |
73 | 73 | ||
74 | int __irq_offset_value; | ||
75 | #ifdef CONFIG_PPC32 | ||
76 | EXPORT_SYMBOL(__irq_offset_value); | ||
77 | #endif | ||
78 | |||
74 | static int ppc_spurious_interrupts; | 79 | static int ppc_spurious_interrupts; |
75 | 80 | ||
76 | #if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP) | 81 | #if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP) |
@@ -98,7 +103,6 @@ extern atomic_t ipi_sent; | |||
98 | EXPORT_SYMBOL(irq_desc); | 103 | EXPORT_SYMBOL(irq_desc); |
99 | 104 | ||
100 | int distribute_irqs = 1; | 105 | int distribute_irqs = 1; |
101 | int __irq_offset_value; | ||
102 | u64 ppc64_interrupt_controller; | 106 | u64 ppc64_interrupt_controller; |
103 | #endif /* CONFIG_PPC64 */ | 107 | #endif /* CONFIG_PPC64 */ |
104 | 108 | ||
@@ -311,7 +315,6 @@ void __init init_IRQ(void) | |||
311 | } | 315 | } |
312 | 316 | ||
313 | #ifdef CONFIG_PPC64 | 317 | #ifdef CONFIG_PPC64 |
314 | #ifndef CONFIG_PPC_ISERIES | ||
315 | /* | 318 | /* |
316 | * Virtual IRQ mapping code, used on systems with XICS interrupt controllers. | 319 | * Virtual IRQ mapping code, used on systems with XICS interrupt controllers. |
317 | */ | 320 | */ |
@@ -420,8 +423,6 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) | |||
420 | 423 | ||
421 | } | 424 | } |
422 | 425 | ||
423 | #endif /* CONFIG_PPC_ISERIES */ | ||
424 | |||
425 | #ifdef CONFIG_IRQSTACKS | 426 | #ifdef CONFIG_IRQSTACKS |
426 | struct thread_info *softirq_ctx[NR_CPUS]; | 427 | struct thread_info *softirq_ctx[NR_CPUS]; |
427 | struct thread_info *hardirq_ctx[NR_CPUS]; | 428 | struct thread_info *hardirq_ctx[NR_CPUS]; |
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c new file mode 100644 index 000000000000..511af54e6230 --- /dev/null +++ b/arch/powerpc/kernel/kprobes.c | |||
@@ -0,0 +1,459 @@ | |||
1 | /* | ||
2 | * Kernel Probes (KProbes) | ||
3 | * arch/ppc64/kernel/kprobes.c | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | * | ||
19 | * Copyright (C) IBM Corporation, 2002, 2004 | ||
20 | * | ||
21 | * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel | ||
22 | * Probes initial implementation ( includes contributions from | ||
23 | * Rusty Russell). | ||
24 | * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes | ||
25 | * interface to access function arguments. | ||
26 | * 2004-Nov Ananth N Mavinakayanahalli <ananth@in.ibm.com> kprobes port | ||
27 | * for PPC64 | ||
28 | */ | ||
29 | |||
30 | #include <linux/config.h> | ||
31 | #include <linux/kprobes.h> | ||
32 | #include <linux/ptrace.h> | ||
33 | #include <linux/preempt.h> | ||
34 | #include <asm/cacheflush.h> | ||
35 | #include <asm/kdebug.h> | ||
36 | #include <asm/sstep.h> | ||
37 | |||
38 | static DECLARE_MUTEX(kprobe_mutex); | ||
39 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; | ||
40 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | ||
41 | |||
42 | int __kprobes arch_prepare_kprobe(struct kprobe *p) | ||
43 | { | ||
44 | int ret = 0; | ||
45 | kprobe_opcode_t insn = *p->addr; | ||
46 | |||
47 | if ((unsigned long)p->addr & 0x03) { | ||
48 | printk("Attempt to register kprobe at an unaligned address\n"); | ||
49 | ret = -EINVAL; | ||
50 | } else if (IS_MTMSRD(insn) || IS_RFID(insn)) { | ||
51 | printk("Cannot register a kprobe on rfid or mtmsrd\n"); | ||
52 | ret = -EINVAL; | ||
53 | } | ||
54 | |||
55 | /* insn must be on a special executable page on ppc64 */ | ||
56 | if (!ret) { | ||
57 | down(&kprobe_mutex); | ||
58 | p->ainsn.insn = get_insn_slot(); | ||
59 | up(&kprobe_mutex); | ||
60 | if (!p->ainsn.insn) | ||
61 | ret = -ENOMEM; | ||
62 | } | ||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | void __kprobes arch_copy_kprobe(struct kprobe *p) | ||
67 | { | ||
68 | memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | ||
69 | p->opcode = *p->addr; | ||
70 | } | ||
71 | |||
72 | void __kprobes arch_arm_kprobe(struct kprobe *p) | ||
73 | { | ||
74 | *p->addr = BREAKPOINT_INSTRUCTION; | ||
75 | flush_icache_range((unsigned long) p->addr, | ||
76 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | ||
77 | } | ||
78 | |||
79 | void __kprobes arch_disarm_kprobe(struct kprobe *p) | ||
80 | { | ||
81 | *p->addr = p->opcode; | ||
82 | flush_icache_range((unsigned long) p->addr, | ||
83 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | ||
84 | } | ||
85 | |||
86 | void __kprobes arch_remove_kprobe(struct kprobe *p) | ||
87 | { | ||
88 | down(&kprobe_mutex); | ||
89 | free_insn_slot(p->ainsn.insn); | ||
90 | up(&kprobe_mutex); | ||
91 | } | ||
92 | |||
93 | static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | ||
94 | { | ||
95 | kprobe_opcode_t insn = *p->ainsn.insn; | ||
96 | |||
97 | regs->msr |= MSR_SE; | ||
98 | |||
99 | /* single step inline if it is a trap variant */ | ||
100 | if (is_trap(insn)) | ||
101 | regs->nip = (unsigned long)p->addr; | ||
102 | else | ||
103 | regs->nip = (unsigned long)p->ainsn.insn; | ||
104 | } | ||
105 | |||
106 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | ||
107 | { | ||
108 | kcb->prev_kprobe.kp = kprobe_running(); | ||
109 | kcb->prev_kprobe.status = kcb->kprobe_status; | ||
110 | kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr; | ||
111 | } | ||
112 | |||
113 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | ||
114 | { | ||
115 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | ||
116 | kcb->kprobe_status = kcb->prev_kprobe.status; | ||
117 | kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr; | ||
118 | } | ||
119 | |||
120 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | ||
121 | struct kprobe_ctlblk *kcb) | ||
122 | { | ||
123 | __get_cpu_var(current_kprobe) = p; | ||
124 | kcb->kprobe_saved_msr = regs->msr; | ||
125 | } | ||
126 | |||
127 | /* Called with kretprobe_lock held */ | ||
128 | void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, | ||
129 | struct pt_regs *regs) | ||
130 | { | ||
131 | struct kretprobe_instance *ri; | ||
132 | |||
133 | if ((ri = get_free_rp_inst(rp)) != NULL) { | ||
134 | ri->rp = rp; | ||
135 | ri->task = current; | ||
136 | ri->ret_addr = (kprobe_opcode_t *)regs->link; | ||
137 | |||
138 | /* Replace the return addr with trampoline addr */ | ||
139 | regs->link = (unsigned long)kretprobe_trampoline; | ||
140 | add_rp_inst(ri); | ||
141 | } else { | ||
142 | rp->nmissed++; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | static inline int kprobe_handler(struct pt_regs *regs) | ||
147 | { | ||
148 | struct kprobe *p; | ||
149 | int ret = 0; | ||
150 | unsigned int *addr = (unsigned int *)regs->nip; | ||
151 | struct kprobe_ctlblk *kcb; | ||
152 | |||
153 | /* | ||
154 | * We don't want to be preempted for the entire | ||
155 | * duration of kprobe processing | ||
156 | */ | ||
157 | preempt_disable(); | ||
158 | kcb = get_kprobe_ctlblk(); | ||
159 | |||
160 | /* Check we're not actually recursing */ | ||
161 | if (kprobe_running()) { | ||
162 | p = get_kprobe(addr); | ||
163 | if (p) { | ||
164 | kprobe_opcode_t insn = *p->ainsn.insn; | ||
165 | if (kcb->kprobe_status == KPROBE_HIT_SS && | ||
166 | is_trap(insn)) { | ||
167 | regs->msr &= ~MSR_SE; | ||
168 | regs->msr |= kcb->kprobe_saved_msr; | ||
169 | goto no_kprobe; | ||
170 | } | ||
171 | /* We have reentered the kprobe_handler(), since | ||
172 | * another probe was hit while within the handler. | ||
173 | * We here save the original kprobes variables and | ||
174 | * just single step on the instruction of the new probe | ||
175 | * without calling any user handlers. | ||
176 | */ | ||
177 | save_previous_kprobe(kcb); | ||
178 | set_current_kprobe(p, regs, kcb); | ||
179 | kcb->kprobe_saved_msr = regs->msr; | ||
180 | p->nmissed++; | ||
181 | prepare_singlestep(p, regs); | ||
182 | kcb->kprobe_status = KPROBE_REENTER; | ||
183 | return 1; | ||
184 | } else { | ||
185 | p = __get_cpu_var(current_kprobe); | ||
186 | if (p->break_handler && p->break_handler(p, regs)) { | ||
187 | goto ss_probe; | ||
188 | } | ||
189 | } | ||
190 | goto no_kprobe; | ||
191 | } | ||
192 | |||
193 | p = get_kprobe(addr); | ||
194 | if (!p) { | ||
195 | if (*addr != BREAKPOINT_INSTRUCTION) { | ||
196 | /* | ||
197 | * PowerPC has multiple variants of the "trap" | ||
198 | * instruction. If the current instruction is a | ||
199 | * trap variant, it could belong to someone else | ||
200 | */ | ||
201 | kprobe_opcode_t cur_insn = *addr; | ||
202 | if (is_trap(cur_insn)) | ||
203 | goto no_kprobe; | ||
204 | /* | ||
205 | * The breakpoint instruction was removed right | ||
206 | * after we hit it. Another cpu has removed | ||
207 | * either a probepoint or a debugger breakpoint | ||
208 | * at this address. In either case, no further | ||
209 | * handling of this interrupt is appropriate. | ||
210 | */ | ||
211 | ret = 1; | ||
212 | } | ||
213 | /* Not one of ours: let kernel handle it */ | ||
214 | goto no_kprobe; | ||
215 | } | ||
216 | |||
217 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; | ||
218 | set_current_kprobe(p, regs, kcb); | ||
219 | if (p->pre_handler && p->pre_handler(p, regs)) | ||
220 | /* handler has already set things up, so skip ss setup */ | ||
221 | return 1; | ||
222 | |||
223 | ss_probe: | ||
224 | prepare_singlestep(p, regs); | ||
225 | kcb->kprobe_status = KPROBE_HIT_SS; | ||
226 | return 1; | ||
227 | |||
228 | no_kprobe: | ||
229 | preempt_enable_no_resched(); | ||
230 | return ret; | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * Function return probe trampoline: | ||
235 | * - init_kprobes() establishes a probepoint here | ||
236 | * - When the probed function returns, this probe | ||
237 | * causes the handlers to fire | ||
238 | */ | ||
239 | void kretprobe_trampoline_holder(void) | ||
240 | { | ||
241 | asm volatile(".global kretprobe_trampoline\n" | ||
242 | "kretprobe_trampoline:\n" | ||
243 | "nop\n"); | ||
244 | } | ||
245 | |||
246 | /* | ||
247 | * Called when the probe at kretprobe trampoline is hit | ||
248 | */ | ||
249 | int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | ||
250 | { | ||
251 | struct kretprobe_instance *ri = NULL; | ||
252 | struct hlist_head *head; | ||
253 | struct hlist_node *node, *tmp; | ||
254 | unsigned long flags, orig_ret_address = 0; | ||
255 | unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; | ||
256 | |||
257 | spin_lock_irqsave(&kretprobe_lock, flags); | ||
258 | head = kretprobe_inst_table_head(current); | ||
259 | |||
260 | /* | ||
261 | * It is possible to have multiple instances associated with a given | ||
262 | * task either because an multiple functions in the call path | ||
263 | * have a return probe installed on them, and/or more then one return | ||
264 | * return probe was registered for a target function. | ||
265 | * | ||
266 | * We can handle this because: | ||
267 | * - instances are always inserted at the head of the list | ||
268 | * - when multiple return probes are registered for the same | ||
269 | * function, the first instance's ret_addr will point to the | ||
270 | * real return address, and all the rest will point to | ||
271 | * kretprobe_trampoline | ||
272 | */ | ||
273 | hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { | ||
274 | if (ri->task != current) | ||
275 | /* another task is sharing our hash bucket */ | ||
276 | continue; | ||
277 | |||
278 | if (ri->rp && ri->rp->handler) | ||
279 | ri->rp->handler(ri, regs); | ||
280 | |||
281 | orig_ret_address = (unsigned long)ri->ret_addr; | ||
282 | recycle_rp_inst(ri); | ||
283 | |||
284 | if (orig_ret_address != trampoline_address) | ||
285 | /* | ||
286 | * This is the real return address. Any other | ||
287 | * instances associated with this task are for | ||
288 | * other calls deeper on the call stack | ||
289 | */ | ||
290 | break; | ||
291 | } | ||
292 | |||
293 | BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); | ||
294 | regs->nip = orig_ret_address; | ||
295 | |||
296 | reset_current_kprobe(); | ||
297 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
298 | preempt_enable_no_resched(); | ||
299 | |||
300 | /* | ||
301 | * By returning a non-zero value, we are telling | ||
302 | * kprobe_handler() that we don't want the post_handler | ||
303 | * to run (and have re-enabled preemption) | ||
304 | */ | ||
305 | return 1; | ||
306 | } | ||
307 | |||
308 | /* | ||
309 | * Called after single-stepping. p->addr is the address of the | ||
310 | * instruction whose first byte has been replaced by the "breakpoint" | ||
311 | * instruction. To avoid the SMP problems that can occur when we | ||
312 | * temporarily put back the original opcode to single-step, we | ||
313 | * single-stepped a copy of the instruction. The address of this | ||
314 | * copy is p->ainsn.insn. | ||
315 | */ | ||
316 | static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) | ||
317 | { | ||
318 | int ret; | ||
319 | unsigned int insn = *p->ainsn.insn; | ||
320 | |||
321 | regs->nip = (unsigned long)p->addr; | ||
322 | ret = emulate_step(regs, insn); | ||
323 | if (ret == 0) | ||
324 | regs->nip = (unsigned long)p->addr + 4; | ||
325 | } | ||
326 | |||
327 | static inline int post_kprobe_handler(struct pt_regs *regs) | ||
328 | { | ||
329 | struct kprobe *cur = kprobe_running(); | ||
330 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
331 | |||
332 | if (!cur) | ||
333 | return 0; | ||
334 | |||
335 | if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { | ||
336 | kcb->kprobe_status = KPROBE_HIT_SSDONE; | ||
337 | cur->post_handler(cur, regs, 0); | ||
338 | } | ||
339 | |||
340 | resume_execution(cur, regs); | ||
341 | regs->msr |= kcb->kprobe_saved_msr; | ||
342 | |||
343 | /*Restore back the original saved kprobes variables and continue. */ | ||
344 | if (kcb->kprobe_status == KPROBE_REENTER) { | ||
345 | restore_previous_kprobe(kcb); | ||
346 | goto out; | ||
347 | } | ||
348 | reset_current_kprobe(); | ||
349 | out: | ||
350 | preempt_enable_no_resched(); | ||
351 | |||
352 | /* | ||
353 | * if somebody else is singlestepping across a probe point, msr | ||
354 | * will have SE set, in which case, continue the remaining processing | ||
355 | * of do_debug, as if this is not a probe hit. | ||
356 | */ | ||
357 | if (regs->msr & MSR_SE) | ||
358 | return 0; | ||
359 | |||
360 | return 1; | ||
361 | } | ||
362 | |||
363 | static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | ||
364 | { | ||
365 | struct kprobe *cur = kprobe_running(); | ||
366 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
367 | |||
368 | if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) | ||
369 | return 1; | ||
370 | |||
371 | if (kcb->kprobe_status & KPROBE_HIT_SS) { | ||
372 | resume_execution(cur, regs); | ||
373 | regs->msr &= ~MSR_SE; | ||
374 | regs->msr |= kcb->kprobe_saved_msr; | ||
375 | |||
376 | reset_current_kprobe(); | ||
377 | preempt_enable_no_resched(); | ||
378 | } | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | /* | ||
383 | * Wrapper routine to for handling exceptions. | ||
384 | */ | ||
385 | int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | ||
386 | unsigned long val, void *data) | ||
387 | { | ||
388 | struct die_args *args = (struct die_args *)data; | ||
389 | int ret = NOTIFY_DONE; | ||
390 | |||
391 | switch (val) { | ||
392 | case DIE_BPT: | ||
393 | if (kprobe_handler(args->regs)) | ||
394 | ret = NOTIFY_STOP; | ||
395 | break; | ||
396 | case DIE_SSTEP: | ||
397 | if (post_kprobe_handler(args->regs)) | ||
398 | ret = NOTIFY_STOP; | ||
399 | break; | ||
400 | case DIE_PAGE_FAULT: | ||
401 | /* kprobe_running() needs smp_processor_id() */ | ||
402 | preempt_disable(); | ||
403 | if (kprobe_running() && | ||
404 | kprobe_fault_handler(args->regs, args->trapnr)) | ||
405 | ret = NOTIFY_STOP; | ||
406 | preempt_enable(); | ||
407 | break; | ||
408 | default: | ||
409 | break; | ||
410 | } | ||
411 | return ret; | ||
412 | } | ||
413 | |||
414 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | ||
415 | { | ||
416 | struct jprobe *jp = container_of(p, struct jprobe, kp); | ||
417 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
418 | |||
419 | memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs)); | ||
420 | |||
421 | /* setup return addr to the jprobe handler routine */ | ||
422 | regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry); | ||
423 | regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc); | ||
424 | |||
425 | return 1; | ||
426 | } | ||
427 | |||
428 | void __kprobes jprobe_return(void) | ||
429 | { | ||
430 | asm volatile("trap" ::: "memory"); | ||
431 | } | ||
432 | |||
433 | void __kprobes jprobe_return_end(void) | ||
434 | { | ||
435 | }; | ||
436 | |||
437 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | ||
438 | { | ||
439 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
440 | |||
441 | /* | ||
442 | * FIXME - we should ideally be validating that we got here 'cos | ||
443 | * of the "trap" in jprobe_return() above, before restoring the | ||
444 | * saved regs... | ||
445 | */ | ||
446 | memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs)); | ||
447 | preempt_enable_no_resched(); | ||
448 | return 1; | ||
449 | } | ||
450 | |||
451 | static struct kprobe trampoline_p = { | ||
452 | .addr = (kprobe_opcode_t *) &kretprobe_trampoline, | ||
453 | .pre_handler = trampoline_probe_handler | ||
454 | }; | ||
455 | |||
456 | int __init arch_init_kprobes(void) | ||
457 | { | ||
458 | return register_kprobe(&trampoline_p); | ||
459 | } | ||
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 1b3ba8a440a6..9dda16ccde78 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
@@ -42,32 +42,6 @@ | |||
42 | 42 | ||
43 | /* #define LPARCFG_DEBUG */ | 43 | /* #define LPARCFG_DEBUG */ |
44 | 44 | ||
45 | /* find a better place for this function... */ | ||
46 | static void log_plpar_hcall_return(unsigned long rc, char *tag) | ||
47 | { | ||
48 | if (rc == 0) /* success, return */ | ||
49 | return; | ||
50 | /* check for null tag ? */ | ||
51 | if (rc == H_Hardware) | ||
52 | printk(KERN_INFO | ||
53 | "plpar-hcall (%s) failed with hardware fault\n", tag); | ||
54 | else if (rc == H_Function) | ||
55 | printk(KERN_INFO | ||
56 | "plpar-hcall (%s) failed; function not allowed\n", tag); | ||
57 | else if (rc == H_Authority) | ||
58 | printk(KERN_INFO | ||
59 | "plpar-hcall (%s) failed; not authorized to this function\n", | ||
60 | tag); | ||
61 | else if (rc == H_Parameter) | ||
62 | printk(KERN_INFO "plpar-hcall (%s) failed; Bad parameter(s)\n", | ||
63 | tag); | ||
64 | else | ||
65 | printk(KERN_INFO | ||
66 | "plpar-hcall (%s) failed with unexpected rc(0x%lx)\n", | ||
67 | tag, rc); | ||
68 | |||
69 | } | ||
70 | |||
71 | static struct proc_dir_entry *proc_ppc64_lparcfg; | 45 | static struct proc_dir_entry *proc_ppc64_lparcfg; |
72 | #define LPARCFG_BUFF_SIZE 4096 | 46 | #define LPARCFG_BUFF_SIZE 4096 |
73 | 47 | ||
@@ -172,6 +146,31 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
172 | /* | 146 | /* |
173 | * Methods used to fetch LPAR data when running on a pSeries platform. | 147 | * Methods used to fetch LPAR data when running on a pSeries platform. |
174 | */ | 148 | */ |
149 | /* find a better place for this function... */ | ||
150 | static void log_plpar_hcall_return(unsigned long rc, char *tag) | ||
151 | { | ||
152 | if (rc == 0) /* success, return */ | ||
153 | return; | ||
154 | /* check for null tag ? */ | ||
155 | if (rc == H_Hardware) | ||
156 | printk(KERN_INFO | ||
157 | "plpar-hcall (%s) failed with hardware fault\n", tag); | ||
158 | else if (rc == H_Function) | ||
159 | printk(KERN_INFO | ||
160 | "plpar-hcall (%s) failed; function not allowed\n", tag); | ||
161 | else if (rc == H_Authority) | ||
162 | printk(KERN_INFO | ||
163 | "plpar-hcall (%s) failed; not authorized to this function\n", | ||
164 | tag); | ||
165 | else if (rc == H_Parameter) | ||
166 | printk(KERN_INFO "plpar-hcall (%s) failed; Bad parameter(s)\n", | ||
167 | tag); | ||
168 | else | ||
169 | printk(KERN_INFO | ||
170 | "plpar-hcall (%s) failed with unexpected rc(0x%lx)\n", | ||
171 | tag, rc); | ||
172 | |||
173 | } | ||
175 | 174 | ||
176 | /* | 175 | /* |
177 | * H_GET_PPP hcall returns info in 4 parms. | 176 | * H_GET_PPP hcall returns info in 4 parms. |
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c new file mode 100644 index 000000000000..97c51e452be7 --- /dev/null +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -0,0 +1,358 @@ | |||
1 | /* | ||
2 | * machine_kexec.c - handle transition of Linux booting another kernel | ||
3 | * | ||
4 | * Copyright (C) 2004-2005, IBM Corp. | ||
5 | * | ||
6 | * Created by: Milton D Miller II | ||
7 | * | ||
8 | * This source code is licensed under the GNU General Public License, | ||
9 | * Version 2. See the file COPYING for more details. | ||
10 | */ | ||
11 | |||
12 | |||
13 | #include <linux/cpumask.h> | ||
14 | #include <linux/kexec.h> | ||
15 | #include <linux/smp.h> | ||
16 | #include <linux/thread_info.h> | ||
17 | #include <linux/errno.h> | ||
18 | |||
19 | #include <asm/page.h> | ||
20 | #include <asm/current.h> | ||
21 | #include <asm/machdep.h> | ||
22 | #include <asm/cacheflush.h> | ||
23 | #include <asm/paca.h> | ||
24 | #include <asm/mmu.h> | ||
25 | #include <asm/sections.h> /* _end */ | ||
26 | #include <asm/prom.h> | ||
27 | #include <asm/smp.h> | ||
28 | |||
29 | #define HASH_GROUP_SIZE 0x80 /* size of each hash group, asm/mmu.h */ | ||
30 | |||
31 | /* Have this around till we move it into crash specific file */ | ||
32 | note_buf_t crash_notes[NR_CPUS]; | ||
33 | |||
34 | /* Dummy for now. Not sure if we need to have a crash shutdown in here | ||
35 | * and if what it will achieve. Letting it be now to compile the code | ||
36 | * in generic kexec environment | ||
37 | */ | ||
38 | void machine_crash_shutdown(struct pt_regs *regs) | ||
39 | { | ||
40 | /* do nothing right now */ | ||
41 | /* smp_relase_cpus() if we want smp on panic kernel */ | ||
42 | /* cpu_irq_down to isolate us until we are ready */ | ||
43 | } | ||
44 | |||
45 | int machine_kexec_prepare(struct kimage *image) | ||
46 | { | ||
47 | int i; | ||
48 | unsigned long begin, end; /* limits of segment */ | ||
49 | unsigned long low, high; /* limits of blocked memory range */ | ||
50 | struct device_node *node; | ||
51 | unsigned long *basep; | ||
52 | unsigned int *sizep; | ||
53 | |||
54 | if (!ppc_md.hpte_clear_all) | ||
55 | return -ENOENT; | ||
56 | |||
57 | /* | ||
58 | * Since we use the kernel fault handlers and paging code to | ||
59 | * handle the virtual mode, we must make sure no destination | ||
60 | * overlaps kernel static data or bss. | ||
61 | */ | ||
62 | for (i = 0; i < image->nr_segments; i++) | ||
63 | if (image->segment[i].mem < __pa(_end)) | ||
64 | return -ETXTBSY; | ||
65 | |||
66 | /* | ||
67 | * For non-LPAR, we absolutely can not overwrite the mmu hash | ||
68 | * table, since we are still using the bolted entries in it to | ||
69 | * do the copy. Check that here. | ||
70 | * | ||
71 | * It is safe if the end is below the start of the blocked | ||
72 | * region (end <= low), or if the beginning is after the | ||
73 | * end of the blocked region (begin >= high). Use the | ||
74 | * boolean identity !(a || b) === (!a && !b). | ||
75 | */ | ||
76 | if (htab_address) { | ||
77 | low = __pa(htab_address); | ||
78 | high = low + (htab_hash_mask + 1) * HASH_GROUP_SIZE; | ||
79 | |||
80 | for (i = 0; i < image->nr_segments; i++) { | ||
81 | begin = image->segment[i].mem; | ||
82 | end = begin + image->segment[i].memsz; | ||
83 | |||
84 | if ((begin < high) && (end > low)) | ||
85 | return -ETXTBSY; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /* We also should not overwrite the tce tables */ | ||
90 | for (node = of_find_node_by_type(NULL, "pci"); node != NULL; | ||
91 | node = of_find_node_by_type(node, "pci")) { | ||
92 | basep = (unsigned long *)get_property(node, "linux,tce-base", | ||
93 | NULL); | ||
94 | sizep = (unsigned int *)get_property(node, "linux,tce-size", | ||
95 | NULL); | ||
96 | if (basep == NULL || sizep == NULL) | ||
97 | continue; | ||
98 | |||
99 | low = *basep; | ||
100 | high = low + (*sizep); | ||
101 | |||
102 | for (i = 0; i < image->nr_segments; i++) { | ||
103 | begin = image->segment[i].mem; | ||
104 | end = begin + image->segment[i].memsz; | ||
105 | |||
106 | if ((begin < high) && (end > low)) | ||
107 | return -ETXTBSY; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | void machine_kexec_cleanup(struct kimage *image) | ||
115 | { | ||
116 | /* we do nothing in prepare that needs to be undone */ | ||
117 | } | ||
118 | |||
119 | #define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE) | ||
120 | |||
121 | static void copy_segments(unsigned long ind) | ||
122 | { | ||
123 | unsigned long entry; | ||
124 | unsigned long *ptr; | ||
125 | void *dest; | ||
126 | void *addr; | ||
127 | |||
128 | /* | ||
129 | * We rely on kexec_load to create a lists that properly | ||
130 | * initializes these pointers before they are used. | ||
131 | * We will still crash if the list is wrong, but at least | ||
132 | * the compiler will be quiet. | ||
133 | */ | ||
134 | ptr = NULL; | ||
135 | dest = NULL; | ||
136 | |||
137 | for (entry = ind; !(entry & IND_DONE); entry = *ptr++) { | ||
138 | addr = __va(entry & PAGE_MASK); | ||
139 | |||
140 | switch (entry & IND_FLAGS) { | ||
141 | case IND_DESTINATION: | ||
142 | dest = addr; | ||
143 | break; | ||
144 | case IND_INDIRECTION: | ||
145 | ptr = addr; | ||
146 | break; | ||
147 | case IND_SOURCE: | ||
148 | copy_page(dest, addr); | ||
149 | dest += PAGE_SIZE; | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | void kexec_copy_flush(struct kimage *image) | ||
155 | { | ||
156 | long i, nr_segments = image->nr_segments; | ||
157 | struct kexec_segment ranges[KEXEC_SEGMENT_MAX]; | ||
158 | |||
159 | /* save the ranges on the stack to efficiently flush the icache */ | ||
160 | memcpy(ranges, image->segment, sizeof(ranges)); | ||
161 | |||
162 | /* | ||
163 | * After this call we may not use anything allocated in dynamic | ||
164 | * memory, including *image. | ||
165 | * | ||
166 | * Only globals and the stack are allowed. | ||
167 | */ | ||
168 | copy_segments(image->head); | ||
169 | |||
170 | /* | ||
171 | * we need to clear the icache for all dest pages sometime, | ||
172 | * including ones that were in place on the original copy | ||
173 | */ | ||
174 | for (i = 0; i < nr_segments; i++) | ||
175 | flush_icache_range(ranges[i].mem + KERNELBASE, | ||
176 | ranges[i].mem + KERNELBASE + | ||
177 | ranges[i].memsz); | ||
178 | } | ||
179 | |||
180 | #ifdef CONFIG_SMP | ||
181 | |||
182 | /* FIXME: we should schedule this function to be called on all cpus based | ||
183 | * on calling the interrupts, but we would like to call it off irq level | ||
184 | * so that the interrupt controller is clean. | ||
185 | */ | ||
186 | void kexec_smp_down(void *arg) | ||
187 | { | ||
188 | if (ppc_md.kexec_cpu_down) | ||
189 | ppc_md.kexec_cpu_down(0, 1); | ||
190 | |||
191 | local_irq_disable(); | ||
192 | kexec_smp_wait(); | ||
193 | /* NOTREACHED */ | ||
194 | } | ||
195 | |||
196 | static void kexec_prepare_cpus(void) | ||
197 | { | ||
198 | int my_cpu, i, notified=-1; | ||
199 | |||
200 | smp_call_function(kexec_smp_down, NULL, 0, /* wait */0); | ||
201 | my_cpu = get_cpu(); | ||
202 | |||
203 | /* check the others cpus are now down (via paca hw cpu id == -1) */ | ||
204 | for (i=0; i < NR_CPUS; i++) { | ||
205 | if (i == my_cpu) | ||
206 | continue; | ||
207 | |||
208 | while (paca[i].hw_cpu_id != -1) { | ||
209 | barrier(); | ||
210 | if (!cpu_possible(i)) { | ||
211 | printk("kexec: cpu %d hw_cpu_id %d is not" | ||
212 | " possible, ignoring\n", | ||
213 | i, paca[i].hw_cpu_id); | ||
214 | break; | ||
215 | } | ||
216 | if (!cpu_online(i)) { | ||
217 | /* Fixme: this can be spinning in | ||
218 | * pSeries_secondary_wait with a paca | ||
219 | * waiting for it to go online. | ||
220 | */ | ||
221 | printk("kexec: cpu %d hw_cpu_id %d is not" | ||
222 | " online, ignoring\n", | ||
223 | i, paca[i].hw_cpu_id); | ||
224 | break; | ||
225 | } | ||
226 | if (i != notified) { | ||
227 | printk( "kexec: waiting for cpu %d (physical" | ||
228 | " %d) to go down\n", | ||
229 | i, paca[i].hw_cpu_id); | ||
230 | notified = i; | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | |||
235 | /* after we tell the others to go down */ | ||
236 | if (ppc_md.kexec_cpu_down) | ||
237 | ppc_md.kexec_cpu_down(0, 0); | ||
238 | |||
239 | put_cpu(); | ||
240 | |||
241 | local_irq_disable(); | ||
242 | } | ||
243 | |||
244 | #else /* ! SMP */ | ||
245 | |||
246 | static void kexec_prepare_cpus(void) | ||
247 | { | ||
248 | /* | ||
249 | * move the secondarys to us so that we can copy | ||
250 | * the new kernel 0-0x100 safely | ||
251 | * | ||
252 | * do this if kexec in setup.c ? | ||
253 | * | ||
254 | * We need to release the cpus if we are ever going from an | ||
255 | * UP to an SMP kernel. | ||
256 | */ | ||
257 | smp_release_cpus(); | ||
258 | if (ppc_md.kexec_cpu_down) | ||
259 | ppc_md.kexec_cpu_down(0, 0); | ||
260 | local_irq_disable(); | ||
261 | } | ||
262 | |||
263 | #endif /* SMP */ | ||
264 | |||
265 | /* | ||
266 | * kexec thread structure and stack. | ||
267 | * | ||
268 | * We need to make sure that this is 16384-byte aligned due to the | ||
269 | * way process stacks are handled. It also must be statically allocated | ||
270 | * or allocated as part of the kimage, because everything else may be | ||
271 | * overwritten when we copy the kexec image. We piggyback on the | ||
272 | * "init_task" linker section here to statically allocate a stack. | ||
273 | * | ||
274 | * We could use a smaller stack if we don't care about anything using | ||
275 | * current, but that audit has not been performed. | ||
276 | */ | ||
277 | union thread_union kexec_stack | ||
278 | __attribute__((__section__(".data.init_task"))) = { }; | ||
279 | |||
280 | /* Our assembly helper, in kexec_stub.S */ | ||
281 | extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, | ||
282 | void *image, void *control, | ||
283 | void (*clear_all)(void)) ATTRIB_NORET; | ||
284 | |||
285 | /* too late to fail here */ | ||
286 | void machine_kexec(struct kimage *image) | ||
287 | { | ||
288 | |||
289 | /* prepare control code if any */ | ||
290 | |||
291 | /* shutdown other cpus into our wait loop and quiesce interrupts */ | ||
292 | kexec_prepare_cpus(); | ||
293 | |||
294 | /* switch to a staticly allocated stack. Based on irq stack code. | ||
295 | * XXX: the task struct will likely be invalid once we do the copy! | ||
296 | */ | ||
297 | kexec_stack.thread_info.task = current_thread_info()->task; | ||
298 | kexec_stack.thread_info.flags = 0; | ||
299 | |||
300 | /* Some things are best done in assembly. Finding globals with | ||
301 | * a toc is easier in C, so pass in what we can. | ||
302 | */ | ||
303 | kexec_sequence(&kexec_stack, image->start, image, | ||
304 | page_address(image->control_code_page), | ||
305 | ppc_md.hpte_clear_all); | ||
306 | /* NOTREACHED */ | ||
307 | } | ||
308 | |||
309 | /* Values we need to export to the second kernel via the device tree. */ | ||
310 | static unsigned long htab_base, htab_size, kernel_end; | ||
311 | |||
312 | static struct property htab_base_prop = { | ||
313 | .name = "linux,htab-base", | ||
314 | .length = sizeof(unsigned long), | ||
315 | .value = (unsigned char *)&htab_base, | ||
316 | }; | ||
317 | |||
318 | static struct property htab_size_prop = { | ||
319 | .name = "linux,htab-size", | ||
320 | .length = sizeof(unsigned long), | ||
321 | .value = (unsigned char *)&htab_size, | ||
322 | }; | ||
323 | |||
324 | static struct property kernel_end_prop = { | ||
325 | .name = "linux,kernel-end", | ||
326 | .length = sizeof(unsigned long), | ||
327 | .value = (unsigned char *)&kernel_end, | ||
328 | }; | ||
329 | |||
330 | static void __init export_htab_values(void) | ||
331 | { | ||
332 | struct device_node *node; | ||
333 | |||
334 | node = of_find_node_by_path("/chosen"); | ||
335 | if (!node) | ||
336 | return; | ||
337 | |||
338 | kernel_end = __pa(_end); | ||
339 | prom_add_property(node, &kernel_end_prop); | ||
340 | |||
341 | /* On machines with no htab htab_address is NULL */ | ||
342 | if (NULL == htab_address) | ||
343 | goto out; | ||
344 | |||
345 | htab_base = __pa(htab_address); | ||
346 | prom_add_property(node, &htab_base_prop); | ||
347 | |||
348 | htab_size = 1UL << ppc64_pft_size; | ||
349 | prom_add_property(node, &htab_size_prop); | ||
350 | |||
351 | out: | ||
352 | of_node_put(node); | ||
353 | } | ||
354 | |||
355 | void __init kexec_setup(void) | ||
356 | { | ||
357 | export_htab_values(); | ||
358 | } | ||
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index f6d84a75ed26..624a983a9676 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -27,14 +27,6 @@ | |||
27 | 27 | ||
28 | .text | 28 | .text |
29 | 29 | ||
30 | .align 5 | ||
31 | _GLOBAL(__delay) | ||
32 | cmpwi 0,r3,0 | ||
33 | mtctr r3 | ||
34 | beqlr | ||
35 | 1: bdnz 1b | ||
36 | blr | ||
37 | |||
38 | /* | 30 | /* |
39 | * This returns the high 64 bits of the product of two 64-bit numbers. | 31 | * This returns the high 64 bits of the product of two 64-bit numbers. |
40 | */ | 32 | */ |
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c new file mode 100644 index 000000000000..928b8581fcb0 --- /dev/null +++ b/arch/powerpc/kernel/module_64.c | |||
@@ -0,0 +1,455 @@ | |||
1 | /* Kernel module help for PPC64. | ||
2 | Copyright (C) 2001, 2003 Rusty Russell IBM Corporation. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/elf.h> | ||
20 | #include <linux/moduleloader.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/vmalloc.h> | ||
23 | #include <asm/module.h> | ||
24 | #include <asm/uaccess.h> | ||
25 | |||
26 | /* FIXME: We don't do .init separately. To do this, we'd need to have | ||
27 | a separate r2 value in the init and core section, and stub between | ||
28 | them, too. | ||
29 | |||
30 | Using a magic allocator which places modules within 32MB solves | ||
31 | this, and makes other things simpler. Anton? | ||
32 | --RR. */ | ||
33 | #if 0 | ||
34 | #define DEBUGP printk | ||
35 | #else | ||
36 | #define DEBUGP(fmt , ...) | ||
37 | #endif | ||
38 | |||
39 | /* There's actually a third entry here, but it's unused */ | ||
40 | struct ppc64_opd_entry | ||
41 | { | ||
42 | unsigned long funcaddr; | ||
43 | unsigned long r2; | ||
44 | }; | ||
45 | |||
46 | /* Like PPC32, we need little trampolines to do > 24-bit jumps (into | ||
47 | the kernel itself). But on PPC64, these need to be used for every | ||
48 | jump, actually, to reset r2 (TOC+0x8000). */ | ||
49 | struct ppc64_stub_entry | ||
50 | { | ||
51 | /* 28 byte jump instruction sequence (7 instructions) */ | ||
52 | unsigned char jump[28]; | ||
53 | unsigned char unused[4]; | ||
54 | /* Data for the above code */ | ||
55 | struct ppc64_opd_entry opd; | ||
56 | }; | ||
57 | |||
58 | /* We use a stub to fix up r2 (TOC ptr) and to jump to the (external) | ||
59 | function which may be more than 24-bits away. We could simply | ||
60 | patch the new r2 value and function pointer into the stub, but it's | ||
61 | significantly shorter to put these values at the end of the stub | ||
62 | code, and patch the stub address (32-bits relative to the TOC ptr, | ||
63 | r2) into the stub. */ | ||
64 | static struct ppc64_stub_entry ppc64_stub = | ||
65 | { .jump = { | ||
66 | 0x3d, 0x82, 0x00, 0x00, /* addis r12,r2, <high> */ | ||
67 | 0x39, 0x8c, 0x00, 0x00, /* addi r12,r12, <low> */ | ||
68 | /* Save current r2 value in magic place on the stack. */ | ||
69 | 0xf8, 0x41, 0x00, 0x28, /* std r2,40(r1) */ | ||
70 | 0xe9, 0x6c, 0x00, 0x20, /* ld r11,32(r12) */ | ||
71 | 0xe8, 0x4c, 0x00, 0x28, /* ld r2,40(r12) */ | ||
72 | 0x7d, 0x69, 0x03, 0xa6, /* mtctr r11 */ | ||
73 | 0x4e, 0x80, 0x04, 0x20 /* bctr */ | ||
74 | } }; | ||
75 | |||
76 | /* Count how many different 24-bit relocations (different symbol, | ||
77 | different addend) */ | ||
78 | static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num) | ||
79 | { | ||
80 | unsigned int i, j, ret = 0; | ||
81 | |||
82 | /* FIXME: Only count external ones --RR */ | ||
83 | /* Sure, this is order(n^2), but it's usually short, and not | ||
84 | time critical */ | ||
85 | for (i = 0; i < num; i++) { | ||
86 | /* Only count 24-bit relocs, others don't need stubs */ | ||
87 | if (ELF64_R_TYPE(rela[i].r_info) != R_PPC_REL24) | ||
88 | continue; | ||
89 | for (j = 0; j < i; j++) { | ||
90 | /* If this addend appeared before, it's | ||
91 | already been counted */ | ||
92 | if (rela[i].r_info == rela[j].r_info | ||
93 | && rela[i].r_addend == rela[j].r_addend) | ||
94 | break; | ||
95 | } | ||
96 | if (j == i) ret++; | ||
97 | } | ||
98 | return ret; | ||
99 | } | ||
100 | |||
101 | void *module_alloc(unsigned long size) | ||
102 | { | ||
103 | if (size == 0) | ||
104 | return NULL; | ||
105 | |||
106 | return vmalloc_exec(size); | ||
107 | } | ||
108 | |||
109 | /* Free memory returned from module_alloc */ | ||
110 | void module_free(struct module *mod, void *module_region) | ||
111 | { | ||
112 | vfree(module_region); | ||
113 | /* FIXME: If module_region == mod->init_region, trim exception | ||
114 | table entries. */ | ||
115 | } | ||
116 | |||
117 | /* Get size of potential trampolines required. */ | ||
118 | static unsigned long get_stubs_size(const Elf64_Ehdr *hdr, | ||
119 | const Elf64_Shdr *sechdrs) | ||
120 | { | ||
121 | /* One extra reloc so it's always 0-funcaddr terminated */ | ||
122 | unsigned long relocs = 1; | ||
123 | unsigned i; | ||
124 | |||
125 | /* Every relocated section... */ | ||
126 | for (i = 1; i < hdr->e_shnum; i++) { | ||
127 | if (sechdrs[i].sh_type == SHT_RELA) { | ||
128 | DEBUGP("Found relocations in section %u\n", i); | ||
129 | DEBUGP("Ptr: %p. Number: %lu\n", | ||
130 | (void *)sechdrs[i].sh_addr, | ||
131 | sechdrs[i].sh_size / sizeof(Elf64_Rela)); | ||
132 | relocs += count_relocs((void *)sechdrs[i].sh_addr, | ||
133 | sechdrs[i].sh_size | ||
134 | / sizeof(Elf64_Rela)); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | DEBUGP("Looks like a total of %lu stubs, max\n", relocs); | ||
139 | return relocs * sizeof(struct ppc64_stub_entry); | ||
140 | } | ||
141 | |||
142 | static void dedotify_versions(struct modversion_info *vers, | ||
143 | unsigned long size) | ||
144 | { | ||
145 | struct modversion_info *end; | ||
146 | |||
147 | for (end = (void *)vers + size; vers < end; vers++) | ||
148 | if (vers->name[0] == '.') | ||
149 | memmove(vers->name, vers->name+1, strlen(vers->name)); | ||
150 | } | ||
151 | |||
152 | /* Undefined symbols which refer to .funcname, hack to funcname */ | ||
153 | static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) | ||
154 | { | ||
155 | unsigned int i; | ||
156 | |||
157 | for (i = 1; i < numsyms; i++) { | ||
158 | if (syms[i].st_shndx == SHN_UNDEF) { | ||
159 | char *name = strtab + syms[i].st_name; | ||
160 | if (name[0] == '.') | ||
161 | memmove(name, name+1, strlen(name)); | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | |||
166 | int module_frob_arch_sections(Elf64_Ehdr *hdr, | ||
167 | Elf64_Shdr *sechdrs, | ||
168 | char *secstrings, | ||
169 | struct module *me) | ||
170 | { | ||
171 | unsigned int i; | ||
172 | |||
173 | /* Find .toc and .stubs sections, symtab and strtab */ | ||
174 | for (i = 1; i < hdr->e_shnum; i++) { | ||
175 | char *p; | ||
176 | if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0) | ||
177 | me->arch.stubs_section = i; | ||
178 | else if (strcmp(secstrings + sechdrs[i].sh_name, ".toc") == 0) | ||
179 | me->arch.toc_section = i; | ||
180 | else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0) | ||
181 | dedotify_versions((void *)hdr + sechdrs[i].sh_offset, | ||
182 | sechdrs[i].sh_size); | ||
183 | |||
184 | /* We don't handle .init for the moment: rename to _init */ | ||
185 | while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init"))) | ||
186 | p[0] = '_'; | ||
187 | |||
188 | if (sechdrs[i].sh_type == SHT_SYMTAB) | ||
189 | dedotify((void *)hdr + sechdrs[i].sh_offset, | ||
190 | sechdrs[i].sh_size / sizeof(Elf64_Sym), | ||
191 | (void *)hdr | ||
192 | + sechdrs[sechdrs[i].sh_link].sh_offset); | ||
193 | } | ||
194 | if (!me->arch.stubs_section || !me->arch.toc_section) { | ||
195 | printk("%s: doesn't contain .toc or .stubs.\n", me->name); | ||
196 | return -ENOEXEC; | ||
197 | } | ||
198 | |||
199 | /* Override the stubs size */ | ||
200 | sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | int apply_relocate(Elf64_Shdr *sechdrs, | ||
205 | const char *strtab, | ||
206 | unsigned int symindex, | ||
207 | unsigned int relsec, | ||
208 | struct module *me) | ||
209 | { | ||
210 | printk(KERN_ERR "%s: Non-ADD RELOCATION unsupported\n", me->name); | ||
211 | return -ENOEXEC; | ||
212 | } | ||
213 | |||
214 | /* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this | ||
215 | gives the value maximum span in an instruction which uses a signed | ||
216 | offset) */ | ||
217 | static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) | ||
218 | { | ||
219 | return sechdrs[me->arch.toc_section].sh_addr + 0x8000; | ||
220 | } | ||
221 | |||
222 | /* Both low and high 16 bits are added as SIGNED additions, so if low | ||
223 | 16 bits has high bit set, high 16 bits must be adjusted. These | ||
224 | macros do that (stolen from binutils). */ | ||
225 | #define PPC_LO(v) ((v) & 0xffff) | ||
226 | #define PPC_HI(v) (((v) >> 16) & 0xffff) | ||
227 | #define PPC_HA(v) PPC_HI ((v) + 0x8000) | ||
228 | |||
229 | /* Patch stub to reference function and correct r2 value. */ | ||
230 | static inline int create_stub(Elf64_Shdr *sechdrs, | ||
231 | struct ppc64_stub_entry *entry, | ||
232 | struct ppc64_opd_entry *opd, | ||
233 | struct module *me) | ||
234 | { | ||
235 | Elf64_Half *loc1, *loc2; | ||
236 | long reladdr; | ||
237 | |||
238 | *entry = ppc64_stub; | ||
239 | |||
240 | loc1 = (Elf64_Half *)&entry->jump[2]; | ||
241 | loc2 = (Elf64_Half *)&entry->jump[6]; | ||
242 | |||
243 | /* Stub uses address relative to r2. */ | ||
244 | reladdr = (unsigned long)entry - my_r2(sechdrs, me); | ||
245 | if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) { | ||
246 | printk("%s: Address %p of stub out of range of %p.\n", | ||
247 | me->name, (void *)reladdr, (void *)my_r2); | ||
248 | return 0; | ||
249 | } | ||
250 | DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr); | ||
251 | |||
252 | *loc1 = PPC_HA(reladdr); | ||
253 | *loc2 = PPC_LO(reladdr); | ||
254 | entry->opd.funcaddr = opd->funcaddr; | ||
255 | entry->opd.r2 = opd->r2; | ||
256 | return 1; | ||
257 | } | ||
258 | |||
259 | /* Create stub to jump to function described in this OPD: we need the | ||
260 | stub to set up the TOC ptr (r2) for the function. */ | ||
261 | static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, | ||
262 | unsigned long opdaddr, | ||
263 | struct module *me) | ||
264 | { | ||
265 | struct ppc64_stub_entry *stubs; | ||
266 | struct ppc64_opd_entry *opd = (void *)opdaddr; | ||
267 | unsigned int i, num_stubs; | ||
268 | |||
269 | num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs); | ||
270 | |||
271 | /* Find this stub, or if that fails, the next avail. entry */ | ||
272 | stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr; | ||
273 | for (i = 0; stubs[i].opd.funcaddr; i++) { | ||
274 | BUG_ON(i >= num_stubs); | ||
275 | |||
276 | if (stubs[i].opd.funcaddr == opd->funcaddr) | ||
277 | return (unsigned long)&stubs[i]; | ||
278 | } | ||
279 | |||
280 | if (!create_stub(sechdrs, &stubs[i], opd, me)) | ||
281 | return 0; | ||
282 | |||
283 | return (unsigned long)&stubs[i]; | ||
284 | } | ||
285 | |||
286 | /* We expect a noop next: if it is, replace it with instruction to | ||
287 | restore r2. */ | ||
288 | static int restore_r2(u32 *instruction, struct module *me) | ||
289 | { | ||
290 | if (*instruction != 0x60000000) { | ||
291 | printk("%s: Expect noop after relocate, got %08x\n", | ||
292 | me->name, *instruction); | ||
293 | return 0; | ||
294 | } | ||
295 | *instruction = 0xe8410028; /* ld r2,40(r1) */ | ||
296 | return 1; | ||
297 | } | ||
298 | |||
299 | int apply_relocate_add(Elf64_Shdr *sechdrs, | ||
300 | const char *strtab, | ||
301 | unsigned int symindex, | ||
302 | unsigned int relsec, | ||
303 | struct module *me) | ||
304 | { | ||
305 | unsigned int i; | ||
306 | Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr; | ||
307 | Elf64_Sym *sym; | ||
308 | unsigned long *location; | ||
309 | unsigned long value; | ||
310 | |||
311 | DEBUGP("Applying ADD relocate section %u to %u\n", relsec, | ||
312 | sechdrs[relsec].sh_info); | ||
313 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { | ||
314 | /* This is where to make the change */ | ||
315 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr | ||
316 | + rela[i].r_offset; | ||
317 | /* This is the symbol it is referring to */ | ||
318 | sym = (Elf64_Sym *)sechdrs[symindex].sh_addr | ||
319 | + ELF64_R_SYM(rela[i].r_info); | ||
320 | |||
321 | DEBUGP("RELOC at %p: %li-type as %s (%lu) + %li\n", | ||
322 | location, (long)ELF64_R_TYPE(rela[i].r_info), | ||
323 | strtab + sym->st_name, (unsigned long)sym->st_value, | ||
324 | (long)rela[i].r_addend); | ||
325 | |||
326 | /* `Everything is relative'. */ | ||
327 | value = sym->st_value + rela[i].r_addend; | ||
328 | |||
329 | switch (ELF64_R_TYPE(rela[i].r_info)) { | ||
330 | case R_PPC64_ADDR32: | ||
331 | /* Simply set it */ | ||
332 | *(u32 *)location = value; | ||
333 | break; | ||
334 | |||
335 | case R_PPC64_ADDR64: | ||
336 | /* Simply set it */ | ||
337 | *(unsigned long *)location = value; | ||
338 | break; | ||
339 | |||
340 | case R_PPC64_TOC: | ||
341 | *(unsigned long *)location = my_r2(sechdrs, me); | ||
342 | break; | ||
343 | |||
344 | case R_PPC64_TOC16: | ||
345 | /* Subtact TOC pointer */ | ||
346 | value -= my_r2(sechdrs, me); | ||
347 | if (value + 0x8000 > 0xffff) { | ||
348 | printk("%s: bad TOC16 relocation (%lu)\n", | ||
349 | me->name, value); | ||
350 | return -ENOEXEC; | ||
351 | } | ||
352 | *((uint16_t *) location) | ||
353 | = (*((uint16_t *) location) & ~0xffff) | ||
354 | | (value & 0xffff); | ||
355 | break; | ||
356 | |||
357 | case R_PPC64_TOC16_DS: | ||
358 | /* Subtact TOC pointer */ | ||
359 | value -= my_r2(sechdrs, me); | ||
360 | if ((value & 3) != 0 || value + 0x8000 > 0xffff) { | ||
361 | printk("%s: bad TOC16_DS relocation (%lu)\n", | ||
362 | me->name, value); | ||
363 | return -ENOEXEC; | ||
364 | } | ||
365 | *((uint16_t *) location) | ||
366 | = (*((uint16_t *) location) & ~0xfffc) | ||
367 | | (value & 0xfffc); | ||
368 | break; | ||
369 | |||
370 | case R_PPC_REL24: | ||
371 | /* FIXME: Handle weak symbols here --RR */ | ||
372 | if (sym->st_shndx == SHN_UNDEF) { | ||
373 | /* External: go via stub */ | ||
374 | value = stub_for_addr(sechdrs, value, me); | ||
375 | if (!value) | ||
376 | return -ENOENT; | ||
377 | if (!restore_r2((u32 *)location + 1, me)) | ||
378 | return -ENOEXEC; | ||
379 | } | ||
380 | |||
381 | /* Convert value to relative */ | ||
382 | value -= (unsigned long)location; | ||
383 | if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){ | ||
384 | printk("%s: REL24 %li out of range!\n", | ||
385 | me->name, (long int)value); | ||
386 | return -ENOEXEC; | ||
387 | } | ||
388 | |||
389 | /* Only replace bits 2 through 26 */ | ||
390 | *(uint32_t *)location | ||
391 | = (*(uint32_t *)location & ~0x03fffffc) | ||
392 | | (value & 0x03fffffc); | ||
393 | break; | ||
394 | |||
395 | default: | ||
396 | printk("%s: Unknown ADD relocation: %lu\n", | ||
397 | me->name, | ||
398 | (unsigned long)ELF64_R_TYPE(rela[i].r_info)); | ||
399 | return -ENOEXEC; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | LIST_HEAD(module_bug_list); | ||
407 | |||
408 | int module_finalize(const Elf_Ehdr *hdr, | ||
409 | const Elf_Shdr *sechdrs, struct module *me) | ||
410 | { | ||
411 | char *secstrings; | ||
412 | unsigned int i; | ||
413 | |||
414 | me->arch.bug_table = NULL; | ||
415 | me->arch.num_bugs = 0; | ||
416 | |||
417 | /* Find the __bug_table section, if present */ | ||
418 | secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | ||
419 | for (i = 1; i < hdr->e_shnum; i++) { | ||
420 | if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table")) | ||
421 | continue; | ||
422 | me->arch.bug_table = (void *) sechdrs[i].sh_addr; | ||
423 | me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry); | ||
424 | break; | ||
425 | } | ||
426 | |||
427 | /* | ||
428 | * Strictly speaking this should have a spinlock to protect against | ||
429 | * traversals, but since we only traverse on BUG()s, a spinlock | ||
430 | * could potentially lead to deadlock and thus be counter-productive. | ||
431 | */ | ||
432 | list_add(&me->arch.bug_list, &module_bug_list); | ||
433 | |||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | void module_arch_cleanup(struct module *mod) | ||
438 | { | ||
439 | list_del(&mod->arch.bug_list); | ||
440 | } | ||
441 | |||
442 | struct bug_entry *module_find_bug(unsigned long bugaddr) | ||
443 | { | ||
444 | struct mod_arch_specific *mod; | ||
445 | unsigned int i; | ||
446 | struct bug_entry *bug; | ||
447 | |||
448 | list_for_each_entry(mod, &module_bug_list, bug_list) { | ||
449 | bug = mod->bug_table; | ||
450 | for (i = 0; i < mod->num_bugs; ++i, ++bug) | ||
451 | if (bugaddr == bug->bug_addr) | ||
452 | return bug; | ||
453 | } | ||
454 | return NULL; | ||
455 | } | ||
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c new file mode 100644 index 000000000000..c0fcd29918ce --- /dev/null +++ b/arch/powerpc/kernel/nvram_64.c | |||
@@ -0,0 +1,742 @@ | |||
1 | /* | ||
2 | * c 2001 PPC 64 Team, IBM Corp | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * /dev/nvram driver for PPC64 | ||
10 | * | ||
11 | * This perhaps should live in drivers/char | ||
12 | * | ||
13 | * TODO: Split the /dev/nvram part (that one can use | ||
14 | * drivers/char/generic_nvram.c) from the arch & partition | ||
15 | * parsing code. | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | |||
20 | #include <linux/types.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include <linux/miscdevice.h> | ||
24 | #include <linux/fcntl.h> | ||
25 | #include <linux/nvram.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <asm/uaccess.h> | ||
30 | #include <asm/nvram.h> | ||
31 | #include <asm/rtas.h> | ||
32 | #include <asm/prom.h> | ||
33 | #include <asm/machdep.h> | ||
34 | |||
35 | #undef DEBUG_NVRAM | ||
36 | |||
37 | static int nvram_scan_partitions(void); | ||
38 | static int nvram_setup_partition(void); | ||
39 | static int nvram_create_os_partition(void); | ||
40 | static int nvram_remove_os_partition(void); | ||
41 | |||
42 | static struct nvram_partition * nvram_part; | ||
43 | static long nvram_error_log_index = -1; | ||
44 | static long nvram_error_log_size = 0; | ||
45 | |||
46 | int no_logging = 1; /* Until we initialize everything, | ||
47 | * make sure we don't try logging | ||
48 | * anything */ | ||
49 | |||
50 | extern volatile int error_log_cnt; | ||
51 | |||
52 | struct err_log_info { | ||
53 | int error_type; | ||
54 | unsigned int seq_num; | ||
55 | }; | ||
56 | |||
57 | static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin) | ||
58 | { | ||
59 | int size; | ||
60 | |||
61 | if (ppc_md.nvram_size == NULL) | ||
62 | return -ENODEV; | ||
63 | size = ppc_md.nvram_size(); | ||
64 | |||
65 | switch (origin) { | ||
66 | case 1: | ||
67 | offset += file->f_pos; | ||
68 | break; | ||
69 | case 2: | ||
70 | offset += size; | ||
71 | break; | ||
72 | } | ||
73 | if (offset < 0) | ||
74 | return -EINVAL; | ||
75 | file->f_pos = offset; | ||
76 | return file->f_pos; | ||
77 | } | ||
78 | |||
79 | |||
80 | static ssize_t dev_nvram_read(struct file *file, char __user *buf, | ||
81 | size_t count, loff_t *ppos) | ||
82 | { | ||
83 | ssize_t len; | ||
84 | char *tmp_buffer; | ||
85 | int size; | ||
86 | |||
87 | if (ppc_md.nvram_size == NULL) | ||
88 | return -ENODEV; | ||
89 | size = ppc_md.nvram_size(); | ||
90 | |||
91 | if (!access_ok(VERIFY_WRITE, buf, count)) | ||
92 | return -EFAULT; | ||
93 | if (*ppos >= size) | ||
94 | return 0; | ||
95 | if (count > size) | ||
96 | count = size; | ||
97 | |||
98 | tmp_buffer = (char *) kmalloc(count, GFP_KERNEL); | ||
99 | if (!tmp_buffer) { | ||
100 | printk(KERN_ERR "dev_read_nvram: kmalloc failed\n"); | ||
101 | return -ENOMEM; | ||
102 | } | ||
103 | |||
104 | len = ppc_md.nvram_read(tmp_buffer, count, ppos); | ||
105 | if ((long)len <= 0) { | ||
106 | kfree(tmp_buffer); | ||
107 | return len; | ||
108 | } | ||
109 | |||
110 | if (copy_to_user(buf, tmp_buffer, len)) { | ||
111 | kfree(tmp_buffer); | ||
112 | return -EFAULT; | ||
113 | } | ||
114 | |||
115 | kfree(tmp_buffer); | ||
116 | return len; | ||
117 | |||
118 | } | ||
119 | |||
120 | static ssize_t dev_nvram_write(struct file *file, const char __user *buf, | ||
121 | size_t count, loff_t *ppos) | ||
122 | { | ||
123 | ssize_t len; | ||
124 | char * tmp_buffer; | ||
125 | int size; | ||
126 | |||
127 | if (ppc_md.nvram_size == NULL) | ||
128 | return -ENODEV; | ||
129 | size = ppc_md.nvram_size(); | ||
130 | |||
131 | if (!access_ok(VERIFY_READ, buf, count)) | ||
132 | return -EFAULT; | ||
133 | if (*ppos >= size) | ||
134 | return 0; | ||
135 | if (count > size) | ||
136 | count = size; | ||
137 | |||
138 | tmp_buffer = (char *) kmalloc(count, GFP_KERNEL); | ||
139 | if (!tmp_buffer) { | ||
140 | printk(KERN_ERR "dev_nvram_write: kmalloc failed\n"); | ||
141 | return -ENOMEM; | ||
142 | } | ||
143 | |||
144 | if (copy_from_user(tmp_buffer, buf, count)) { | ||
145 | kfree(tmp_buffer); | ||
146 | return -EFAULT; | ||
147 | } | ||
148 | |||
149 | len = ppc_md.nvram_write(tmp_buffer, count, ppos); | ||
150 | if ((long)len <= 0) { | ||
151 | kfree(tmp_buffer); | ||
152 | return len; | ||
153 | } | ||
154 | |||
155 | kfree(tmp_buffer); | ||
156 | return len; | ||
157 | } | ||
158 | |||
159 | static int dev_nvram_ioctl(struct inode *inode, struct file *file, | ||
160 | unsigned int cmd, unsigned long arg) | ||
161 | { | ||
162 | switch(cmd) { | ||
163 | #ifdef CONFIG_PPC_PMAC | ||
164 | case OBSOLETE_PMAC_NVRAM_GET_OFFSET: | ||
165 | printk(KERN_WARNING "nvram: Using obsolete PMAC_NVRAM_GET_OFFSET ioctl\n"); | ||
166 | case IOC_NVRAM_GET_OFFSET: { | ||
167 | int part, offset; | ||
168 | |||
169 | if (_machine != PLATFORM_POWERMAC) | ||
170 | return -EINVAL; | ||
171 | if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) | ||
172 | return -EFAULT; | ||
173 | if (part < pmac_nvram_OF || part > pmac_nvram_NR) | ||
174 | return -EINVAL; | ||
175 | offset = pmac_get_partition(part); | ||
176 | if (offset < 0) | ||
177 | return offset; | ||
178 | if (copy_to_user((void __user*)arg, &offset, sizeof(offset)) != 0) | ||
179 | return -EFAULT; | ||
180 | return 0; | ||
181 | } | ||
182 | #endif /* CONFIG_PPC_PMAC */ | ||
183 | } | ||
184 | return -EINVAL; | ||
185 | } | ||
186 | |||
187 | struct file_operations nvram_fops = { | ||
188 | .owner = THIS_MODULE, | ||
189 | .llseek = dev_nvram_llseek, | ||
190 | .read = dev_nvram_read, | ||
191 | .write = dev_nvram_write, | ||
192 | .ioctl = dev_nvram_ioctl, | ||
193 | }; | ||
194 | |||
195 | static struct miscdevice nvram_dev = { | ||
196 | NVRAM_MINOR, | ||
197 | "nvram", | ||
198 | &nvram_fops | ||
199 | }; | ||
200 | |||
201 | |||
202 | #ifdef DEBUG_NVRAM | ||
203 | static void nvram_print_partitions(char * label) | ||
204 | { | ||
205 | struct list_head * p; | ||
206 | struct nvram_partition * tmp_part; | ||
207 | |||
208 | printk(KERN_WARNING "--------%s---------\n", label); | ||
209 | printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n"); | ||
210 | list_for_each(p, &nvram_part->partition) { | ||
211 | tmp_part = list_entry(p, struct nvram_partition, partition); | ||
212 | printk(KERN_WARNING "%d \t%02x\t%02x\t%d\t%s\n", | ||
213 | tmp_part->index, tmp_part->header.signature, | ||
214 | tmp_part->header.checksum, tmp_part->header.length, | ||
215 | tmp_part->header.name); | ||
216 | } | ||
217 | } | ||
218 | #endif | ||
219 | |||
220 | |||
221 | static int nvram_write_header(struct nvram_partition * part) | ||
222 | { | ||
223 | loff_t tmp_index; | ||
224 | int rc; | ||
225 | |||
226 | tmp_index = part->index; | ||
227 | rc = ppc_md.nvram_write((char *)&part->header, NVRAM_HEADER_LEN, &tmp_index); | ||
228 | |||
229 | return rc; | ||
230 | } | ||
231 | |||
232 | |||
233 | static unsigned char nvram_checksum(struct nvram_header *p) | ||
234 | { | ||
235 | unsigned int c_sum, c_sum2; | ||
236 | unsigned short *sp = (unsigned short *)p->name; /* assume 6 shorts */ | ||
237 | c_sum = p->signature + p->length + sp[0] + sp[1] + sp[2] + sp[3] + sp[4] + sp[5]; | ||
238 | |||
239 | /* The sum may have spilled into the 3rd byte. Fold it back. */ | ||
240 | c_sum = ((c_sum & 0xffff) + (c_sum >> 16)) & 0xffff; | ||
241 | /* The sum cannot exceed 2 bytes. Fold it into a checksum */ | ||
242 | c_sum2 = (c_sum >> 8) + (c_sum << 8); | ||
243 | c_sum = ((c_sum + c_sum2) >> 8) & 0xff; | ||
244 | return c_sum; | ||
245 | } | ||
246 | |||
247 | |||
248 | /* | ||
249 | * Find an nvram partition, sig can be 0 for any | ||
250 | * partition or name can be NULL for any name, else | ||
251 | * tries to match both | ||
252 | */ | ||
253 | struct nvram_partition *nvram_find_partition(int sig, const char *name) | ||
254 | { | ||
255 | struct nvram_partition * part; | ||
256 | struct list_head * p; | ||
257 | |||
258 | list_for_each(p, &nvram_part->partition) { | ||
259 | part = list_entry(p, struct nvram_partition, partition); | ||
260 | |||
261 | if (sig && part->header.signature != sig) | ||
262 | continue; | ||
263 | if (name && 0 != strncmp(name, part->header.name, 12)) | ||
264 | continue; | ||
265 | return part; | ||
266 | } | ||
267 | return NULL; | ||
268 | } | ||
269 | EXPORT_SYMBOL(nvram_find_partition); | ||
270 | |||
271 | |||
272 | static int nvram_remove_os_partition(void) | ||
273 | { | ||
274 | struct list_head *i; | ||
275 | struct list_head *j; | ||
276 | struct nvram_partition * part; | ||
277 | struct nvram_partition * cur_part; | ||
278 | int rc; | ||
279 | |||
280 | list_for_each(i, &nvram_part->partition) { | ||
281 | part = list_entry(i, struct nvram_partition, partition); | ||
282 | if (part->header.signature != NVRAM_SIG_OS) | ||
283 | continue; | ||
284 | |||
285 | /* Make os partition a free partition */ | ||
286 | part->header.signature = NVRAM_SIG_FREE; | ||
287 | sprintf(part->header.name, "wwwwwwwwwwww"); | ||
288 | part->header.checksum = nvram_checksum(&part->header); | ||
289 | |||
290 | /* Merge contiguous free partitions backwards */ | ||
291 | list_for_each_prev(j, &part->partition) { | ||
292 | cur_part = list_entry(j, struct nvram_partition, partition); | ||
293 | if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) { | ||
294 | break; | ||
295 | } | ||
296 | |||
297 | part->header.length += cur_part->header.length; | ||
298 | part->header.checksum = nvram_checksum(&part->header); | ||
299 | part->index = cur_part->index; | ||
300 | |||
301 | list_del(&cur_part->partition); | ||
302 | kfree(cur_part); | ||
303 | j = &part->partition; /* fixup our loop */ | ||
304 | } | ||
305 | |||
306 | /* Merge contiguous free partitions forwards */ | ||
307 | list_for_each(j, &part->partition) { | ||
308 | cur_part = list_entry(j, struct nvram_partition, partition); | ||
309 | if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) { | ||
310 | break; | ||
311 | } | ||
312 | |||
313 | part->header.length += cur_part->header.length; | ||
314 | part->header.checksum = nvram_checksum(&part->header); | ||
315 | |||
316 | list_del(&cur_part->partition); | ||
317 | kfree(cur_part); | ||
318 | j = &part->partition; /* fixup our loop */ | ||
319 | } | ||
320 | |||
321 | rc = nvram_write_header(part); | ||
322 | if (rc <= 0) { | ||
323 | printk(KERN_ERR "nvram_remove_os_partition: nvram_write failed (%d)\n", rc); | ||
324 | return rc; | ||
325 | } | ||
326 | |||
327 | } | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | /* nvram_create_os_partition | ||
333 | * | ||
334 | * Create a OS linux partition to buffer error logs. | ||
335 | * Will create a partition starting at the first free | ||
336 | * space found if space has enough room. | ||
337 | */ | ||
338 | static int nvram_create_os_partition(void) | ||
339 | { | ||
340 | struct nvram_partition *part; | ||
341 | struct nvram_partition *new_part; | ||
342 | struct nvram_partition *free_part = NULL; | ||
343 | int seq_init[2] = { 0, 0 }; | ||
344 | loff_t tmp_index; | ||
345 | long size = 0; | ||
346 | int rc; | ||
347 | |||
348 | /* Find a free partition that will give us the maximum needed size | ||
349 | If can't find one that will give us the minimum size needed */ | ||
350 | list_for_each_entry(part, &nvram_part->partition, partition) { | ||
351 | if (part->header.signature != NVRAM_SIG_FREE) | ||
352 | continue; | ||
353 | |||
354 | if (part->header.length >= NVRAM_MAX_REQ) { | ||
355 | size = NVRAM_MAX_REQ; | ||
356 | free_part = part; | ||
357 | break; | ||
358 | } | ||
359 | if (!size && part->header.length >= NVRAM_MIN_REQ) { | ||
360 | size = NVRAM_MIN_REQ; | ||
361 | free_part = part; | ||
362 | } | ||
363 | } | ||
364 | if (!size) | ||
365 | return -ENOSPC; | ||
366 | |||
367 | /* Create our OS partition */ | ||
368 | new_part = kmalloc(sizeof(*new_part), GFP_KERNEL); | ||
369 | if (!new_part) { | ||
370 | printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n"); | ||
371 | return -ENOMEM; | ||
372 | } | ||
373 | |||
374 | new_part->index = free_part->index; | ||
375 | new_part->header.signature = NVRAM_SIG_OS; | ||
376 | new_part->header.length = size; | ||
377 | strcpy(new_part->header.name, "ppc64,linux"); | ||
378 | new_part->header.checksum = nvram_checksum(&new_part->header); | ||
379 | |||
380 | rc = nvram_write_header(new_part); | ||
381 | if (rc <= 0) { | ||
382 | printk(KERN_ERR "nvram_create_os_partition: nvram_write_header \ | ||
383 | failed (%d)\n", rc); | ||
384 | return rc; | ||
385 | } | ||
386 | |||
387 | /* make sure and initialize to zero the sequence number and the error | ||
388 | type logged */ | ||
389 | tmp_index = new_part->index + NVRAM_HEADER_LEN; | ||
390 | rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index); | ||
391 | if (rc <= 0) { | ||
392 | printk(KERN_ERR "nvram_create_os_partition: nvram_write " | ||
393 | "failed (%d)\n", rc); | ||
394 | return rc; | ||
395 | } | ||
396 | |||
397 | nvram_error_log_index = new_part->index + NVRAM_HEADER_LEN; | ||
398 | nvram_error_log_size = ((part->header.length - 1) * | ||
399 | NVRAM_BLOCK_LEN) - sizeof(struct err_log_info); | ||
400 | |||
401 | list_add_tail(&new_part->partition, &free_part->partition); | ||
402 | |||
403 | if (free_part->header.length <= size) { | ||
404 | list_del(&free_part->partition); | ||
405 | kfree(free_part); | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | /* Adjust the partition we stole the space from */ | ||
410 | free_part->index += size * NVRAM_BLOCK_LEN; | ||
411 | free_part->header.length -= size; | ||
412 | free_part->header.checksum = nvram_checksum(&free_part->header); | ||
413 | |||
414 | rc = nvram_write_header(free_part); | ||
415 | if (rc <= 0) { | ||
416 | printk(KERN_ERR "nvram_create_os_partition: nvram_write_header " | ||
417 | "failed (%d)\n", rc); | ||
418 | return rc; | ||
419 | } | ||
420 | |||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | |||
425 | /* nvram_setup_partition | ||
426 | * | ||
427 | * This will setup the partition we need for buffering the | ||
428 | * error logs and cleanup partitions if needed. | ||
429 | * | ||
430 | * The general strategy is the following: | ||
431 | * 1.) If there is ppc64,linux partition large enough then use it. | ||
432 | * 2.) If there is not a ppc64,linux partition large enough, search | ||
433 | * for a free partition that is large enough. | ||
434 | * 3.) If there is not a free partition large enough remove | ||
435 | * _all_ OS partitions and consolidate the space. | ||
436 | * 4.) Will first try getting a chunk that will satisfy the maximum | ||
437 | * error log size (NVRAM_MAX_REQ). | ||
438 | * 5.) If the max chunk cannot be allocated then try finding a chunk | ||
439 | * that will satisfy the minum needed (NVRAM_MIN_REQ). | ||
440 | */ | ||
441 | static int nvram_setup_partition(void) | ||
442 | { | ||
443 | struct list_head * p; | ||
444 | struct nvram_partition * part; | ||
445 | int rc; | ||
446 | |||
447 | /* For now, we don't do any of this on pmac, until I | ||
448 | * have figured out if it's worth killing some unused stuffs | ||
449 | * in our nvram, as Apple defined partitions use pretty much | ||
450 | * all of the space | ||
451 | */ | ||
452 | if (_machine == PLATFORM_POWERMAC) | ||
453 | return -ENOSPC; | ||
454 | |||
455 | /* see if we have an OS partition that meets our needs. | ||
456 | will try getting the max we need. If not we'll delete | ||
457 | partitions and try again. */ | ||
458 | list_for_each(p, &nvram_part->partition) { | ||
459 | part = list_entry(p, struct nvram_partition, partition); | ||
460 | if (part->header.signature != NVRAM_SIG_OS) | ||
461 | continue; | ||
462 | |||
463 | if (strcmp(part->header.name, "ppc64,linux")) | ||
464 | continue; | ||
465 | |||
466 | if (part->header.length >= NVRAM_MIN_REQ) { | ||
467 | /* found our partition */ | ||
468 | nvram_error_log_index = part->index + NVRAM_HEADER_LEN; | ||
469 | nvram_error_log_size = ((part->header.length - 1) * | ||
470 | NVRAM_BLOCK_LEN) - sizeof(struct err_log_info); | ||
471 | return 0; | ||
472 | } | ||
473 | } | ||
474 | |||
475 | /* try creating a partition with the free space we have */ | ||
476 | rc = nvram_create_os_partition(); | ||
477 | if (!rc) { | ||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | /* need to free up some space */ | ||
482 | rc = nvram_remove_os_partition(); | ||
483 | if (rc) { | ||
484 | return rc; | ||
485 | } | ||
486 | |||
487 | /* create a partition in this new space */ | ||
488 | rc = nvram_create_os_partition(); | ||
489 | if (rc) { | ||
490 | printk(KERN_ERR "nvram_create_os_partition: Could not find a " | ||
491 | "NVRAM partition large enough\n"); | ||
492 | return rc; | ||
493 | } | ||
494 | |||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | |||
499 | static int nvram_scan_partitions(void) | ||
500 | { | ||
501 | loff_t cur_index = 0; | ||
502 | struct nvram_header phead; | ||
503 | struct nvram_partition * tmp_part; | ||
504 | unsigned char c_sum; | ||
505 | char * header; | ||
506 | int total_size; | ||
507 | int err; | ||
508 | |||
509 | if (ppc_md.nvram_size == NULL) | ||
510 | return -ENODEV; | ||
511 | total_size = ppc_md.nvram_size(); | ||
512 | |||
513 | header = (char *) kmalloc(NVRAM_HEADER_LEN, GFP_KERNEL); | ||
514 | if (!header) { | ||
515 | printk(KERN_ERR "nvram_scan_partitions: Failed kmalloc\n"); | ||
516 | return -ENOMEM; | ||
517 | } | ||
518 | |||
519 | while (cur_index < total_size) { | ||
520 | |||
521 | err = ppc_md.nvram_read(header, NVRAM_HEADER_LEN, &cur_index); | ||
522 | if (err != NVRAM_HEADER_LEN) { | ||
523 | printk(KERN_ERR "nvram_scan_partitions: Error parsing " | ||
524 | "nvram partitions\n"); | ||
525 | goto out; | ||
526 | } | ||
527 | |||
528 | cur_index -= NVRAM_HEADER_LEN; /* nvram_read will advance us */ | ||
529 | |||
530 | memcpy(&phead, header, NVRAM_HEADER_LEN); | ||
531 | |||
532 | err = 0; | ||
533 | c_sum = nvram_checksum(&phead); | ||
534 | if (c_sum != phead.checksum) { | ||
535 | printk(KERN_WARNING "WARNING: nvram partition checksum" | ||
536 | " was %02x, should be %02x!\n", | ||
537 | phead.checksum, c_sum); | ||
538 | printk(KERN_WARNING "Terminating nvram partition scan\n"); | ||
539 | goto out; | ||
540 | } | ||
541 | if (!phead.length) { | ||
542 | printk(KERN_WARNING "WARNING: nvram corruption " | ||
543 | "detected: 0-length partition\n"); | ||
544 | goto out; | ||
545 | } | ||
546 | tmp_part = (struct nvram_partition *) | ||
547 | kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); | ||
548 | err = -ENOMEM; | ||
549 | if (!tmp_part) { | ||
550 | printk(KERN_ERR "nvram_scan_partitions: kmalloc failed\n"); | ||
551 | goto out; | ||
552 | } | ||
553 | |||
554 | memcpy(&tmp_part->header, &phead, NVRAM_HEADER_LEN); | ||
555 | tmp_part->index = cur_index; | ||
556 | list_add_tail(&tmp_part->partition, &nvram_part->partition); | ||
557 | |||
558 | cur_index += phead.length * NVRAM_BLOCK_LEN; | ||
559 | } | ||
560 | err = 0; | ||
561 | |||
562 | out: | ||
563 | kfree(header); | ||
564 | return err; | ||
565 | } | ||
566 | |||
567 | static int __init nvram_init(void) | ||
568 | { | ||
569 | int error; | ||
570 | int rc; | ||
571 | |||
572 | if (ppc_md.nvram_size == NULL || ppc_md.nvram_size() <= 0) | ||
573 | return -ENODEV; | ||
574 | |||
575 | rc = misc_register(&nvram_dev); | ||
576 | if (rc != 0) { | ||
577 | printk(KERN_ERR "nvram_init: failed to register device\n"); | ||
578 | return rc; | ||
579 | } | ||
580 | |||
581 | /* initialize our anchor for the nvram partition list */ | ||
582 | nvram_part = (struct nvram_partition *) kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); | ||
583 | if (!nvram_part) { | ||
584 | printk(KERN_ERR "nvram_init: Failed kmalloc\n"); | ||
585 | return -ENOMEM; | ||
586 | } | ||
587 | INIT_LIST_HEAD(&nvram_part->partition); | ||
588 | |||
589 | /* Get all the NVRAM partitions */ | ||
590 | error = nvram_scan_partitions(); | ||
591 | if (error) { | ||
592 | printk(KERN_ERR "nvram_init: Failed nvram_scan_partitions\n"); | ||
593 | return error; | ||
594 | } | ||
595 | |||
596 | if(nvram_setup_partition()) | ||
597 | printk(KERN_WARNING "nvram_init: Could not find nvram partition" | ||
598 | " for nvram buffered error logging.\n"); | ||
599 | |||
600 | #ifdef DEBUG_NVRAM | ||
601 | nvram_print_partitions("NVRAM Partitions"); | ||
602 | #endif | ||
603 | |||
604 | return rc; | ||
605 | } | ||
606 | |||
607 | void __exit nvram_cleanup(void) | ||
608 | { | ||
609 | misc_deregister( &nvram_dev ); | ||
610 | } | ||
611 | |||
612 | |||
613 | #ifdef CONFIG_PPC_PSERIES | ||
614 | |||
615 | /* nvram_write_error_log | ||
616 | * | ||
617 | * We need to buffer the error logs into nvram to ensure that we have | ||
618 | * the failure information to decode. If we have a severe error there | ||
619 | * is no way to guarantee that the OS or the machine is in a state to | ||
620 | * get back to user land and write the error to disk. For example if | ||
621 | * the SCSI device driver causes a Machine Check by writing to a bad | ||
622 | * IO address, there is no way of guaranteeing that the device driver | ||
623 | * is in any state that is would also be able to write the error data | ||
624 | * captured to disk, thus we buffer it in NVRAM for analysis on the | ||
625 | * next boot. | ||
626 | * | ||
627 | * In NVRAM the partition containing the error log buffer will looks like: | ||
628 | * Header (in bytes): | ||
629 | * +-----------+----------+--------+------------+------------------+ | ||
630 | * | signature | checksum | length | name | data | | ||
631 | * |0 |1 |2 3|4 15|16 length-1| | ||
632 | * +-----------+----------+--------+------------+------------------+ | ||
633 | * | ||
634 | * The 'data' section would look like (in bytes): | ||
635 | * +--------------+------------+-----------------------------------+ | ||
636 | * | event_logged | sequence # | error log | | ||
637 | * |0 3|4 7|8 nvram_error_log_size-1| | ||
638 | * +--------------+------------+-----------------------------------+ | ||
639 | * | ||
640 | * event_logged: 0 if event has not been logged to syslog, 1 if it has | ||
641 | * sequence #: The unique sequence # for each event. (until it wraps) | ||
642 | * error log: The error log from event_scan | ||
643 | */ | ||
644 | int nvram_write_error_log(char * buff, int length, unsigned int err_type) | ||
645 | { | ||
646 | int rc; | ||
647 | loff_t tmp_index; | ||
648 | struct err_log_info info; | ||
649 | |||
650 | if (no_logging) { | ||
651 | return -EPERM; | ||
652 | } | ||
653 | |||
654 | if (nvram_error_log_index == -1) { | ||
655 | return -ESPIPE; | ||
656 | } | ||
657 | |||
658 | if (length > nvram_error_log_size) { | ||
659 | length = nvram_error_log_size; | ||
660 | } | ||
661 | |||
662 | info.error_type = err_type; | ||
663 | info.seq_num = error_log_cnt; | ||
664 | |||
665 | tmp_index = nvram_error_log_index; | ||
666 | |||
667 | rc = ppc_md.nvram_write((char *)&info, sizeof(struct err_log_info), &tmp_index); | ||
668 | if (rc <= 0) { | ||
669 | printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc); | ||
670 | return rc; | ||
671 | } | ||
672 | |||
673 | rc = ppc_md.nvram_write(buff, length, &tmp_index); | ||
674 | if (rc <= 0) { | ||
675 | printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc); | ||
676 | return rc; | ||
677 | } | ||
678 | |||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | /* nvram_read_error_log | ||
683 | * | ||
684 | * Reads nvram for error log for at most 'length' | ||
685 | */ | ||
686 | int nvram_read_error_log(char * buff, int length, unsigned int * err_type) | ||
687 | { | ||
688 | int rc; | ||
689 | loff_t tmp_index; | ||
690 | struct err_log_info info; | ||
691 | |||
692 | if (nvram_error_log_index == -1) | ||
693 | return -1; | ||
694 | |||
695 | if (length > nvram_error_log_size) | ||
696 | length = nvram_error_log_size; | ||
697 | |||
698 | tmp_index = nvram_error_log_index; | ||
699 | |||
700 | rc = ppc_md.nvram_read((char *)&info, sizeof(struct err_log_info), &tmp_index); | ||
701 | if (rc <= 0) { | ||
702 | printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc); | ||
703 | return rc; | ||
704 | } | ||
705 | |||
706 | rc = ppc_md.nvram_read(buff, length, &tmp_index); | ||
707 | if (rc <= 0) { | ||
708 | printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc); | ||
709 | return rc; | ||
710 | } | ||
711 | |||
712 | error_log_cnt = info.seq_num; | ||
713 | *err_type = info.error_type; | ||
714 | |||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | /* This doesn't actually zero anything, but it sets the event_logged | ||
719 | * word to tell that this event is safely in syslog. | ||
720 | */ | ||
721 | int nvram_clear_error_log(void) | ||
722 | { | ||
723 | loff_t tmp_index; | ||
724 | int clear_word = ERR_FLAG_ALREADY_LOGGED; | ||
725 | int rc; | ||
726 | |||
727 | tmp_index = nvram_error_log_index; | ||
728 | |||
729 | rc = ppc_md.nvram_write((char *)&clear_word, sizeof(int), &tmp_index); | ||
730 | if (rc <= 0) { | ||
731 | printk(KERN_ERR "nvram_clear_error_log: Failed nvram_write (%d)\n", rc); | ||
732 | return rc; | ||
733 | } | ||
734 | |||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | #endif /* CONFIG_PPC_PSERIES */ | ||
739 | |||
740 | module_init(nvram_init); | ||
741 | module_exit(nvram_cleanup); | ||
742 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c new file mode 100644 index 000000000000..5a5b24685081 --- /dev/null +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -0,0 +1,1381 @@ | |||
1 | /* | ||
2 | * Port for PPC64 David Engebretsen, IBM Corp. | ||
3 | * Contains common pci routines for ppc64 platform, pSeries and iSeries brands. | ||
4 | * | ||
5 | * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM | ||
6 | * Rework, based on alpha PCI code. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #undef DEBUG | ||
15 | |||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/bootmem.h> | ||
22 | #include <linux/mm.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/syscalls.h> | ||
25 | |||
26 | #include <asm/processor.h> | ||
27 | #include <asm/io.h> | ||
28 | #include <asm/prom.h> | ||
29 | #include <asm/pci-bridge.h> | ||
30 | #include <asm/byteorder.h> | ||
31 | #include <asm/irq.h> | ||
32 | #include <asm/machdep.h> | ||
33 | #include <asm/ppc-pci.h> | ||
34 | |||
35 | #ifdef DEBUG | ||
36 | #include <asm/udbg.h> | ||
37 | #define DBG(fmt...) udbg_printf(fmt) | ||
38 | #else | ||
39 | #define DBG(fmt...) | ||
40 | #endif | ||
41 | |||
42 | unsigned long pci_probe_only = 1; | ||
43 | unsigned long pci_assign_all_buses = 0; | ||
44 | |||
45 | /* | ||
46 | * legal IO pages under MAX_ISA_PORT. This is to ensure we don't touch | ||
47 | * devices we don't have access to. | ||
48 | */ | ||
49 | unsigned long io_page_mask; | ||
50 | |||
51 | EXPORT_SYMBOL(io_page_mask); | ||
52 | |||
53 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
54 | static void fixup_resource(struct resource *res, struct pci_dev *dev); | ||
55 | static void do_bus_setup(struct pci_bus *bus); | ||
56 | #endif | ||
57 | |||
58 | unsigned int pcibios_assign_all_busses(void) | ||
59 | { | ||
60 | return pci_assign_all_buses; | ||
61 | } | ||
62 | |||
63 | /* pci_io_base -- the base address from which io bars are offsets. | ||
64 | * This is the lowest I/O base address (so bar values are always positive), | ||
65 | * and it *must* be the start of ISA space if an ISA bus exists because | ||
66 | * ISA drivers use hard coded offsets. If no ISA bus exists a dummy | ||
67 | * page is mapped and isa_io_limit prevents access to it. | ||
68 | */ | ||
69 | unsigned long isa_io_base; /* NULL if no ISA bus */ | ||
70 | EXPORT_SYMBOL(isa_io_base); | ||
71 | unsigned long pci_io_base; | ||
72 | EXPORT_SYMBOL(pci_io_base); | ||
73 | |||
74 | void iSeries_pcibios_init(void); | ||
75 | |||
76 | LIST_HEAD(hose_list); | ||
77 | |||
78 | struct dma_mapping_ops pci_dma_ops; | ||
79 | EXPORT_SYMBOL(pci_dma_ops); | ||
80 | |||
81 | int global_phb_number; /* Global phb counter */ | ||
82 | |||
83 | /* Cached ISA bridge dev. */ | ||
84 | struct pci_dev *ppc64_isabridge_dev = NULL; | ||
85 | |||
86 | static void fixup_broken_pcnet32(struct pci_dev* dev) | ||
87 | { | ||
88 | if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { | ||
89 | dev->vendor = PCI_VENDOR_ID_AMD; | ||
90 | pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); | ||
91 | } | ||
92 | } | ||
93 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); | ||
94 | |||
95 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
96 | struct resource *res) | ||
97 | { | ||
98 | unsigned long offset = 0; | ||
99 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
100 | |||
101 | if (!hose) | ||
102 | return; | ||
103 | |||
104 | if (res->flags & IORESOURCE_IO) | ||
105 | offset = (unsigned long)hose->io_base_virt - pci_io_base; | ||
106 | |||
107 | if (res->flags & IORESOURCE_MEM) | ||
108 | offset = hose->pci_mem_offset; | ||
109 | |||
110 | region->start = res->start - offset; | ||
111 | region->end = res->end - offset; | ||
112 | } | ||
113 | |||
114 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
115 | struct pci_bus_region *region) | ||
116 | { | ||
117 | unsigned long offset = 0; | ||
118 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
119 | |||
120 | if (!hose) | ||
121 | return; | ||
122 | |||
123 | if (res->flags & IORESOURCE_IO) | ||
124 | offset = (unsigned long)hose->io_base_virt - pci_io_base; | ||
125 | |||
126 | if (res->flags & IORESOURCE_MEM) | ||
127 | offset = hose->pci_mem_offset; | ||
128 | |||
129 | res->start = region->start + offset; | ||
130 | res->end = region->end + offset; | ||
131 | } | ||
132 | |||
133 | #ifdef CONFIG_HOTPLUG | ||
134 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
135 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
136 | #endif | ||
137 | |||
138 | /* | ||
139 | * We need to avoid collisions with `mirrored' VGA ports | ||
140 | * and other strange ISA hardware, so we always want the | ||
141 | * addresses to be allocated in the 0x000-0x0ff region | ||
142 | * modulo 0x400. | ||
143 | * | ||
144 | * Why? Because some silly external IO cards only decode | ||
145 | * the low 10 bits of the IO address. The 0x00-0xff region | ||
146 | * is reserved for motherboard devices that decode all 16 | ||
147 | * bits, so it's ok to allocate at, say, 0x2800-0x28ff, | ||
148 | * but we want to try to avoid allocating at 0x2900-0x2bff | ||
149 | * which might have be mirrored at 0x0100-0x03ff.. | ||
150 | */ | ||
151 | void pcibios_align_resource(void *data, struct resource *res, | ||
152 | unsigned long size, unsigned long align) | ||
153 | { | ||
154 | struct pci_dev *dev = data; | ||
155 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
156 | unsigned long start = res->start; | ||
157 | unsigned long alignto; | ||
158 | |||
159 | if (res->flags & IORESOURCE_IO) { | ||
160 | unsigned long offset = (unsigned long)hose->io_base_virt - | ||
161 | pci_io_base; | ||
162 | /* Make sure we start at our min on all hoses */ | ||
163 | if (start - offset < PCIBIOS_MIN_IO) | ||
164 | start = PCIBIOS_MIN_IO + offset; | ||
165 | |||
166 | /* | ||
167 | * Put everything into 0x00-0xff region modulo 0x400 | ||
168 | */ | ||
169 | if (start & 0x300) | ||
170 | start = (start + 0x3ff) & ~0x3ff; | ||
171 | |||
172 | } else if (res->flags & IORESOURCE_MEM) { | ||
173 | /* Make sure we start at our min on all hoses */ | ||
174 | if (start - hose->pci_mem_offset < PCIBIOS_MIN_MEM) | ||
175 | start = PCIBIOS_MIN_MEM + hose->pci_mem_offset; | ||
176 | |||
177 | /* Align to multiple of size of minimum base. */ | ||
178 | alignto = max(0x1000UL, align); | ||
179 | start = ALIGN(start, alignto); | ||
180 | } | ||
181 | |||
182 | res->start = start; | ||
183 | } | ||
184 | |||
185 | static DEFINE_SPINLOCK(hose_spinlock); | ||
186 | |||
187 | /* | ||
188 | * pci_controller(phb) initialized common variables. | ||
189 | */ | ||
190 | static void __devinit pci_setup_pci_controller(struct pci_controller *hose) | ||
191 | { | ||
192 | memset(hose, 0, sizeof(struct pci_controller)); | ||
193 | |||
194 | spin_lock(&hose_spinlock); | ||
195 | hose->global_number = global_phb_number++; | ||
196 | list_add_tail(&hose->list_node, &hose_list); | ||
197 | spin_unlock(&hose_spinlock); | ||
198 | } | ||
199 | |||
200 | static void add_linux_pci_domain(struct device_node *dev, | ||
201 | struct pci_controller *phb) | ||
202 | { | ||
203 | struct property *of_prop; | ||
204 | unsigned int size; | ||
205 | |||
206 | of_prop = (struct property *) | ||
207 | get_property(dev, "linux,pci-domain", &size); | ||
208 | if (of_prop != NULL) | ||
209 | return; | ||
210 | WARN_ON(of_prop && size < sizeof(int)); | ||
211 | if (of_prop && size < sizeof(int)) | ||
212 | of_prop = NULL; | ||
213 | size = sizeof(struct property) + sizeof(int); | ||
214 | if (of_prop == NULL) { | ||
215 | if (mem_init_done) | ||
216 | of_prop = kmalloc(size, GFP_KERNEL); | ||
217 | else | ||
218 | of_prop = alloc_bootmem(size); | ||
219 | } | ||
220 | memset(of_prop, 0, sizeof(struct property)); | ||
221 | of_prop->name = "linux,pci-domain"; | ||
222 | of_prop->length = sizeof(int); | ||
223 | of_prop->value = (unsigned char *)&of_prop[1]; | ||
224 | *((int *)of_prop->value) = phb->global_number; | ||
225 | prom_add_property(dev, of_prop); | ||
226 | } | ||
227 | |||
228 | struct pci_controller * pcibios_alloc_controller(struct device_node *dev) | ||
229 | { | ||
230 | struct pci_controller *phb; | ||
231 | |||
232 | if (mem_init_done) | ||
233 | phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL); | ||
234 | else | ||
235 | phb = alloc_bootmem(sizeof (struct pci_controller)); | ||
236 | if (phb == NULL) | ||
237 | return NULL; | ||
238 | pci_setup_pci_controller(phb); | ||
239 | phb->arch_data = dev; | ||
240 | phb->is_dynamic = mem_init_done; | ||
241 | if (dev) | ||
242 | add_linux_pci_domain(dev, phb); | ||
243 | return phb; | ||
244 | } | ||
245 | |||
246 | void pcibios_free_controller(struct pci_controller *phb) | ||
247 | { | ||
248 | if (phb->arch_data) { | ||
249 | struct device_node *np = phb->arch_data; | ||
250 | int *domain = (int *)get_property(np, | ||
251 | "linux,pci-domain", NULL); | ||
252 | if (domain) | ||
253 | *domain = -1; | ||
254 | } | ||
255 | if (phb->is_dynamic) | ||
256 | kfree(phb); | ||
257 | } | ||
258 | |||
259 | static void __init pcibios_claim_one_bus(struct pci_bus *b) | ||
260 | { | ||
261 | struct pci_dev *dev; | ||
262 | struct pci_bus *child_bus; | ||
263 | |||
264 | list_for_each_entry(dev, &b->devices, bus_list) { | ||
265 | int i; | ||
266 | |||
267 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
268 | struct resource *r = &dev->resource[i]; | ||
269 | |||
270 | if (r->parent || !r->start || !r->flags) | ||
271 | continue; | ||
272 | pci_claim_resource(dev, i); | ||
273 | } | ||
274 | } | ||
275 | |||
276 | list_for_each_entry(child_bus, &b->children, node) | ||
277 | pcibios_claim_one_bus(child_bus); | ||
278 | } | ||
279 | |||
280 | #ifndef CONFIG_PPC_ISERIES | ||
281 | static void __init pcibios_claim_of_setup(void) | ||
282 | { | ||
283 | struct pci_bus *b; | ||
284 | |||
285 | list_for_each_entry(b, &pci_root_buses, node) | ||
286 | pcibios_claim_one_bus(b); | ||
287 | } | ||
288 | #endif | ||
289 | |||
290 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
291 | static u32 get_int_prop(struct device_node *np, const char *name, u32 def) | ||
292 | { | ||
293 | u32 *prop; | ||
294 | int len; | ||
295 | |||
296 | prop = (u32 *) get_property(np, name, &len); | ||
297 | if (prop && len >= 4) | ||
298 | return *prop; | ||
299 | return def; | ||
300 | } | ||
301 | |||
302 | static unsigned int pci_parse_of_flags(u32 addr0) | ||
303 | { | ||
304 | unsigned int flags = 0; | ||
305 | |||
306 | if (addr0 & 0x02000000) { | ||
307 | flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY; | ||
308 | flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64; | ||
309 | flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M; | ||
310 | if (addr0 & 0x40000000) | ||
311 | flags |= IORESOURCE_PREFETCH | ||
312 | | PCI_BASE_ADDRESS_MEM_PREFETCH; | ||
313 | } else if (addr0 & 0x01000000) | ||
314 | flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; | ||
315 | return flags; | ||
316 | } | ||
317 | |||
318 | #define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1]) | ||
319 | |||
320 | static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) | ||
321 | { | ||
322 | u64 base, size; | ||
323 | unsigned int flags; | ||
324 | struct resource *res; | ||
325 | u32 *addrs, i; | ||
326 | int proplen; | ||
327 | |||
328 | addrs = (u32 *) get_property(node, "assigned-addresses", &proplen); | ||
329 | if (!addrs) | ||
330 | return; | ||
331 | for (; proplen >= 20; proplen -= 20, addrs += 5) { | ||
332 | flags = pci_parse_of_flags(addrs[0]); | ||
333 | if (!flags) | ||
334 | continue; | ||
335 | base = GET_64BIT(addrs, 1); | ||
336 | size = GET_64BIT(addrs, 3); | ||
337 | if (!size) | ||
338 | continue; | ||
339 | i = addrs[0] & 0xff; | ||
340 | if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { | ||
341 | res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; | ||
342 | } else if (i == dev->rom_base_reg) { | ||
343 | res = &dev->resource[PCI_ROM_RESOURCE]; | ||
344 | flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE; | ||
345 | } else { | ||
346 | printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i); | ||
347 | continue; | ||
348 | } | ||
349 | res->start = base; | ||
350 | res->end = base + size - 1; | ||
351 | res->flags = flags; | ||
352 | res->name = pci_name(dev); | ||
353 | fixup_resource(res, dev); | ||
354 | } | ||
355 | } | ||
356 | |||
357 | struct pci_dev *of_create_pci_dev(struct device_node *node, | ||
358 | struct pci_bus *bus, int devfn) | ||
359 | { | ||
360 | struct pci_dev *dev; | ||
361 | const char *type; | ||
362 | |||
363 | dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); | ||
364 | if (!dev) | ||
365 | return NULL; | ||
366 | type = get_property(node, "device_type", NULL); | ||
367 | if (type == NULL) | ||
368 | type = ""; | ||
369 | |||
370 | memset(dev, 0, sizeof(struct pci_dev)); | ||
371 | dev->bus = bus; | ||
372 | dev->sysdata = node; | ||
373 | dev->dev.parent = bus->bridge; | ||
374 | dev->dev.bus = &pci_bus_type; | ||
375 | dev->devfn = devfn; | ||
376 | dev->multifunction = 0; /* maybe a lie? */ | ||
377 | |||
378 | dev->vendor = get_int_prop(node, "vendor-id", 0xffff); | ||
379 | dev->device = get_int_prop(node, "device-id", 0xffff); | ||
380 | dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0); | ||
381 | dev->subsystem_device = get_int_prop(node, "subsystem-id", 0); | ||
382 | |||
383 | dev->cfg_size = 256; /*pci_cfg_space_size(dev);*/ | ||
384 | |||
385 | sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), | ||
386 | dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); | ||
387 | dev->class = get_int_prop(node, "class-code", 0); | ||
388 | |||
389 | dev->current_state = 4; /* unknown power state */ | ||
390 | |||
391 | if (!strcmp(type, "pci")) { | ||
392 | /* a PCI-PCI bridge */ | ||
393 | dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; | ||
394 | dev->rom_base_reg = PCI_ROM_ADDRESS1; | ||
395 | } else if (!strcmp(type, "cardbus")) { | ||
396 | dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; | ||
397 | } else { | ||
398 | dev->hdr_type = PCI_HEADER_TYPE_NORMAL; | ||
399 | dev->rom_base_reg = PCI_ROM_ADDRESS; | ||
400 | dev->irq = NO_IRQ; | ||
401 | if (node->n_intrs > 0) { | ||
402 | dev->irq = node->intrs[0].line; | ||
403 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, | ||
404 | dev->irq); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | pci_parse_of_addrs(node, dev); | ||
409 | |||
410 | pci_device_add(dev, bus); | ||
411 | |||
412 | /* XXX pci_scan_msi_device(dev); */ | ||
413 | |||
414 | return dev; | ||
415 | } | ||
416 | EXPORT_SYMBOL(of_create_pci_dev); | ||
417 | |||
418 | void __devinit of_scan_bus(struct device_node *node, | ||
419 | struct pci_bus *bus) | ||
420 | { | ||
421 | struct device_node *child = NULL; | ||
422 | u32 *reg; | ||
423 | int reglen, devfn; | ||
424 | struct pci_dev *dev; | ||
425 | |||
426 | while ((child = of_get_next_child(node, child)) != NULL) { | ||
427 | reg = (u32 *) get_property(child, "reg", ®len); | ||
428 | if (reg == NULL || reglen < 20) | ||
429 | continue; | ||
430 | devfn = (reg[0] >> 8) & 0xff; | ||
431 | /* create a new pci_dev for this device */ | ||
432 | dev = of_create_pci_dev(child, bus, devfn); | ||
433 | if (!dev) | ||
434 | continue; | ||
435 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | ||
436 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | ||
437 | of_scan_pci_bridge(child, dev); | ||
438 | } | ||
439 | |||
440 | do_bus_setup(bus); | ||
441 | } | ||
442 | EXPORT_SYMBOL(of_scan_bus); | ||
443 | |||
444 | void __devinit of_scan_pci_bridge(struct device_node *node, | ||
445 | struct pci_dev *dev) | ||
446 | { | ||
447 | struct pci_bus *bus; | ||
448 | u32 *busrange, *ranges; | ||
449 | int len, i, mode; | ||
450 | struct resource *res; | ||
451 | unsigned int flags; | ||
452 | u64 size; | ||
453 | |||
454 | /* parse bus-range property */ | ||
455 | busrange = (u32 *) get_property(node, "bus-range", &len); | ||
456 | if (busrange == NULL || len != 8) { | ||
457 | printk(KERN_ERR "Can't get bus-range for PCI-PCI bridge %s\n", | ||
458 | node->full_name); | ||
459 | return; | ||
460 | } | ||
461 | ranges = (u32 *) get_property(node, "ranges", &len); | ||
462 | if (ranges == NULL) { | ||
463 | printk(KERN_ERR "Can't get ranges for PCI-PCI bridge %s\n", | ||
464 | node->full_name); | ||
465 | return; | ||
466 | } | ||
467 | |||
468 | bus = pci_add_new_bus(dev->bus, dev, busrange[0]); | ||
469 | if (!bus) { | ||
470 | printk(KERN_ERR "Failed to create pci bus for %s\n", | ||
471 | node->full_name); | ||
472 | return; | ||
473 | } | ||
474 | |||
475 | bus->primary = dev->bus->number; | ||
476 | bus->subordinate = busrange[1]; | ||
477 | bus->bridge_ctl = 0; | ||
478 | bus->sysdata = node; | ||
479 | |||
480 | /* parse ranges property */ | ||
481 | /* PCI #address-cells == 3 and #size-cells == 2 always */ | ||
482 | res = &dev->resource[PCI_BRIDGE_RESOURCES]; | ||
483 | for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) { | ||
484 | res->flags = 0; | ||
485 | bus->resource[i] = res; | ||
486 | ++res; | ||
487 | } | ||
488 | i = 1; | ||
489 | for (; len >= 32; len -= 32, ranges += 8) { | ||
490 | flags = pci_parse_of_flags(ranges[0]); | ||
491 | size = GET_64BIT(ranges, 6); | ||
492 | if (flags == 0 || size == 0) | ||
493 | continue; | ||
494 | if (flags & IORESOURCE_IO) { | ||
495 | res = bus->resource[0]; | ||
496 | if (res->flags) { | ||
497 | printk(KERN_ERR "PCI: ignoring extra I/O range" | ||
498 | " for bridge %s\n", node->full_name); | ||
499 | continue; | ||
500 | } | ||
501 | } else { | ||
502 | if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { | ||
503 | printk(KERN_ERR "PCI: too many memory ranges" | ||
504 | " for bridge %s\n", node->full_name); | ||
505 | continue; | ||
506 | } | ||
507 | res = bus->resource[i]; | ||
508 | ++i; | ||
509 | } | ||
510 | res->start = GET_64BIT(ranges, 1); | ||
511 | res->end = res->start + size - 1; | ||
512 | res->flags = flags; | ||
513 | fixup_resource(res, dev); | ||
514 | } | ||
515 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), | ||
516 | bus->number); | ||
517 | |||
518 | mode = PCI_PROBE_NORMAL; | ||
519 | if (ppc_md.pci_probe_mode) | ||
520 | mode = ppc_md.pci_probe_mode(bus); | ||
521 | if (mode == PCI_PROBE_DEVTREE) | ||
522 | of_scan_bus(node, bus); | ||
523 | else if (mode == PCI_PROBE_NORMAL) | ||
524 | pci_scan_child_bus(bus); | ||
525 | } | ||
526 | EXPORT_SYMBOL(of_scan_pci_bridge); | ||
527 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
528 | |||
529 | void __devinit scan_phb(struct pci_controller *hose) | ||
530 | { | ||
531 | struct pci_bus *bus; | ||
532 | struct device_node *node = hose->arch_data; | ||
533 | int i, mode; | ||
534 | struct resource *res; | ||
535 | |||
536 | bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node); | ||
537 | if (bus == NULL) { | ||
538 | printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", | ||
539 | hose->global_number); | ||
540 | return; | ||
541 | } | ||
542 | bus->secondary = hose->first_busno; | ||
543 | hose->bus = bus; | ||
544 | |||
545 | bus->resource[0] = res = &hose->io_resource; | ||
546 | if (res->flags && request_resource(&ioport_resource, res)) | ||
547 | printk(KERN_ERR "Failed to request PCI IO region " | ||
548 | "on PCI domain %04x\n", hose->global_number); | ||
549 | |||
550 | for (i = 0; i < 3; ++i) { | ||
551 | res = &hose->mem_resources[i]; | ||
552 | bus->resource[i+1] = res; | ||
553 | if (res->flags && request_resource(&iomem_resource, res)) | ||
554 | printk(KERN_ERR "Failed to request PCI memory region " | ||
555 | "on PCI domain %04x\n", hose->global_number); | ||
556 | } | ||
557 | |||
558 | mode = PCI_PROBE_NORMAL; | ||
559 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
560 | if (ppc_md.pci_probe_mode) | ||
561 | mode = ppc_md.pci_probe_mode(bus); | ||
562 | if (mode == PCI_PROBE_DEVTREE) { | ||
563 | bus->subordinate = hose->last_busno; | ||
564 | of_scan_bus(node, bus); | ||
565 | } | ||
566 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
567 | if (mode == PCI_PROBE_NORMAL) | ||
568 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); | ||
569 | pci_bus_add_devices(bus); | ||
570 | } | ||
571 | |||
572 | static int __init pcibios_init(void) | ||
573 | { | ||
574 | struct pci_controller *hose, *tmp; | ||
575 | |||
576 | /* For now, override phys_mem_access_prot. If we need it, | ||
577 | * later, we may move that initialization to each ppc_md | ||
578 | */ | ||
579 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; | ||
580 | |||
581 | #ifdef CONFIG_PPC_ISERIES | ||
582 | iSeries_pcibios_init(); | ||
583 | #endif | ||
584 | |||
585 | printk("PCI: Probing PCI hardware\n"); | ||
586 | |||
587 | /* Scan all of the recorded PCI controllers. */ | ||
588 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) | ||
589 | scan_phb(hose); | ||
590 | |||
591 | #ifndef CONFIG_PPC_ISERIES | ||
592 | if (pci_probe_only) | ||
593 | pcibios_claim_of_setup(); | ||
594 | else | ||
595 | /* FIXME: `else' will be removed when | ||
596 | pci_assign_unassigned_resources() is able to work | ||
597 | correctly with [partially] allocated PCI tree. */ | ||
598 | pci_assign_unassigned_resources(); | ||
599 | #endif /* !CONFIG_PPC_ISERIES */ | ||
600 | |||
601 | /* Call machine dependent final fixup */ | ||
602 | if (ppc_md.pcibios_fixup) | ||
603 | ppc_md.pcibios_fixup(); | ||
604 | |||
605 | /* Cache the location of the ISA bridge (if we have one) */ | ||
606 | ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); | ||
607 | if (ppc64_isabridge_dev != NULL) | ||
608 | printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev)); | ||
609 | |||
610 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
611 | /* map in PCI I/O space */ | ||
612 | phbs_remap_io(); | ||
613 | #endif | ||
614 | |||
615 | printk("PCI: Probing PCI hardware done\n"); | ||
616 | |||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | subsys_initcall(pcibios_init); | ||
621 | |||
622 | char __init *pcibios_setup(char *str) | ||
623 | { | ||
624 | return str; | ||
625 | } | ||
626 | |||
627 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
628 | { | ||
629 | u16 cmd, oldcmd; | ||
630 | int i; | ||
631 | |||
632 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
633 | oldcmd = cmd; | ||
634 | |||
635 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
636 | struct resource *res = &dev->resource[i]; | ||
637 | |||
638 | /* Only set up the requested stuff */ | ||
639 | if (!(mask & (1<<i))) | ||
640 | continue; | ||
641 | |||
642 | if (res->flags & IORESOURCE_IO) | ||
643 | cmd |= PCI_COMMAND_IO; | ||
644 | if (res->flags & IORESOURCE_MEM) | ||
645 | cmd |= PCI_COMMAND_MEMORY; | ||
646 | } | ||
647 | |||
648 | if (cmd != oldcmd) { | ||
649 | printk(KERN_DEBUG "PCI: Enabling device: (%s), cmd %x\n", | ||
650 | pci_name(dev), cmd); | ||
651 | /* Enable the appropriate bits in the PCI command register. */ | ||
652 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
653 | } | ||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | /* | ||
658 | * Return the domain number for this bus. | ||
659 | */ | ||
660 | int pci_domain_nr(struct pci_bus *bus) | ||
661 | { | ||
662 | #ifdef CONFIG_PPC_ISERIES | ||
663 | return 0; | ||
664 | #else | ||
665 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
666 | |||
667 | return hose->global_number; | ||
668 | #endif | ||
669 | } | ||
670 | |||
671 | EXPORT_SYMBOL(pci_domain_nr); | ||
672 | |||
673 | /* Decide whether to display the domain number in /proc */ | ||
674 | int pci_proc_domain(struct pci_bus *bus) | ||
675 | { | ||
676 | #ifdef CONFIG_PPC_ISERIES | ||
677 | return 0; | ||
678 | #else | ||
679 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
680 | return hose->buid; | ||
681 | #endif | ||
682 | } | ||
683 | |||
684 | /* | ||
685 | * Platform support for /proc/bus/pci/X/Y mmap()s, | ||
686 | * modelled on the sparc64 implementation by Dave Miller. | ||
687 | * -- paulus. | ||
688 | */ | ||
689 | |||
690 | /* | ||
691 | * Adjust vm_pgoff of VMA such that it is the physical page offset | ||
692 | * corresponding to the 32-bit pci bus offset for DEV requested by the user. | ||
693 | * | ||
694 | * Basically, the user finds the base address for his device which he wishes | ||
695 | * to mmap. They read the 32-bit value from the config space base register, | ||
696 | * add whatever PAGE_SIZE multiple offset they wish, and feed this into the | ||
697 | * offset parameter of mmap on /proc/bus/pci/XXX for that device. | ||
698 | * | ||
699 | * Returns negative error code on failure, zero on success. | ||
700 | */ | ||
701 | static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | ||
702 | unsigned long *offset, | ||
703 | enum pci_mmap_state mmap_state) | ||
704 | { | ||
705 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
706 | unsigned long io_offset = 0; | ||
707 | int i, res_bit; | ||
708 | |||
709 | if (hose == 0) | ||
710 | return NULL; /* should never happen */ | ||
711 | |||
712 | /* If memory, add on the PCI bridge address offset */ | ||
713 | if (mmap_state == pci_mmap_mem) { | ||
714 | *offset += hose->pci_mem_offset; | ||
715 | res_bit = IORESOURCE_MEM; | ||
716 | } else { | ||
717 | io_offset = (unsigned long)hose->io_base_virt - pci_io_base; | ||
718 | *offset += io_offset; | ||
719 | res_bit = IORESOURCE_IO; | ||
720 | } | ||
721 | |||
722 | /* | ||
723 | * Check that the offset requested corresponds to one of the | ||
724 | * resources of the device. | ||
725 | */ | ||
726 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
727 | struct resource *rp = &dev->resource[i]; | ||
728 | int flags = rp->flags; | ||
729 | |||
730 | /* treat ROM as memory (should be already) */ | ||
731 | if (i == PCI_ROM_RESOURCE) | ||
732 | flags |= IORESOURCE_MEM; | ||
733 | |||
734 | /* Active and same type? */ | ||
735 | if ((flags & res_bit) == 0) | ||
736 | continue; | ||
737 | |||
738 | /* In the range of this resource? */ | ||
739 | if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end) | ||
740 | continue; | ||
741 | |||
742 | /* found it! construct the final physical address */ | ||
743 | if (mmap_state == pci_mmap_io) | ||
744 | *offset += hose->io_base_phys - io_offset; | ||
745 | return rp; | ||
746 | } | ||
747 | |||
748 | return NULL; | ||
749 | } | ||
750 | |||
751 | /* | ||
752 | * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci | ||
753 | * device mapping. | ||
754 | */ | ||
755 | static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | ||
756 | pgprot_t protection, | ||
757 | enum pci_mmap_state mmap_state, | ||
758 | int write_combine) | ||
759 | { | ||
760 | unsigned long prot = pgprot_val(protection); | ||
761 | |||
762 | /* Write combine is always 0 on non-memory space mappings. On | ||
763 | * memory space, if the user didn't pass 1, we check for a | ||
764 | * "prefetchable" resource. This is a bit hackish, but we use | ||
765 | * this to workaround the inability of /sysfs to provide a write | ||
766 | * combine bit | ||
767 | */ | ||
768 | if (mmap_state != pci_mmap_mem) | ||
769 | write_combine = 0; | ||
770 | else if (write_combine == 0) { | ||
771 | if (rp->flags & IORESOURCE_PREFETCH) | ||
772 | write_combine = 1; | ||
773 | } | ||
774 | |||
775 | /* XXX would be nice to have a way to ask for write-through */ | ||
776 | prot |= _PAGE_NO_CACHE; | ||
777 | if (write_combine) | ||
778 | prot &= ~_PAGE_GUARDED; | ||
779 | else | ||
780 | prot |= _PAGE_GUARDED; | ||
781 | |||
782 | printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, | ||
783 | prot); | ||
784 | |||
785 | return __pgprot(prot); | ||
786 | } | ||
787 | |||
788 | /* | ||
789 | * This one is used by /dev/mem and fbdev who have no clue about the | ||
790 | * PCI device, it tries to find the PCI device first and calls the | ||
791 | * above routine | ||
792 | */ | ||
793 | pgprot_t pci_phys_mem_access_prot(struct file *file, | ||
794 | unsigned long pfn, | ||
795 | unsigned long size, | ||
796 | pgprot_t protection) | ||
797 | { | ||
798 | struct pci_dev *pdev = NULL; | ||
799 | struct resource *found = NULL; | ||
800 | unsigned long prot = pgprot_val(protection); | ||
801 | unsigned long offset = pfn << PAGE_SHIFT; | ||
802 | int i; | ||
803 | |||
804 | if (page_is_ram(pfn)) | ||
805 | return __pgprot(prot); | ||
806 | |||
807 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; | ||
808 | |||
809 | for_each_pci_dev(pdev) { | ||
810 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
811 | struct resource *rp = &pdev->resource[i]; | ||
812 | int flags = rp->flags; | ||
813 | |||
814 | /* Active and same type? */ | ||
815 | if ((flags & IORESOURCE_MEM) == 0) | ||
816 | continue; | ||
817 | /* In the range of this resource? */ | ||
818 | if (offset < (rp->start & PAGE_MASK) || | ||
819 | offset > rp->end) | ||
820 | continue; | ||
821 | found = rp; | ||
822 | break; | ||
823 | } | ||
824 | if (found) | ||
825 | break; | ||
826 | } | ||
827 | if (found) { | ||
828 | if (found->flags & IORESOURCE_PREFETCH) | ||
829 | prot &= ~_PAGE_GUARDED; | ||
830 | pci_dev_put(pdev); | ||
831 | } | ||
832 | |||
833 | DBG("non-PCI map for %lx, prot: %lx\n", offset, prot); | ||
834 | |||
835 | return __pgprot(prot); | ||
836 | } | ||
837 | |||
838 | |||
839 | /* | ||
840 | * Perform the actual remap of the pages for a PCI device mapping, as | ||
841 | * appropriate for this architecture. The region in the process to map | ||
842 | * is described by vm_start and vm_end members of VMA, the base physical | ||
843 | * address is found in vm_pgoff. | ||
844 | * The pci device structure is provided so that architectures may make mapping | ||
845 | * decisions on a per-device or per-bus basis. | ||
846 | * | ||
847 | * Returns a negative error code on failure, zero on success. | ||
848 | */ | ||
849 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | ||
850 | enum pci_mmap_state mmap_state, | ||
851 | int write_combine) | ||
852 | { | ||
853 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | ||
854 | struct resource *rp; | ||
855 | int ret; | ||
856 | |||
857 | rp = __pci_mmap_make_offset(dev, &offset, mmap_state); | ||
858 | if (rp == NULL) | ||
859 | return -EINVAL; | ||
860 | |||
861 | vma->vm_pgoff = offset >> PAGE_SHIFT; | ||
862 | vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO; | ||
863 | vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, | ||
864 | vma->vm_page_prot, | ||
865 | mmap_state, write_combine); | ||
866 | |||
867 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | ||
868 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | ||
869 | |||
870 | return ret; | ||
871 | } | ||
872 | |||
873 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
874 | static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) | ||
875 | { | ||
876 | struct pci_dev *pdev; | ||
877 | struct device_node *np; | ||
878 | |||
879 | pdev = to_pci_dev (dev); | ||
880 | np = pci_device_to_OF_node(pdev); | ||
881 | if (np == NULL || np->full_name == NULL) | ||
882 | return 0; | ||
883 | return sprintf(buf, "%s", np->full_name); | ||
884 | } | ||
885 | static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); | ||
886 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
887 | |||
888 | void pcibios_add_platform_entries(struct pci_dev *pdev) | ||
889 | { | ||
890 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
891 | device_create_file(&pdev->dev, &dev_attr_devspec); | ||
892 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
893 | } | ||
894 | |||
895 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
896 | |||
897 | #define ISA_SPACE_MASK 0x1 | ||
898 | #define ISA_SPACE_IO 0x1 | ||
899 | |||
900 | static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node, | ||
901 | unsigned long phb_io_base_phys, | ||
902 | void __iomem * phb_io_base_virt) | ||
903 | { | ||
904 | struct isa_range *range; | ||
905 | unsigned long pci_addr; | ||
906 | unsigned int isa_addr; | ||
907 | unsigned int size; | ||
908 | int rlen = 0; | ||
909 | |||
910 | range = (struct isa_range *) get_property(isa_node, "ranges", &rlen); | ||
911 | if (range == NULL || (rlen < sizeof(struct isa_range))) { | ||
912 | printk(KERN_ERR "no ISA ranges or unexpected isa range size," | ||
913 | "mapping 64k\n"); | ||
914 | __ioremap_explicit(phb_io_base_phys, | ||
915 | (unsigned long)phb_io_base_virt, | ||
916 | 0x10000, _PAGE_NO_CACHE | _PAGE_GUARDED); | ||
917 | return; | ||
918 | } | ||
919 | |||
920 | /* From "ISA Binding to 1275" | ||
921 | * The ranges property is laid out as an array of elements, | ||
922 | * each of which comprises: | ||
923 | * cells 0 - 1: an ISA address | ||
924 | * cells 2 - 4: a PCI address | ||
925 | * (size depending on dev->n_addr_cells) | ||
926 | * cell 5: the size of the range | ||
927 | */ | ||
928 | if ((range->isa_addr.a_hi && ISA_SPACE_MASK) == ISA_SPACE_IO) { | ||
929 | isa_addr = range->isa_addr.a_lo; | ||
930 | pci_addr = (unsigned long) range->pci_addr.a_mid << 32 | | ||
931 | range->pci_addr.a_lo; | ||
932 | |||
933 | /* Assume these are both zero */ | ||
934 | if ((pci_addr != 0) || (isa_addr != 0)) { | ||
935 | printk(KERN_ERR "unexpected isa to pci mapping: %s\n", | ||
936 | __FUNCTION__); | ||
937 | return; | ||
938 | } | ||
939 | |||
940 | size = PAGE_ALIGN(range->size); | ||
941 | |||
942 | __ioremap_explicit(phb_io_base_phys, | ||
943 | (unsigned long) phb_io_base_virt, | ||
944 | size, _PAGE_NO_CACHE | _PAGE_GUARDED); | ||
945 | } | ||
946 | } | ||
947 | |||
948 | void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, | ||
949 | struct device_node *dev, int prim) | ||
950 | { | ||
951 | unsigned int *ranges, pci_space; | ||
952 | unsigned long size; | ||
953 | int rlen = 0; | ||
954 | int memno = 0; | ||
955 | struct resource *res; | ||
956 | int np, na = prom_n_addr_cells(dev); | ||
957 | unsigned long pci_addr, cpu_phys_addr; | ||
958 | |||
959 | np = na + 5; | ||
960 | |||
961 | /* From "PCI Binding to 1275" | ||
962 | * The ranges property is laid out as an array of elements, | ||
963 | * each of which comprises: | ||
964 | * cells 0 - 2: a PCI address | ||
965 | * cells 3 or 3+4: a CPU physical address | ||
966 | * (size depending on dev->n_addr_cells) | ||
967 | * cells 4+5 or 5+6: the size of the range | ||
968 | */ | ||
969 | ranges = (unsigned int *) get_property(dev, "ranges", &rlen); | ||
970 | if (ranges == NULL) | ||
971 | return; | ||
972 | hose->io_base_phys = 0; | ||
973 | while ((rlen -= np * sizeof(unsigned int)) >= 0) { | ||
974 | res = NULL; | ||
975 | pci_space = ranges[0]; | ||
976 | pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2]; | ||
977 | |||
978 | cpu_phys_addr = ranges[3]; | ||
979 | if (na >= 2) | ||
980 | cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4]; | ||
981 | |||
982 | size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4]; | ||
983 | ranges += np; | ||
984 | if (size == 0) | ||
985 | continue; | ||
986 | |||
987 | /* Now consume following elements while they are contiguous */ | ||
988 | while (rlen >= np * sizeof(unsigned int)) { | ||
989 | unsigned long addr, phys; | ||
990 | |||
991 | if (ranges[0] != pci_space) | ||
992 | break; | ||
993 | addr = ((unsigned long)ranges[1] << 32) | ranges[2]; | ||
994 | phys = ranges[3]; | ||
995 | if (na >= 2) | ||
996 | phys = (phys << 32) | ranges[4]; | ||
997 | if (addr != pci_addr + size || | ||
998 | phys != cpu_phys_addr + size) | ||
999 | break; | ||
1000 | |||
1001 | size += ((unsigned long)ranges[na+3] << 32) | ||
1002 | | ranges[na+4]; | ||
1003 | ranges += np; | ||
1004 | rlen -= np * sizeof(unsigned int); | ||
1005 | } | ||
1006 | |||
1007 | switch ((pci_space >> 24) & 0x3) { | ||
1008 | case 1: /* I/O space */ | ||
1009 | hose->io_base_phys = cpu_phys_addr; | ||
1010 | hose->pci_io_size = size; | ||
1011 | |||
1012 | res = &hose->io_resource; | ||
1013 | res->flags = IORESOURCE_IO; | ||
1014 | res->start = pci_addr; | ||
1015 | DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number, | ||
1016 | res->start, res->start + size - 1); | ||
1017 | break; | ||
1018 | case 2: /* memory space */ | ||
1019 | memno = 0; | ||
1020 | while (memno < 3 && hose->mem_resources[memno].flags) | ||
1021 | ++memno; | ||
1022 | |||
1023 | if (memno == 0) | ||
1024 | hose->pci_mem_offset = cpu_phys_addr - pci_addr; | ||
1025 | if (memno < 3) { | ||
1026 | res = &hose->mem_resources[memno]; | ||
1027 | res->flags = IORESOURCE_MEM; | ||
1028 | res->start = cpu_phys_addr; | ||
1029 | DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number, | ||
1030 | res->start, res->start + size - 1); | ||
1031 | } | ||
1032 | break; | ||
1033 | } | ||
1034 | if (res != NULL) { | ||
1035 | res->name = dev->full_name; | ||
1036 | res->end = res->start + size - 1; | ||
1037 | res->parent = NULL; | ||
1038 | res->sibling = NULL; | ||
1039 | res->child = NULL; | ||
1040 | } | ||
1041 | } | ||
1042 | } | ||
1043 | |||
1044 | void __init pci_setup_phb_io(struct pci_controller *hose, int primary) | ||
1045 | { | ||
1046 | unsigned long size = hose->pci_io_size; | ||
1047 | unsigned long io_virt_offset; | ||
1048 | struct resource *res; | ||
1049 | struct device_node *isa_dn; | ||
1050 | |||
1051 | hose->io_base_virt = reserve_phb_iospace(size); | ||
1052 | DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", | ||
1053 | hose->global_number, hose->io_base_phys, | ||
1054 | (unsigned long) hose->io_base_virt); | ||
1055 | |||
1056 | if (primary) { | ||
1057 | pci_io_base = (unsigned long)hose->io_base_virt; | ||
1058 | isa_dn = of_find_node_by_type(NULL, "isa"); | ||
1059 | if (isa_dn) { | ||
1060 | isa_io_base = pci_io_base; | ||
1061 | pci_process_ISA_OF_ranges(isa_dn, hose->io_base_phys, | ||
1062 | hose->io_base_virt); | ||
1063 | of_node_put(isa_dn); | ||
1064 | /* Allow all IO */ | ||
1065 | io_page_mask = -1; | ||
1066 | } | ||
1067 | } | ||
1068 | |||
1069 | io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base; | ||
1070 | res = &hose->io_resource; | ||
1071 | res->start += io_virt_offset; | ||
1072 | res->end += io_virt_offset; | ||
1073 | } | ||
1074 | |||
1075 | void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose, | ||
1076 | int primary) | ||
1077 | { | ||
1078 | unsigned long size = hose->pci_io_size; | ||
1079 | unsigned long io_virt_offset; | ||
1080 | struct resource *res; | ||
1081 | |||
1082 | hose->io_base_virt = __ioremap(hose->io_base_phys, size, | ||
1083 | _PAGE_NO_CACHE | _PAGE_GUARDED); | ||
1084 | DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", | ||
1085 | hose->global_number, hose->io_base_phys, | ||
1086 | (unsigned long) hose->io_base_virt); | ||
1087 | |||
1088 | if (primary) | ||
1089 | pci_io_base = (unsigned long)hose->io_base_virt; | ||
1090 | |||
1091 | io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base; | ||
1092 | res = &hose->io_resource; | ||
1093 | res->start += io_virt_offset; | ||
1094 | res->end += io_virt_offset; | ||
1095 | } | ||
1096 | |||
1097 | |||
1098 | static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys, | ||
1099 | unsigned long *start_virt, unsigned long *size) | ||
1100 | { | ||
1101 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
1102 | struct pci_bus_region region; | ||
1103 | struct resource *res; | ||
1104 | |||
1105 | if (bus->self) { | ||
1106 | res = bus->resource[0]; | ||
1107 | pcibios_resource_to_bus(bus->self, ®ion, res); | ||
1108 | *start_phys = hose->io_base_phys + region.start; | ||
1109 | *start_virt = (unsigned long) hose->io_base_virt + | ||
1110 | region.start; | ||
1111 | if (region.end > region.start) | ||
1112 | *size = region.end - region.start + 1; | ||
1113 | else { | ||
1114 | printk("%s(): unexpected region 0x%lx->0x%lx\n", | ||
1115 | __FUNCTION__, region.start, region.end); | ||
1116 | return 1; | ||
1117 | } | ||
1118 | |||
1119 | } else { | ||
1120 | /* Root Bus */ | ||
1121 | res = &hose->io_resource; | ||
1122 | *start_phys = hose->io_base_phys; | ||
1123 | *start_virt = (unsigned long) hose->io_base_virt; | ||
1124 | if (res->end > res->start) | ||
1125 | *size = res->end - res->start + 1; | ||
1126 | else { | ||
1127 | printk("%s(): unexpected region 0x%lx->0x%lx\n", | ||
1128 | __FUNCTION__, res->start, res->end); | ||
1129 | return 1; | ||
1130 | } | ||
1131 | } | ||
1132 | |||
1133 | return 0; | ||
1134 | } | ||
1135 | |||
1136 | int unmap_bus_range(struct pci_bus *bus) | ||
1137 | { | ||
1138 | unsigned long start_phys; | ||
1139 | unsigned long start_virt; | ||
1140 | unsigned long size; | ||
1141 | |||
1142 | if (!bus) { | ||
1143 | printk(KERN_ERR "%s() expected bus\n", __FUNCTION__); | ||
1144 | return 1; | ||
1145 | } | ||
1146 | |||
1147 | if (get_bus_io_range(bus, &start_phys, &start_virt, &size)) | ||
1148 | return 1; | ||
1149 | if (iounmap_explicit((void __iomem *) start_virt, size)) | ||
1150 | return 1; | ||
1151 | |||
1152 | return 0; | ||
1153 | } | ||
1154 | EXPORT_SYMBOL(unmap_bus_range); | ||
1155 | |||
1156 | int remap_bus_range(struct pci_bus *bus) | ||
1157 | { | ||
1158 | unsigned long start_phys; | ||
1159 | unsigned long start_virt; | ||
1160 | unsigned long size; | ||
1161 | |||
1162 | if (!bus) { | ||
1163 | printk(KERN_ERR "%s() expected bus\n", __FUNCTION__); | ||
1164 | return 1; | ||
1165 | } | ||
1166 | |||
1167 | |||
1168 | if (get_bus_io_range(bus, &start_phys, &start_virt, &size)) | ||
1169 | return 1; | ||
1170 | if (start_phys == 0) | ||
1171 | return 1; | ||
1172 | printk("mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size); | ||
1173 | if (__ioremap_explicit(start_phys, start_virt, size, | ||
1174 | _PAGE_NO_CACHE | _PAGE_GUARDED)) | ||
1175 | return 1; | ||
1176 | |||
1177 | return 0; | ||
1178 | } | ||
1179 | EXPORT_SYMBOL(remap_bus_range); | ||
1180 | |||
1181 | void phbs_remap_io(void) | ||
1182 | { | ||
1183 | struct pci_controller *hose, *tmp; | ||
1184 | |||
1185 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) | ||
1186 | remap_bus_range(hose->bus); | ||
1187 | } | ||
1188 | |||
1189 | /* | ||
1190 | * ppc64 can have multifunction devices that do not respond to function 0. | ||
1191 | * In this case we must scan all functions. | ||
1192 | * XXX this can go now, we use the OF device tree in all the | ||
1193 | * cases that caused problems. -- paulus | ||
1194 | */ | ||
1195 | int pcibios_scan_all_fns(struct pci_bus *bus, int devfn) | ||
1196 | { | ||
1197 | return 0; | ||
1198 | } | ||
1199 | |||
1200 | static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) | ||
1201 | { | ||
1202 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
1203 | unsigned long start, end, mask, offset; | ||
1204 | |||
1205 | if (res->flags & IORESOURCE_IO) { | ||
1206 | offset = (unsigned long)hose->io_base_virt - pci_io_base; | ||
1207 | |||
1208 | start = res->start += offset; | ||
1209 | end = res->end += offset; | ||
1210 | |||
1211 | /* Need to allow IO access to pages that are in the | ||
1212 | ISA range */ | ||
1213 | if (start < MAX_ISA_PORT) { | ||
1214 | if (end > MAX_ISA_PORT) | ||
1215 | end = MAX_ISA_PORT; | ||
1216 | |||
1217 | start >>= PAGE_SHIFT; | ||
1218 | end >>= PAGE_SHIFT; | ||
1219 | |||
1220 | /* get the range of pages for the map */ | ||
1221 | mask = ((1 << (end+1)) - 1) ^ ((1 << start) - 1); | ||
1222 | io_page_mask |= mask; | ||
1223 | } | ||
1224 | } else if (res->flags & IORESOURCE_MEM) { | ||
1225 | res->start += hose->pci_mem_offset; | ||
1226 | res->end += hose->pci_mem_offset; | ||
1227 | } | ||
1228 | } | ||
1229 | |||
1230 | void __devinit pcibios_fixup_device_resources(struct pci_dev *dev, | ||
1231 | struct pci_bus *bus) | ||
1232 | { | ||
1233 | /* Update device resources. */ | ||
1234 | int i; | ||
1235 | |||
1236 | for (i = 0; i < PCI_NUM_RESOURCES; i++) | ||
1237 | if (dev->resource[i].flags) | ||
1238 | fixup_resource(&dev->resource[i], dev); | ||
1239 | } | ||
1240 | EXPORT_SYMBOL(pcibios_fixup_device_resources); | ||
1241 | |||
1242 | static void __devinit do_bus_setup(struct pci_bus *bus) | ||
1243 | { | ||
1244 | struct pci_dev *dev; | ||
1245 | |||
1246 | ppc_md.iommu_bus_setup(bus); | ||
1247 | |||
1248 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
1249 | ppc_md.iommu_dev_setup(dev); | ||
1250 | |||
1251 | if (ppc_md.irq_bus_setup) | ||
1252 | ppc_md.irq_bus_setup(bus); | ||
1253 | } | ||
1254 | |||
1255 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | ||
1256 | { | ||
1257 | struct pci_dev *dev = bus->self; | ||
1258 | |||
1259 | if (dev && pci_probe_only && | ||
1260 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
1261 | /* This is a subordinate bridge */ | ||
1262 | |||
1263 | pci_read_bridge_bases(bus); | ||
1264 | pcibios_fixup_device_resources(dev, bus); | ||
1265 | } | ||
1266 | |||
1267 | do_bus_setup(bus); | ||
1268 | |||
1269 | if (!pci_probe_only) | ||
1270 | return; | ||
1271 | |||
1272 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
1273 | if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) | ||
1274 | pcibios_fixup_device_resources(dev, bus); | ||
1275 | } | ||
1276 | EXPORT_SYMBOL(pcibios_fixup_bus); | ||
1277 | |||
1278 | /* | ||
1279 | * Reads the interrupt pin to determine if interrupt is use by card. | ||
1280 | * If the interrupt is used, then gets the interrupt line from the | ||
1281 | * openfirmware and sets it in the pci_dev and pci_config line. | ||
1282 | */ | ||
1283 | int pci_read_irq_line(struct pci_dev *pci_dev) | ||
1284 | { | ||
1285 | u8 intpin; | ||
1286 | struct device_node *node; | ||
1287 | |||
1288 | pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &intpin); | ||
1289 | if (intpin == 0) | ||
1290 | return 0; | ||
1291 | |||
1292 | node = pci_device_to_OF_node(pci_dev); | ||
1293 | if (node == NULL) | ||
1294 | return -1; | ||
1295 | |||
1296 | if (node->n_intrs == 0) | ||
1297 | return -1; | ||
1298 | |||
1299 | pci_dev->irq = node->intrs[0].line; | ||
1300 | |||
1301 | pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq); | ||
1302 | |||
1303 | return 0; | ||
1304 | } | ||
1305 | EXPORT_SYMBOL(pci_read_irq_line); | ||
1306 | |||
1307 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
1308 | const struct resource *rsrc, | ||
1309 | u64 *start, u64 *end) | ||
1310 | { | ||
1311 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
1312 | unsigned long offset = 0; | ||
1313 | |||
1314 | if (hose == NULL) | ||
1315 | return; | ||
1316 | |||
1317 | if (rsrc->flags & IORESOURCE_IO) | ||
1318 | offset = pci_io_base - (unsigned long)hose->io_base_virt + | ||
1319 | hose->io_base_phys; | ||
1320 | |||
1321 | *start = rsrc->start + offset; | ||
1322 | *end = rsrc->end + offset; | ||
1323 | } | ||
1324 | |||
1325 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
1326 | |||
1327 | |||
1328 | #define IOBASE_BRIDGE_NUMBER 0 | ||
1329 | #define IOBASE_MEMORY 1 | ||
1330 | #define IOBASE_IO 2 | ||
1331 | #define IOBASE_ISA_IO 3 | ||
1332 | #define IOBASE_ISA_MEM 4 | ||
1333 | |||
1334 | long sys_pciconfig_iobase(long which, unsigned long in_bus, | ||
1335 | unsigned long in_devfn) | ||
1336 | { | ||
1337 | struct pci_controller* hose; | ||
1338 | struct list_head *ln; | ||
1339 | struct pci_bus *bus = NULL; | ||
1340 | struct device_node *hose_node; | ||
1341 | |||
1342 | /* Argh ! Please forgive me for that hack, but that's the | ||
1343 | * simplest way to get existing XFree to not lockup on some | ||
1344 | * G5 machines... So when something asks for bus 0 io base | ||
1345 | * (bus 0 is HT root), we return the AGP one instead. | ||
1346 | */ | ||
1347 | if (machine_is_compatible("MacRISC4")) | ||
1348 | if (in_bus == 0) | ||
1349 | in_bus = 0xf0; | ||
1350 | |||
1351 | /* That syscall isn't quite compatible with PCI domains, but it's | ||
1352 | * used on pre-domains setup. We return the first match | ||
1353 | */ | ||
1354 | |||
1355 | for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { | ||
1356 | bus = pci_bus_b(ln); | ||
1357 | if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate)) | ||
1358 | break; | ||
1359 | bus = NULL; | ||
1360 | } | ||
1361 | if (bus == NULL || bus->sysdata == NULL) | ||
1362 | return -ENODEV; | ||
1363 | |||
1364 | hose_node = (struct device_node *)bus->sysdata; | ||
1365 | hose = PCI_DN(hose_node)->phb; | ||
1366 | |||
1367 | switch (which) { | ||
1368 | case IOBASE_BRIDGE_NUMBER: | ||
1369 | return (long)hose->first_busno; | ||
1370 | case IOBASE_MEMORY: | ||
1371 | return (long)hose->pci_mem_offset; | ||
1372 | case IOBASE_IO: | ||
1373 | return (long)hose->io_base_phys; | ||
1374 | case IOBASE_ISA_IO: | ||
1375 | return (long)isa_io_base; | ||
1376 | case IOBASE_ISA_MEM: | ||
1377 | return -EINVAL; | ||
1378 | } | ||
1379 | |||
1380 | return -EOPNOTSUPP; | ||
1381 | } | ||
diff --git a/arch/powerpc/kernel/pci_direct_iommu.c b/arch/powerpc/kernel/pci_direct_iommu.c new file mode 100644 index 000000000000..e1a32f802c0b --- /dev/null +++ b/arch/powerpc/kernel/pci_direct_iommu.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Support for DMA from PCI devices to main memory on | ||
3 | * machines without an iommu or with directly addressable | ||
4 | * RAM (typically a pmac with 2Gb of RAM or less) | ||
5 | * | ||
6 | * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/bootmem.h> | ||
20 | #include <linux/mm.h> | ||
21 | #include <linux/dma-mapping.h> | ||
22 | |||
23 | #include <asm/sections.h> | ||
24 | #include <asm/io.h> | ||
25 | #include <asm/prom.h> | ||
26 | #include <asm/pci-bridge.h> | ||
27 | #include <asm/machdep.h> | ||
28 | #include <asm/pmac_feature.h> | ||
29 | #include <asm/abs_addr.h> | ||
30 | #include <asm/ppc-pci.h> | ||
31 | |||
32 | static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size, | ||
33 | dma_addr_t *dma_handle, gfp_t flag) | ||
34 | { | ||
35 | void *ret; | ||
36 | |||
37 | ret = (void *)__get_free_pages(flag, get_order(size)); | ||
38 | if (ret != NULL) { | ||
39 | memset(ret, 0, size); | ||
40 | *dma_handle = virt_to_abs(ret); | ||
41 | } | ||
42 | return ret; | ||
43 | } | ||
44 | |||
45 | static void pci_direct_free_coherent(struct device *hwdev, size_t size, | ||
46 | void *vaddr, dma_addr_t dma_handle) | ||
47 | { | ||
48 | free_pages((unsigned long)vaddr, get_order(size)); | ||
49 | } | ||
50 | |||
51 | static dma_addr_t pci_direct_map_single(struct device *hwdev, void *ptr, | ||
52 | size_t size, enum dma_data_direction direction) | ||
53 | { | ||
54 | return virt_to_abs(ptr); | ||
55 | } | ||
56 | |||
57 | static void pci_direct_unmap_single(struct device *hwdev, dma_addr_t dma_addr, | ||
58 | size_t size, enum dma_data_direction direction) | ||
59 | { | ||
60 | } | ||
61 | |||
62 | static int pci_direct_map_sg(struct device *hwdev, struct scatterlist *sg, | ||
63 | int nents, enum dma_data_direction direction) | ||
64 | { | ||
65 | int i; | ||
66 | |||
67 | for (i = 0; i < nents; i++, sg++) { | ||
68 | sg->dma_address = page_to_phys(sg->page) + sg->offset; | ||
69 | sg->dma_length = sg->length; | ||
70 | } | ||
71 | |||
72 | return nents; | ||
73 | } | ||
74 | |||
75 | static void pci_direct_unmap_sg(struct device *hwdev, struct scatterlist *sg, | ||
76 | int nents, enum dma_data_direction direction) | ||
77 | { | ||
78 | } | ||
79 | |||
80 | static int pci_direct_dma_supported(struct device *dev, u64 mask) | ||
81 | { | ||
82 | return mask < 0x100000000ull; | ||
83 | } | ||
84 | |||
85 | void __init pci_direct_iommu_init(void) | ||
86 | { | ||
87 | pci_dma_ops.alloc_coherent = pci_direct_alloc_coherent; | ||
88 | pci_dma_ops.free_coherent = pci_direct_free_coherent; | ||
89 | pci_dma_ops.map_single = pci_direct_map_single; | ||
90 | pci_dma_ops.unmap_single = pci_direct_unmap_single; | ||
91 | pci_dma_ops.map_sg = pci_direct_map_sg; | ||
92 | pci_dma_ops.unmap_sg = pci_direct_unmap_sg; | ||
93 | pci_dma_ops.dma_supported = pci_direct_dma_supported; | ||
94 | } | ||
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c new file mode 100644 index 000000000000..12c4c9e9bbc7 --- /dev/null +++ b/arch/powerpc/kernel/pci_dn.c | |||
@@ -0,0 +1,230 @@ | |||
1 | /* | ||
2 | * pci_dn.c | ||
3 | * | ||
4 | * Copyright (C) 2001 Todd Inglett, IBM Corporation | ||
5 | * | ||
6 | * PCI manipulation via device_nodes. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/string.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/bootmem.h> | ||
28 | |||
29 | #include <asm/io.h> | ||
30 | #include <asm/prom.h> | ||
31 | #include <asm/pci-bridge.h> | ||
32 | #include <asm/pSeries_reconfig.h> | ||
33 | #include <asm/ppc-pci.h> | ||
34 | |||
35 | /* | ||
36 | * Traverse_func that inits the PCI fields of the device node. | ||
37 | * NOTE: this *must* be done before read/write config to the device. | ||
38 | */ | ||
39 | static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) | ||
40 | { | ||
41 | struct pci_controller *phb = data; | ||
42 | int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL); | ||
43 | u32 *regs; | ||
44 | struct pci_dn *pdn; | ||
45 | |||
46 | if (mem_init_done) | ||
47 | pdn = kmalloc(sizeof(*pdn), GFP_KERNEL); | ||
48 | else | ||
49 | pdn = alloc_bootmem(sizeof(*pdn)); | ||
50 | if (pdn == NULL) | ||
51 | return NULL; | ||
52 | memset(pdn, 0, sizeof(*pdn)); | ||
53 | dn->data = pdn; | ||
54 | pdn->node = dn; | ||
55 | pdn->phb = phb; | ||
56 | regs = (u32 *)get_property(dn, "reg", NULL); | ||
57 | if (regs) { | ||
58 | /* First register entry is addr (00BBSS00) */ | ||
59 | pdn->busno = (regs[0] >> 16) & 0xff; | ||
60 | pdn->devfn = (regs[0] >> 8) & 0xff; | ||
61 | } | ||
62 | |||
63 | pdn->pci_ext_config_space = (type && *type == 1); | ||
64 | return NULL; | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | * Traverse a device tree stopping each PCI device in the tree. | ||
69 | * This is done depth first. As each node is processed, a "pre" | ||
70 | * function is called and the children are processed recursively. | ||
71 | * | ||
72 | * The "pre" func returns a value. If non-zero is returned from | ||
73 | * the "pre" func, the traversal stops and this value is returned. | ||
74 | * This return value is useful when using traverse as a method of | ||
75 | * finding a device. | ||
76 | * | ||
77 | * NOTE: we do not run the func for devices that do not appear to | ||
78 | * be PCI except for the start node which we assume (this is good | ||
79 | * because the start node is often a phb which may be missing PCI | ||
80 | * properties). | ||
81 | * We use the class-code as an indicator. If we run into | ||
82 | * one of these nodes we also assume its siblings are non-pci for | ||
83 | * performance. | ||
84 | */ | ||
85 | void *traverse_pci_devices(struct device_node *start, traverse_func pre, | ||
86 | void *data) | ||
87 | { | ||
88 | struct device_node *dn, *nextdn; | ||
89 | void *ret; | ||
90 | |||
91 | /* We started with a phb, iterate all childs */ | ||
92 | for (dn = start->child; dn; dn = nextdn) { | ||
93 | u32 *classp, class; | ||
94 | |||
95 | nextdn = NULL; | ||
96 | classp = (u32 *)get_property(dn, "class-code", NULL); | ||
97 | class = classp ? *classp : 0; | ||
98 | |||
99 | if (pre && ((ret = pre(dn, data)) != NULL)) | ||
100 | return ret; | ||
101 | |||
102 | /* If we are a PCI bridge, go down */ | ||
103 | if (dn->child && ((class >> 8) == PCI_CLASS_BRIDGE_PCI || | ||
104 | (class >> 8) == PCI_CLASS_BRIDGE_CARDBUS)) | ||
105 | /* Depth first...do children */ | ||
106 | nextdn = dn->child; | ||
107 | else if (dn->sibling) | ||
108 | /* ok, try next sibling instead. */ | ||
109 | nextdn = dn->sibling; | ||
110 | if (!nextdn) { | ||
111 | /* Walk up to next valid sibling. */ | ||
112 | do { | ||
113 | dn = dn->parent; | ||
114 | if (dn == start) | ||
115 | return NULL; | ||
116 | } while (dn->sibling == NULL); | ||
117 | nextdn = dn->sibling; | ||
118 | } | ||
119 | } | ||
120 | return NULL; | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * pci_devs_phb_init_dynamic - setup pci devices under this PHB | ||
125 | * phb: pci-to-host bridge (top-level bridge connecting to cpu) | ||
126 | * | ||
127 | * This routine is called both during boot, (before the memory | ||
128 | * subsystem is set up, before kmalloc is valid) and during the | ||
129 | * dynamic lpar operation of adding a PHB to a running system. | ||
130 | */ | ||
131 | void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) | ||
132 | { | ||
133 | struct device_node * dn = (struct device_node *) phb->arch_data; | ||
134 | struct pci_dn *pdn; | ||
135 | |||
136 | /* PHB nodes themselves must not match */ | ||
137 | update_dn_pci_info(dn, phb); | ||
138 | pdn = dn->data; | ||
139 | if (pdn) { | ||
140 | pdn->devfn = pdn->busno = -1; | ||
141 | pdn->phb = phb; | ||
142 | } | ||
143 | |||
144 | /* Update dn->phb ptrs for new phb and children devices */ | ||
145 | traverse_pci_devices(dn, update_dn_pci_info, phb); | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * Traversal func that looks for a <busno,devfcn> value. | ||
150 | * If found, the pci_dn is returned (thus terminating the traversal). | ||
151 | */ | ||
152 | static void *is_devfn_node(struct device_node *dn, void *data) | ||
153 | { | ||
154 | int busno = ((unsigned long)data >> 8) & 0xff; | ||
155 | int devfn = ((unsigned long)data) & 0xff; | ||
156 | struct pci_dn *pci = dn->data; | ||
157 | |||
158 | if (pci && (devfn == pci->devfn) && (busno == pci->busno)) | ||
159 | return dn; | ||
160 | return NULL; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * This is the "slow" path for looking up a device_node from a | ||
165 | * pci_dev. It will hunt for the device under its parent's | ||
166 | * phb and then update sysdata for a future fastpath. | ||
167 | * | ||
168 | * It may also do fixups on the actual device since this happens | ||
169 | * on the first read/write. | ||
170 | * | ||
171 | * Note that it also must deal with devices that don't exist. | ||
172 | * In this case it may probe for real hardware ("just in case") | ||
173 | * and add a device_node to the device tree if necessary. | ||
174 | * | ||
175 | */ | ||
176 | struct device_node *fetch_dev_dn(struct pci_dev *dev) | ||
177 | { | ||
178 | struct device_node *orig_dn = dev->sysdata; | ||
179 | struct device_node *dn; | ||
180 | unsigned long searchval = (dev->bus->number << 8) | dev->devfn; | ||
181 | |||
182 | dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval); | ||
183 | if (dn) | ||
184 | dev->sysdata = dn; | ||
185 | return dn; | ||
186 | } | ||
187 | EXPORT_SYMBOL(fetch_dev_dn); | ||
188 | |||
189 | static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) | ||
190 | { | ||
191 | struct device_node *np = node; | ||
192 | struct pci_dn *pci = NULL; | ||
193 | int err = NOTIFY_OK; | ||
194 | |||
195 | switch (action) { | ||
196 | case PSERIES_RECONFIG_ADD: | ||
197 | pci = np->parent->data; | ||
198 | if (pci) | ||
199 | update_dn_pci_info(np, pci->phb); | ||
200 | break; | ||
201 | default: | ||
202 | err = NOTIFY_DONE; | ||
203 | break; | ||
204 | } | ||
205 | return err; | ||
206 | } | ||
207 | |||
208 | static struct notifier_block pci_dn_reconfig_nb = { | ||
209 | .notifier_call = pci_dn_reconfig_notifier, | ||
210 | }; | ||
211 | |||
212 | /** | ||
213 | * pci_devs_phb_init - Initialize phbs and pci devs under them. | ||
214 | * | ||
215 | * This routine walks over all phb's (pci-host bridges) on the | ||
216 | * system, and sets up assorted pci-related structures | ||
217 | * (including pci info in the device node structs) for each | ||
218 | * pci device found underneath. This routine runs once, | ||
219 | * early in the boot sequence. | ||
220 | */ | ||
221 | void __init pci_devs_phb_init(void) | ||
222 | { | ||
223 | struct pci_controller *phb, *tmp; | ||
224 | |||
225 | /* This must be done first so the device nodes have valid pci info! */ | ||
226 | list_for_each_entry_safe(phb, tmp, &hose_list, list_node) | ||
227 | pci_devs_phb_init_dynamic(phb); | ||
228 | |||
229 | pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb); | ||
230 | } | ||
diff --git a/arch/powerpc/kernel/pci_iommu.c b/arch/powerpc/kernel/pci_iommu.c new file mode 100644 index 000000000000..bdf15dbbf4f0 --- /dev/null +++ b/arch/powerpc/kernel/pci_iommu.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * arch/ppc64/kernel/pci_iommu.c | ||
3 | * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation | ||
4 | * | ||
5 | * Rewrite, cleanup, new allocation schemes: | ||
6 | * Copyright (C) 2004 Olof Johansson, IBM Corporation | ||
7 | * | ||
8 | * Dynamic DMA mapping support, platform-independent parts. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | */ | ||
24 | |||
25 | |||
26 | #include <linux/init.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/mm.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/string.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/dma-mapping.h> | ||
34 | #include <asm/io.h> | ||
35 | #include <asm/prom.h> | ||
36 | #include <asm/iommu.h> | ||
37 | #include <asm/pci-bridge.h> | ||
38 | #include <asm/machdep.h> | ||
39 | #include <asm/ppc-pci.h> | ||
40 | |||
41 | /* | ||
42 | * We can use ->sysdata directly and avoid the extra work in | ||
43 | * pci_device_to_OF_node since ->sysdata will have been initialised | ||
44 | * in the iommu init code for all devices. | ||
45 | */ | ||
46 | #define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata)) | ||
47 | |||
48 | static inline struct iommu_table *devnode_table(struct device *dev) | ||
49 | { | ||
50 | struct pci_dev *pdev; | ||
51 | |||
52 | if (!dev) { | ||
53 | pdev = ppc64_isabridge_dev; | ||
54 | if (!pdev) | ||
55 | return NULL; | ||
56 | } else | ||
57 | pdev = to_pci_dev(dev); | ||
58 | |||
59 | return PCI_DN(PCI_GET_DN(pdev))->iommu_table; | ||
60 | } | ||
61 | |||
62 | |||
63 | /* Allocates a contiguous real buffer and creates mappings over it. | ||
64 | * Returns the virtual address of the buffer and sets dma_handle | ||
65 | * to the dma address (mapping) of the first page. | ||
66 | */ | ||
67 | static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size, | ||
68 | dma_addr_t *dma_handle, gfp_t flag) | ||
69 | { | ||
70 | return iommu_alloc_coherent(devnode_table(hwdev), size, dma_handle, | ||
71 | flag); | ||
72 | } | ||
73 | |||
74 | static void pci_iommu_free_coherent(struct device *hwdev, size_t size, | ||
75 | void *vaddr, dma_addr_t dma_handle) | ||
76 | { | ||
77 | iommu_free_coherent(devnode_table(hwdev), size, vaddr, dma_handle); | ||
78 | } | ||
79 | |||
80 | /* Creates TCEs for a user provided buffer. The user buffer must be | ||
81 | * contiguous real kernel storage (not vmalloc). The address of the buffer | ||
82 | * passed here is the kernel (virtual) address of the buffer. The buffer | ||
83 | * need not be page aligned, the dma_addr_t returned will point to the same | ||
84 | * byte within the page as vaddr. | ||
85 | */ | ||
86 | static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr, | ||
87 | size_t size, enum dma_data_direction direction) | ||
88 | { | ||
89 | return iommu_map_single(devnode_table(hwdev), vaddr, size, direction); | ||
90 | } | ||
91 | |||
92 | |||
93 | static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle, | ||
94 | size_t size, enum dma_data_direction direction) | ||
95 | { | ||
96 | iommu_unmap_single(devnode_table(hwdev), dma_handle, size, direction); | ||
97 | } | ||
98 | |||
99 | |||
100 | static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist, | ||
101 | int nelems, enum dma_data_direction direction) | ||
102 | { | ||
103 | return iommu_map_sg(pdev, devnode_table(pdev), sglist, | ||
104 | nelems, direction); | ||
105 | } | ||
106 | |||
107 | static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist, | ||
108 | int nelems, enum dma_data_direction direction) | ||
109 | { | ||
110 | iommu_unmap_sg(devnode_table(pdev), sglist, nelems, direction); | ||
111 | } | ||
112 | |||
113 | /* We support DMA to/from any memory page via the iommu */ | ||
114 | static int pci_iommu_dma_supported(struct device *dev, u64 mask) | ||
115 | { | ||
116 | return 1; | ||
117 | } | ||
118 | |||
119 | void pci_iommu_init(void) | ||
120 | { | ||
121 | pci_dma_ops.alloc_coherent = pci_iommu_alloc_coherent; | ||
122 | pci_dma_ops.free_coherent = pci_iommu_free_coherent; | ||
123 | pci_dma_ops.map_single = pci_iommu_map_single; | ||
124 | pci_dma_ops.unmap_single = pci_iommu_unmap_single; | ||
125 | pci_dma_ops.map_sg = pci_iommu_map_sg; | ||
126 | pci_dma_ops.unmap_sg = pci_iommu_unmap_sg; | ||
127 | pci_dma_ops.dma_supported = pci_iommu_dma_supported; | ||
128 | } | ||
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 5dcf4ba05ee8..59846b40d521 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -105,6 +105,13 @@ EXPORT_SYMBOL(__clear_user); | |||
105 | EXPORT_SYMBOL(__strncpy_from_user); | 105 | EXPORT_SYMBOL(__strncpy_from_user); |
106 | EXPORT_SYMBOL(__strnlen_user); | 106 | EXPORT_SYMBOL(__strnlen_user); |
107 | 107 | ||
108 | #ifndef __powerpc64__ | ||
109 | EXPORT_SYMBOL(__ide_mm_insl); | ||
110 | EXPORT_SYMBOL(__ide_mm_outsw); | ||
111 | EXPORT_SYMBOL(__ide_mm_insw); | ||
112 | EXPORT_SYMBOL(__ide_mm_outsl); | ||
113 | #endif | ||
114 | |||
108 | EXPORT_SYMBOL(_insb); | 115 | EXPORT_SYMBOL(_insb); |
109 | EXPORT_SYMBOL(_outsb); | 116 | EXPORT_SYMBOL(_outsb); |
110 | EXPORT_SYMBOL(_insw); | 117 | EXPORT_SYMBOL(_insw); |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 6a5b468edb4d..3bf968e74095 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -1368,6 +1368,7 @@ prom_n_addr_cells(struct device_node* np) | |||
1368 | /* No #address-cells property for the root node, default to 1 */ | 1368 | /* No #address-cells property for the root node, default to 1 */ |
1369 | return 1; | 1369 | return 1; |
1370 | } | 1370 | } |
1371 | EXPORT_SYMBOL(prom_n_addr_cells); | ||
1371 | 1372 | ||
1372 | int | 1373 | int |
1373 | prom_n_size_cells(struct device_node* np) | 1374 | prom_n_size_cells(struct device_node* np) |
@@ -1383,6 +1384,7 @@ prom_n_size_cells(struct device_node* np) | |||
1383 | /* No #size-cells property for the root node, default to 1 */ | 1384 | /* No #size-cells property for the root node, default to 1 */ |
1384 | return 1; | 1385 | return 1; |
1385 | } | 1386 | } |
1387 | EXPORT_SYMBOL(prom_n_size_cells); | ||
1386 | 1388 | ||
1387 | /** | 1389 | /** |
1388 | * Work out the sense (active-low level / active-high edge) | 1390 | * Work out the sense (active-low level / active-high edge) |
diff --git a/arch/powerpc/kernel/rtas-rtc.c b/arch/powerpc/kernel/rtas-rtc.c new file mode 100644 index 000000000000..635d3b9a8811 --- /dev/null +++ b/arch/powerpc/kernel/rtas-rtc.c | |||
@@ -0,0 +1,105 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/time.h> | ||
3 | #include <linux/timer.h> | ||
4 | #include <linux/init.h> | ||
5 | #include <linux/rtc.h> | ||
6 | #include <linux/delay.h> | ||
7 | #include <asm/prom.h> | ||
8 | #include <asm/rtas.h> | ||
9 | #include <asm/time.h> | ||
10 | |||
11 | |||
12 | #define MAX_RTC_WAIT 5000 /* 5 sec */ | ||
13 | #define RTAS_CLOCK_BUSY (-2) | ||
14 | unsigned long __init rtas_get_boot_time(void) | ||
15 | { | ||
16 | int ret[8]; | ||
17 | int error, wait_time; | ||
18 | u64 max_wait_tb; | ||
19 | |||
20 | max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; | ||
21 | do { | ||
22 | error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); | ||
23 | if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { | ||
24 | wait_time = rtas_extended_busy_delay_time(error); | ||
25 | /* This is boot time so we spin. */ | ||
26 | udelay(wait_time*1000); | ||
27 | error = RTAS_CLOCK_BUSY; | ||
28 | } | ||
29 | } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); | ||
30 | |||
31 | if (error != 0 && printk_ratelimit()) { | ||
32 | printk(KERN_WARNING "error: reading the clock failed (%d)\n", | ||
33 | error); | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]); | ||
38 | } | ||
39 | |||
40 | /* NOTE: get_rtc_time will get an error if executed in interrupt context | ||
41 | * and if a delay is needed to read the clock. In this case we just | ||
42 | * silently return without updating rtc_tm. | ||
43 | */ | ||
44 | void rtas_get_rtc_time(struct rtc_time *rtc_tm) | ||
45 | { | ||
46 | int ret[8]; | ||
47 | int error, wait_time; | ||
48 | u64 max_wait_tb; | ||
49 | |||
50 | max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; | ||
51 | do { | ||
52 | error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); | ||
53 | if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { | ||
54 | if (in_interrupt() && printk_ratelimit()) { | ||
55 | memset(&rtc_tm, 0, sizeof(struct rtc_time)); | ||
56 | printk(KERN_WARNING "error: reading clock" | ||
57 | " would delay interrupt\n"); | ||
58 | return; /* delay not allowed */ | ||
59 | } | ||
60 | wait_time = rtas_extended_busy_delay_time(error); | ||
61 | msleep(wait_time); | ||
62 | error = RTAS_CLOCK_BUSY; | ||
63 | } | ||
64 | } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); | ||
65 | |||
66 | if (error != 0 && printk_ratelimit()) { | ||
67 | printk(KERN_WARNING "error: reading the clock failed (%d)\n", | ||
68 | error); | ||
69 | return; | ||
70 | } | ||
71 | |||
72 | rtc_tm->tm_sec = ret[5]; | ||
73 | rtc_tm->tm_min = ret[4]; | ||
74 | rtc_tm->tm_hour = ret[3]; | ||
75 | rtc_tm->tm_mday = ret[2]; | ||
76 | rtc_tm->tm_mon = ret[1] - 1; | ||
77 | rtc_tm->tm_year = ret[0] - 1900; | ||
78 | } | ||
79 | |||
80 | int rtas_set_rtc_time(struct rtc_time *tm) | ||
81 | { | ||
82 | int error, wait_time; | ||
83 | u64 max_wait_tb; | ||
84 | |||
85 | max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; | ||
86 | do { | ||
87 | error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL, | ||
88 | tm->tm_year + 1900, tm->tm_mon + 1, | ||
89 | tm->tm_mday, tm->tm_hour, tm->tm_min, | ||
90 | tm->tm_sec, 0); | ||
91 | if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { | ||
92 | if (in_interrupt()) | ||
93 | return 1; /* probably decrementer */ | ||
94 | wait_time = rtas_extended_busy_delay_time(error); | ||
95 | msleep(wait_time); | ||
96 | error = RTAS_CLOCK_BUSY; | ||
97 | } | ||
98 | } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); | ||
99 | |||
100 | if (error != 0 && printk_ratelimit()) | ||
101 | printk(KERN_WARNING "error: setting the clock failed (%d)\n", | ||
102 | error); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 0e5a8e116653..60dec2401c26 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
@@ -304,75 +304,18 @@ static int __devinit setup_phb(struct device_node *dev, | |||
304 | struct pci_controller *phb, | 304 | struct pci_controller *phb, |
305 | unsigned int addr_size_words) | 305 | unsigned int addr_size_words) |
306 | { | 306 | { |
307 | pci_setup_pci_controller(phb); | ||
308 | |||
309 | if (is_python(dev)) | 307 | if (is_python(dev)) |
310 | python_countermeasures(dev, addr_size_words); | 308 | python_countermeasures(dev, addr_size_words); |
311 | 309 | ||
312 | if (phb_set_bus_ranges(dev, phb)) | 310 | if (phb_set_bus_ranges(dev, phb)) |
313 | return 1; | 311 | return 1; |
314 | 312 | ||
315 | phb->arch_data = dev; | ||
316 | phb->ops = &rtas_pci_ops; | 313 | phb->ops = &rtas_pci_ops; |
317 | phb->buid = get_phb_buid(dev); | 314 | phb->buid = get_phb_buid(dev); |
318 | 315 | ||
319 | return 0; | 316 | return 0; |
320 | } | 317 | } |
321 | 318 | ||
322 | static void __devinit add_linux_pci_domain(struct device_node *dev, | ||
323 | struct pci_controller *phb, | ||
324 | struct property *of_prop) | ||
325 | { | ||
326 | memset(of_prop, 0, sizeof(struct property)); | ||
327 | of_prop->name = "linux,pci-domain"; | ||
328 | of_prop->length = sizeof(phb->global_number); | ||
329 | of_prop->value = (unsigned char *)&of_prop[1]; | ||
330 | memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number)); | ||
331 | prom_add_property(dev, of_prop); | ||
332 | } | ||
333 | |||
334 | static struct pci_controller * __init alloc_phb(struct device_node *dev, | ||
335 | unsigned int addr_size_words) | ||
336 | { | ||
337 | struct pci_controller *phb; | ||
338 | struct property *of_prop; | ||
339 | |||
340 | phb = alloc_bootmem(sizeof(struct pci_controller)); | ||
341 | if (phb == NULL) | ||
342 | return NULL; | ||
343 | |||
344 | of_prop = alloc_bootmem(sizeof(struct property) + | ||
345 | sizeof(phb->global_number)); | ||
346 | if (!of_prop) | ||
347 | return NULL; | ||
348 | |||
349 | if (setup_phb(dev, phb, addr_size_words)) | ||
350 | return NULL; | ||
351 | |||
352 | add_linux_pci_domain(dev, phb, of_prop); | ||
353 | |||
354 | return phb; | ||
355 | } | ||
356 | |||
357 | static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words) | ||
358 | { | ||
359 | struct pci_controller *phb; | ||
360 | |||
361 | phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), | ||
362 | GFP_KERNEL); | ||
363 | if (phb == NULL) | ||
364 | return NULL; | ||
365 | |||
366 | if (setup_phb(dev, phb, addr_size_words)) | ||
367 | return NULL; | ||
368 | |||
369 | phb->is_dynamic = 1; | ||
370 | |||
371 | /* TODO: linux,pci-domain? */ | ||
372 | |||
373 | return phb; | ||
374 | } | ||
375 | |||
376 | unsigned long __init find_and_init_phbs(void) | 319 | unsigned long __init find_and_init_phbs(void) |
377 | { | 320 | { |
378 | struct device_node *node; | 321 | struct device_node *node; |
@@ -397,10 +340,10 @@ unsigned long __init find_and_init_phbs(void) | |||
397 | if (node->type == NULL || strcmp(node->type, "pci") != 0) | 340 | if (node->type == NULL || strcmp(node->type, "pci") != 0) |
398 | continue; | 341 | continue; |
399 | 342 | ||
400 | phb = alloc_phb(node, root_size_cells); | 343 | phb = pcibios_alloc_controller(node); |
401 | if (!phb) | 344 | if (!phb) |
402 | continue; | 345 | continue; |
403 | 346 | setup_phb(node, phb, root_size_cells); | |
404 | pci_process_bridge_OF_ranges(phb, node, 0); | 347 | pci_process_bridge_OF_ranges(phb, node, 0); |
405 | pci_setup_phb_io(phb, index == 0); | 348 | pci_setup_phb_io(phb, index == 0); |
406 | #ifdef CONFIG_PPC_PSERIES | 349 | #ifdef CONFIG_PPC_PSERIES |
@@ -446,10 +389,10 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) | |||
446 | root_size_cells = prom_n_size_cells(root); | 389 | root_size_cells = prom_n_size_cells(root); |
447 | 390 | ||
448 | primary = list_empty(&hose_list); | 391 | primary = list_empty(&hose_list); |
449 | phb = alloc_phb_dynamic(dn, root_size_cells); | 392 | phb = pcibios_alloc_controller(dn); |
450 | if (!phb) | 393 | if (!phb) |
451 | return NULL; | 394 | return NULL; |
452 | 395 | setup_phb(dn, phb, root_size_cells); | |
453 | pci_process_bridge_OF_ranges(phb, dn, primary); | 396 | pci_process_bridge_OF_ranges(phb, dn, primary); |
454 | 397 | ||
455 | pci_setup_phb_io_dynamic(phb, primary); | 398 | pci_setup_phb_io_dynamic(phb, primary); |
@@ -505,8 +448,7 @@ int pcibios_remove_root_bus(struct pci_controller *phb) | |||
505 | } | 448 | } |
506 | 449 | ||
507 | list_del(&phb->list_node); | 450 | list_del(&phb->list_node); |
508 | if (phb->is_dynamic) | 451 | pcibios_free_controller(phb); |
509 | kfree(phb); | ||
510 | 452 | ||
511 | return 0; | 453 | return 0; |
512 | } | 454 | } |
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 33e7f2c7f194..bd3eb4292b53 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #undef DEBUG | 59 | #undef DEBUG |
60 | 60 | ||
61 | #ifdef DEBUG | 61 | #ifdef DEBUG |
62 | #include <asm/udbg.h> | ||
62 | #define DBG(fmt...) udbg_printf(fmt) | 63 | #define DBG(fmt...) udbg_printf(fmt) |
63 | #else | 64 | #else |
64 | #define DBG(fmt...) | 65 | #define DBG(fmt...) |
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index c98cfcc9cd9a..e5694335bf10 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -57,10 +57,6 @@ extern void power4_idle(void); | |||
57 | boot_infos_t *boot_infos; | 57 | boot_infos_t *boot_infos; |
58 | struct ide_machdep_calls ppc_ide_md; | 58 | struct ide_machdep_calls ppc_ide_md; |
59 | 59 | ||
60 | /* XXX should go elsewhere */ | ||
61 | int __irq_offset_value; | ||
62 | EXPORT_SYMBOL(__irq_offset_value); | ||
63 | |||
64 | int boot_cpuid; | 60 | int boot_cpuid; |
65 | EXPORT_SYMBOL_GPL(boot_cpuid); | 61 | EXPORT_SYMBOL_GPL(boot_cpuid); |
66 | int boot_cpuid_phys; | 62 | int boot_cpuid_phys; |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index fdbd9f9122f2..608fee7c7e20 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <asm/firmware.h> | 59 | #include <asm/firmware.h> |
60 | #include <asm/xmon.h> | 60 | #include <asm/xmon.h> |
61 | #include <asm/udbg.h> | 61 | #include <asm/udbg.h> |
62 | #include <asm/kexec.h> | ||
62 | 63 | ||
63 | #include "setup.h" | 64 | #include "setup.h" |
64 | 65 | ||
@@ -415,6 +416,10 @@ void __init setup_system(void) | |||
415 | */ | 416 | */ |
416 | unflatten_device_tree(); | 417 | unflatten_device_tree(); |
417 | 418 | ||
419 | #ifdef CONFIG_KEXEC | ||
420 | kexec_setup(); /* requires unflattened device tree. */ | ||
421 | #endif | ||
422 | |||
418 | /* | 423 | /* |
419 | * Fill the ppc64_caches & systemcfg structures with informations | 424 | * Fill the ppc64_caches & systemcfg structures with informations |
420 | * retreived from the device-tree. Need to be called before | 425 | * retreived from the device-tree. Need to be called before |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 8bdf95b7e420..5a2eba60dd39 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -403,8 +403,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, | |||
403 | ELF_NFPREG * sizeof(double))) | 403 | ELF_NFPREG * sizeof(double))) |
404 | return 1; | 404 | return 1; |
405 | 405 | ||
406 | current->thread.fpscr.val = 0; /* turn off all fp exceptions */ | ||
407 | |||
408 | #ifdef CONFIG_ALTIVEC | 406 | #ifdef CONFIG_ALTIVEC |
409 | /* save altivec registers */ | 407 | /* save altivec registers */ |
410 | if (current->thread.used_vr) { | 408 | if (current->thread.used_vr) { |
@@ -818,6 +816,9 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, | |||
818 | goto badframe; | 816 | goto badframe; |
819 | regs->link = (unsigned long) frame->tramp; | 817 | regs->link = (unsigned long) frame->tramp; |
820 | } | 818 | } |
819 | |||
820 | current->thread.fpscr.val = 0; /* turn off all fp exceptions */ | ||
821 | |||
821 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) | 822 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) |
822 | goto badframe; | 823 | goto badframe; |
823 | regs->gpr[1] = newsp; | 824 | regs->gpr[1] = newsp; |
@@ -1097,6 +1098,8 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
1097 | regs->link = (unsigned long) frame->mctx.tramp; | 1098 | regs->link = (unsigned long) frame->mctx.tramp; |
1098 | } | 1099 | } |
1099 | 1100 | ||
1101 | current->thread.fpscr.val = 0; /* turn off all fp exceptions */ | ||
1102 | |||
1100 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) | 1103 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) |
1101 | goto badframe; | 1104 | goto badframe; |
1102 | regs->gpr[1] = newsp; | 1105 | regs->gpr[1] = newsp; |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 58194e150711..1decf2785530 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -131,9 +131,6 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
131 | 131 | ||
132 | flush_fp_to_thread(current); | 132 | flush_fp_to_thread(current); |
133 | 133 | ||
134 | /* Make sure signal doesn't get spurrious FP exceptions */ | ||
135 | current->thread.fpscr.val = 0; | ||
136 | |||
137 | #ifdef CONFIG_ALTIVEC | 134 | #ifdef CONFIG_ALTIVEC |
138 | err |= __put_user(v_regs, &sc->v_regs); | 135 | err |= __put_user(v_regs, &sc->v_regs); |
139 | 136 | ||
@@ -423,6 +420,9 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, | |||
423 | if (err) | 420 | if (err) |
424 | goto badframe; | 421 | goto badframe; |
425 | 422 | ||
423 | /* Make sure signal handler doesn't get spurious FP exceptions */ | ||
424 | current->thread.fpscr.val = 0; | ||
425 | |||
426 | /* Set up to return from userspace. */ | 426 | /* Set up to return from userspace. */ |
427 | if (vdso64_rt_sigtramp && current->thread.vdso_base) { | 427 | if (vdso64_rt_sigtramp && current->thread.vdso_base) { |
428 | regs->link = current->thread.vdso_base + vdso64_rt_sigtramp; | 428 | regs->link = current->thread.vdso_base + vdso64_rt_sigtramp; |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 62dfc5b8d765..30374d2f88e5 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -49,15 +49,16 @@ | |||
49 | #include <asm/paca.h> | 49 | #include <asm/paca.h> |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | int smp_hw_index[NR_CPUS]; | ||
53 | struct thread_info *secondary_ti; | ||
54 | |||
55 | #ifdef DEBUG | 52 | #ifdef DEBUG |
53 | #include <asm/udbg.h> | ||
56 | #define DBG(fmt...) udbg_printf(fmt) | 54 | #define DBG(fmt...) udbg_printf(fmt) |
57 | #else | 55 | #else |
58 | #define DBG(fmt...) | 56 | #define DBG(fmt...) |
59 | #endif | 57 | #endif |
60 | 58 | ||
59 | int smp_hw_index[NR_CPUS]; | ||
60 | struct thread_info *secondary_ti; | ||
61 | |||
61 | cpumask_t cpu_possible_map = CPU_MASK_NONE; | 62 | cpumask_t cpu_possible_map = CPU_MASK_NONE; |
62 | cpumask_t cpu_online_map = CPU_MASK_NONE; | 63 | cpumask_t cpu_online_map = CPU_MASK_NONE; |
63 | cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; | 64 | cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 070b4b458aaf..de8479769bb7 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -130,6 +130,34 @@ unsigned long tb_last_stamp; | |||
130 | */ | 130 | */ |
131 | DEFINE_PER_CPU(unsigned long, last_jiffy); | 131 | DEFINE_PER_CPU(unsigned long, last_jiffy); |
132 | 132 | ||
133 | void __delay(unsigned long loops) | ||
134 | { | ||
135 | unsigned long start; | ||
136 | int diff; | ||
137 | |||
138 | if (__USE_RTC()) { | ||
139 | start = get_rtcl(); | ||
140 | do { | ||
141 | /* the RTCL register wraps at 1000000000 */ | ||
142 | diff = get_rtcl() - start; | ||
143 | if (diff < 0) | ||
144 | diff += 1000000000; | ||
145 | } while (diff < loops); | ||
146 | } else { | ||
147 | start = get_tbl(); | ||
148 | while (get_tbl() - start < loops) | ||
149 | HMT_low(); | ||
150 | HMT_medium(); | ||
151 | } | ||
152 | } | ||
153 | EXPORT_SYMBOL(__delay); | ||
154 | |||
155 | void udelay(unsigned long usecs) | ||
156 | { | ||
157 | __delay(tb_ticks_per_usec * usecs); | ||
158 | } | ||
159 | EXPORT_SYMBOL(udelay); | ||
160 | |||
133 | static __inline__ void timer_check_rtc(void) | 161 | static __inline__ void timer_check_rtc(void) |
134 | { | 162 | { |
135 | /* | 163 | /* |
diff --git a/arch/powerpc/kernel/vdso32/cacheflush.S b/arch/powerpc/kernel/vdso32/cacheflush.S index c8db993574ee..09629aea3e47 100644 --- a/arch/powerpc/kernel/vdso32/cacheflush.S +++ b/arch/powerpc/kernel/vdso32/cacheflush.S | |||
@@ -35,6 +35,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) | |||
35 | subf r8,r6,r4 /* compute length */ | 35 | subf r8,r6,r4 /* compute length */ |
36 | add r8,r8,r5 /* ensure we get enough */ | 36 | add r8,r8,r5 /* ensure we get enough */ |
37 | srwi. r8,r8,7 /* compute line count */ | 37 | srwi. r8,r8,7 /* compute line count */ |
38 | crclr cr0*4+so | ||
38 | beqlr /* nothing to do? */ | 39 | beqlr /* nothing to do? */ |
39 | mtctr r8 | 40 | mtctr r8 |
40 | mr r3,r6 | 41 | mr r3,r6 |
@@ -58,6 +59,7 @@ V_FUNCTION_END(__kernel_sync_dicache) | |||
58 | */ | 59 | */ |
59 | V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) | 60 | V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) |
60 | .cfi_startproc | 61 | .cfi_startproc |
62 | crclr cr0*4+so | ||
61 | sync | 63 | sync |
62 | isync | 64 | isync |
63 | li r3,0 | 65 | li r3,0 |
diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S index a08c26e87835..4709f1d9542c 100644 --- a/arch/powerpc/kernel/vdso32/datapage.S +++ b/arch/powerpc/kernel/vdso32/datapage.S | |||
@@ -54,7 +54,6 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map) | |||
54 | .cfi_startproc | 54 | .cfi_startproc |
55 | mflr r12 | 55 | mflr r12 |
56 | .cfi_register lr,r12 | 56 | .cfi_register lr,r12 |
57 | |||
58 | mr r4,r3 | 57 | mr r4,r3 |
59 | bl __get_datapage@local | 58 | bl __get_datapage@local |
60 | mtlr r12 | 59 | mtlr r12 |
@@ -63,6 +62,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map) | |||
63 | beqlr | 62 | beqlr |
64 | li r0,__NR_syscalls | 63 | li r0,__NR_syscalls |
65 | stw r0,0(r4) | 64 | stw r0,0(r4) |
65 | crclr cr0*4+so | ||
66 | blr | 66 | blr |
67 | .cfi_endproc | 67 | .cfi_endproc |
68 | V_FUNCTION_END(__kernel_get_syscall_map) | 68 | V_FUNCTION_END(__kernel_get_syscall_map) |
@@ -77,8 +77,10 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq) | |||
77 | mflr r12 | 77 | mflr r12 |
78 | .cfi_register lr,r12 | 78 | .cfi_register lr,r12 |
79 | bl __get_datapage@local | 79 | bl __get_datapage@local |
80 | lwz r3,CFG_TB_TICKS_PER_SEC(r3) | ||
81 | lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3) | 80 | lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3) |
81 | lwz r3,CFG_TB_TICKS_PER_SEC(r3) | ||
82 | mtlr r12 | 82 | mtlr r12 |
83 | crclr cr0*4+so | ||
84 | blr | ||
83 | .cfi_endproc | 85 | .cfi_endproc |
84 | V_FUNCTION_END(__kernel_get_tbfreq) | 86 | V_FUNCTION_END(__kernel_get_tbfreq) |
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index aeb5fc9b87b3..7eebff03a041 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S | |||
@@ -59,6 +59,7 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) | |||
59 | stw r5,TZONE_TZ_DSTTIME(r11) | 59 | stw r5,TZONE_TZ_DSTTIME(r11) |
60 | 60 | ||
61 | 1: mtlr r12 | 61 | 1: mtlr r12 |
62 | crclr cr0*4+so | ||
62 | li r3,0 | 63 | li r3,0 |
63 | blr | 64 | blr |
64 | 65 | ||
@@ -83,7 +84,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
83 | /* Check for supported clock IDs */ | 84 | /* Check for supported clock IDs */ |
84 | cmpli cr0,r3,CLOCK_REALTIME | 85 | cmpli cr0,r3,CLOCK_REALTIME |
85 | cmpli cr1,r3,CLOCK_MONOTONIC | 86 | cmpli cr1,r3,CLOCK_MONOTONIC |
86 | cror cr0,cr0,cr1 | 87 | cror cr0*4+eq,cr0*4+eq,cr1*4+eq |
87 | bne cr0,99f | 88 | bne cr0,99f |
88 | 89 | ||
89 | mflr r12 /* r12 saves lr */ | 90 | mflr r12 /* r12 saves lr */ |
@@ -91,7 +92,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
91 | mr r10,r3 /* r10 saves id */ | 92 | mr r10,r3 /* r10 saves id */ |
92 | mr r11,r4 /* r11 saves tp */ | 93 | mr r11,r4 /* r11 saves tp */ |
93 | bl __get_datapage@local /* get data page */ | 94 | bl __get_datapage@local /* get data page */ |
94 | mr r9, r3 /* datapage ptr in r9 */ | 95 | mr r9,r3 /* datapage ptr in r9 */ |
95 | beq cr1,50f /* if monotonic -> jump there */ | 96 | beq cr1,50f /* if monotonic -> jump there */ |
96 | 97 | ||
97 | /* | 98 | /* |
@@ -117,6 +118,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
117 | mulli r5,r5,1000 | 118 | mulli r5,r5,1000 |
118 | stw r5,TSPC32_TV_NSEC(r11) | 119 | stw r5,TSPC32_TV_NSEC(r11) |
119 | mtlr r12 | 120 | mtlr r12 |
121 | crclr cr0*4+so | ||
120 | li r3,0 | 122 | li r3,0 |
121 | blr | 123 | blr |
122 | 124 | ||
@@ -173,14 +175,19 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
173 | add r4,r4,r7 | 175 | add r4,r4,r7 |
174 | lis r5,NSEC_PER_SEC@h | 176 | lis r5,NSEC_PER_SEC@h |
175 | ori r5,r5,NSEC_PER_SEC@l | 177 | ori r5,r5,NSEC_PER_SEC@l |
176 | cmpli cr0,r4,r5 | 178 | cmpl cr0,r4,r5 |
179 | cmpli cr1,r4,0 | ||
177 | blt 1f | 180 | blt 1f |
178 | subf r4,r5,r4 | 181 | subf r4,r5,r4 |
179 | addi r3,r3,1 | 182 | addi r3,r3,1 |
183 | 1: bge cr1,1f | ||
184 | addi r3,r3,-1 | ||
185 | add r4,r4,r5 | ||
180 | 1: stw r3,TSPC32_TV_SEC(r11) | 186 | 1: stw r3,TSPC32_TV_SEC(r11) |
181 | stw r4,TSPC32_TV_NSEC(r11) | 187 | stw r4,TSPC32_TV_NSEC(r11) |
182 | 188 | ||
183 | mtlr r12 | 189 | mtlr r12 |
190 | crclr cr0*4+so | ||
184 | li r3,0 | 191 | li r3,0 |
185 | blr | 192 | blr |
186 | 193 | ||
@@ -210,11 +217,12 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) | |||
210 | /* Check for supported clock IDs */ | 217 | /* Check for supported clock IDs */ |
211 | cmpwi cr0,r3,CLOCK_REALTIME | 218 | cmpwi cr0,r3,CLOCK_REALTIME |
212 | cmpwi cr1,r3,CLOCK_MONOTONIC | 219 | cmpwi cr1,r3,CLOCK_MONOTONIC |
213 | cror cr0,cr0,cr1 | 220 | cror cr0*4+eq,cr0*4+eq,cr1*4+eq |
214 | bne cr0,99f | 221 | bne cr0,99f |
215 | 222 | ||
216 | li r3,0 | 223 | li r3,0 |
217 | cmpli cr0,r4,0 | 224 | cmpli cr0,r4,0 |
225 | crclr cr0*4+so | ||
218 | beqlr | 226 | beqlr |
219 | lis r5,CLOCK_REALTIME_RES@h | 227 | lis r5,CLOCK_REALTIME_RES@h |
220 | ori r5,r5,CLOCK_REALTIME_RES@l | 228 | ori r5,r5,CLOCK_REALTIME_RES@l |
diff --git a/arch/powerpc/kernel/vdso64/cacheflush.S b/arch/powerpc/kernel/vdso64/cacheflush.S index d4a0ad28d534..cb4ae0a5edd0 100644 --- a/arch/powerpc/kernel/vdso64/cacheflush.S +++ b/arch/powerpc/kernel/vdso64/cacheflush.S | |||
@@ -35,6 +35,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) | |||
35 | subf r8,r6,r4 /* compute length */ | 35 | subf r8,r6,r4 /* compute length */ |
36 | add r8,r8,r5 /* ensure we get enough */ | 36 | add r8,r8,r5 /* ensure we get enough */ |
37 | srwi. r8,r8,7 /* compute line count */ | 37 | srwi. r8,r8,7 /* compute line count */ |
38 | crclr cr0*4+so | ||
38 | beqlr /* nothing to do? */ | 39 | beqlr /* nothing to do? */ |
39 | mtctr r8 | 40 | mtctr r8 |
40 | mr r3,r6 | 41 | mr r3,r6 |
@@ -58,6 +59,7 @@ V_FUNCTION_END(__kernel_sync_dicache) | |||
58 | */ | 59 | */ |
59 | V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) | 60 | V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) |
60 | .cfi_startproc | 61 | .cfi_startproc |
62 | crclr cr0*4+so | ||
61 | sync | 63 | sync |
62 | isync | 64 | isync |
63 | li r3,0 | 65 | li r3,0 |
diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S index e67eda0f8cda..3b2dd7d0c1eb 100644 --- a/arch/powerpc/kernel/vdso64/datapage.S +++ b/arch/powerpc/kernel/vdso64/datapage.S | |||
@@ -54,12 +54,12 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map) | |||
54 | .cfi_startproc | 54 | .cfi_startproc |
55 | mflr r12 | 55 | mflr r12 |
56 | .cfi_register lr,r12 | 56 | .cfi_register lr,r12 |
57 | |||
58 | mr r4,r3 | 57 | mr r4,r3 |
59 | bl V_LOCAL_FUNC(__get_datapage) | 58 | bl V_LOCAL_FUNC(__get_datapage) |
60 | mtlr r12 | 59 | mtlr r12 |
61 | addi r3,r3,CFG_SYSCALL_MAP64 | 60 | addi r3,r3,CFG_SYSCALL_MAP64 |
62 | cmpli cr0,r4,0 | 61 | cmpli cr0,r4,0 |
62 | crclr cr0*4+so | ||
63 | beqlr | 63 | beqlr |
64 | li r0,__NR_syscalls | 64 | li r0,__NR_syscalls |
65 | stw r0,0(r4) | 65 | stw r0,0(r4) |
@@ -80,5 +80,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq) | |||
80 | bl V_LOCAL_FUNC(__get_datapage) | 80 | bl V_LOCAL_FUNC(__get_datapage) |
81 | ld r3,CFG_TB_TICKS_PER_SEC(r3) | 81 | ld r3,CFG_TB_TICKS_PER_SEC(r3) |
82 | mtlr r12 | 82 | mtlr r12 |
83 | crclr cr0*4+so | ||
84 | blr | ||
83 | .cfi_endproc | 85 | .cfi_endproc |
84 | V_FUNCTION_END(__kernel_get_tbfreq) | 86 | V_FUNCTION_END(__kernel_get_tbfreq) |
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index d371c02a8c0e..ccaeda5136d1 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S | |||
@@ -1,4 +1,5 @@ | |||
1 | /* | 1 | |
2 | /* | ||
2 | * Userland implementation of gettimeofday() for 64 bits processes in a | 3 | * Userland implementation of gettimeofday() for 64 bits processes in a |
3 | * ppc64 kernel for use in the vDSO | 4 | * ppc64 kernel for use in the vDSO |
4 | * | 5 | * |
@@ -51,6 +52,7 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) | |||
51 | stw r4,TZONE_TZ_MINWEST(r10) | 52 | stw r4,TZONE_TZ_MINWEST(r10) |
52 | stw r5,TZONE_TZ_DSTTIME(r10) | 53 | stw r5,TZONE_TZ_DSTTIME(r10) |
53 | 1: mtlr r12 | 54 | 1: mtlr r12 |
55 | crclr cr0*4+so | ||
54 | li r3,0 /* always success */ | 56 | li r3,0 /* always success */ |
55 | blr | 57 | blr |
56 | .cfi_endproc | 58 | .cfi_endproc |
@@ -68,7 +70,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
68 | /* Check for supported clock IDs */ | 70 | /* Check for supported clock IDs */ |
69 | cmpwi cr0,r3,CLOCK_REALTIME | 71 | cmpwi cr0,r3,CLOCK_REALTIME |
70 | cmpwi cr1,r3,CLOCK_MONOTONIC | 72 | cmpwi cr1,r3,CLOCK_MONOTONIC |
71 | cror cr0,cr0,cr1 | 73 | cror cr0*4+eq,cr0*4+eq,cr1*4+eq |
72 | bne cr0,99f | 74 | bne cr0,99f |
73 | 75 | ||
74 | mflr r12 /* r12 saves lr */ | 76 | mflr r12 /* r12 saves lr */ |
@@ -84,19 +86,21 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
84 | 86 | ||
85 | bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ | 87 | bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ |
86 | 88 | ||
87 | lis r7,0x3b9a /* r7 = 1000000000 = NSEC_PER_SEC */ | 89 | lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ |
88 | ori r7,r7,0xca00 | 90 | ori r7,r7,16960 |
89 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ | 91 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ |
90 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ | 92 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ |
91 | std r5,TSPC64_TV_SEC(r11) /* store sec in tv */ | 93 | std r5,TSPC64_TV_SEC(r11) /* store sec in tv */ |
92 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ | 94 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ |
93 | mulld r0,r0,r7 /* nsec = (xsec * NSEC_PER_SEC) / | 95 | mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / |
94 | * XSEC_PER_SEC | 96 | * XSEC_PER_SEC |
95 | */ | 97 | */ |
96 | rldicl r0,r0,44,20 | 98 | rldicl r0,r0,44,20 |
99 | mulli r0,r0,1000 /* nsec = usec * 1000 */ | ||
97 | std r0,TSPC64_TV_NSEC(r11) /* store nsec in tp */ | 100 | std r0,TSPC64_TV_NSEC(r11) /* store nsec in tp */ |
98 | 101 | ||
99 | mtlr r12 | 102 | mtlr r12 |
103 | crclr cr0*4+so | ||
100 | li r3,0 | 104 | li r3,0 |
101 | blr | 105 | blr |
102 | 106 | ||
@@ -106,15 +110,16 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
106 | 110 | ||
107 | 50: bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ | 111 | 50: bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ |
108 | 112 | ||
109 | lis r7,0x3b9a /* r7 = 1000000000 = NSEC_PER_SEC */ | 113 | lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ |
110 | ori r7,r7,0xca00 | 114 | ori r7,r7,16960 |
111 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ | 115 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ |
112 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ | 116 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ |
113 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ | 117 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ |
114 | mulld r0,r0,r7 /* nsec = (xsec * NSEC_PER_SEC) / | 118 | mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / |
115 | * XSEC_PER_SEC | 119 | * XSEC_PER_SEC |
116 | */ | 120 | */ |
117 | rldicl r6,r0,44,20 | 121 | rldicl r6,r0,44,20 |
122 | mulli r6,r6,1000 /* nsec = usec * 1000 */ | ||
118 | 123 | ||
119 | /* now we must fixup using wall to monotonic. We need to snapshot | 124 | /* now we must fixup using wall to monotonic. We need to snapshot |
120 | * that value and do the counter trick again. Fortunately, we still | 125 | * that value and do the counter trick again. Fortunately, we still |
@@ -123,8 +128,8 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
123 | * can be used | 128 | * can be used |
124 | */ | 129 | */ |
125 | 130 | ||
126 | lwz r4,WTOM_CLOCK_SEC(r9) | 131 | lwa r4,WTOM_CLOCK_SEC(r3) |
127 | lwz r7,WTOM_CLOCK_NSEC(r9) | 132 | lwa r7,WTOM_CLOCK_NSEC(r3) |
128 | 133 | ||
129 | /* We now have our result in r4,r7. We create a fake dependency | 134 | /* We now have our result in r4,r7. We create a fake dependency |
130 | * on that result and re-check the counter | 135 | * on that result and re-check the counter |
@@ -144,14 +149,19 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
144 | add r7,r7,r6 | 149 | add r7,r7,r6 |
145 | lis r9,NSEC_PER_SEC@h | 150 | lis r9,NSEC_PER_SEC@h |
146 | ori r9,r9,NSEC_PER_SEC@l | 151 | ori r9,r9,NSEC_PER_SEC@l |
147 | cmpli cr0,r7,r9 | 152 | cmpl cr0,r7,r9 |
153 | cmpli cr1,r7,0 | ||
148 | blt 1f | 154 | blt 1f |
149 | subf r7,r9,r7 | 155 | subf r7,r9,r7 |
150 | addi r4,r4,1 | 156 | addi r4,r4,1 |
157 | 1: bge cr1,1f | ||
158 | addi r4,r4,-1 | ||
159 | add r7,r7,r9 | ||
151 | 1: std r4,TSPC64_TV_SEC(r11) | 160 | 1: std r4,TSPC64_TV_SEC(r11) |
152 | std r7,TSPC64_TV_NSEC(r11) | 161 | std r7,TSPC64_TV_NSEC(r11) |
153 | 162 | ||
154 | mtlr r12 | 163 | mtlr r12 |
164 | crclr cr0*4+so | ||
155 | li r3,0 | 165 | li r3,0 |
156 | blr | 166 | blr |
157 | 167 | ||
@@ -181,11 +191,12 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) | |||
181 | /* Check for supported clock IDs */ | 191 | /* Check for supported clock IDs */ |
182 | cmpwi cr0,r3,CLOCK_REALTIME | 192 | cmpwi cr0,r3,CLOCK_REALTIME |
183 | cmpwi cr1,r3,CLOCK_MONOTONIC | 193 | cmpwi cr1,r3,CLOCK_MONOTONIC |
184 | cror cr0,cr0,cr1 | 194 | cror cr0*4+eq,cr0*4+eq,cr1*4+eq |
185 | bne cr0,99f | 195 | bne cr0,99f |
186 | 196 | ||
187 | li r3,0 | 197 | li r3,0 |
188 | cmpli cr0,r4,0 | 198 | cmpli cr0,r4,0 |
199 | crclr cr0*4+so | ||
189 | beqlr | 200 | beqlr |
190 | lis r5,CLOCK_REALTIME_RES@h | 201 | lis r5,CLOCK_REALTIME_RES@h |
191 | ori r5,r5,CLOCK_REALTIME_RES@l | 202 | ori r5,r5,CLOCK_REALTIME_RES@l |
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index af9ca0eb6d55..5d581bb3aa12 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Modifications by Kumar Gala (kumar.gala@freescale.com) to support | 2 | * Modifications by Kumar Gala (galak@kernel.crashing.org) to support |
3 | * E500 Book E processors. | 3 | * E500 Book E processors. |
4 | * | 4 | * |
5 | * Copyright 2004 Freescale Semiconductor, Inc | 5 | * Copyright 2004 Freescale Semiconductor, Inc |
diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c index 9b5aa6808eb8..9584608fd768 100644 --- a/arch/powerpc/mm/lmb.c +++ b/arch/powerpc/mm/lmb.c | |||
@@ -22,35 +22,38 @@ | |||
22 | #include "mmu_decl.h" /* for __max_low_memory */ | 22 | #include "mmu_decl.h" /* for __max_low_memory */ |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | struct lmb lmb; | ||
26 | |||
27 | #undef DEBUG | 25 | #undef DEBUG |
28 | 26 | ||
27 | #ifdef DEBUG | ||
28 | #include <asm/udbg.h> | ||
29 | #define DBG(fmt...) udbg_printf(fmt) | ||
30 | #else | ||
31 | #define DBG(fmt...) | ||
32 | #endif | ||
33 | |||
34 | struct lmb lmb; | ||
35 | |||
29 | void lmb_dump_all(void) | 36 | void lmb_dump_all(void) |
30 | { | 37 | { |
31 | #ifdef DEBUG | 38 | #ifdef DEBUG |
32 | unsigned long i; | 39 | unsigned long i; |
33 | 40 | ||
34 | udbg_printf("lmb_dump_all:\n"); | 41 | DBG("lmb_dump_all:\n"); |
35 | udbg_printf(" memory.cnt = 0x%lx\n", | 42 | DBG(" memory.cnt = 0x%lx\n", lmb.memory.cnt); |
36 | lmb.memory.cnt); | 43 | DBG(" memory.size = 0x%lx\n", lmb.memory.size); |
37 | udbg_printf(" memory.size = 0x%lx\n", | ||
38 | lmb.memory.size); | ||
39 | for (i=0; i < lmb.memory.cnt ;i++) { | 44 | for (i=0; i < lmb.memory.cnt ;i++) { |
40 | udbg_printf(" memory.region[0x%x].base = 0x%lx\n", | 45 | DBG(" memory.region[0x%x].base = 0x%lx\n", |
41 | i, lmb.memory.region[i].base); | 46 | i, lmb.memory.region[i].base); |
42 | udbg_printf(" .size = 0x%lx\n", | 47 | DBG(" .size = 0x%lx\n", |
43 | lmb.memory.region[i].size); | 48 | lmb.memory.region[i].size); |
44 | } | 49 | } |
45 | 50 | ||
46 | udbg_printf("\n reserved.cnt = 0x%lx\n", | 51 | DBG("\n reserved.cnt = 0x%lx\n", lmb.reserved.cnt); |
47 | lmb.reserved.cnt); | 52 | DBG(" reserved.size = 0x%lx\n", lmb.reserved.size); |
48 | udbg_printf(" reserved.size = 0x%lx\n", | ||
49 | lmb.reserved.size); | ||
50 | for (i=0; i < lmb.reserved.cnt ;i++) { | 53 | for (i=0; i < lmb.reserved.cnt ;i++) { |
51 | udbg_printf(" reserved.region[0x%x].base = 0x%lx\n", | 54 | DBG(" reserved.region[0x%x].base = 0x%lx\n", |
52 | i, lmb.reserved.region[i].base); | 55 | i, lmb.reserved.region[i].base); |
53 | udbg_printf(" .size = 0x%lx\n", | 56 | DBG(" .size = 0x%lx\n", |
54 | lmb.reserved.region[i].size); | 57 | lmb.reserved.region[i].size); |
55 | } | 58 | } |
56 | #endif /* DEBUG */ | 59 | #endif /* DEBUG */ |
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index e2c95fcb8055..4bd7b0a70996 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
@@ -200,6 +200,8 @@ void show_mem(void) | |||
200 | unsigned long flags; | 200 | unsigned long flags; |
201 | pgdat_resize_lock(pgdat, &flags); | 201 | pgdat_resize_lock(pgdat, &flags); |
202 | for (i = 0; i < pgdat->node_spanned_pages; i++) { | 202 | for (i = 0; i < pgdat->node_spanned_pages; i++) { |
203 | if (!pfn_valid(pgdat->node_start_pfn + i)) | ||
204 | continue; | ||
203 | page = pgdat_page_nr(pgdat, i); | 205 | page = pgdat_page_nr(pgdat, i); |
204 | total++; | 206 | total++; |
205 | if (PageHighMem(page)) | 207 | if (PageHighMem(page)) |
@@ -336,7 +338,7 @@ void __init mem_init(void) | |||
336 | struct page *page; | 338 | struct page *page; |
337 | unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize; | 339 | unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize; |
338 | 340 | ||
339 | num_physpages = max_pfn; /* RAM is assumed contiguous */ | 341 | num_physpages = lmb.memory.size >> PAGE_SHIFT; |
340 | high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); | 342 | high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); |
341 | 343 | ||
342 | #ifdef CONFIG_NEED_MULTIPLE_NODES | 344 | #ifdef CONFIG_NEED_MULTIPLE_NODES |
@@ -348,11 +350,13 @@ void __init mem_init(void) | |||
348 | } | 350 | } |
349 | } | 351 | } |
350 | #else | 352 | #else |
351 | max_mapnr = num_physpages; | 353 | max_mapnr = max_pfn; |
352 | totalram_pages += free_all_bootmem(); | 354 | totalram_pages += free_all_bootmem(); |
353 | #endif | 355 | #endif |
354 | for_each_pgdat(pgdat) { | 356 | for_each_pgdat(pgdat) { |
355 | for (i = 0; i < pgdat->node_spanned_pages; i++) { | 357 | for (i = 0; i < pgdat->node_spanned_pages; i++) { |
358 | if (!pfn_valid(pgdat->node_start_pfn + i)) | ||
359 | continue; | ||
356 | page = pgdat_page_nr(pgdat, i); | 360 | page = pgdat_page_nr(pgdat, i); |
357 | if (PageReserved(page)) | 361 | if (PageReserved(page)) |
358 | reservedpages++; | 362 | reservedpages++; |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index bd2cf1336885..f72cf87364cb 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -483,6 +483,7 @@ static void __init setup_nonnuma(void) | |||
483 | { | 483 | { |
484 | unsigned long top_of_ram = lmb_end_of_DRAM(); | 484 | unsigned long top_of_ram = lmb_end_of_DRAM(); |
485 | unsigned long total_ram = lmb_phys_mem_size(); | 485 | unsigned long total_ram = lmb_phys_mem_size(); |
486 | unsigned int i; | ||
486 | 487 | ||
487 | printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", | 488 | printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", |
488 | top_of_ram, total_ram); | 489 | top_of_ram, total_ram); |
@@ -490,7 +491,9 @@ static void __init setup_nonnuma(void) | |||
490 | (top_of_ram - total_ram) >> 20); | 491 | (top_of_ram - total_ram) >> 20); |
491 | 492 | ||
492 | map_cpu_to_node(boot_cpuid, 0); | 493 | map_cpu_to_node(boot_cpuid, 0); |
493 | add_region(0, 0, lmb_end_of_DRAM() >> PAGE_SHIFT); | 494 | for (i = 0; i < lmb.memory.cnt; ++i) |
495 | add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT, | ||
496 | lmb_size_pages(&lmb.memory, i)); | ||
494 | node_set_online(0); | 497 | node_set_online(0); |
495 | } | 498 | } |
496 | 499 | ||
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c index 86124a94c9af..26539cda6023 100644 --- a/arch/powerpc/oprofile/op_model_fsl_booke.c +++ b/arch/powerpc/oprofile/op_model_fsl_booke.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Copyright (c) 2004 Freescale Semiconductor, Inc | 7 | * Copyright (c) 2004 Freescale Semiconductor, Inc |
8 | * | 8 | * |
9 | * Author: Andy Fleming | 9 | * Author: Andy Fleming |
10 | * Maintainer: Kumar Gala <Kumar.Gala@freescale.com> | 10 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | 13 | * modify it under the terms of the GNU General Public License |
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 4099ddab9205..dda5f2c72c25 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
@@ -257,6 +257,13 @@ void __init chrp_setup_arch(void) | |||
257 | if (rtas_token("display-character") >= 0) | 257 | if (rtas_token("display-character") >= 0) |
258 | ppc_md.progress = rtas_progress; | 258 | ppc_md.progress = rtas_progress; |
259 | 259 | ||
260 | /* use RTAS time-of-day routines if available */ | ||
261 | if (rtas_token("get-time-of-day") != RTAS_UNKNOWN_SERVICE) { | ||
262 | ppc_md.get_boot_time = rtas_get_boot_time; | ||
263 | ppc_md.get_rtc_time = rtas_get_rtc_time; | ||
264 | ppc_md.set_rtc_time = rtas_set_rtc_time; | ||
265 | } | ||
266 | |||
260 | #ifdef CONFIG_BOOTX_TEXT | 267 | #ifdef CONFIG_BOOTX_TEXT |
261 | if (ppc_md.progress == NULL && boot_text_mapped) | 268 | if (ppc_md.progress == NULL && boot_text_mapped) |
262 | ppc_md.progress = btext_progress; | 269 | ppc_md.progress = btext_progress; |
@@ -505,9 +512,11 @@ void __init chrp_init(void) | |||
505 | ppc_md.halt = rtas_halt; | 512 | ppc_md.halt = rtas_halt; |
506 | 513 | ||
507 | ppc_md.time_init = chrp_time_init; | 514 | ppc_md.time_init = chrp_time_init; |
515 | ppc_md.calibrate_decr = chrp_calibrate_decr; | ||
516 | |||
517 | /* this may get overridden with rtas routines later... */ | ||
508 | ppc_md.set_rtc_time = chrp_set_rtc_time; | 518 | ppc_md.set_rtc_time = chrp_set_rtc_time; |
509 | ppc_md.get_rtc_time = chrp_get_rtc_time; | 519 | ppc_md.get_rtc_time = chrp_get_rtc_time; |
510 | ppc_md.calibrate_decr = chrp_calibrate_decr; | ||
511 | 520 | ||
512 | #ifdef CONFIG_SMP | 521 | #ifdef CONFIG_SMP |
513 | smp_ops = &chrp_smp_ops; | 522 | smp_ops = &chrp_smp_ops; |
diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c index bb2315997d45..b616053bc331 100644 --- a/arch/powerpc/platforms/chrp/smp.c +++ b/arch/powerpc/platforms/chrp/smp.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/machdep.h> | 34 | #include <asm/machdep.h> |
35 | #include <asm/smp.h> | 35 | #include <asm/smp.h> |
36 | #include <asm/mpic.h> | 36 | #include <asm/mpic.h> |
37 | #include <asm/rtas.h> | ||
37 | 38 | ||
38 | static void __devinit smp_chrp_kick_cpu(int nr) | 39 | static void __devinit smp_chrp_kick_cpu(int nr) |
39 | { | 40 | { |
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c index 9e53535ddb82..737ee5d9f0aa 100644 --- a/arch/powerpc/platforms/chrp/time.c +++ b/arch/powerpc/platforms/chrp/time.c | |||
@@ -87,7 +87,6 @@ int chrp_set_rtc_time(struct rtc_time *tmarg) | |||
87 | 87 | ||
88 | chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); | 88 | chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); |
89 | 89 | ||
90 | tm.tm_year -= 1900; | ||
91 | if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | 90 | if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
92 | BIN_TO_BCD(tm.tm_sec); | 91 | BIN_TO_BCD(tm.tm_sec); |
93 | BIN_TO_BCD(tm.tm_min); | 92 | BIN_TO_BCD(tm.tm_min); |
@@ -156,7 +155,7 @@ void chrp_get_rtc_time(struct rtc_time *tm) | |||
156 | BCD_TO_BIN(mon); | 155 | BCD_TO_BIN(mon); |
157 | BCD_TO_BIN(year); | 156 | BCD_TO_BIN(year); |
158 | } | 157 | } |
159 | if ((year += 1900) < 1970) | 158 | if (year < 70) |
160 | year += 100; | 159 | year += 100; |
161 | tm->tm_sec = sec; | 160 | tm->tm_sec = sec; |
162 | tm->tm_min = min; | 161 | tm->tm_min = min; |
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index 01090e9ce0cf..a58daa153686 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c | |||
@@ -42,13 +42,6 @@ | |||
42 | #include "irq.h" | 42 | #include "irq.h" |
43 | #include "call_pci.h" | 43 | #include "call_pci.h" |
44 | 44 | ||
45 | /* This maps virtual irq numbers to real irqs */ | ||
46 | unsigned int virt_irq_to_real_map[NR_IRQS]; | ||
47 | |||
48 | /* The next available virtual irq number */ | ||
49 | /* Note: the pcnet32 driver assumes irq numbers < 2 aren't valid. :( */ | ||
50 | static int next_virtual_irq = 2; | ||
51 | |||
52 | static long Pci_Interrupt_Count; | 45 | static long Pci_Interrupt_Count; |
53 | static long Pci_Event_Count; | 46 | static long Pci_Event_Count; |
54 | 47 | ||
@@ -350,26 +343,14 @@ static hw_irq_controller iSeries_IRQ_handler = { | |||
350 | int __init iSeries_allocate_IRQ(HvBusNumber busNumber, | 343 | int __init iSeries_allocate_IRQ(HvBusNumber busNumber, |
351 | HvSubBusNumber subBusNumber, HvAgentId deviceId) | 344 | HvSubBusNumber subBusNumber, HvAgentId deviceId) |
352 | { | 345 | { |
353 | unsigned int realirq, virtirq; | 346 | int virtirq; |
347 | unsigned int realirq; | ||
354 | u8 idsel = (deviceId >> 4); | 348 | u8 idsel = (deviceId >> 4); |
355 | u8 function = deviceId & 7; | 349 | u8 function = deviceId & 7; |
356 | 350 | ||
357 | virtirq = next_virtual_irq++; | ||
358 | realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function; | 351 | realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function; |
359 | virt_irq_to_real_map[virtirq] = realirq; | 352 | virtirq = virt_irq_create_mapping(realirq); |
360 | 353 | ||
361 | irq_desc[virtirq].handler = &iSeries_IRQ_handler; | 354 | irq_desc[virtirq].handler = &iSeries_IRQ_handler; |
362 | return virtirq; | 355 | return virtirq; |
363 | } | 356 | } |
364 | |||
365 | int virt_irq_create_mapping(unsigned int real_irq) | ||
366 | { | ||
367 | BUG(); /* Don't call this on iSeries, yet */ | ||
368 | |||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | void virt_irq_init(void) | ||
373 | { | ||
374 | return; | ||
375 | } | ||
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 4b75131773a6..dafc518fbb83 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c | |||
@@ -244,10 +244,9 @@ unsigned long __init find_and_init_phbs(void) | |||
244 | if (ret == 0) { | 244 | if (ret == 0) { |
245 | printk("bus %d appears to exist\n", bus); | 245 | printk("bus %d appears to exist\n", bus); |
246 | 246 | ||
247 | phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL); | 247 | phb = pcibios_alloc_controller(NULL); |
248 | if (phb == NULL) | 248 | if (phb == NULL) |
249 | return -ENOMEM; | 249 | return -ENOMEM; |
250 | pci_setup_pci_controller(phb); | ||
251 | 250 | ||
252 | phb->pci_mem_offset = phb->local_number = bus; | 251 | phb->pci_mem_offset = phb->local_number = bus; |
253 | phb->first_busno = bus; | 252 | phb->first_busno = bus; |
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 6a29f301436b..da26639190db 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <asm/sections.h> | 39 | #include <asm/sections.h> |
40 | #include <asm/iommu.h> | 40 | #include <asm/iommu.h> |
41 | #include <asm/firmware.h> | 41 | #include <asm/firmware.h> |
42 | #include <asm/systemcfg.h> | ||
43 | #include <asm/system.h> | 42 | #include <asm/system.h> |
44 | #include <asm/time.h> | 43 | #include <asm/time.h> |
45 | #include <asm/paca.h> | 44 | #include <asm/paca.h> |
@@ -548,8 +547,6 @@ static unsigned long __init build_iSeries_Memory_Map(void) | |||
548 | */ | 547 | */ |
549 | static void __init iSeries_setup_arch(void) | 548 | static void __init iSeries_setup_arch(void) |
550 | { | 549 | { |
551 | unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index; | ||
552 | |||
553 | if (get_paca()->lppaca.shared_proc) { | 550 | if (get_paca()->lppaca.shared_proc) { |
554 | ppc_md.idle_loop = iseries_shared_idle; | 551 | ppc_md.idle_loop = iseries_shared_idle; |
555 | printk(KERN_INFO "Using shared processor idle loop\n"); | 552 | printk(KERN_INFO "Using shared processor idle loop\n"); |
@@ -565,9 +562,6 @@ static void __init iSeries_setup_arch(void) | |||
565 | itVpdAreas.xSlicMaxLogicalProcs); | 562 | itVpdAreas.xSlicMaxLogicalProcs); |
566 | printk("Max physical processors = %d\n", | 563 | printk("Max physical processors = %d\n", |
567 | itVpdAreas.xSlicMaxPhysicalProcs); | 564 | itVpdAreas.xSlicMaxPhysicalProcs); |
568 | |||
569 | _systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR; | ||
570 | printk("Processor version = %x\n", _systemcfg->processor); | ||
571 | } | 565 | } |
572 | 566 | ||
573 | static void iSeries_show_cpuinfo(struct seq_file *m) | 567 | static void iSeries_show_cpuinfo(struct seq_file *m) |
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 895aeb3f75d0..f40451da037c 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c | |||
@@ -326,26 +326,12 @@ static int __init add_bridge(struct device_node *dev) | |||
326 | dev->full_name); | 326 | dev->full_name); |
327 | } | 327 | } |
328 | 328 | ||
329 | hose = alloc_bootmem(sizeof(struct pci_controller)); | 329 | hose = pcibios_alloc_controller(dev); |
330 | if (hose == NULL) | 330 | if (hose == NULL) |
331 | return -ENOMEM; | 331 | return -ENOMEM; |
332 | pci_setup_pci_controller(hose); | ||
333 | |||
334 | hose->arch_data = dev; | ||
335 | hose->first_busno = bus_range ? bus_range[0] : 0; | 332 | hose->first_busno = bus_range ? bus_range[0] : 0; |
336 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | 333 | hose->last_busno = bus_range ? bus_range[1] : 0xff; |
337 | 334 | ||
338 | of_prop = alloc_bootmem(sizeof(struct property) + | ||
339 | sizeof(hose->global_number)); | ||
340 | if (of_prop) { | ||
341 | memset(of_prop, 0, sizeof(struct property)); | ||
342 | of_prop->name = "linux,pci-domain"; | ||
343 | of_prop->length = sizeof(hose->global_number); | ||
344 | of_prop->value = (unsigned char *)&of_prop[1]; | ||
345 | memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number)); | ||
346 | prom_add_property(dev, of_prop); | ||
347 | } | ||
348 | |||
349 | disp_name = NULL; | 335 | disp_name = NULL; |
350 | if (device_is_compatible(dev, "u3-agp")) { | 336 | if (device_is_compatible(dev, "u3-agp")) { |
351 | setup_u3_agp(hose); | 337 | setup_u3_agp(hose); |
diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c index 40fc07a8e606..15846cc938ac 100644 --- a/arch/powerpc/platforms/maple/time.c +++ b/arch/powerpc/platforms/maple/time.c | |||
@@ -158,6 +158,11 @@ int maple_set_rtc_time(struct rtc_time *tm) | |||
158 | return 0; | 158 | return 0; |
159 | } | 159 | } |
160 | 160 | ||
161 | static struct resource rtc_iores = { | ||
162 | .name = "rtc", | ||
163 | .flags = IORESOURCE_BUSY, | ||
164 | }; | ||
165 | |||
161 | unsigned long __init maple_get_boot_time(void) | 166 | unsigned long __init maple_get_boot_time(void) |
162 | { | 167 | { |
163 | struct rtc_time tm; | 168 | struct rtc_time tm; |
@@ -172,7 +177,11 @@ unsigned long __init maple_get_boot_time(void) | |||
172 | printk(KERN_INFO "Maple: No device node for RTC, assuming " | 177 | printk(KERN_INFO "Maple: No device node for RTC, assuming " |
173 | "legacy address (0x%x)\n", maple_rtc_addr); | 178 | "legacy address (0x%x)\n", maple_rtc_addr); |
174 | } | 179 | } |
175 | 180 | ||
181 | rtc_iores.start = maple_rtc_addr; | ||
182 | rtc_iores.end = maple_rtc_addr + 7; | ||
183 | request_resource(&ioport_resource, &rtc_iores); | ||
184 | |||
176 | maple_get_rtc_time(&tm); | 185 | maple_get_rtc_time(&tm); |
177 | return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, | 186 | return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, |
178 | tm.tm_hour, tm.tm_min, tm.tm_sec); | 187 | tm.tm_hour, tm.tm_min, tm.tm_sec); |
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 10f1d942c661..0d7fa00fcb00 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
@@ -2362,6 +2362,14 @@ static struct pmac_mb_def pmac_mb_defs[] = { | |||
2362 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | 2362 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, |
2363 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | 2363 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, |
2364 | }, | 2364 | }, |
2365 | { "PowerBook5,8", "PowerBook G4 15\"", | ||
2366 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
2367 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
2368 | }, | ||
2369 | { "PowerBook5,9", "PowerBook G4 17\"", | ||
2370 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
2371 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
2372 | }, | ||
2365 | { "PowerBook6,1", "PowerBook G4 12\"", | 2373 | { "PowerBook6,1", "PowerBook G4 12\"", |
2366 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | 2374 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, |
2367 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | 2375 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, |
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index dfd41b9781a9..443be526cde7 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
@@ -640,15 +640,16 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
640 | * the reg address cell, we shall fix that by killing struct | 640 | * the reg address cell, we shall fix that by killing struct |
641 | * reg_property and using some accessor functions instead | 641 | * reg_property and using some accessor functions instead |
642 | */ | 642 | */ |
643 | hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000); | 643 | hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, |
644 | 0x02000000); | ||
644 | 645 | ||
645 | /* | 646 | /* |
646 | * /ht node doesn't expose a "ranges" property, so we "remove" regions that | 647 | * /ht node doesn't expose a "ranges" property, so we "remove" |
647 | * have been allocated to AGP. So far, this version of the code doesn't assign | 648 | * regions that have been allocated to AGP. So far, this version of |
648 | * any of the 0xfxxxxxxx "fine" memory regions to /ht. | 649 | * the code doesn't assign any of the 0xfxxxxxxx "fine" memory regions |
649 | * We need to fix that sooner or later by either parsing all child "ranges" | 650 | * to /ht. We need to fix that sooner or later by either parsing all |
650 | * properties or figuring out the U3 address space decoding logic and | 651 | * child "ranges" properties or figuring out the U3 address space |
651 | * then read its configuration register (if any). | 652 | * decoding logic and then read its configuration register (if any). |
652 | */ | 653 | */ |
653 | hose->io_base_phys = 0xf4000000; | 654 | hose->io_base_phys = 0xf4000000; |
654 | hose->pci_io_size = 0x00400000; | 655 | hose->pci_io_size = 0x00400000; |
@@ -671,10 +672,10 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
671 | return; | 672 | return; |
672 | } | 673 | } |
673 | 674 | ||
674 | /* We "remove" the AGP resources from the resources allocated to HT, that | 675 | /* We "remove" the AGP resources from the resources allocated to HT, |
675 | * is we create "holes". However, that code does assumptions that so far | 676 | * that is we create "holes". However, that code does assumptions |
676 | * happen to be true (cross fingers...), typically that resources in the | 677 | * that so far happen to be true (cross fingers...), typically that |
677 | * AGP node are properly ordered | 678 | * resources in the AGP node are properly ordered |
678 | */ | 679 | */ |
679 | cur = 0; | 680 | cur = 0; |
680 | for (i=0; i<3; i++) { | 681 | for (i=0; i<3; i++) { |
@@ -684,23 +685,30 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
684 | /* We don't care about "fine" resources */ | 685 | /* We don't care about "fine" resources */ |
685 | if (res->start >= 0xf0000000) | 686 | if (res->start >= 0xf0000000) |
686 | continue; | 687 | continue; |
687 | /* Check if it's just a matter of "shrinking" us in one direction */ | 688 | /* Check if it's just a matter of "shrinking" us in one |
689 | * direction | ||
690 | */ | ||
688 | if (hose->mem_resources[cur].start == res->start) { | 691 | if (hose->mem_resources[cur].start == res->start) { |
689 | DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n", | 692 | DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n", |
690 | cur, hose->mem_resources[cur].start, res->end + 1); | 693 | cur, hose->mem_resources[cur].start, |
694 | res->end + 1); | ||
691 | hose->mem_resources[cur].start = res->end + 1; | 695 | hose->mem_resources[cur].start = res->end + 1; |
692 | continue; | 696 | continue; |
693 | } | 697 | } |
694 | if (hose->mem_resources[cur].end == res->end) { | 698 | if (hose->mem_resources[cur].end == res->end) { |
695 | DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n", | 699 | DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n", |
696 | cur, hose->mem_resources[cur].end, res->start - 1); | 700 | cur, hose->mem_resources[cur].end, |
701 | res->start - 1); | ||
697 | hose->mem_resources[cur].end = res->start - 1; | 702 | hose->mem_resources[cur].end = res->start - 1; |
698 | continue; | 703 | continue; |
699 | } | 704 | } |
700 | /* No, it's not the case, we need a hole */ | 705 | /* No, it's not the case, we need a hole */ |
701 | if (cur == 2) { | 706 | if (cur == 2) { |
702 | /* not enough resources for a hole, we drop part of the range */ | 707 | /* not enough resources for a hole, we drop part |
703 | printk(KERN_WARNING "Running out of resources for /ht host !\n"); | 708 | * of the range |
709 | */ | ||
710 | printk(KERN_WARNING "Running out of resources" | ||
711 | " for /ht host !\n"); | ||
704 | hose->mem_resources[cur].end = res->start - 1; | 712 | hose->mem_resources[cur].end = res->start - 1; |
705 | continue; | 713 | continue; |
706 | } | 714 | } |
@@ -714,17 +722,6 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
714 | hose->mem_resources[cur-1].end = res->start - 1; | 722 | hose->mem_resources[cur-1].end = res->start - 1; |
715 | } | 723 | } |
716 | } | 724 | } |
717 | |||
718 | /* XXX this needs to be converged between ppc32 and ppc64... */ | ||
719 | static struct pci_controller * __init pcibios_alloc_controller(void) | ||
720 | { | ||
721 | struct pci_controller *hose; | ||
722 | |||
723 | hose = alloc_bootmem(sizeof(struct pci_controller)); | ||
724 | if (hose) | ||
725 | pci_setup_pci_controller(hose); | ||
726 | return hose; | ||
727 | } | ||
728 | #endif | 725 | #endif |
729 | 726 | ||
730 | /* | 727 | /* |
@@ -756,11 +753,16 @@ static int __init add_bridge(struct device_node *dev) | |||
756 | #endif | 753 | #endif |
757 | bus_range = (int *) get_property(dev, "bus-range", &len); | 754 | bus_range = (int *) get_property(dev, "bus-range", &len); |
758 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 755 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
759 | printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", | 756 | printk(KERN_WARNING "Can't get bus-range for %s, assume" |
760 | dev->full_name); | 757 | " bus 0\n", dev->full_name); |
761 | } | 758 | } |
762 | 759 | ||
760 | /* XXX Different prototypes, to be merged */ | ||
761 | #ifdef CONFIG_PPC64 | ||
762 | hose = pcibios_alloc_controller(dev); | ||
763 | #else | ||
763 | hose = pcibios_alloc_controller(); | 764 | hose = pcibios_alloc_controller(); |
765 | #endif | ||
764 | if (!hose) | 766 | if (!hose) |
765 | return -ENOMEM; | 767 | return -ENOMEM; |
766 | hose->arch_data = dev; | 768 | hose->arch_data = dev; |
@@ -768,7 +770,7 @@ static int __init add_bridge(struct device_node *dev) | |||
768 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | 770 | hose->last_busno = bus_range ? bus_range[1] : 0xff; |
769 | 771 | ||
770 | disp_name = NULL; | 772 | disp_name = NULL; |
771 | #ifdef CONFIG_POWER4 | 773 | #ifdef CONFIG_PPC64 |
772 | if (device_is_compatible(dev, "u3-agp")) { | 774 | if (device_is_compatible(dev, "u3-agp")) { |
773 | setup_u3_agp(hose); | 775 | setup_u3_agp(hose); |
774 | disp_name = "U3-AGP"; | 776 | disp_name = "U3-AGP"; |
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index 5947b21a8588..feb0a94e7819 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c | |||
@@ -102,7 +102,7 @@ static unsigned long from_rtc_time(struct rtc_time *tm) | |||
102 | static unsigned long cuda_get_time(void) | 102 | static unsigned long cuda_get_time(void) |
103 | { | 103 | { |
104 | struct adb_request req; | 104 | struct adb_request req; |
105 | unsigned long now; | 105 | unsigned int now; |
106 | 106 | ||
107 | if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) | 107 | if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) |
108 | return 0; | 108 | return 0; |
@@ -113,7 +113,7 @@ static unsigned long cuda_get_time(void) | |||
113 | req.reply_len); | 113 | req.reply_len); |
114 | now = (req.reply[3] << 24) + (req.reply[4] << 16) | 114 | now = (req.reply[3] << 24) + (req.reply[4] << 16) |
115 | + (req.reply[5] << 8) + req.reply[6]; | 115 | + (req.reply[5] << 8) + req.reply[6]; |
116 | return now - RTC_OFFSET; | 116 | return ((unsigned long)now) - RTC_OFFSET; |
117 | } | 117 | } |
118 | 118 | ||
119 | #define cuda_get_rtc_time(tm) to_rtc_time(cuda_get_time(), (tm)) | 119 | #define cuda_get_rtc_time(tm) to_rtc_time(cuda_get_time(), (tm)) |
@@ -146,7 +146,7 @@ static int cuda_set_rtc_time(struct rtc_time *tm) | |||
146 | static unsigned long pmu_get_time(void) | 146 | static unsigned long pmu_get_time(void) |
147 | { | 147 | { |
148 | struct adb_request req; | 148 | struct adb_request req; |
149 | unsigned long now; | 149 | unsigned int now; |
150 | 150 | ||
151 | if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) | 151 | if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) |
152 | return 0; | 152 | return 0; |
@@ -156,7 +156,7 @@ static unsigned long pmu_get_time(void) | |||
156 | req.reply_len); | 156 | req.reply_len); |
157 | now = (req.reply[0] << 24) + (req.reply[1] << 16) | 157 | now = (req.reply[0] << 24) + (req.reply[1] << 16) |
158 | + (req.reply[2] << 8) + req.reply[3]; | 158 | + (req.reply[2] << 8) + req.reply[3]; |
159 | return now - RTC_OFFSET; | 159 | return ((unsigned long)now) - RTC_OFFSET; |
160 | } | 160 | } |
161 | 161 | ||
162 | #define pmu_get_rtc_time(tm) to_rtc_time(pmu_get_time(), (tm)) | 162 | #define pmu_get_rtc_time(tm) to_rtc_time(pmu_get_time(), (tm)) |
@@ -199,6 +199,7 @@ static unsigned long smu_get_time(void) | |||
199 | #define smu_set_rtc_time(tm, spin) 0 | 199 | #define smu_set_rtc_time(tm, spin) 0 |
200 | #endif | 200 | #endif |
201 | 201 | ||
202 | /* Can't be __init, it's called when suspending and resuming */ | ||
202 | unsigned long pmac_get_boot_time(void) | 203 | unsigned long pmac_get_boot_time(void) |
203 | { | 204 | { |
204 | /* Get the time from the RTC, used only at boot time */ | 205 | /* Get the time from the RTC, used only at boot time */ |
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index e7ca5b1f591e..06d5ef501218 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile | |||
@@ -4,4 +4,7 @@ obj-$(CONFIG_SMP) += smp.o | |||
4 | obj-$(CONFIG_IBMVIO) += vio.o | 4 | obj-$(CONFIG_IBMVIO) += vio.o |
5 | obj-$(CONFIG_XICS) += xics.o | 5 | obj-$(CONFIG_XICS) += xics.o |
6 | obj-$(CONFIG_SCANLOG) += scanlog.o | 6 | obj-$(CONFIG_SCANLOG) += scanlog.o |
7 | obj-$(CONFIG_EEH) += eeh.o eeh_event.o | 7 | obj-$(CONFIG_EEH) += eeh.o eeh_event.o |
8 | |||
9 | obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o | ||
10 | obj-$(CONFIG_HVCS) += hvcserver.o | ||
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 79de2310e70b..c8d2a40dc5b4 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -86,7 +86,8 @@ static int ibm_read_slot_reset_state; | |||
86 | static int ibm_read_slot_reset_state2; | 86 | static int ibm_read_slot_reset_state2; |
87 | static int ibm_slot_error_detail; | 87 | static int ibm_slot_error_detail; |
88 | 88 | ||
89 | static int eeh_subsystem_enabled; | 89 | int eeh_subsystem_enabled; |
90 | EXPORT_SYMBOL(eeh_subsystem_enabled); | ||
90 | 91 | ||
91 | /* Lock to avoid races due to multiple reports of an error */ | 92 | /* Lock to avoid races due to multiple reports of an error */ |
92 | static DEFINE_SPINLOCK(confirm_error_lock); | 93 | static DEFINE_SPINLOCK(confirm_error_lock); |
diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c new file mode 100644 index 000000000000..138e128a3886 --- /dev/null +++ b/arch/powerpc/platforms/pseries/hvconsole.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * hvconsole.c | ||
3 | * Copyright (C) 2004 Hollis Blanchard, IBM Corporation | ||
4 | * Copyright (C) 2004 IBM Corporation | ||
5 | * | ||
6 | * Additional Author(s): | ||
7 | * Ryan S. Arnold <rsa@us.ibm.com> | ||
8 | * | ||
9 | * LPAR console support. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <asm/hvcall.h> | ||
29 | #include <asm/hvconsole.h> | ||
30 | |||
31 | /** | ||
32 | * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper | ||
33 | * @vtermno: The vtermno or unit_address of the adapter from which to fetch the | ||
34 | * data. | ||
35 | * @buf: The character buffer into which to put the character data fetched from | ||
36 | * firmware. | ||
37 | * @count: not used? | ||
38 | */ | ||
39 | int hvc_get_chars(uint32_t vtermno, char *buf, int count) | ||
40 | { | ||
41 | unsigned long got; | ||
42 | |||
43 | if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got, | ||
44 | (unsigned long *)buf, (unsigned long *)buf+1) == H_Success) | ||
45 | return got; | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | EXPORT_SYMBOL(hvc_get_chars); | ||
50 | |||
51 | |||
52 | /** | ||
53 | * hvc_put_chars: send characters to firmware for denoted vterm adapter | ||
54 | * @vtermno: The vtermno or unit_address of the adapter from which the data | ||
55 | * originated. | ||
56 | * @buf: The character buffer that contains the character data to send to | ||
57 | * firmware. | ||
58 | * @count: Send this number of characters. | ||
59 | */ | ||
60 | int hvc_put_chars(uint32_t vtermno, const char *buf, int count) | ||
61 | { | ||
62 | unsigned long *lbuf = (unsigned long *) buf; | ||
63 | long ret; | ||
64 | |||
65 | ret = plpar_hcall_norets(H_PUT_TERM_CHAR, vtermno, count, lbuf[0], | ||
66 | lbuf[1]); | ||
67 | if (ret == H_Success) | ||
68 | return count; | ||
69 | if (ret == H_Busy) | ||
70 | return 0; | ||
71 | return -EIO; | ||
72 | } | ||
73 | |||
74 | EXPORT_SYMBOL(hvc_put_chars); | ||
diff --git a/arch/powerpc/platforms/pseries/hvcserver.c b/arch/powerpc/platforms/pseries/hvcserver.c new file mode 100644 index 000000000000..4d584172055a --- /dev/null +++ b/arch/powerpc/platforms/pseries/hvcserver.c | |||
@@ -0,0 +1,251 @@ | |||
1 | /* | ||
2 | * hvcserver.c | ||
3 | * Copyright (C) 2004 Ryan S Arnold, IBM Corporation | ||
4 | * | ||
5 | * PPC64 virtual I/O console server support. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/slab.h> | ||
26 | |||
27 | #include <asm/hvcall.h> | ||
28 | #include <asm/hvcserver.h> | ||
29 | #include <asm/io.h> | ||
30 | |||
31 | #define HVCS_ARCH_VERSION "1.0.0" | ||
32 | |||
33 | MODULE_AUTHOR("Ryan S. Arnold <rsa@us.ibm.com>"); | ||
34 | MODULE_DESCRIPTION("IBM hvcs ppc64 API"); | ||
35 | MODULE_LICENSE("GPL"); | ||
36 | MODULE_VERSION(HVCS_ARCH_VERSION); | ||
37 | |||
38 | /* | ||
39 | * Convert arch specific return codes into relevant errnos. The hvcs | ||
40 | * functions aren't performance sensitive, so this conversion isn't an | ||
41 | * issue. | ||
42 | */ | ||
43 | int hvcs_convert(long to_convert) | ||
44 | { | ||
45 | switch (to_convert) { | ||
46 | case H_Success: | ||
47 | return 0; | ||
48 | case H_Parameter: | ||
49 | return -EINVAL; | ||
50 | case H_Hardware: | ||
51 | return -EIO; | ||
52 | case H_Busy: | ||
53 | case H_LongBusyOrder1msec: | ||
54 | case H_LongBusyOrder10msec: | ||
55 | case H_LongBusyOrder100msec: | ||
56 | case H_LongBusyOrder1sec: | ||
57 | case H_LongBusyOrder10sec: | ||
58 | case H_LongBusyOrder100sec: | ||
59 | return -EBUSY; | ||
60 | case H_Function: /* fall through */ | ||
61 | default: | ||
62 | return -EPERM; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * hvcs_free_partner_info - free pi allocated by hvcs_get_partner_info | ||
68 | * @head: list_head pointer for an allocated list of partner info structs to | ||
69 | * free. | ||
70 | * | ||
71 | * This function is used to free the partner info list that was returned by | ||
72 | * calling hvcs_get_partner_info(). | ||
73 | */ | ||
74 | int hvcs_free_partner_info(struct list_head *head) | ||
75 | { | ||
76 | struct hvcs_partner_info *pi; | ||
77 | struct list_head *element; | ||
78 | |||
79 | if (!head) | ||
80 | return -EINVAL; | ||
81 | |||
82 | while (!list_empty(head)) { | ||
83 | element = head->next; | ||
84 | pi = list_entry(element, struct hvcs_partner_info, node); | ||
85 | list_del(element); | ||
86 | kfree(pi); | ||
87 | } | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | EXPORT_SYMBOL(hvcs_free_partner_info); | ||
92 | |||
93 | /* Helper function for hvcs_get_partner_info */ | ||
94 | int hvcs_next_partner(uint32_t unit_address, | ||
95 | unsigned long last_p_partition_ID, | ||
96 | unsigned long last_p_unit_address, unsigned long *pi_buff) | ||
97 | |||
98 | { | ||
99 | long retval; | ||
100 | retval = plpar_hcall_norets(H_VTERM_PARTNER_INFO, unit_address, | ||
101 | last_p_partition_ID, | ||
102 | last_p_unit_address, virt_to_phys(pi_buff)); | ||
103 | return hvcs_convert(retval); | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * hvcs_get_partner_info - Get all of the partner info for a vty-server adapter | ||
108 | * @unit_address: The unit_address of the vty-server adapter for which this | ||
109 | * function is fetching partner info. | ||
110 | * @head: An initialized list_head pointer to an empty list to use to return the | ||
111 | * list of partner info fetched from the hypervisor to the caller. | ||
112 | * @pi_buff: A page sized buffer pre-allocated prior to calling this function | ||
113 | * that is to be used to be used by firmware as an iterator to keep track | ||
114 | * of the partner info retrieval. | ||
115 | * | ||
116 | * This function returns non-zero on success, or if there is no partner info. | ||
117 | * | ||
118 | * The pi_buff is pre-allocated prior to calling this function because this | ||
119 | * function may be called with a spin_lock held and kmalloc of a page is not | ||
120 | * recommended as GFP_ATOMIC. | ||
121 | * | ||
122 | * The first long of this buffer is used to store a partner unit address. The | ||
123 | * second long is used to store a partner partition ID and starting at | ||
124 | * pi_buff[2] is the 79 character Converged Location Code (diff size than the | ||
125 | * unsigned longs, hence the casting mumbo jumbo you see later). | ||
126 | * | ||
127 | * Invocation of this function should always be followed by an invocation of | ||
128 | * hvcs_free_partner_info() using a pointer to the SAME list head instance | ||
129 | * that was passed as a parameter to this function. | ||
130 | */ | ||
131 | int hvcs_get_partner_info(uint32_t unit_address, struct list_head *head, | ||
132 | unsigned long *pi_buff) | ||
133 | { | ||
134 | /* | ||
135 | * Dealt with as longs because of the hcall interface even though the | ||
136 | * values are uint32_t. | ||
137 | */ | ||
138 | unsigned long last_p_partition_ID; | ||
139 | unsigned long last_p_unit_address; | ||
140 | struct hvcs_partner_info *next_partner_info = NULL; | ||
141 | int more = 1; | ||
142 | int retval; | ||
143 | |||
144 | memset(pi_buff, 0x00, PAGE_SIZE); | ||
145 | /* invalid parameters */ | ||
146 | if (!head || !pi_buff) | ||
147 | return -EINVAL; | ||
148 | |||
149 | last_p_partition_ID = last_p_unit_address = ~0UL; | ||
150 | INIT_LIST_HEAD(head); | ||
151 | |||
152 | do { | ||
153 | retval = hvcs_next_partner(unit_address, last_p_partition_ID, | ||
154 | last_p_unit_address, pi_buff); | ||
155 | if (retval) { | ||
156 | /* | ||
157 | * Don't indicate that we've failed if we have | ||
158 | * any list elements. | ||
159 | */ | ||
160 | if (!list_empty(head)) | ||
161 | return 0; | ||
162 | return retval; | ||
163 | } | ||
164 | |||
165 | last_p_partition_ID = pi_buff[0]; | ||
166 | last_p_unit_address = pi_buff[1]; | ||
167 | |||
168 | /* This indicates that there are no further partners */ | ||
169 | if (last_p_partition_ID == ~0UL | ||
170 | && last_p_unit_address == ~0UL) | ||
171 | break; | ||
172 | |||
173 | /* This is a very small struct and will be freed soon in | ||
174 | * hvcs_free_partner_info(). */ | ||
175 | next_partner_info = kmalloc(sizeof(struct hvcs_partner_info), | ||
176 | GFP_ATOMIC); | ||
177 | |||
178 | if (!next_partner_info) { | ||
179 | printk(KERN_WARNING "HVCONSOLE: kmalloc() failed to" | ||
180 | " allocate partner info struct.\n"); | ||
181 | hvcs_free_partner_info(head); | ||
182 | return -ENOMEM; | ||
183 | } | ||
184 | |||
185 | next_partner_info->unit_address | ||
186 | = (unsigned int)last_p_unit_address; | ||
187 | next_partner_info->partition_ID | ||
188 | = (unsigned int)last_p_partition_ID; | ||
189 | |||
190 | /* copy the Null-term char too */ | ||
191 | strncpy(&next_partner_info->location_code[0], | ||
192 | (char *)&pi_buff[2], | ||
193 | strlen((char *)&pi_buff[2]) + 1); | ||
194 | |||
195 | list_add_tail(&(next_partner_info->node), head); | ||
196 | next_partner_info = NULL; | ||
197 | |||
198 | } while (more); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | EXPORT_SYMBOL(hvcs_get_partner_info); | ||
203 | |||
204 | /** | ||
205 | * hvcs_register_connection - establish a connection between this vty-server and | ||
206 | * a vty. | ||
207 | * @unit_address: The unit address of the vty-server adapter that is to be | ||
208 | * establish a connection. | ||
209 | * @p_partition_ID: The partition ID of the vty adapter that is to be connected. | ||
210 | * @p_unit_address: The unit address of the vty adapter to which the vty-server | ||
211 | * is to be connected. | ||
212 | * | ||
213 | * If this function is called once and -EINVAL is returned it may | ||
214 | * indicate that the partner info needs to be refreshed for the | ||
215 | * target unit address at which point the caller must invoke | ||
216 | * hvcs_get_partner_info() and then call this function again. If, | ||
217 | * for a second time, -EINVAL is returned then it indicates that | ||
218 | * there is probably already a partner connection registered to a | ||
219 | * different vty-server adapter. It is also possible that a second | ||
220 | * -EINVAL may indicate that one of the parms is not valid, for | ||
221 | * instance if the link was removed between the vty-server adapter | ||
222 | * and the vty adapter that you are trying to open. Don't shoot the | ||
223 | * messenger. Firmware implemented it this way. | ||
224 | */ | ||
225 | int hvcs_register_connection( uint32_t unit_address, | ||
226 | uint32_t p_partition_ID, uint32_t p_unit_address) | ||
227 | { | ||
228 | long retval; | ||
229 | retval = plpar_hcall_norets(H_REGISTER_VTERM, unit_address, | ||
230 | p_partition_ID, p_unit_address); | ||
231 | return hvcs_convert(retval); | ||
232 | } | ||
233 | EXPORT_SYMBOL(hvcs_register_connection); | ||
234 | |||
235 | /** | ||
236 | * hvcs_free_connection - free the connection between a vty-server and vty | ||
237 | * @unit_address: The unit address of the vty-server that is to have its | ||
238 | * connection severed. | ||
239 | * | ||
240 | * This function is used to free the partner connection between a vty-server | ||
241 | * adapter and a vty adapter. | ||
242 | * | ||
243 | * If -EBUSY is returned continue to call this function until 0 is returned. | ||
244 | */ | ||
245 | int hvcs_free_connection(uint32_t unit_address) | ||
246 | { | ||
247 | long retval; | ||
248 | retval = plpar_hcall_norets(H_FREE_VTERM, unit_address); | ||
249 | return hvcs_convert(retval); | ||
250 | } | ||
251 | EXPORT_SYMBOL(hvcs_free_connection); | ||
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 31990829310c..4a465f067ede 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -200,14 +200,12 @@ static void __init pSeries_setup_arch(void) | |||
200 | if (ppc64_interrupt_controller == IC_OPEN_PIC) { | 200 | if (ppc64_interrupt_controller == IC_OPEN_PIC) { |
201 | ppc_md.init_IRQ = pSeries_init_mpic; | 201 | ppc_md.init_IRQ = pSeries_init_mpic; |
202 | ppc_md.get_irq = mpic_get_irq; | 202 | ppc_md.get_irq = mpic_get_irq; |
203 | ppc_md.cpu_irq_down = mpic_teardown_this_cpu; | ||
204 | /* Allocate the mpic now, so that find_and_init_phbs() can | 203 | /* Allocate the mpic now, so that find_and_init_phbs() can |
205 | * fill the ISUs */ | 204 | * fill the ISUs */ |
206 | pSeries_setup_mpic(); | 205 | pSeries_setup_mpic(); |
207 | } else { | 206 | } else { |
208 | ppc_md.init_IRQ = xics_init_IRQ; | 207 | ppc_md.init_IRQ = xics_init_IRQ; |
209 | ppc_md.get_irq = xics_get_irq; | 208 | ppc_md.get_irq = xics_get_irq; |
210 | ppc_md.cpu_irq_down = xics_teardown_cpu; | ||
211 | } | 209 | } |
212 | 210 | ||
213 | #ifdef CONFIG_SMP | 211 | #ifdef CONFIG_SMP |
@@ -506,7 +504,7 @@ static void pseries_dedicated_idle(void) | |||
506 | lpaca->lppaca.idle = 1; | 504 | lpaca->lppaca.idle = 1; |
507 | 505 | ||
508 | if (!need_resched()) { | 506 | if (!need_resched()) { |
509 | start_snooze = __get_tb() + | 507 | start_snooze = get_tb() + |
510 | *smt_snooze_delay * tb_ticks_per_usec; | 508 | *smt_snooze_delay * tb_ticks_per_usec; |
511 | 509 | ||
512 | while (!need_resched() && !cpu_is_offline(cpu)) { | 510 | while (!need_resched() && !cpu_is_offline(cpu)) { |
@@ -520,7 +518,7 @@ static void pseries_dedicated_idle(void) | |||
520 | HMT_very_low(); | 518 | HMT_very_low(); |
521 | 519 | ||
522 | if (*smt_snooze_delay != 0 && | 520 | if (*smt_snooze_delay != 0 && |
523 | __get_tb() > start_snooze) { | 521 | get_tb() > start_snooze) { |
524 | HMT_medium(); | 522 | HMT_medium(); |
525 | dedicated_idle_sleep(cpu); | 523 | dedicated_idle_sleep(cpu); |
526 | } | 524 | } |
@@ -595,6 +593,27 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus) | |||
595 | return PCI_PROBE_NORMAL; | 593 | return PCI_PROBE_NORMAL; |
596 | } | 594 | } |
597 | 595 | ||
596 | #ifdef CONFIG_KEXEC | ||
597 | static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) | ||
598 | { | ||
599 | /* Don't risk a hypervisor call if we're crashing */ | ||
600 | if (!crash_shutdown) { | ||
601 | unsigned long vpa = __pa(&get_paca()->lppaca); | ||
602 | |||
603 | if (unregister_vpa(hard_smp_processor_id(), vpa)) { | ||
604 | printk("VPA deregistration of cpu %u (hw_cpu_id %d) " | ||
605 | "failed\n", smp_processor_id(), | ||
606 | hard_smp_processor_id()); | ||
607 | } | ||
608 | } | ||
609 | |||
610 | if (ppc64_interrupt_controller == IC_OPEN_PIC) | ||
611 | mpic_teardown_this_cpu(secondary); | ||
612 | else | ||
613 | xics_teardown_cpu(secondary); | ||
614 | } | ||
615 | #endif | ||
616 | |||
598 | struct machdep_calls __initdata pSeries_md = { | 617 | struct machdep_calls __initdata pSeries_md = { |
599 | .probe = pSeries_probe, | 618 | .probe = pSeries_probe, |
600 | .setup_arch = pSeries_setup_arch, | 619 | .setup_arch = pSeries_setup_arch, |
@@ -617,4 +636,7 @@ struct machdep_calls __initdata pSeries_md = { | |||
617 | .check_legacy_ioport = pSeries_check_legacy_ioport, | 636 | .check_legacy_ioport = pSeries_check_legacy_ioport, |
618 | .system_reset_exception = pSeries_system_reset_exception, | 637 | .system_reset_exception = pSeries_system_reset_exception, |
619 | .machine_check_exception = pSeries_machine_check_exception, | 638 | .machine_check_exception = pSeries_machine_check_exception, |
639 | #ifdef CONFIG_KEXEC | ||
640 | .kexec_cpu_down = pseries_kexec_cpu_down, | ||
641 | #endif | ||
620 | }; | 642 | }; |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 5800cde7d5ad..25181c594d73 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include "plpar_wrappers.h" | 51 | #include "plpar_wrappers.h" |
52 | 52 | ||
53 | #ifdef DEBUG | 53 | #ifdef DEBUG |
54 | #include <asm/udbg.h> | ||
54 | #define DBG(fmt...) udbg_printf(fmt) | 55 | #define DBG(fmt...) udbg_printf(fmt) |
55 | #else | 56 | #else |
56 | #define DBG(fmt...) | 57 | #define DBG(fmt...) |
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index ef4356b29a97..c45a6ad5f3b7 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/cpumask.h> | 19 | #include <linux/cpumask.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/sysrq.h> | 21 | #include <linux/sysrq.h> |
22 | #include <linux/interrupt.h> | ||
22 | 23 | ||
23 | #include <asm/ptrace.h> | 24 | #include <asm/ptrace.h> |
24 | #include <asm/string.h> | 25 | #include <asm/string.h> |