diff options
Diffstat (limited to 'include/asm-ppc64/abs_addr.h')
-rw-r--r-- | include/asm-ppc64/abs_addr.h | 86 |
1 files changed, 22 insertions, 64 deletions
diff --git a/include/asm-ppc64/abs_addr.h b/include/asm-ppc64/abs_addr.h index 6d4e8e787058..84c24d4cdb71 100644 --- a/include/asm-ppc64/abs_addr.h +++ b/include/asm-ppc64/abs_addr.h | |||
@@ -16,93 +16,51 @@ | |||
16 | #include <asm/page.h> | 16 | #include <asm/page.h> |
17 | #include <asm/prom.h> | 17 | #include <asm/prom.h> |
18 | #include <asm/lmb.h> | 18 | #include <asm/lmb.h> |
19 | #include <asm/firmware.h> | ||
19 | 20 | ||
20 | typedef u32 msChunks_entry; | 21 | struct mschunks_map { |
21 | struct msChunks { | ||
22 | unsigned long num_chunks; | 22 | unsigned long num_chunks; |
23 | unsigned long chunk_size; | 23 | unsigned long chunk_size; |
24 | unsigned long chunk_shift; | 24 | unsigned long chunk_shift; |
25 | unsigned long chunk_mask; | 25 | unsigned long chunk_mask; |
26 | msChunks_entry *abs; | 26 | u32 *mapping; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | extern struct msChunks msChunks; | 29 | extern struct mschunks_map mschunks_map; |
30 | 30 | ||
31 | extern unsigned long msChunks_alloc(unsigned long, unsigned long, unsigned long); | 31 | /* Chunks are 256 KB */ |
32 | extern unsigned long reloc_offset(void); | 32 | #define MSCHUNKS_CHUNK_SHIFT (18) |
33 | #define MSCHUNKS_CHUNK_SIZE (1UL << MSCHUNKS_CHUNK_SHIFT) | ||
34 | #define MSCHUNKS_OFFSET_MASK (MSCHUNKS_CHUNK_SIZE - 1) | ||
33 | 35 | ||
34 | #ifdef CONFIG_MSCHUNKS | 36 | static inline unsigned long chunk_to_addr(unsigned long chunk) |
35 | |||
36 | static inline unsigned long | ||
37 | chunk_to_addr(unsigned long chunk) | ||
38 | { | 37 | { |
39 | unsigned long offset = reloc_offset(); | 38 | return chunk << MSCHUNKS_CHUNK_SHIFT; |
40 | struct msChunks *_msChunks = PTRRELOC(&msChunks); | ||
41 | |||
42 | return chunk << _msChunks->chunk_shift; | ||
43 | } | 39 | } |
44 | 40 | ||
45 | static inline unsigned long | 41 | static inline unsigned long addr_to_chunk(unsigned long addr) |
46 | addr_to_chunk(unsigned long addr) | ||
47 | { | 42 | { |
48 | unsigned long offset = reloc_offset(); | 43 | return addr >> MSCHUNKS_CHUNK_SHIFT; |
49 | struct msChunks *_msChunks = PTRRELOC(&msChunks); | ||
50 | |||
51 | return addr >> _msChunks->chunk_shift; | ||
52 | } | 44 | } |
53 | 45 | ||
54 | static inline unsigned long | 46 | static inline unsigned long phys_to_abs(unsigned long pa) |
55 | chunk_offset(unsigned long addr) | ||
56 | { | 47 | { |
57 | unsigned long offset = reloc_offset(); | 48 | unsigned long chunk; |
58 | struct msChunks *_msChunks = PTRRELOC(&msChunks); | ||
59 | 49 | ||
60 | return addr & _msChunks->chunk_mask; | 50 | /* This is a no-op on non-iSeries */ |
61 | } | 51 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) |
52 | return pa; | ||
62 | 53 | ||
63 | static inline unsigned long | 54 | chunk = addr_to_chunk(pa); |
64 | abs_chunk(unsigned long pchunk) | ||
65 | { | ||
66 | unsigned long offset = reloc_offset(); | ||
67 | struct msChunks *_msChunks = PTRRELOC(&msChunks); | ||
68 | if ( pchunk >= _msChunks->num_chunks ) { | ||
69 | return pchunk; | ||
70 | } | ||
71 | return PTRRELOC(_msChunks->abs)[pchunk]; | ||
72 | } | ||
73 | 55 | ||
74 | /* A macro so it can take pointers or unsigned long. */ | 56 | if (chunk < mschunks_map.num_chunks) |
75 | #define phys_to_abs(pa) \ | 57 | chunk = mschunks_map.mapping[chunk]; |
76 | ({ unsigned long _pa = (unsigned long)(pa); \ | ||
77 | chunk_to_addr(abs_chunk(addr_to_chunk(_pa))) + chunk_offset(_pa); \ | ||
78 | }) | ||
79 | 58 | ||
80 | static inline unsigned long | 59 | return chunk_to_addr(chunk) + (pa & MSCHUNKS_OFFSET_MASK); |
81 | physRpn_to_absRpn(unsigned long rpn) | ||
82 | { | ||
83 | unsigned long pa = rpn << PAGE_SHIFT; | ||
84 | unsigned long aa = phys_to_abs(pa); | ||
85 | return (aa >> PAGE_SHIFT); | ||
86 | } | 60 | } |
87 | 61 | ||
88 | /* A macro so it can take pointers or unsigned long. */ | ||
89 | #define abs_to_phys(aa) lmb_abs_to_phys((unsigned long)(aa)) | ||
90 | |||
91 | #else /* !CONFIG_MSCHUNKS */ | ||
92 | |||
93 | #define chunk_to_addr(chunk) ((unsigned long)(chunk)) | ||
94 | #define addr_to_chunk(addr) (addr) | ||
95 | #define chunk_offset(addr) (0) | ||
96 | #define abs_chunk(pchunk) (pchunk) | ||
97 | |||
98 | #define phys_to_abs(pa) (pa) | ||
99 | #define physRpn_to_absRpn(rpn) (rpn) | ||
100 | #define abs_to_phys(aa) (aa) | ||
101 | |||
102 | #endif /* !CONFIG_MSCHUNKS */ | ||
103 | |||
104 | /* Convenience macros */ | 62 | /* Convenience macros */ |
105 | #define virt_to_abs(va) phys_to_abs(__pa(va)) | 63 | #define virt_to_abs(va) phys_to_abs(__pa(va)) |
106 | #define abs_to_virt(aa) __va(abs_to_phys(aa)) | 64 | #define abs_to_virt(aa) __va(aa) |
107 | 65 | ||
108 | #endif /* _ABS_ADDR_H */ | 66 | #endif /* _ABS_ADDR_H */ |