diff options
Diffstat (limited to 'arch/mips/mm/page.c')
-rw-r--r-- | arch/mips/mm/page.c | 67 |
1 files changed, 18 insertions, 49 deletions
diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c index cc0b626858b3..98f530e18216 100644 --- a/arch/mips/mm/page.c +++ b/arch/mips/mm/page.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org) | 6 | * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org) |
7 | * Copyright (C) 2007 Maciej W. Rozycki | 7 | * Copyright (C) 2007 Maciej W. Rozycki |
8 | * Copyright (C) 2008 Thiemo Seufer | 8 | * Copyright (C) 2008 Thiemo Seufer |
9 | * Copyright (C) 2012 MIPS Technologies, Inc. | ||
9 | */ | 10 | */ |
10 | #include <linux/init.h> | 11 | #include <linux/init.h> |
11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
@@ -71,45 +72,6 @@ static struct uasm_reloc __cpuinitdata relocs[5]; | |||
71 | #define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010) | 72 | #define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010) |
72 | #define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020) | 73 | #define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020) |
73 | 74 | ||
74 | /* | ||
75 | * Maximum sizes: | ||
76 | * | ||
77 | * R4000 128 bytes S-cache: 0x058 bytes | ||
78 | * R4600 v1.7: 0x05c bytes | ||
79 | * R4600 v2.0: 0x060 bytes | ||
80 | * With prefetching, 16 word strides 0x120 bytes | ||
81 | */ | ||
82 | |||
83 | static u32 clear_page_array[0x120 / 4]; | ||
84 | |||
85 | #ifdef CONFIG_SIBYTE_DMA_PAGEOPS | ||
86 | void clear_page_cpu(void *page) __attribute__((alias("clear_page_array"))); | ||
87 | #else | ||
88 | void clear_page(void *page) __attribute__((alias("clear_page_array"))); | ||
89 | #endif | ||
90 | |||
91 | EXPORT_SYMBOL(clear_page); | ||
92 | |||
93 | /* | ||
94 | * Maximum sizes: | ||
95 | * | ||
96 | * R4000 128 bytes S-cache: 0x11c bytes | ||
97 | * R4600 v1.7: 0x080 bytes | ||
98 | * R4600 v2.0: 0x07c bytes | ||
99 | * With prefetching, 16 word strides 0x540 bytes | ||
100 | */ | ||
101 | static u32 copy_page_array[0x540 / 4]; | ||
102 | |||
103 | #ifdef CONFIG_SIBYTE_DMA_PAGEOPS | ||
104 | void | ||
105 | copy_page_cpu(void *to, void *from) __attribute__((alias("copy_page_array"))); | ||
106 | #else | ||
107 | void copy_page(void *to, void *from) __attribute__((alias("copy_page_array"))); | ||
108 | #endif | ||
109 | |||
110 | EXPORT_SYMBOL(copy_page); | ||
111 | |||
112 | |||
113 | static int pref_bias_clear_store __cpuinitdata; | 75 | static int pref_bias_clear_store __cpuinitdata; |
114 | static int pref_bias_copy_load __cpuinitdata; | 76 | static int pref_bias_copy_load __cpuinitdata; |
115 | static int pref_bias_copy_store __cpuinitdata; | 77 | static int pref_bias_copy_store __cpuinitdata; |
@@ -282,10 +244,15 @@ static inline void __cpuinit build_clear_pref(u32 **buf, int off) | |||
282 | } | 244 | } |
283 | } | 245 | } |
284 | 246 | ||
247 | extern u32 __clear_page_start; | ||
248 | extern u32 __clear_page_end; | ||
249 | extern u32 __copy_page_start; | ||
250 | extern u32 __copy_page_end; | ||
251 | |||
285 | void __cpuinit build_clear_page(void) | 252 | void __cpuinit build_clear_page(void) |
286 | { | 253 | { |
287 | int off; | 254 | int off; |
288 | u32 *buf = (u32 *)&clear_page_array; | 255 | u32 *buf = &__clear_page_start; |
289 | struct uasm_label *l = labels; | 256 | struct uasm_label *l = labels; |
290 | struct uasm_reloc *r = relocs; | 257 | struct uasm_reloc *r = relocs; |
291 | int i; | 258 | int i; |
@@ -356,17 +323,17 @@ void __cpuinit build_clear_page(void) | |||
356 | uasm_i_jr(&buf, RA); | 323 | uasm_i_jr(&buf, RA); |
357 | uasm_i_nop(&buf); | 324 | uasm_i_nop(&buf); |
358 | 325 | ||
359 | BUG_ON(buf > clear_page_array + ARRAY_SIZE(clear_page_array)); | 326 | BUG_ON(buf > &__clear_page_end); |
360 | 327 | ||
361 | uasm_resolve_relocs(relocs, labels); | 328 | uasm_resolve_relocs(relocs, labels); |
362 | 329 | ||
363 | pr_debug("Synthesized clear page handler (%u instructions).\n", | 330 | pr_debug("Synthesized clear page handler (%u instructions).\n", |
364 | (u32)(buf - clear_page_array)); | 331 | (u32)(buf - &__clear_page_start)); |
365 | 332 | ||
366 | pr_debug("\t.set push\n"); | 333 | pr_debug("\t.set push\n"); |
367 | pr_debug("\t.set noreorder\n"); | 334 | pr_debug("\t.set noreorder\n"); |
368 | for (i = 0; i < (buf - clear_page_array); i++) | 335 | for (i = 0; i < (buf - &__clear_page_start); i++) |
369 | pr_debug("\t.word 0x%08x\n", clear_page_array[i]); | 336 | pr_debug("\t.word 0x%08x\n", (&__clear_page_start)[i]); |
370 | pr_debug("\t.set pop\n"); | 337 | pr_debug("\t.set pop\n"); |
371 | } | 338 | } |
372 | 339 | ||
@@ -427,7 +394,7 @@ static inline void build_copy_store_pref(u32 **buf, int off) | |||
427 | void __cpuinit build_copy_page(void) | 394 | void __cpuinit build_copy_page(void) |
428 | { | 395 | { |
429 | int off; | 396 | int off; |
430 | u32 *buf = (u32 *)©_page_array; | 397 | u32 *buf = &__copy_page_start; |
431 | struct uasm_label *l = labels; | 398 | struct uasm_label *l = labels; |
432 | struct uasm_reloc *r = relocs; | 399 | struct uasm_reloc *r = relocs; |
433 | int i; | 400 | int i; |
@@ -595,21 +562,23 @@ void __cpuinit build_copy_page(void) | |||
595 | uasm_i_jr(&buf, RA); | 562 | uasm_i_jr(&buf, RA); |
596 | uasm_i_nop(&buf); | 563 | uasm_i_nop(&buf); |
597 | 564 | ||
598 | BUG_ON(buf > copy_page_array + ARRAY_SIZE(copy_page_array)); | 565 | BUG_ON(buf > &__copy_page_end); |
599 | 566 | ||
600 | uasm_resolve_relocs(relocs, labels); | 567 | uasm_resolve_relocs(relocs, labels); |
601 | 568 | ||
602 | pr_debug("Synthesized copy page handler (%u instructions).\n", | 569 | pr_debug("Synthesized copy page handler (%u instructions).\n", |
603 | (u32)(buf - copy_page_array)); | 570 | (u32)(buf - &__copy_page_start)); |
604 | 571 | ||
605 | pr_debug("\t.set push\n"); | 572 | pr_debug("\t.set push\n"); |
606 | pr_debug("\t.set noreorder\n"); | 573 | pr_debug("\t.set noreorder\n"); |
607 | for (i = 0; i < (buf - copy_page_array); i++) | 574 | for (i = 0; i < (buf - &__copy_page_start); i++) |
608 | pr_debug("\t.word 0x%08x\n", copy_page_array[i]); | 575 | pr_debug("\t.word 0x%08x\n", (&__copy_page_start)[i]); |
609 | pr_debug("\t.set pop\n"); | 576 | pr_debug("\t.set pop\n"); |
610 | } | 577 | } |
611 | 578 | ||
612 | #ifdef CONFIG_SIBYTE_DMA_PAGEOPS | 579 | #ifdef CONFIG_SIBYTE_DMA_PAGEOPS |
580 | extern void clear_page_cpu(void *page); | ||
581 | extern void copy_page_cpu(void *to, void *from); | ||
613 | 582 | ||
614 | /* | 583 | /* |
615 | * Pad descriptors to cacheline, since each is exclusively owned by a | 584 | * Pad descriptors to cacheline, since each is exclusively owned by a |