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 */ |
