diff options
| -rw-r--r-- | arch/ppc64/kernel/LparData.c | 79 | ||||
| -rw-r--r-- | arch/ppc64/kernel/Makefile | 5 | ||||
| -rw-r--r-- | arch/ppc64/kernel/head.S | 6 | ||||
| -rw-r--r-- | arch/ppc64/kernel/lparmap.c | 31 | ||||
| -rw-r--r-- | include/asm-ppc64/iSeries/LparMap.h | 9 |
5 files changed, 51 insertions, 79 deletions
diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c index 76cfd1449d52..1c11031c838e 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/ppc64/kernel/LparData.c | |||
| @@ -32,32 +32,12 @@ | |||
| 32 | /* The HvReleaseData is the root of the information shared between | 32 | /* The HvReleaseData is the root of the information shared between |
| 33 | * the hypervisor and Linux. | 33 | * the hypervisor and Linux. |
| 34 | */ | 34 | */ |
| 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 | ||
| 55 | struct HvReleaseData hvReleaseData = { | 35 | struct HvReleaseData hvReleaseData = { |
| 56 | .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ | 36 | .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ |
| 57 | .xSize = sizeof(struct HvReleaseData), | 37 | .xSize = sizeof(struct HvReleaseData), |
| 58 | .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas), | 38 | .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas), |
| 59 | .xSlicNacaAddr = &naca, /* 64-bit Naca address */ | 39 | .xSlicNacaAddr = &naca, /* 64-bit Naca address */ |
| 60 | .xMsNucDataOffset = (u32)((unsigned long)&xLparMap - KERNELBASE), | 40 | .xMsNucDataOffset = LPARMAP_PHYS, |
| 61 | .xFlags = HVREL_TAGSINACTIVE /* tags inactive */ | 41 | .xFlags = HVREL_TAGSINACTIVE /* tags inactive */ |
| 62 | /* 64 bit */ | 42 | /* 64 bit */ |
| 63 | /* shared processors */ | 43 | /* shared processors */ |
| @@ -70,63 +50,6 @@ struct HvReleaseData hvReleaseData = { | |||
| 70 | 0xa7, 0x40, 0xf2, 0x4b, | 50 | 0xa7, 0x40, 0xf2, 0x4b, |
| 71 | 0xf4, 0x4b, 0xf6, 0xf4 }, | 51 | 0xf4, 0x4b, 0xf6, 0xf4 }, |
| 72 | }; | 52 | }; |
| 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 | }; | ||
| 130 | 53 | ||
| 131 | extern void system_reset_iSeries(void); | 54 | extern void system_reset_iSeries(void); |
| 132 | extern void machine_check_iSeries(void); | 55 | extern void machine_check_iSeries(void); |
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index d9b2660ef221..2ecccb6b4f8c 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile | |||
| @@ -73,3 +73,8 @@ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | |||
| 73 | obj-$(CONFIG_KPROBES) += kprobes.o | 73 | obj-$(CONFIG_KPROBES) += kprobes.o |
| 74 | 74 | ||
| 75 | CFLAGS_ioctl32.o += -Ifs/ | 75 | CFLAGS_ioctl32.o += -Ifs/ |
| 76 | |||
| 77 | ifeq ($(CONFIG_PPC_ISERIES),y) | ||
| 78 | arch/ppc64/kernel/head.o: arch/ppc64/kernel/lparmap.s | ||
| 79 | AFLAGS_head.o += -Iarch/ppc64/kernel | ||
| 80 | endif | ||
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 784f56d4684c..accaa052d31f 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <asm/cputable.h> | 38 | #include <asm/cputable.h> |
| 39 | #include <asm/setup.h> | 39 | #include <asm/setup.h> |
| 40 | #include <asm/hvcall.h> | 40 | #include <asm/hvcall.h> |
| 41 | #include <asm/iSeries/LparMap.h> | ||
| 41 | 42 | ||
| 42 | #ifdef CONFIG_PPC_ISERIES | 43 | #ifdef CONFIG_PPC_ISERIES |
| 43 | #define DO_SOFT_DISABLE | 44 | #define DO_SOFT_DISABLE |
| @@ -679,6 +680,11 @@ hardware_interrupt_iSeries_masked: | |||
| 679 | .globl fwnmi_data_area | 680 | .globl fwnmi_data_area |
| 680 | fwnmi_data_area: | 681 | fwnmi_data_area: |
| 681 | 682 | ||
| 683 | #ifdef CONFIG_PPC_ISERIES | ||
| 684 | . = LPARMAP_PHYS | ||
| 685 | #include "lparmap.s" | ||
| 686 | #endif /* CONFIG_PPC_ISERIES */ | ||
| 687 | |||
| 682 | /* | 688 | /* |
| 683 | * Vectors for the FWNMI option. Share common code. | 689 | * Vectors for the FWNMI option. Share common code. |
| 684 | */ | 690 | */ |
diff --git a/arch/ppc64/kernel/lparmap.c b/arch/ppc64/kernel/lparmap.c new file mode 100644 index 000000000000..b81de286df5e --- /dev/null +++ b/arch/ppc64/kernel/lparmap.c | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005 Stephen Rothwell IBM Corp. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version | ||
| 7 | * 2 of the License, or (at your option) any later version. | ||
| 8 | */ | ||
| 9 | #include <asm/mmu.h> | ||
| 10 | #include <asm/page.h> | ||
| 11 | #include <asm/iSeries/LparMap.h> | ||
| 12 | |||
| 13 | const struct LparMap __attribute__((__section__(".text"))) xLparMap = { | ||
| 14 | .xNumberEsids = HvEsidsToMap, | ||
| 15 | .xNumberRanges = HvRangesToMap, | ||
| 16 | .xSegmentTableOffs = STAB0_PAGE, | ||
| 17 | |||
| 18 | .xEsids = { | ||
| 19 | { .xKernelEsid = GET_ESID(KERNELBASE), | ||
| 20 | .xKernelVsid = KERNEL_VSID(KERNELBASE), }, | ||
| 21 | { .xKernelEsid = GET_ESID(VMALLOCBASE), | ||
| 22 | .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, | ||
| 23 | }, | ||
| 24 | |||
| 25 | .xRanges = { | ||
| 26 | { .xPages = HvPagesToMap, | ||
| 27 | .xOffset = 0, | ||
| 28 | .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT), | ||
| 29 | }, | ||
| 30 | }, | ||
| 31 | }; | ||
diff --git a/include/asm-ppc64/iSeries/LparMap.h b/include/asm-ppc64/iSeries/LparMap.h index 5c32e38c1c01..a6840b186d03 100644 --- a/include/asm-ppc64/iSeries/LparMap.h +++ b/include/asm-ppc64/iSeries/LparMap.h | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | #ifndef _LPARMAP_H | 19 | #ifndef _LPARMAP_H |
| 20 | #define _LPARMAP_H | 20 | #define _LPARMAP_H |
| 21 | 21 | ||
| 22 | #ifndef __ASSEMBLY__ | ||
| 23 | |||
| 22 | #include <asm/types.h> | 24 | #include <asm/types.h> |
| 23 | 25 | ||
| 24 | /* | 26 | /* |
| @@ -71,6 +73,11 @@ struct LparMap { | |||
| 71 | } xRanges[HvRangesToMap]; | 73 | } xRanges[HvRangesToMap]; |
| 72 | }; | 74 | }; |
| 73 | 75 | ||
| 74 | extern struct LparMap xLparMap; | 76 | extern const struct LparMap xLparMap; |
| 77 | |||
| 78 | #endif /* __ASSEMBLY__ */ | ||
| 79 | |||
| 80 | /* the fixed address where the LparMap exists */ | ||
| 81 | #define LPARMAP_PHYS 0x7000 | ||
| 75 | 82 | ||
| 76 | #endif /* _LPARMAP_H */ | 83 | #endif /* _LPARMAP_H */ |
