diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2008-04-10 02:39:18 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-04-15 07:21:25 -0400 |
commit | 3eb9cf076180ed2003db77bd2c33ac4ed0211089 (patch) | |
tree | adddbf53de36e21b015515ab692db05f0fcbec8e /arch | |
parent | a7e695f6bf37f829a01e693a1569e96a842a1017 (diff) |
[POWERPC] iSeries: Use alternate paca structure for booting
The iSeries HV only needs the first two fields of the paca statically
initialised, so create an alternate paca that contains only those and
switch to our real paca immediately after boot.
This is in order to make the 1024 cpu patches easier since they will no
longer have to statically initialise the pacas for iSeries.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/exception.S | 12 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/lpardata.c | 39 |
3 files changed, 53 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index e932b43bd82f..292c6d8db0e1 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -44,6 +44,9 @@ | |||
44 | #include <asm/mmu.h> | 44 | #include <asm/mmu.h> |
45 | #include <asm/hvcall.h> | 45 | #include <asm/hvcall.h> |
46 | #endif | 46 | #endif |
47 | #ifdef CONFIG_PPC_ISERIES | ||
48 | #include <asm/iseries/alpaca.h> | ||
49 | #endif | ||
47 | 50 | ||
48 | #define DEFINE(sym, val) \ | 51 | #define DEFINE(sym, val) \ |
49 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | 52 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) |
@@ -321,6 +324,9 @@ int main(void) | |||
321 | DEFINE(PAGE_OFFSET_VSID, KERNEL_VSID(PAGE_OFFSET)); | 324 | DEFINE(PAGE_OFFSET_VSID, KERNEL_VSID(PAGE_OFFSET)); |
322 | DEFINE(VMALLOC_START_ESID, GET_ESID(VMALLOC_START)); | 325 | DEFINE(VMALLOC_START_ESID, GET_ESID(VMALLOC_START)); |
323 | DEFINE(VMALLOC_START_VSID, KERNEL_VSID(VMALLOC_START)); | 326 | DEFINE(VMALLOC_START_VSID, KERNEL_VSID(VMALLOC_START)); |
327 | |||
328 | /* alpaca */ | ||
329 | DEFINE(ALPACA_SIZE, sizeof(struct alpaca)); | ||
324 | #endif | 330 | #endif |
325 | 331 | ||
326 | DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE); | 332 | DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE); |
diff --git a/arch/powerpc/platforms/iseries/exception.S b/arch/powerpc/platforms/iseries/exception.S index 5381038f0881..c775cd4b3d6e 100644 --- a/arch/powerpc/platforms/iseries/exception.S +++ b/arch/powerpc/platforms/iseries/exception.S | |||
@@ -38,11 +38,19 @@ | |||
38 | 38 | ||
39 | .globl system_reset_iSeries | 39 | .globl system_reset_iSeries |
40 | system_reset_iSeries: | 40 | system_reset_iSeries: |
41 | mfspr r13,SPRN_SPRG3 /* Get paca address */ | 41 | mfspr r13,SPRN_SPRG3 /* Get alpaca address */ |
42 | LOAD_REG_IMMEDIATE(r23, alpaca) | ||
43 | li r0,ALPACA_SIZE | ||
44 | sub r23,r13,r23 | ||
45 | divdu r23,r23,r0 /* r23 has cpu number */ | ||
46 | LOAD_REG_IMMEDIATE(r13, paca) | ||
47 | mulli r0,r23,PACA_SIZE | ||
48 | add r13,r13,r0 | ||
49 | mtspr SPRN_SPRG3,r13 /* Save it away for the future */ | ||
42 | mfmsr r24 | 50 | mfmsr r24 |
43 | ori r24,r24,MSR_RI | 51 | ori r24,r24,MSR_RI |
44 | mtmsrd r24 /* RI on */ | 52 | mtmsrd r24 /* RI on */ |
45 | lhz r24,PACAPACAINDEX(r13) /* Get processor # */ | 53 | mr r24,r23 |
46 | cmpwi 0,r24,0 /* Are we processor 0? */ | 54 | cmpwi 0,r24,0 /* Are we processor 0? */ |
47 | bne 1f | 55 | bne 1f |
48 | b .__start_initialization_iSeries /* Start up the first processor */ | 56 | b .__start_initialization_iSeries /* Start up the first processor */ |
diff --git a/arch/powerpc/platforms/iseries/lpardata.c b/arch/powerpc/platforms/iseries/lpardata.c index 8162049bb04d..dc8470850a81 100644 --- a/arch/powerpc/platforms/iseries/lpardata.c +++ b/arch/powerpc/platforms/iseries/lpardata.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/paca.h> | 18 | #include <asm/paca.h> |
19 | #include <asm/iseries/lpar_map.h> | 19 | #include <asm/iseries/lpar_map.h> |
20 | #include <asm/iseries/it_lp_queue.h> | 20 | #include <asm/iseries/it_lp_queue.h> |
21 | #include <asm/iseries/alpaca.h> | ||
21 | 22 | ||
22 | #include "naca.h" | 23 | #include "naca.h" |
23 | #include "vpd_areas.h" | 24 | #include "vpd_areas.h" |
@@ -159,6 +160,40 @@ struct SpCommArea xSpCommArea = { | |||
159 | .xFormat = 1, | 160 | .xFormat = 1, |
160 | }; | 161 | }; |
161 | 162 | ||
163 | #define ALPACA_INIT(number) \ | ||
164 | { \ | ||
165 | .lppaca_ptr = &lppaca[number], \ | ||
166 | .reg_save_ptr = &iseries_reg_save[number], \ | ||
167 | } | ||
168 | |||
169 | struct alpaca alpaca[] = { | ||
170 | ALPACA_INIT( 0), | ||
171 | #if NR_CPUS > 1 | ||
172 | ALPACA_INIT( 1), ALPACA_INIT( 2), ALPACA_INIT( 3), | ||
173 | #if NR_CPUS > 4 | ||
174 | ALPACA_INIT( 4), ALPACA_INIT( 5), ALPACA_INIT( 6), ALPACA_INIT( 7), | ||
175 | #if NR_CPUS > 8 | ||
176 | ALPACA_INIT( 8), ALPACA_INIT( 9), ALPACA_INIT(10), ALPACA_INIT(11), | ||
177 | ALPACA_INIT(12), ALPACA_INIT(13), ALPACA_INIT(14), ALPACA_INIT(15), | ||
178 | ALPACA_INIT(16), ALPACA_INIT(17), ALPACA_INIT(18), ALPACA_INIT(19), | ||
179 | ALPACA_INIT(20), ALPACA_INIT(21), ALPACA_INIT(22), ALPACA_INIT(23), | ||
180 | ALPACA_INIT(24), ALPACA_INIT(25), ALPACA_INIT(26), ALPACA_INIT(27), | ||
181 | ALPACA_INIT(28), ALPACA_INIT(29), ALPACA_INIT(30), ALPACA_INIT(31), | ||
182 | #if NR_CPUS > 32 | ||
183 | ALPACA_INIT(32), ALPACA_INIT(33), ALPACA_INIT(34), ALPACA_INIT(35), | ||
184 | ALPACA_INIT(36), ALPACA_INIT(37), ALPACA_INIT(38), ALPACA_INIT(39), | ||
185 | ALPACA_INIT(40), ALPACA_INIT(41), ALPACA_INIT(42), ALPACA_INIT(43), | ||
186 | ALPACA_INIT(44), ALPACA_INIT(45), ALPACA_INIT(46), ALPACA_INIT(47), | ||
187 | ALPACA_INIT(48), ALPACA_INIT(49), ALPACA_INIT(50), ALPACA_INIT(51), | ||
188 | ALPACA_INIT(52), ALPACA_INIT(53), ALPACA_INIT(54), ALPACA_INIT(55), | ||
189 | ALPACA_INIT(56), ALPACA_INIT(57), ALPACA_INIT(58), ALPACA_INIT(59), | ||
190 | ALPACA_INIT(60), ALPACA_INIT(61), ALPACA_INIT(62), ALPACA_INIT(63), | ||
191 | #endif | ||
192 | #endif | ||
193 | #endif | ||
194 | #endif | ||
195 | }; | ||
196 | |||
162 | /* The LparMap data is now located at offset 0x6000 in head.S | 197 | /* The LparMap data is now located at offset 0x6000 in head.S |
163 | * It was put there so that the HvReleaseData could address it | 198 | * It was put there so that the HvReleaseData could address it |
164 | * with a 32-bit offset as required by the iSeries hypervisor | 199 | * with a 32-bit offset as required by the iSeries hypervisor |
@@ -185,7 +220,7 @@ struct ItVpdAreas itVpdAreas = { | |||
185 | .xSlicVpdLens = { /* VPD lengths */ | 220 | .xSlicVpdLens = { /* VPD lengths */ |
186 | 0,0,0, /* 0 - 2 */ | 221 | 0,0,0, /* 0 - 2 */ |
187 | sizeof(xItExtVpdPanel), /* 3 Extended VPD */ | 222 | sizeof(xItExtVpdPanel), /* 3 Extended VPD */ |
188 | sizeof(struct paca_struct), /* 4 length of Paca */ | 223 | sizeof(struct alpaca), /* 4 length of (fake) Paca */ |
189 | 0, /* 5 */ | 224 | 0, /* 5 */ |
190 | sizeof(struct ItIplParmsReal),/* 6 length of IPL parms */ | 225 | sizeof(struct ItIplParmsReal),/* 6 length of IPL parms */ |
191 | 26992, /* 7 length of MS VPD */ | 226 | 26992, /* 7 length of MS VPD */ |
@@ -203,7 +238,7 @@ struct ItVpdAreas itVpdAreas = { | |||
203 | .xSlicVpdAdrs = { /* VPD addresses */ | 238 | .xSlicVpdAdrs = { /* VPD addresses */ |
204 | 0,0,0, /* 0 - 2 */ | 239 | 0,0,0, /* 0 - 2 */ |
205 | &xItExtVpdPanel, /* 3 Extended VPD */ | 240 | &xItExtVpdPanel, /* 3 Extended VPD */ |
206 | &paca[0], /* 4 first Paca */ | 241 | &alpaca[0], /* 4 first (fake) Paca */ |
207 | 0, /* 5 */ | 242 | 0, /* 5 */ |
208 | &xItIplParmsReal, /* 6 IPL parms */ | 243 | &xItIplParmsReal, /* 6 IPL parms */ |
209 | &xMsVpd, /* 7 MS Vpd */ | 244 | &xMsVpd, /* 7 MS Vpd */ |