diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/Makefile | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/cpu_setup_power4.S | 233 | ||||
-rw-r--r-- | arch/powerpc/kernel/firmware.c | 45 | ||||
-rw-r--r-- | arch/powerpc/kernel/ioctl32.c | 49 | ||||
-rw-r--r-- | arch/powerpc/kernel/paca.c | 143 | ||||
-rw-r--r-- | arch/powerpc/kernel/ppc_ksyms.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom.c | 9 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 170 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/vio.c | 27 |
11 files changed, 638 insertions, 50 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index cbdc14261655..92cfabf929bc 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | ifeq ($(CONFIG_PPC64),y) | 5 | ifeq ($(CONFIG_PPC64),y) |
6 | EXTRA_CFLAGS += -mno-minimal-toc | 6 | EXTRA_CFLAGS += -mno-minimal-toc |
7 | CFLAGS_ioctl32.o += -Ifs/ | ||
7 | endif | 8 | endif |
8 | ifeq ($(CONFIG_PPC32),y) | 9 | ifeq ($(CONFIG_PPC32),y) |
9 | CFLAGS_prom_init.o += -fPIC | 10 | CFLAGS_prom_init.o += -fPIC |
@@ -13,7 +14,9 @@ endif | |||
13 | obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ | 14 | obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ |
14 | irq.o signal_32.o pmc.o | 15 | irq.o signal_32.o pmc.o |
15 | obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ | 16 | obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ |
16 | signal_64.o ptrace32.o systbl.o | 17 | signal_64.o ptrace32.o systbl.o \ |
18 | paca.o ioctl32.o cpu_setup_power4.o \ | ||
19 | firmware.o | ||
17 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 20 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
18 | obj-$(CONFIG_POWER4) += idle_power4.o | 21 | obj-$(CONFIG_POWER4) += idle_power4.o |
19 | obj-$(CONFIG_PPC_OF) += of_device.o | 22 | obj-$(CONFIG_PPC_OF) += of_device.o |
diff --git a/arch/powerpc/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_power4.S new file mode 100644 index 000000000000..cca942fe6115 --- /dev/null +++ b/arch/powerpc/kernel/cpu_setup_power4.S | |||
@@ -0,0 +1,233 @@ | |||
1 | /* | ||
2 | * This file contains low level CPU setup functions. | ||
3 | * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org) | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <asm/processor.h> | ||
14 | #include <asm/page.h> | ||
15 | #include <asm/cputable.h> | ||
16 | #include <asm/ppc_asm.h> | ||
17 | #include <asm/asm-offsets.h> | ||
18 | #include <asm/cache.h> | ||
19 | |||
20 | _GLOBAL(__970_cpu_preinit) | ||
21 | /* | ||
22 | * Do nothing if not running in HV mode | ||
23 | */ | ||
24 | mfmsr r0 | ||
25 | rldicl. r0,r0,4,63 | ||
26 | beqlr | ||
27 | |||
28 | /* | ||
29 | * Deal only with PPC970 and PPC970FX. | ||
30 | */ | ||
31 | mfspr r0,SPRN_PVR | ||
32 | srwi r0,r0,16 | ||
33 | cmpwi r0,0x39 | ||
34 | beq 1f | ||
35 | cmpwi r0,0x3c | ||
36 | beq 1f | ||
37 | cmpwi r0,0x44 | ||
38 | bnelr | ||
39 | 1: | ||
40 | |||
41 | /* Make sure HID4:rm_ci is off before MMU is turned off, that large | ||
42 | * pages are enabled with HID4:61 and clear HID5:DCBZ_size and | ||
43 | * HID5:DCBZ32_ill | ||
44 | */ | ||
45 | li r0,0 | ||
46 | mfspr r3,SPRN_HID4 | ||
47 | rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ | ||
48 | rldimi r3,r0,2,61 /* clear bit 61 (lg_pg_en) */ | ||
49 | sync | ||
50 | mtspr SPRN_HID4,r3 | ||
51 | isync | ||
52 | sync | ||
53 | mfspr r3,SPRN_HID5 | ||
54 | rldimi r3,r0,6,56 /* clear bits 56 & 57 (DCBZ*) */ | ||
55 | sync | ||
56 | mtspr SPRN_HID5,r3 | ||
57 | isync | ||
58 | sync | ||
59 | |||
60 | /* Setup some basic HID1 features */ | ||
61 | mfspr r0,SPRN_HID1 | ||
62 | li r3,0x1200 /* enable i-fetch cacheability */ | ||
63 | sldi r3,r3,44 /* and prefetch */ | ||
64 | or r0,r0,r3 | ||
65 | mtspr SPRN_HID1,r0 | ||
66 | mtspr SPRN_HID1,r0 | ||
67 | isync | ||
68 | |||
69 | /* Clear HIOR */ | ||
70 | li r0,0 | ||
71 | sync | ||
72 | mtspr SPRN_HIOR,0 /* Clear interrupt prefix */ | ||
73 | isync | ||
74 | blr | ||
75 | |||
76 | _GLOBAL(__setup_cpu_power4) | ||
77 | blr | ||
78 | |||
79 | _GLOBAL(__setup_cpu_be) | ||
80 | /* Set large page sizes LP=0: 16MB, LP=1: 64KB */ | ||
81 | addi r3, 0, 0 | ||
82 | ori r3, r3, HID6_LB | ||
83 | sldi r3, r3, 32 | ||
84 | nor r3, r3, r3 | ||
85 | mfspr r4, SPRN_HID6 | ||
86 | and r4, r4, r3 | ||
87 | addi r3, 0, 0x02000 | ||
88 | sldi r3, r3, 32 | ||
89 | or r4, r4, r3 | ||
90 | mtspr SPRN_HID6, r4 | ||
91 | blr | ||
92 | |||
93 | _GLOBAL(__setup_cpu_ppc970) | ||
94 | mfspr r0,SPRN_HID0 | ||
95 | li r11,5 /* clear DOZE and SLEEP */ | ||
96 | rldimi r0,r11,52,8 /* set NAP and DPM */ | ||
97 | mtspr SPRN_HID0,r0 | ||
98 | mfspr r0,SPRN_HID0 | ||
99 | mfspr r0,SPRN_HID0 | ||
100 | mfspr r0,SPRN_HID0 | ||
101 | mfspr r0,SPRN_HID0 | ||
102 | mfspr r0,SPRN_HID0 | ||
103 | mfspr r0,SPRN_HID0 | ||
104 | sync | ||
105 | isync | ||
106 | blr | ||
107 | |||
108 | /* Definitions for the table use to save CPU states */ | ||
109 | #define CS_HID0 0 | ||
110 | #define CS_HID1 8 | ||
111 | #define CS_HID4 16 | ||
112 | #define CS_HID5 24 | ||
113 | #define CS_SIZE 32 | ||
114 | |||
115 | .data | ||
116 | .balign L1_CACHE_BYTES,0 | ||
117 | cpu_state_storage: | ||
118 | .space CS_SIZE | ||
119 | .balign L1_CACHE_BYTES,0 | ||
120 | .text | ||
121 | |||
122 | /* Called in normal context to backup CPU 0 state. This | ||
123 | * does not include cache settings. This function is also | ||
124 | * called for machine sleep. This does not include the MMU | ||
125 | * setup, BATs, etc... but rather the "special" registers | ||
126 | * like HID0, HID1, HID4, etc... | ||
127 | */ | ||
128 | _GLOBAL(__save_cpu_setup) | ||
129 | /* Some CR fields are volatile, we back it up all */ | ||
130 | mfcr r7 | ||
131 | |||
132 | /* Get storage ptr */ | ||
133 | LOADADDR(r5,cpu_state_storage) | ||
134 | |||
135 | /* We only deal with 970 for now */ | ||
136 | mfspr r0,SPRN_PVR | ||
137 | srwi r0,r0,16 | ||
138 | cmpwi r0,0x39 | ||
139 | beq 1f | ||
140 | cmpwi r0,0x3c | ||
141 | beq 1f | ||
142 | cmpwi r0,0x44 | ||
143 | bne 2f | ||
144 | |||
145 | 1: /* Save HID0,1,4 and 5 */ | ||
146 | mfspr r3,SPRN_HID0 | ||
147 | std r3,CS_HID0(r5) | ||
148 | mfspr r3,SPRN_HID1 | ||
149 | std r3,CS_HID1(r5) | ||
150 | mfspr r3,SPRN_HID4 | ||
151 | std r3,CS_HID4(r5) | ||
152 | mfspr r3,SPRN_HID5 | ||
153 | std r3,CS_HID5(r5) | ||
154 | |||
155 | 2: | ||
156 | mtcr r7 | ||
157 | blr | ||
158 | |||
159 | /* Called with no MMU context (typically MSR:IR/DR off) to | ||
160 | * restore CPU state as backed up by the previous | ||
161 | * function. This does not include cache setting | ||
162 | */ | ||
163 | _GLOBAL(__restore_cpu_setup) | ||
164 | /* Get storage ptr (FIXME when using anton reloc as we | ||
165 | * are running with translation disabled here | ||
166 | */ | ||
167 | LOADADDR(r5,cpu_state_storage) | ||
168 | |||
169 | /* We only deal with 970 for now */ | ||
170 | mfspr r0,SPRN_PVR | ||
171 | srwi r0,r0,16 | ||
172 | cmpwi r0,0x39 | ||
173 | beq 1f | ||
174 | cmpwi r0,0x3c | ||
175 | beq 1f | ||
176 | cmpwi r0,0x44 | ||
177 | bnelr | ||
178 | |||
179 | 1: /* Before accessing memory, we make sure rm_ci is clear */ | ||
180 | li r0,0 | ||
181 | mfspr r3,SPRN_HID4 | ||
182 | rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ | ||
183 | sync | ||
184 | mtspr SPRN_HID4,r3 | ||
185 | isync | ||
186 | sync | ||
187 | |||
188 | /* Clear interrupt prefix */ | ||
189 | li r0,0 | ||
190 | sync | ||
191 | mtspr SPRN_HIOR,0 | ||
192 | isync | ||
193 | |||
194 | /* Restore HID0 */ | ||
195 | ld r3,CS_HID0(r5) | ||
196 | sync | ||
197 | isync | ||
198 | mtspr SPRN_HID0,r3 | ||
199 | mfspr r3,SPRN_HID0 | ||
200 | mfspr r3,SPRN_HID0 | ||
201 | mfspr r3,SPRN_HID0 | ||
202 | mfspr r3,SPRN_HID0 | ||
203 | mfspr r3,SPRN_HID0 | ||
204 | mfspr r3,SPRN_HID0 | ||
205 | sync | ||
206 | isync | ||
207 | |||
208 | /* Restore HID1 */ | ||
209 | ld r3,CS_HID1(r5) | ||
210 | sync | ||
211 | isync | ||
212 | mtspr SPRN_HID1,r3 | ||
213 | mtspr SPRN_HID1,r3 | ||
214 | sync | ||
215 | isync | ||
216 | |||
217 | /* Restore HID4 */ | ||
218 | ld r3,CS_HID4(r5) | ||
219 | sync | ||
220 | isync | ||
221 | mtspr SPRN_HID4,r3 | ||
222 | sync | ||
223 | isync | ||
224 | |||
225 | /* Restore HID5 */ | ||
226 | ld r3,CS_HID5(r5) | ||
227 | sync | ||
228 | isync | ||
229 | mtspr SPRN_HID5,r3 | ||
230 | sync | ||
231 | isync | ||
232 | blr | ||
233 | |||
diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c new file mode 100644 index 000000000000..65eae752a527 --- /dev/null +++ b/arch/powerpc/kernel/firmware.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Extracted from cputable.c | ||
3 | * | ||
4 | * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) | ||
5 | * | ||
6 | * Modifications for ppc64: | ||
7 | * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com> | ||
8 | * Copyright (C) 2005 Stephen Rothwell, IBM Corporation | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version | ||
13 | * 2 of the License, or (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/config.h> | ||
17 | |||
18 | #include <asm/firmware.h> | ||
19 | |||
20 | unsigned long ppc64_firmware_features; | ||
21 | |||
22 | #ifdef CONFIG_PPC_PSERIES | ||
23 | firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = { | ||
24 | {FW_FEATURE_PFT, "hcall-pft"}, | ||
25 | {FW_FEATURE_TCE, "hcall-tce"}, | ||
26 | {FW_FEATURE_SPRG0, "hcall-sprg0"}, | ||
27 | {FW_FEATURE_DABR, "hcall-dabr"}, | ||
28 | {FW_FEATURE_COPY, "hcall-copy"}, | ||
29 | {FW_FEATURE_ASR, "hcall-asr"}, | ||
30 | {FW_FEATURE_DEBUG, "hcall-debug"}, | ||
31 | {FW_FEATURE_PERF, "hcall-perf"}, | ||
32 | {FW_FEATURE_DUMP, "hcall-dump"}, | ||
33 | {FW_FEATURE_INTERRUPT, "hcall-interrupt"}, | ||
34 | {FW_FEATURE_MIGRATE, "hcall-migrate"}, | ||
35 | {FW_FEATURE_PERFMON, "hcall-perfmon"}, | ||
36 | {FW_FEATURE_CRQ, "hcall-crq"}, | ||
37 | {FW_FEATURE_VIO, "hcall-vio"}, | ||
38 | {FW_FEATURE_RDMA, "hcall-rdma"}, | ||
39 | {FW_FEATURE_LLAN, "hcall-lLAN"}, | ||
40 | {FW_FEATURE_BULK, "hcall-bulk"}, | ||
41 | {FW_FEATURE_XDABR, "hcall-xdabr"}, | ||
42 | {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, | ||
43 | {FW_FEATURE_SPLPAR, "hcall-splpar"}, | ||
44 | }; | ||
45 | #endif | ||
diff --git a/arch/powerpc/kernel/ioctl32.c b/arch/powerpc/kernel/ioctl32.c new file mode 100644 index 000000000000..3fa6a93adbd0 --- /dev/null +++ b/arch/powerpc/kernel/ioctl32.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * ioctl32.c: Conversion between 32bit and 64bit native ioctls. | ||
3 | * | ||
4 | * Based on sparc64 ioctl32.c by: | ||
5 | * | ||
6 | * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) | ||
7 | * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) | ||
8 | * | ||
9 | * ppc64 changes: | ||
10 | * | ||
11 | * Copyright (C) 2000 Ken Aaker (kdaaker@rchland.vnet.ibm.com) | ||
12 | * Copyright (C) 2001 Anton Blanchard (antonb@au.ibm.com) | ||
13 | * | ||
14 | * These routines maintain argument size conversion between 32bit and 64bit | ||
15 | * ioctls. | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or | ||
18 | * modify it under the terms of the GNU General Public License | ||
19 | * as published by the Free Software Foundation; either version | ||
20 | * 2 of the License, or (at your option) any later version. | ||
21 | */ | ||
22 | |||
23 | #define INCLUDES | ||
24 | #include "compat_ioctl.c" | ||
25 | #include <linux/syscalls.h> | ||
26 | |||
27 | #define CODE | ||
28 | #include "compat_ioctl.c" | ||
29 | |||
30 | #define HANDLE_IOCTL(cmd,handler) { cmd, (ioctl_trans_handler_t)handler, NULL }, | ||
31 | #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl) | ||
32 | |||
33 | #define IOCTL_TABLE_START \ | ||
34 | struct ioctl_trans ioctl_start[] = { | ||
35 | #define IOCTL_TABLE_END \ | ||
36 | }; | ||
37 | |||
38 | IOCTL_TABLE_START | ||
39 | #include <linux/compat_ioctl.h> | ||
40 | #define DECLARES | ||
41 | #include "compat_ioctl.c" | ||
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 | ||
48 | |||
49 | int ioctl_table_size = ARRAY_SIZE(ioctl_start); | ||
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c new file mode 100644 index 000000000000..179948eb0580 --- /dev/null +++ b/arch/powerpc/kernel/paca.c | |||
@@ -0,0 +1,143 @@ | |||
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 | |||
10 | #include <linux/config.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/threads.h> | ||
13 | #include <linux/module.h> | ||
14 | |||
15 | #include <asm/processor.h> | ||
16 | #include <asm/ptrace.h> | ||
17 | #include <asm/page.h> | ||
18 | |||
19 | #include <asm/lppaca.h> | ||
20 | #include <asm/iseries/it_lp_queue.h> | ||
21 | #include <asm/paca.h> | ||
22 | |||
23 | static union { | ||
24 | struct systemcfg data; | ||
25 | u8 page[PAGE_SIZE]; | ||
26 | } systemcfg_store __attribute__((__section__(".data.page.aligned"))); | ||
27 | struct systemcfg *systemcfg = &systemcfg_store.data; | ||
28 | EXPORT_SYMBOL(systemcfg); | ||
29 | |||
30 | |||
31 | /* This symbol is provided by the linker - let it fill in the paca | ||
32 | * field correctly */ | ||
33 | extern unsigned long __toc_start; | ||
34 | |||
35 | /* The Paca is an array with one entry per processor. Each contains an | ||
36 | * lppaca, which contains the information shared between the | ||
37 | * hypervisor and Linux. Each also contains an ItLpRegSave area which | ||
38 | * is used by the hypervisor to save registers. | ||
39 | * On systems with hardware multi-threading, there are two threads | ||
40 | * per processor. The Paca array must contain an entry for each thread. | ||
41 | * The VPD Areas will give a max logical processors = 2 * max physical | ||
42 | * processors. The processor VPD array needs one entry per physical | ||
43 | * processor (not thread). | ||
44 | */ | ||
45 | #define PACA_INIT_COMMON(number, start, asrr, asrv) \ | ||
46 | .lock_token = 0x8000, \ | ||
47 | .paca_index = (number), /* Paca Index */ \ | ||
48 | .default_decr = 0x00ff0000, /* Initial Decr */ \ | ||
49 | .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ | ||
50 | .stab_real = (asrr), /* Real pointer to segment table */ \ | ||
51 | .stab_addr = (asrv), /* Virt pointer to segment table */ \ | ||
52 | .cpu_start = (start), /* Processor start */ \ | ||
53 | .hw_cpu_id = 0xffff, \ | ||
54 | .lppaca = { \ | ||
55 | .desc = 0xd397d781, /* "LpPa" */ \ | ||
56 | .size = sizeof(struct lppaca), \ | ||
57 | .dyn_proc_status = 2, \ | ||
58 | .decr_val = 0x00ff0000, \ | ||
59 | .fpregs_in_use = 1, \ | ||
60 | .end_of_quantum = 0xfffffffffffffffful, \ | ||
61 | .slb_count = 64, \ | ||
62 | .vmxregs_in_use = 0, \ | ||
63 | }, \ | ||
64 | |||
65 | #ifdef CONFIG_PPC_ISERIES | ||
66 | #define PACA_INIT_ISERIES(number) \ | ||
67 | .lppaca_ptr = &paca[number].lppaca, \ | ||
68 | .reg_save_ptr = &paca[number].reg_save, \ | ||
69 | .reg_save = { \ | ||
70 | .xDesc = 0xd397d9e2, /* "LpRS" */ \ | ||
71 | .xSize = sizeof(struct ItLpRegSave) \ | ||
72 | } | ||
73 | |||
74 | #define PACA_INIT(number) \ | ||
75 | { \ | ||
76 | PACA_INIT_COMMON(number, 0, 0, 0) \ | ||
77 | PACA_INIT_ISERIES(number) \ | ||
78 | } | ||
79 | |||
80 | #define BOOTCPU_PACA_INIT(number) \ | ||
81 | { \ | ||
82 | PACA_INIT_COMMON(number, 1, 0, (u64)&initial_stab) \ | ||
83 | PACA_INIT_ISERIES(number) \ | ||
84 | } | ||
85 | |||
86 | #else | ||
87 | #define PACA_INIT(number) \ | ||
88 | { \ | ||
89 | PACA_INIT_COMMON(number, 0, 0, 0) \ | ||
90 | } | ||
91 | |||
92 | #define BOOTCPU_PACA_INIT(number) \ | ||
93 | { \ | ||
94 | PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, (u64)&initial_stab) \ | ||
95 | } | ||
96 | #endif | ||
97 | |||
98 | struct paca_struct paca[] = { | ||
99 | BOOTCPU_PACA_INIT(0), | ||
100 | #if NR_CPUS > 1 | ||
101 | PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3), | ||
102 | #if NR_CPUS > 4 | ||
103 | PACA_INIT( 4), PACA_INIT( 5), PACA_INIT( 6), PACA_INIT( 7), | ||
104 | #if NR_CPUS > 8 | ||
105 | PACA_INIT( 8), PACA_INIT( 9), PACA_INIT( 10), PACA_INIT( 11), | ||
106 | PACA_INIT( 12), PACA_INIT( 13), PACA_INIT( 14), PACA_INIT( 15), | ||
107 | PACA_INIT( 16), PACA_INIT( 17), PACA_INIT( 18), PACA_INIT( 19), | ||
108 | PACA_INIT( 20), PACA_INIT( 21), PACA_INIT( 22), PACA_INIT( 23), | ||
109 | PACA_INIT( 24), PACA_INIT( 25), PACA_INIT( 26), PACA_INIT( 27), | ||
110 | PACA_INIT( 28), PACA_INIT( 29), PACA_INIT( 30), PACA_INIT( 31), | ||
111 | #if NR_CPUS > 32 | ||
112 | PACA_INIT( 32), PACA_INIT( 33), PACA_INIT( 34), PACA_INIT( 35), | ||
113 | PACA_INIT( 36), PACA_INIT( 37), PACA_INIT( 38), PACA_INIT( 39), | ||
114 | PACA_INIT( 40), PACA_INIT( 41), PACA_INIT( 42), PACA_INIT( 43), | ||
115 | PACA_INIT( 44), PACA_INIT( 45), PACA_INIT( 46), PACA_INIT( 47), | ||
116 | PACA_INIT( 48), PACA_INIT( 49), PACA_INIT( 50), PACA_INIT( 51), | ||
117 | PACA_INIT( 52), PACA_INIT( 53), PACA_INIT( 54), PACA_INIT( 55), | ||
118 | PACA_INIT( 56), PACA_INIT( 57), PACA_INIT( 58), PACA_INIT( 59), | ||
119 | PACA_INIT( 60), PACA_INIT( 61), PACA_INIT( 62), PACA_INIT( 63), | ||
120 | #if NR_CPUS > 64 | ||
121 | PACA_INIT( 64), PACA_INIT( 65), PACA_INIT( 66), PACA_INIT( 67), | ||
122 | PACA_INIT( 68), PACA_INIT( 69), PACA_INIT( 70), PACA_INIT( 71), | ||
123 | PACA_INIT( 72), PACA_INIT( 73), PACA_INIT( 74), PACA_INIT( 75), | ||
124 | PACA_INIT( 76), PACA_INIT( 77), PACA_INIT( 78), PACA_INIT( 79), | ||
125 | PACA_INIT( 80), PACA_INIT( 81), PACA_INIT( 82), PACA_INIT( 83), | ||
126 | PACA_INIT( 84), PACA_INIT( 85), PACA_INIT( 86), PACA_INIT( 87), | ||
127 | PACA_INIT( 88), PACA_INIT( 89), PACA_INIT( 90), PACA_INIT( 91), | ||
128 | PACA_INIT( 92), PACA_INIT( 93), PACA_INIT( 94), PACA_INIT( 95), | ||
129 | PACA_INIT( 96), PACA_INIT( 97), PACA_INIT( 98), PACA_INIT( 99), | ||
130 | PACA_INIT(100), PACA_INIT(101), PACA_INIT(102), PACA_INIT(103), | ||
131 | PACA_INIT(104), PACA_INIT(105), PACA_INIT(106), PACA_INIT(107), | ||
132 | PACA_INIT(108), PACA_INIT(109), PACA_INIT(110), PACA_INIT(111), | ||
133 | PACA_INIT(112), PACA_INIT(113), PACA_INIT(114), PACA_INIT(115), | ||
134 | PACA_INIT(116), PACA_INIT(117), PACA_INIT(118), PACA_INIT(119), | ||
135 | PACA_INIT(120), PACA_INIT(121), PACA_INIT(122), PACA_INIT(123), | ||
136 | PACA_INIT(124), PACA_INIT(125), PACA_INIT(126), PACA_INIT(127), | ||
137 | #endif | ||
138 | #endif | ||
139 | #endif | ||
140 | #endif | ||
141 | #endif | ||
142 | }; | ||
143 | EXPORT_SYMBOL(paca); | ||
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 47d6f7e2ea9f..5d9fd0369aad 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <asm/cputable.h> | 44 | #include <asm/cputable.h> |
45 | #include <asm/btext.h> | 45 | #include <asm/btext.h> |
46 | #include <asm/div64.h> | 46 | #include <asm/div64.h> |
47 | #include <asm/signal.h> | ||
47 | 48 | ||
48 | #ifdef CONFIG_8xx | 49 | #ifdef CONFIG_8xx |
49 | #include <asm/commproc.h> | 50 | #include <asm/commproc.h> |
@@ -56,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs); | |||
56 | extern void alignment_exception(struct pt_regs *regs); | 57 | extern void alignment_exception(struct pt_regs *regs); |
57 | extern void program_check_exception(struct pt_regs *regs); | 58 | extern void program_check_exception(struct pt_regs *regs); |
58 | extern void single_step_exception(struct pt_regs *regs); | 59 | extern void single_step_exception(struct pt_regs *regs); |
59 | extern int do_signal(sigset_t *, struct pt_regs *); | ||
60 | extern int pmac_newworld; | 60 | extern int pmac_newworld; |
61 | extern int sys_sigreturn(struct pt_regs *regs); | 61 | extern int sys_sigreturn(struct pt_regs *regs); |
62 | 62 | ||
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index f645adb57534..5af39f866735 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -1264,7 +1264,14 @@ static int __init early_init_dt_scan_memory(unsigned long node, | |||
1264 | unsigned long l; | 1264 | unsigned long l; |
1265 | 1265 | ||
1266 | /* We are scanning "memory" nodes only */ | 1266 | /* We are scanning "memory" nodes only */ |
1267 | if (type == NULL || strcmp(type, "memory") != 0) | 1267 | if (type == NULL) { |
1268 | /* | ||
1269 | * The longtrail doesn't have a device_type on the | ||
1270 | * /memory node, so look for the node called /memory@0. | ||
1271 | */ | ||
1272 | if (depth != 1 || strcmp(uname, "memory@0") != 0) | ||
1273 | return 0; | ||
1274 | } else if (strcmp(type, "memory") != 0) | ||
1268 | return 0; | 1275 | return 0; |
1269 | 1276 | ||
1270 | reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); | 1277 | reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 58f0917bd6b6..09db1bb9ec91 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -94,11 +94,17 @@ extern const struct linux_logo logo_linux_clut224; | |||
94 | #ifdef CONFIG_PPC64 | 94 | #ifdef CONFIG_PPC64 |
95 | #define RELOC(x) (*PTRRELOC(&(x))) | 95 | #define RELOC(x) (*PTRRELOC(&(x))) |
96 | #define ADDR(x) (u32) add_reloc_offset((unsigned long)(x)) | 96 | #define ADDR(x) (u32) add_reloc_offset((unsigned long)(x)) |
97 | #define OF_WORKAROUNDS 0 | ||
97 | #else | 98 | #else |
98 | #define RELOC(x) (x) | 99 | #define RELOC(x) (x) |
99 | #define ADDR(x) (u32) (x) | 100 | #define ADDR(x) (u32) (x) |
101 | #define OF_WORKAROUNDS of_workarounds | ||
102 | int of_workarounds; | ||
100 | #endif | 103 | #endif |
101 | 104 | ||
105 | #define OF_WA_CLAIM 1 /* do phys/virt claim separately, then map */ | ||
106 | #define OF_WA_LONGTRAIL 2 /* work around longtrail bugs */ | ||
107 | |||
102 | #define PROM_BUG() do { \ | 108 | #define PROM_BUG() do { \ |
103 | prom_printf("kernel BUG at %s line 0x%x!\n", \ | 109 | prom_printf("kernel BUG at %s line 0x%x!\n", \ |
104 | RELOC(__FILE__), __LINE__); \ | 110 | RELOC(__FILE__), __LINE__); \ |
@@ -128,10 +134,11 @@ struct prom_args { | |||
128 | 134 | ||
129 | struct prom_t { | 135 | struct prom_t { |
130 | ihandle root; | 136 | ihandle root; |
131 | ihandle chosen; | 137 | phandle chosen; |
132 | int cpu; | 138 | int cpu; |
133 | ihandle stdout; | 139 | ihandle stdout; |
134 | ihandle mmumap; | 140 | ihandle mmumap; |
141 | ihandle memory; | ||
135 | }; | 142 | }; |
136 | 143 | ||
137 | struct mem_map_entry { | 144 | struct mem_map_entry { |
@@ -360,16 +367,36 @@ static void __init prom_printf(const char *format, ...) | |||
360 | static unsigned int __init prom_claim(unsigned long virt, unsigned long size, | 367 | static unsigned int __init prom_claim(unsigned long virt, unsigned long size, |
361 | unsigned long align) | 368 | unsigned long align) |
362 | { | 369 | { |
363 | int ret; | ||
364 | struct prom_t *_prom = &RELOC(prom); | 370 | struct prom_t *_prom = &RELOC(prom); |
365 | 371 | ||
366 | ret = call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size, | 372 | if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) { |
367 | (prom_arg_t)align); | 373 | /* |
368 | if (ret != -1 && _prom->mmumap != 0) | 374 | * Old OF requires we claim physical and virtual separately |
369 | /* old pmacs need us to map as well */ | 375 | * and then map explicitly (assuming virtual mode) |
376 | */ | ||
377 | int ret; | ||
378 | prom_arg_t result; | ||
379 | |||
380 | ret = call_prom_ret("call-method", 5, 2, &result, | ||
381 | ADDR("claim"), _prom->memory, | ||
382 | align, size, virt); | ||
383 | if (ret != 0 || result == -1) | ||
384 | return -1; | ||
385 | ret = call_prom_ret("call-method", 5, 2, &result, | ||
386 | ADDR("claim"), _prom->mmumap, | ||
387 | align, size, virt); | ||
388 | if (ret != 0) { | ||
389 | call_prom("call-method", 4, 1, ADDR("release"), | ||
390 | _prom->memory, size, virt); | ||
391 | return -1; | ||
392 | } | ||
393 | /* the 0x12 is M (coherence) + PP == read/write */ | ||
370 | call_prom("call-method", 6, 1, | 394 | call_prom("call-method", 6, 1, |
371 | ADDR("map"), _prom->mmumap, 0, size, virt, virt); | 395 | ADDR("map"), _prom->mmumap, 0x12, size, virt, virt); |
372 | return ret; | 396 | return virt; |
397 | } | ||
398 | return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size, | ||
399 | (prom_arg_t)align); | ||
373 | } | 400 | } |
374 | 401 | ||
375 | static void __init __attribute__((noreturn)) prom_panic(const char *reason) | 402 | static void __init __attribute__((noreturn)) prom_panic(const char *reason) |
@@ -415,11 +442,52 @@ static int inline prom_getproplen(phandle node, const char *pname) | |||
415 | return call_prom("getproplen", 2, 1, node, ADDR(pname)); | 442 | return call_prom("getproplen", 2, 1, node, ADDR(pname)); |
416 | } | 443 | } |
417 | 444 | ||
418 | static int inline prom_setprop(phandle node, const char *pname, | 445 | static void add_string(char **str, const char *q) |
419 | void *value, size_t valuelen) | ||
420 | { | 446 | { |
421 | return call_prom("setprop", 4, 1, node, ADDR(pname), | 447 | char *p = *str; |
422 | (u32)(unsigned long) value, (u32) valuelen); | 448 | |
449 | while (*q) | ||
450 | *p++ = *q++; | ||
451 | *p++ = ' '; | ||
452 | *str = p; | ||
453 | } | ||
454 | |||
455 | static char *tohex(unsigned int x) | ||
456 | { | ||
457 | static char digits[] = "0123456789abcdef"; | ||
458 | static char result[9]; | ||
459 | int i; | ||
460 | |||
461 | result[8] = 0; | ||
462 | i = 8; | ||
463 | do { | ||
464 | --i; | ||
465 | result[i] = digits[x & 0xf]; | ||
466 | x >>= 4; | ||
467 | } while (x != 0 && i > 0); | ||
468 | return &result[i]; | ||
469 | } | ||
470 | |||
471 | static int __init prom_setprop(phandle node, const char *nodename, | ||
472 | const char *pname, void *value, size_t valuelen) | ||
473 | { | ||
474 | char cmd[256], *p; | ||
475 | |||
476 | if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL)) | ||
477 | return call_prom("setprop", 4, 1, node, ADDR(pname), | ||
478 | (u32)(unsigned long) value, (u32) valuelen); | ||
479 | |||
480 | /* gah... setprop doesn't work on longtrail, have to use interpret */ | ||
481 | p = cmd; | ||
482 | add_string(&p, "dev"); | ||
483 | add_string(&p, nodename); | ||
484 | add_string(&p, tohex((u32)(unsigned long) value)); | ||
485 | add_string(&p, tohex(valuelen)); | ||
486 | add_string(&p, tohex(ADDR(pname))); | ||
487 | add_string(&p, tohex(strlen(RELOC(pname)))); | ||
488 | add_string(&p, "property"); | ||
489 | *p = 0; | ||
490 | return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd); | ||
423 | } | 491 | } |
424 | 492 | ||
425 | /* We can't use the standard versions because of RELOC headaches. */ | 493 | /* We can't use the standard versions because of RELOC headaches. */ |
@@ -980,7 +1048,7 @@ static void __init prom_instantiate_rtas(void) | |||
980 | 1048 | ||
981 | rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); | 1049 | rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); |
982 | if (!IHANDLE_VALID(rtas_inst)) { | 1050 | if (!IHANDLE_VALID(rtas_inst)) { |
983 | prom_printf("opening rtas package failed"); | 1051 | prom_printf("opening rtas package failed (%x)\n", rtas_inst); |
984 | return; | 1052 | return; |
985 | } | 1053 | } |
986 | 1054 | ||
@@ -988,7 +1056,7 @@ static void __init prom_instantiate_rtas(void) | |||
988 | 1056 | ||
989 | if (call_prom_ret("call-method", 3, 2, &entry, | 1057 | if (call_prom_ret("call-method", 3, 2, &entry, |
990 | ADDR("instantiate-rtas"), | 1058 | ADDR("instantiate-rtas"), |
991 | rtas_inst, base) == PROM_ERROR | 1059 | rtas_inst, base) != 0 |
992 | || entry == 0) { | 1060 | || entry == 0) { |
993 | prom_printf(" failed\n"); | 1061 | prom_printf(" failed\n"); |
994 | return; | 1062 | return; |
@@ -997,8 +1065,10 @@ static void __init prom_instantiate_rtas(void) | |||
997 | 1065 | ||
998 | reserve_mem(base, size); | 1066 | reserve_mem(base, size); |
999 | 1067 | ||
1000 | prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base)); | 1068 | prom_setprop(rtas_node, "/rtas", "linux,rtas-base", |
1001 | prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry)); | 1069 | &base, sizeof(base)); |
1070 | prom_setprop(rtas_node, "/rtas", "linux,rtas-entry", | ||
1071 | &entry, sizeof(entry)); | ||
1002 | 1072 | ||
1003 | prom_debug("rtas base = 0x%x\n", base); | 1073 | prom_debug("rtas base = 0x%x\n", base); |
1004 | prom_debug("rtas entry = 0x%x\n", entry); | 1074 | prom_debug("rtas entry = 0x%x\n", entry); |
@@ -1089,10 +1159,6 @@ static void __init prom_initialize_tce_table(void) | |||
1089 | if (base < local_alloc_bottom) | 1159 | if (base < local_alloc_bottom) |
1090 | local_alloc_bottom = base; | 1160 | local_alloc_bottom = base; |
1091 | 1161 | ||
1092 | /* Save away the TCE table attributes for later use. */ | ||
1093 | prom_setprop(node, "linux,tce-base", &base, sizeof(base)); | ||
1094 | prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize)); | ||
1095 | |||
1096 | /* It seems OF doesn't null-terminate the path :-( */ | 1162 | /* It seems OF doesn't null-terminate the path :-( */ |
1097 | memset(path, 0, sizeof(path)); | 1163 | memset(path, 0, sizeof(path)); |
1098 | /* Call OF to setup the TCE hardware */ | 1164 | /* Call OF to setup the TCE hardware */ |
@@ -1101,6 +1167,10 @@ static void __init prom_initialize_tce_table(void) | |||
1101 | prom_printf("package-to-path failed\n"); | 1167 | prom_printf("package-to-path failed\n"); |
1102 | } | 1168 | } |
1103 | 1169 | ||
1170 | /* Save away the TCE table attributes for later use. */ | ||
1171 | prom_setprop(node, path, "linux,tce-base", &base, sizeof(base)); | ||
1172 | prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize)); | ||
1173 | |||
1104 | prom_debug("TCE table: %s\n", path); | 1174 | prom_debug("TCE table: %s\n", path); |
1105 | prom_debug("\tnode = 0x%x\n", node); | 1175 | prom_debug("\tnode = 0x%x\n", node); |
1106 | prom_debug("\tbase = 0x%x\n", base); | 1176 | prom_debug("\tbase = 0x%x\n", base); |
@@ -1342,6 +1412,7 @@ static void __init prom_init_client_services(unsigned long pp) | |||
1342 | /* | 1412 | /* |
1343 | * For really old powermacs, we need to map things we claim. | 1413 | * For really old powermacs, we need to map things we claim. |
1344 | * For that, we need the ihandle of the mmu. | 1414 | * For that, we need the ihandle of the mmu. |
1415 | * Also, on the longtrail, we need to work around other bugs. | ||
1345 | */ | 1416 | */ |
1346 | static void __init prom_find_mmu(void) | 1417 | static void __init prom_find_mmu(void) |
1347 | { | 1418 | { |
@@ -1355,12 +1426,19 @@ static void __init prom_find_mmu(void) | |||
1355 | if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0) | 1426 | if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0) |
1356 | return; | 1427 | return; |
1357 | version[sizeof(version) - 1] = 0; | 1428 | version[sizeof(version) - 1] = 0; |
1358 | prom_printf("OF version is '%s'\n", version); | ||
1359 | /* XXX might need to add other versions here */ | 1429 | /* XXX might need to add other versions here */ |
1360 | if (strcmp(version, "Open Firmware, 1.0.5") != 0) | 1430 | if (strcmp(version, "Open Firmware, 1.0.5") == 0) |
1431 | of_workarounds = OF_WA_CLAIM; | ||
1432 | else if (strncmp(version, "FirmWorks,3.", 12) == 0) { | ||
1433 | of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL; | ||
1434 | call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim"); | ||
1435 | } else | ||
1361 | return; | 1436 | return; |
1437 | _prom->memory = call_prom("open", 1, 1, ADDR("/memory")); | ||
1362 | prom_getprop(_prom->chosen, "mmu", &_prom->mmumap, | 1438 | prom_getprop(_prom->chosen, "mmu", &_prom->mmumap, |
1363 | sizeof(_prom->mmumap)); | 1439 | sizeof(_prom->mmumap)); |
1440 | if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap)) | ||
1441 | of_workarounds &= ~OF_WA_CLAIM; /* hmmm */ | ||
1364 | } | 1442 | } |
1365 | #else | 1443 | #else |
1366 | #define prom_find_mmu() | 1444 | #define prom_find_mmu() |
@@ -1382,16 +1460,17 @@ static void __init prom_init_stdout(void) | |||
1382 | memset(path, 0, 256); | 1460 | memset(path, 0, 256); |
1383 | call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255); | 1461 | call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255); |
1384 | val = call_prom("instance-to-package", 1, 1, _prom->stdout); | 1462 | val = call_prom("instance-to-package", 1, 1, _prom->stdout); |
1385 | prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val)); | 1463 | prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package", |
1464 | &val, sizeof(val)); | ||
1386 | prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device)); | 1465 | prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device)); |
1387 | prom_setprop(_prom->chosen, "linux,stdout-path", | 1466 | prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path", |
1388 | RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1); | 1467 | path, strlen(path) + 1); |
1389 | 1468 | ||
1390 | /* If it's a display, note it */ | 1469 | /* If it's a display, note it */ |
1391 | memset(type, 0, sizeof(type)); | 1470 | memset(type, 0, sizeof(type)); |
1392 | prom_getprop(val, "device_type", type, sizeof(type)); | 1471 | prom_getprop(val, "device_type", type, sizeof(type)); |
1393 | if (strcmp(type, RELOC("display")) == 0) | 1472 | if (strcmp(type, RELOC("display")) == 0) |
1394 | prom_setprop(val, "linux,boot-display", NULL, 0); | 1473 | prom_setprop(val, path, "linux,boot-display", NULL, 0); |
1395 | } | 1474 | } |
1396 | 1475 | ||
1397 | static void __init prom_close_stdin(void) | 1476 | static void __init prom_close_stdin(void) |
@@ -1514,7 +1593,7 @@ static void __init prom_check_displays(void) | |||
1514 | 1593 | ||
1515 | /* Success */ | 1594 | /* Success */ |
1516 | prom_printf("done\n"); | 1595 | prom_printf("done\n"); |
1517 | prom_setprop(node, "linux,opened", NULL, 0); | 1596 | prom_setprop(node, path, "linux,opened", NULL, 0); |
1518 | 1597 | ||
1519 | /* Setup a usable color table when the appropriate | 1598 | /* Setup a usable color table when the appropriate |
1520 | * method is available. Should update this to set-colors */ | 1599 | * method is available. Should update this to set-colors */ |
@@ -1884,9 +1963,11 @@ static void __init fixup_device_tree(void) | |||
1884 | /* interrupt on this revision of u3 is number 0 and level */ | 1963 | /* interrupt on this revision of u3 is number 0 and level */ |
1885 | interrupts[0] = 0; | 1964 | interrupts[0] = 0; |
1886 | interrupts[1] = 1; | 1965 | interrupts[1] = 1; |
1887 | prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts)); | 1966 | prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts", |
1967 | &interrupts, sizeof(interrupts)); | ||
1888 | parent = (u32)mpic; | 1968 | parent = (u32)mpic; |
1889 | prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent)); | 1969 | prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent", |
1970 | &parent, sizeof(parent)); | ||
1890 | #endif | 1971 | #endif |
1891 | } | 1972 | } |
1892 | 1973 | ||
@@ -1922,11 +2003,11 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4) | |||
1922 | RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; | 2003 | RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; |
1923 | 2004 | ||
1924 | val = RELOC(prom_initrd_start); | 2005 | val = RELOC(prom_initrd_start); |
1925 | prom_setprop(_prom->chosen, "linux,initrd-start", &val, | 2006 | prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start", |
1926 | sizeof(val)); | 2007 | &val, sizeof(val)); |
1927 | val = RELOC(prom_initrd_end); | 2008 | val = RELOC(prom_initrd_end); |
1928 | prom_setprop(_prom->chosen, "linux,initrd-end", &val, | 2009 | prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end", |
1929 | sizeof(val)); | 2010 | &val, sizeof(val)); |
1930 | 2011 | ||
1931 | reserve_mem(RELOC(prom_initrd_start), | 2012 | reserve_mem(RELOC(prom_initrd_start), |
1932 | RELOC(prom_initrd_end) - RELOC(prom_initrd_start)); | 2013 | RELOC(prom_initrd_end) - RELOC(prom_initrd_start)); |
@@ -1969,14 +2050,15 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
1969 | prom_init_client_services(pp); | 2050 | prom_init_client_services(pp); |
1970 | 2051 | ||
1971 | /* | 2052 | /* |
1972 | * Init prom stdout device | 2053 | * See if this OF is old enough that we need to do explicit maps |
2054 | * and other workarounds | ||
1973 | */ | 2055 | */ |
1974 | prom_init_stdout(); | 2056 | prom_find_mmu(); |
1975 | 2057 | ||
1976 | /* | 2058 | /* |
1977 | * See if this OF is old enough that we need to do explicit maps | 2059 | * Init prom stdout device |
1978 | */ | 2060 | */ |
1979 | prom_find_mmu(); | 2061 | prom_init_stdout(); |
1980 | 2062 | ||
1981 | /* | 2063 | /* |
1982 | * Check for an initrd | 2064 | * Check for an initrd |
@@ -1989,7 +2071,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
1989 | */ | 2071 | */ |
1990 | RELOC(of_platform) = prom_find_machine_type(); | 2072 | RELOC(of_platform) = prom_find_machine_type(); |
1991 | getprop_rval = RELOC(of_platform); | 2073 | getprop_rval = RELOC(of_platform); |
1992 | prom_setprop(_prom->chosen, "linux,platform", | 2074 | prom_setprop(_prom->chosen, "/chosen", "linux,platform", |
1993 | &getprop_rval, sizeof(getprop_rval)); | 2075 | &getprop_rval, sizeof(getprop_rval)); |
1994 | 2076 | ||
1995 | #ifdef CONFIG_PPC_PSERIES | 2077 | #ifdef CONFIG_PPC_PSERIES |
@@ -2050,21 +2132,23 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2050 | * Fill in some infos for use by the kernel later on | 2132 | * Fill in some infos for use by the kernel later on |
2051 | */ | 2133 | */ |
2052 | if (RELOC(prom_memory_limit)) | 2134 | if (RELOC(prom_memory_limit)) |
2053 | prom_setprop(_prom->chosen, "linux,memory-limit", | 2135 | prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit", |
2054 | &RELOC(prom_memory_limit), | 2136 | &RELOC(prom_memory_limit), |
2055 | sizeof(prom_memory_limit)); | 2137 | sizeof(prom_memory_limit)); |
2056 | #ifdef CONFIG_PPC64 | 2138 | #ifdef CONFIG_PPC64 |
2057 | if (RELOC(ppc64_iommu_off)) | 2139 | if (RELOC(ppc64_iommu_off)) |
2058 | prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0); | 2140 | prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off", |
2141 | NULL, 0); | ||
2059 | 2142 | ||
2060 | if (RELOC(iommu_force_on)) | 2143 | if (RELOC(iommu_force_on)) |
2061 | prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0); | 2144 | prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on", |
2145 | NULL, 0); | ||
2062 | 2146 | ||
2063 | if (RELOC(prom_tce_alloc_start)) { | 2147 | if (RELOC(prom_tce_alloc_start)) { |
2064 | prom_setprop(_prom->chosen, "linux,tce-alloc-start", | 2148 | prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start", |
2065 | &RELOC(prom_tce_alloc_start), | 2149 | &RELOC(prom_tce_alloc_start), |
2066 | sizeof(prom_tce_alloc_start)); | 2150 | sizeof(prom_tce_alloc_start)); |
2067 | prom_setprop(_prom->chosen, "linux,tce-alloc-end", | 2151 | prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end", |
2068 | &RELOC(prom_tce_alloc_end), | 2152 | &RELOC(prom_tce_alloc_end), |
2069 | sizeof(prom_tce_alloc_end)); | 2153 | sizeof(prom_tce_alloc_end)); |
2070 | } | 2154 | } |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 081d931eae48..a7c4515f320f 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -42,6 +42,7 @@ | |||
42 | 42 | ||
43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
44 | #include <asm/cacheflush.h> | 44 | #include <asm/cacheflush.h> |
45 | #include <asm/sigcontext.h> | ||
45 | #ifdef CONFIG_PPC64 | 46 | #ifdef CONFIG_PPC64 |
46 | #include "ppc32.h" | 47 | #include "ppc32.h" |
47 | #include <asm/unistd.h> | 48 | #include <asm/unistd.h> |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 32f215825e8d..0578f8387603 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -887,10 +887,6 @@ void altivec_unavailable_exception(struct pt_regs *regs) | |||
887 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); | 887 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); |
888 | } | 888 | } |
889 | 889 | ||
890 | #ifdef CONFIG_PPC64 | ||
891 | extern perf_irq_t perf_irq; | ||
892 | #endif | ||
893 | |||
894 | #if defined(CONFIG_PPC64) || defined(CONFIG_E500) | 890 | #if defined(CONFIG_PPC64) || defined(CONFIG_E500) |
895 | void performance_monitor_exception(struct pt_regs *regs) | 891 | void performance_monitor_exception(struct pt_regs *regs) |
896 | { | 892 | { |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 97082a4203ad..71a6addf9f7f 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/iommu.h> | 21 | #include <asm/iommu.h> |
22 | #include <asm/dma.h> | 22 | #include <asm/dma.h> |
23 | #include <asm/vio.h> | 23 | #include <asm/vio.h> |
24 | #include <asm/prom.h> | ||
24 | 25 | ||
25 | static const struct vio_device_id *vio_match_device( | 26 | static const struct vio_device_id *vio_match_device( |
26 | const struct vio_device_id *, const struct vio_dev *); | 27 | const struct vio_device_id *, const struct vio_dev *); |
@@ -265,7 +266,33 @@ static int vio_bus_match(struct device *dev, struct device_driver *drv) | |||
265 | return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL); | 266 | return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL); |
266 | } | 267 | } |
267 | 268 | ||
269 | static int vio_hotplug(struct device *dev, char **envp, int num_envp, | ||
270 | char *buffer, int buffer_size) | ||
271 | { | ||
272 | const struct vio_dev *vio_dev = to_vio_dev(dev); | ||
273 | char *cp; | ||
274 | int length; | ||
275 | |||
276 | if (!num_envp) | ||
277 | return -ENOMEM; | ||
278 | |||
279 | if (!vio_dev->dev.platform_data) | ||
280 | return -ENODEV; | ||
281 | cp = (char *)get_property(vio_dev->dev.platform_data, "compatible", &length); | ||
282 | if (!cp) | ||
283 | return -ENODEV; | ||
284 | |||
285 | envp[0] = buffer; | ||
286 | length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s", | ||
287 | vio_dev->type, cp); | ||
288 | if (buffer_size - length <= 0) | ||
289 | return -ENOMEM; | ||
290 | envp[1] = NULL; | ||
291 | return 0; | ||
292 | } | ||
293 | |||
268 | struct bus_type vio_bus_type = { | 294 | struct bus_type vio_bus_type = { |
269 | .name = "vio", | 295 | .name = "vio", |
296 | .hotplug = vio_hotplug, | ||
270 | .match = vio_bus_match, | 297 | .match = vio_bus_match, |
271 | }; | 298 | }; |