diff options
Diffstat (limited to 'arch/ppc64/kernel/LparData.c')
-rw-r--r-- | arch/ppc64/kernel/LparData.c | 88 |
1 files changed, 82 insertions, 6 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); |