aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2005-07-27 14:44:21 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-27 19:25:58 -0400
commit488f84994c55927eef587a0827dc957c908a0bad (patch)
tree34bdc42927e2eb559bd64039ed87508a440dffc6 /arch/ppc64
parent533f08172e21521a74e15cdef8a13c929596d506 (diff)
[PATCH] ppc64: remove another fixed address constraint
Presently the LparMap, one of the structures the kernel shares with the legacy iSeries hypervisor has a fixed offset address in head.S. This patch changes this so the LparMap is a normally initialized structure, without fixed address. This allows us to use macros to compute some of the values in the structure, which wasn't previously possible because the assembler always uses signed-% which gets the wrong answers for the computations in question. Unfortunately, a gcc bug means that doing this requires another structure (hvReleaseData) to be initialized in asm instead of C, but on the whole the result is cleaner than before. Signed-off-by: David Gibson <dwg@au1.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc64')
-rw-r--r--arch/ppc64/kernel/LparData.c88
-rw-r--r--arch/ppc64/kernel/head.S33
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
36struct HvReleaseData hvReleaseData = { 55struct 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
76extern struct HvReleaseData hvReleaseData;
77
78static 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
111struct 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
55extern void system_reset_iSeries(void); 131extern void system_reset_iSeries(void);
56extern void machine_check_iSeries(void); 132extern 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
524naca: 524naca:
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