diff options
Diffstat (limited to 'arch/ppc64/kernel')
-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/iommu.c | 7 | ||||
-rw-r--r-- | arch/ppc64/kernel/lparmap.c | 31 |
5 files changed, 47 insertions, 81 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/iommu.c b/arch/ppc64/kernel/iommu.c index 8316426ccaf6..845eebd1e28d 100644 --- a/arch/ppc64/kernel/iommu.c +++ b/arch/ppc64/kernel/iommu.c | |||
@@ -242,7 +242,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
242 | dma_addr_t dma_next = 0, dma_addr; | 242 | dma_addr_t dma_next = 0, dma_addr; |
243 | unsigned long flags; | 243 | unsigned long flags; |
244 | struct scatterlist *s, *outs, *segstart; | 244 | struct scatterlist *s, *outs, *segstart; |
245 | int outcount; | 245 | int outcount, incount; |
246 | unsigned long handle; | 246 | unsigned long handle; |
247 | 247 | ||
248 | BUG_ON(direction == DMA_NONE); | 248 | BUG_ON(direction == DMA_NONE); |
@@ -252,6 +252,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
252 | 252 | ||
253 | outs = s = segstart = &sglist[0]; | 253 | outs = s = segstart = &sglist[0]; |
254 | outcount = 1; | 254 | outcount = 1; |
255 | incount = nelems; | ||
255 | handle = 0; | 256 | handle = 0; |
256 | 257 | ||
257 | /* Init first segment length for backout at failure */ | 258 | /* Init first segment length for backout at failure */ |
@@ -338,10 +339,10 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
338 | 339 | ||
339 | DBG("mapped %d elements:\n", outcount); | 340 | DBG("mapped %d elements:\n", outcount); |
340 | 341 | ||
341 | /* For the sake of iommu_free_sg, we clear out the length in the | 342 | /* For the sake of iommu_unmap_sg, we clear out the length in the |
342 | * next entry of the sglist if we didn't fill the list completely | 343 | * next entry of the sglist if we didn't fill the list completely |
343 | */ | 344 | */ |
344 | if (outcount < nelems) { | 345 | if (outcount < incount) { |
345 | outs++; | 346 | outs++; |
346 | outs->dma_address = DMA_ERROR_CODE; | 347 | outs->dma_address = DMA_ERROR_CODE; |
347 | outs->dma_length = 0; | 348 | outs->dma_length = 0; |
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 | }; | ||