diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 08:43:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 08:43:56 -0400 |
commit | d630ba565f3d806d64df4415d4a8457b4ab23db6 (patch) | |
tree | e17a7699cc82b602b32ed27ce032a4a2fcc580f3 /arch/x86/include | |
parent | 5fd862f1db941c302a872ed7e67eab593a6a931a (diff) | |
parent | 6a469e4665bc158599de55d64388861d0a9f10f4 (diff) |
Merge branch 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86: uv2: Workaround for UV2 Hub bug (system global address format)
Diffstat (limited to 'arch/x86/include')
-rw-r--r-- | arch/x86/include/asm/uv/uv_bau.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/uv/uv_hub.h | 37 |
2 files changed, 35 insertions, 3 deletions
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index c568ccca6e0e..8e862aaf0d90 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
@@ -55,6 +55,7 @@ | |||
55 | #define UV_BAU_TUNABLES_DIR "sgi_uv" | 55 | #define UV_BAU_TUNABLES_DIR "sgi_uv" |
56 | #define UV_BAU_TUNABLES_FILE "bau_tunables" | 56 | #define UV_BAU_TUNABLES_FILE "bau_tunables" |
57 | #define WHITESPACE " \t\n" | 57 | #define WHITESPACE " \t\n" |
58 | #define uv_mmask ((1UL << uv_hub_info->m_val) - 1) | ||
58 | #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) | 59 | #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) |
59 | #define cpubit_isset(cpu, bau_local_cpumask) \ | 60 | #define cpubit_isset(cpu, bau_local_cpumask) \ |
60 | test_bit((cpu), (bau_local_cpumask).bits) | 61 | test_bit((cpu), (bau_local_cpumask).bits) |
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index f26544a15214..54a13aaebc40 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h | |||
@@ -46,6 +46,13 @@ | |||
46 | * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant | 46 | * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant |
47 | * of the nasid for socket usage. | 47 | * of the nasid for socket usage. |
48 | * | 48 | * |
49 | * GPA - (global physical address) a socket physical address converted | ||
50 | * so that it can be used by the GRU as a global address. Socket | ||
51 | * physical addresses 1) need additional NASID (node) bits added | ||
52 | * to the high end of the address, and 2) unaliased if the | ||
53 | * partition does not have a physical address 0. In addition, on | ||
54 | * UV2 rev 1, GPAs need the gnode left shifted to bits 39 or 40. | ||
55 | * | ||
49 | * | 56 | * |
50 | * NumaLink Global Physical Address Format: | 57 | * NumaLink Global Physical Address Format: |
51 | * +--------------------------------+---------------------+ | 58 | * +--------------------------------+---------------------+ |
@@ -141,6 +148,8 @@ struct uv_hub_info_s { | |||
141 | unsigned int gnode_extra; | 148 | unsigned int gnode_extra; |
142 | unsigned char hub_revision; | 149 | unsigned char hub_revision; |
143 | unsigned char apic_pnode_shift; | 150 | unsigned char apic_pnode_shift; |
151 | unsigned char m_shift; | ||
152 | unsigned char n_lshift; | ||
144 | unsigned long gnode_upper; | 153 | unsigned long gnode_upper; |
145 | unsigned long lowmem_remap_top; | 154 | unsigned long lowmem_remap_top; |
146 | unsigned long lowmem_remap_base; | 155 | unsigned long lowmem_remap_base; |
@@ -177,6 +186,16 @@ static inline int is_uv2_hub(void) | |||
177 | return uv_hub_info->hub_revision >= UV2_HUB_REVISION_BASE; | 186 | return uv_hub_info->hub_revision >= UV2_HUB_REVISION_BASE; |
178 | } | 187 | } |
179 | 188 | ||
189 | static inline int is_uv2_1_hub(void) | ||
190 | { | ||
191 | return uv_hub_info->hub_revision == UV2_HUB_REVISION_BASE; | ||
192 | } | ||
193 | |||
194 | static inline int is_uv2_2_hub(void) | ||
195 | { | ||
196 | return uv_hub_info->hub_revision == UV2_HUB_REVISION_BASE + 1; | ||
197 | } | ||
198 | |||
180 | union uvh_apicid { | 199 | union uvh_apicid { |
181 | unsigned long v; | 200 | unsigned long v; |
182 | struct uvh_apicid_s { | 201 | struct uvh_apicid_s { |
@@ -276,7 +295,10 @@ static inline unsigned long uv_soc_phys_ram_to_gpa(unsigned long paddr) | |||
276 | { | 295 | { |
277 | if (paddr < uv_hub_info->lowmem_remap_top) | 296 | if (paddr < uv_hub_info->lowmem_remap_top) |
278 | paddr |= uv_hub_info->lowmem_remap_base; | 297 | paddr |= uv_hub_info->lowmem_remap_base; |
279 | return paddr | uv_hub_info->gnode_upper; | 298 | paddr |= uv_hub_info->gnode_upper; |
299 | paddr = ((paddr << uv_hub_info->m_shift) >> uv_hub_info->m_shift) | | ||
300 | ((paddr >> uv_hub_info->m_val) << uv_hub_info->n_lshift); | ||
301 | return paddr; | ||
280 | } | 302 | } |
281 | 303 | ||
282 | 304 | ||
@@ -300,16 +322,19 @@ static inline unsigned long uv_gpa_to_soc_phys_ram(unsigned long gpa) | |||
300 | unsigned long remap_base = uv_hub_info->lowmem_remap_base; | 322 | unsigned long remap_base = uv_hub_info->lowmem_remap_base; |
301 | unsigned long remap_top = uv_hub_info->lowmem_remap_top; | 323 | unsigned long remap_top = uv_hub_info->lowmem_remap_top; |
302 | 324 | ||
325 | gpa = ((gpa << uv_hub_info->m_shift) >> uv_hub_info->m_shift) | | ||
326 | ((gpa >> uv_hub_info->n_lshift) << uv_hub_info->m_val); | ||
327 | gpa = gpa & uv_hub_info->gpa_mask; | ||
303 | if (paddr >= remap_base && paddr < remap_base + remap_top) | 328 | if (paddr >= remap_base && paddr < remap_base + remap_top) |
304 | paddr -= remap_base; | 329 | paddr -= remap_base; |
305 | return paddr; | 330 | return paddr; |
306 | } | 331 | } |
307 | 332 | ||
308 | 333 | ||
309 | /* gnode -> pnode */ | 334 | /* gpa -> pnode */ |
310 | static inline unsigned long uv_gpa_to_gnode(unsigned long gpa) | 335 | static inline unsigned long uv_gpa_to_gnode(unsigned long gpa) |
311 | { | 336 | { |
312 | return gpa >> uv_hub_info->m_val; | 337 | return gpa >> uv_hub_info->n_lshift; |
313 | } | 338 | } |
314 | 339 | ||
315 | /* gpa -> pnode */ | 340 | /* gpa -> pnode */ |
@@ -320,6 +345,12 @@ static inline int uv_gpa_to_pnode(unsigned long gpa) | |||
320 | return uv_gpa_to_gnode(gpa) & n_mask; | 345 | return uv_gpa_to_gnode(gpa) & n_mask; |
321 | } | 346 | } |
322 | 347 | ||
348 | /* gpa -> node offset*/ | ||
349 | static inline unsigned long uv_gpa_to_offset(unsigned long gpa) | ||
350 | { | ||
351 | return (gpa << uv_hub_info->m_shift) >> uv_hub_info->m_shift; | ||
352 | } | ||
353 | |||
323 | /* pnode, offset --> socket virtual */ | 354 | /* pnode, offset --> socket virtual */ |
324 | static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset) | 355 | static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset) |
325 | { | 356 | { |