diff options
Diffstat (limited to 'arch/ppc64')
-rw-r--r-- | arch/ppc64/kernel/LparData.c | 88 | ||||
-rw-r--r-- | arch/ppc64/kernel/head.S | 33 |
2 files changed, 85 insertions, 36 deletions
diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c index 6ffcf67dd507..76cfd1449d52 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/ppc64/kernel/LparData.c | |||
@@ -33,17 +33,36 @@ | |||
33 | * the hypervisor and Linux. | 33 | * the hypervisor and Linux. |
34 | */ | 34 | */ |
35 | 35 | ||
36 | /* | ||
37 | * WARNING - magic here | ||
38 | * | ||
39 | * Ok, this is a horrid hack below, but marginally better than the | ||
40 | * alternatives. What we really want is just to initialize | ||
41 | * hvReleaseData in C as in the #if 0 section here. However, gcc | ||
42 | * refuses to believe that (u32)&x is a constant expression, so will | ||
43 | * not allow the xMsNucDataOffset field to be properly initialized. | ||
44 | * So, we declare hvReleaseData in inline asm instead. We use inline | ||
45 | * asm, rather than a .S file, because the assembler won't generate | ||
46 | * the necessary relocation for the LparMap either, unless that symbol | ||
47 | * is declared in the same source file. Finally, we put the asm in a | ||
48 | * dummy, attribute-used function, instead of at file scope, because | ||
49 | * file scope asms don't allow contraints. We want to use the "i" | ||
50 | * constraints to put sizeof() and offsetof() expressions in there, | ||
51 | * because including asm/offsets.h in C code then stringifying causes | ||
52 | * all manner of warnings. | ||
53 | */ | ||
54 | #if 0 | ||
36 | struct HvReleaseData hvReleaseData = { | 55 | struct HvReleaseData hvReleaseData = { |
37 | .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ | 56 | .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ |
38 | .xSize = sizeof(struct HvReleaseData), | 57 | .xSize = sizeof(struct HvReleaseData), |
39 | .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas), | 58 | .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas), |
40 | .xSlicNacaAddr = &naca, /* 64-bit Naca address */ | 59 | .xSlicNacaAddr = &naca, /* 64-bit Naca address */ |
41 | .xMsNucDataOffset = 0x4800, /* offset of LparMap within loadarea (see head.S) */ | 60 | .xMsNucDataOffset = (u32)((unsigned long)&xLparMap - KERNELBASE), |
42 | .xTagsMode = 1, /* tags inactive */ | 61 | .xFlags = HVREL_TAGSINACTIVE /* tags inactive */ |
43 | .xAddressSize = 0, /* 64 bit */ | 62 | /* 64 bit */ |
44 | .xNoSharedProcs = 0, /* shared processors */ | 63 | /* shared processors */ |
45 | .xNoHMT = 0, /* HMT allowed */ | 64 | /* HMT allowed */ |
46 | .xRsvd2 = 6, /* TEMP: This allows non-GA driver */ | 65 | | 6, /* TEMP: This allows non-GA driver */ |
47 | .xVrmIndex = 4, /* We are v5r2m0 */ | 66 | .xVrmIndex = 4, /* We are v5r2m0 */ |
48 | .xMinSupportedPlicVrmIndex = 3, /* v5r1m0 */ | 67 | .xMinSupportedPlicVrmIndex = 3, /* v5r1m0 */ |
49 | .xMinCompatablePlicVrmIndex = 3, /* v5r1m0 */ | 68 | .xMinCompatablePlicVrmIndex = 3, /* v5r1m0 */ |
@@ -51,6 +70,63 @@ struct HvReleaseData hvReleaseData = { | |||
51 | 0xa7, 0x40, 0xf2, 0x4b, | 70 | 0xa7, 0x40, 0xf2, 0x4b, |
52 | 0xf4, 0x4b, 0xf6, 0xf4 }, | 71 | 0xf4, 0x4b, 0xf6, 0xf4 }, |
53 | }; | 72 | }; |
73 | #endif | ||
74 | |||
75 | |||
76 | extern struct HvReleaseData hvReleaseData; | ||
77 | |||
78 | static void __attribute_used__ hvReleaseData_wrapper(void) | ||
79 | { | ||
80 | /* This doesn't appear to need any alignment (even 4 byte) */ | ||
81 | asm volatile ( | ||
82 | " lparMapPhys = xLparMap - %3\n" | ||
83 | " .data\n" | ||
84 | " .globl hvReleaseData\n" | ||
85 | "hvReleaseData:\n" | ||
86 | " .long 0xc8a5d9c4\n" /* xDesc */ | ||
87 | /* "HvRD" in ebcdic */ | ||
88 | " .short %0\n" /* xSize */ | ||
89 | " .short %1\n" /* xVpdAreasPtrOffset */ | ||
90 | " .llong naca\n" /* xSlicNacaAddr */ | ||
91 | " .long lparMapPhys\n" /* xMsNucDataOffset */ | ||
92 | " .long 0\n" /* xRsvd1 */ | ||
93 | " .short %2\n" /* xFlags */ | ||
94 | " .short 4\n" /* xVrmIndex - v5r2m0 */ | ||
95 | " .short 3\n" /* xMinSupportedPlicVrmIndex - v5r1m0 */ | ||
96 | " .short 3\n" /* xMinCompatablePlicVrmIndex - v5r1m0 */ | ||
97 | " .long 0xd38995a4\n" /* xVrmName */ | ||
98 | " .long 0xa740f24b\n" /* "Linux 2.4.64" ebcdic */ | ||
99 | " .long 0xf44bf6f4\n" | ||
100 | " . = hvReleaseData + %0\n" | ||
101 | " .previous\n" | ||
102 | : : "i"(sizeof(hvReleaseData)), | ||
103 | "i"(offsetof(struct naca_struct, xItVpdAreas)), | ||
104 | "i"(HVREL_TAGSINACTIVE /* tags inactive, 64 bit, */ | ||
105 | /* shared processors, HMT allowed */ | ||
106 | | 6), /* TEMP: This allows non-GA drivers */ | ||
107 | "i"(KERNELBASE) | ||
108 | ); | ||
109 | } | ||
110 | |||
111 | struct LparMap __attribute__((aligned (16))) xLparMap = { | ||
112 | .xNumberEsids = HvEsidsToMap, | ||
113 | .xNumberRanges = HvRangesToMap, | ||
114 | .xSegmentTableOffs = STAB0_PAGE, | ||
115 | |||
116 | .xEsids = { | ||
117 | { .xKernelEsid = GET_ESID(KERNELBASE), | ||
118 | .xKernelVsid = KERNEL_VSID(KERNELBASE), }, | ||
119 | { .xKernelEsid = GET_ESID(VMALLOCBASE), | ||
120 | .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, | ||
121 | }, | ||
122 | |||
123 | .xRanges = { | ||
124 | { .xPages = HvPagesToMap, | ||
125 | .xOffset = 0, | ||
126 | .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT), | ||
127 | }, | ||
128 | }, | ||
129 | }; | ||
54 | 130 | ||
55 | extern void system_reset_iSeries(void); | 131 | extern void system_reset_iSeries(void); |
56 | extern void machine_check_iSeries(void); | 132 | extern void machine_check_iSeries(void); |
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 3f447712e3ff..74fc3bc68604 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
@@ -522,36 +522,9 @@ __end_interrupts: | |||
522 | #ifdef CONFIG_PPC_ISERIES | 522 | #ifdef CONFIG_PPC_ISERIES |
523 | .globl naca | 523 | .globl naca |
524 | naca: | 524 | naca: |
525 | .llong itVpdAreas | 525 | .llong itVpdAreas |
526 | 526 | .llong 0 /* xRamDisk */ | |
527 | /* | 527 | .llong 0 /* xRamDiskSize */ |
528 | * The iSeries LPAR map is at this fixed address | ||
529 | * so that the HvReleaseData structure can address | ||
530 | * it with a 32-bit offset. | ||
531 | * | ||
532 | * The VSID values below are dependent on the | ||
533 | * VSID generation algorithm. See include/asm/mmu_context.h. | ||
534 | */ | ||
535 | |||
536 | . = 0x4800 | ||
537 | |||
538 | .llong 2 /* # ESIDs to be mapped by hypervisor */ | ||
539 | .llong 1 /* # memory ranges to be mapped by hypervisor */ | ||
540 | .llong STAB0_PAGE /* Page # of segment table within load area */ | ||
541 | .llong 0 /* Reserved */ | ||
542 | .llong 0 /* Reserved */ | ||
543 | .llong 0 /* Reserved */ | ||
544 | .llong 0 /* Reserved */ | ||
545 | .llong 0 /* Reserved */ | ||
546 | .llong (KERNELBASE>>SID_SHIFT) | ||
547 | .llong 0x408f92c94 /* KERNELBASE VSID */ | ||
548 | /* We have to list the bolted VMALLOC segment here, too, so that it | ||
549 | * will be restored on shared processor switch */ | ||
550 | .llong (VMALLOCBASE>>SID_SHIFT) | ||
551 | .llong 0xf09b89af5 /* VMALLOCBASE VSID */ | ||
552 | .llong 8192 /* # pages to map (32 MB) */ | ||
553 | .llong 0 /* Offset from start of loadarea to start of map */ | ||
554 | .llong 0x408f92c940000 /* VPN of first page to map */ | ||
555 | 528 | ||
556 | . = 0x6100 | 529 | . = 0x6100 |
557 | 530 | ||