[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>
diff --git a/include/asm-ppc64/iSeries/HvReleaseData.h b/include/asm-ppc64/iSeries/HvReleaseData.h
index 01a1f13..c8162e5 100644
--- a/include/asm-ppc64/iSeries/HvReleaseData.h
+++ b/include/asm-ppc64/iSeries/HvReleaseData.h
@@ -39,6 +39,11 @@
  * know that this PLIC does not support running an OS "that old".
  */
 
+#define	HVREL_TAGSINACTIVE	0x8000
+#define HVREL_32BIT		0x4000
+#define HVREL_NOSHAREDPROCS	0x2000
+#define HVREL_NOHMT		0x1000
+
 struct HvReleaseData {
 	u32	xDesc;		/* Descriptor "HvRD" ebcdic	x00-x03 */
 	u16	xSize;		/* Size of this control block	x04-x05 */
@@ -46,11 +51,7 @@
 	struct  naca_struct	*xSlicNacaAddr; /* Virt addr of SLIC NACA x08-x0F */
 	u32	xMsNucDataOffset; /* Offset of Linux Mapping Data x10-x13 */
 	u32	xRsvd1;		/* Reserved			x14-x17 */
-	u16	xTagsMode:1;	/* 0 == tags active, 1 == tags inactive */
-	u16	xAddressSize:1;	/* 0 == 64-bit, 1 == 32-bit */
-	u16	xNoSharedProcs:1; /* 0 == shared procs, 1 == no shared */
-	u16	xNoHMT:1;	/* 0 == allow HMT, 1 == no HMT */
-	u16	xRsvd2:12;	/* Reserved			x18-x19 */
+	u16	xFlags;
 	u16	xVrmIndex;	/* VRM Index of OS image	x1A-x1B */
 	u16	xMinSupportedPlicVrmIndex; /* Min PLIC level  (soft) x1C-x1D */
 	u16	xMinCompatablePlicVrmIndex; /* Min PLIC levelP (hard) x1E-x1F */
diff --git a/include/asm-ppc64/iSeries/LparMap.h b/include/asm-ppc64/iSeries/LparMap.h
index 038e5df..5c32e38 100644
--- a/include/asm-ppc64/iSeries/LparMap.h
+++ b/include/asm-ppc64/iSeries/LparMap.h
@@ -49,19 +49,26 @@
  * entry to map the Esid to the Vsid.
 */
 
+#define HvEsidsToMap	2
+#define HvRangesToMap	1
+
 /* Hypervisor initially maps 32MB of the load area */
 #define HvPagesToMap	8192
 
 struct LparMap {
-	u64	xNumberEsids;	// Number of ESID/VSID pairs (1)
-	u64	xNumberRanges;	// Number of VA ranges to map (1)
-	u64	xSegmentTableOffs; // Page number within load area of seg table (0)
+	u64	xNumberEsids;	// Number of ESID/VSID pairs
+	u64	xNumberRanges;	// Number of VA ranges to map
+	u64	xSegmentTableOffs; // Page number within load area of seg table
 	u64	xRsvd[5];
-	u64	xKernelEsid;	// Esid used to map kernel load (0x0C00000000)
-	u64	xKernelVsid;	// Vsid used to map kernel load (0x0C00000000)
-	u64	xPages;		// Number of pages to be mapped	(8192)
-	u64	xOffset;	// Offset from start of load area (0)
-	u64	xVPN;		// Virtual Page Number (0x000C000000000000)
+	struct {
+		u64	xKernelEsid;	// Esid used to map kernel load
+		u64	xKernelVsid;	// Vsid used to map kernel load
+	} xEsids[HvEsidsToMap];
+	struct {
+		u64	xPages;		// Number of pages to be mapped
+		u64	xOffset;	// Offset from start of load area
+		u64	xVPN;		// Virtual Page Number
+	} xRanges[HvRangesToMap];
 };
 
 extern struct LparMap		xLparMap;
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
index 8891180..70348a8 100644
--- a/include/asm-ppc64/mmu.h
+++ b/include/asm-ppc64/mmu.h
@@ -338,6 +338,9 @@
 			     | (ea >> SID_SHIFT));
 }
 
+#define VSID_SCRAMBLE(pvsid)	(((pvsid) * VSID_MULTIPLIER) % VSID_MODULUS)
+#define KERNEL_VSID(ea)		VSID_SCRAMBLE(GET_ESID(ea))
+
 #endif /* __ASSEMBLY */
 
 #endif /* _PPC64_MMU_H_ */