blob: 93dc63ed4f2f1048dfbdd4f5165d060dcec3f1b3 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001#ifndef _ABS_ADDR_H
2#define _ABS_ADDR_H
3
4#include <linux/config.h>
5
6/*
7 * c 2001 PPC 64 Team, IBM Corp
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15#include <asm/types.h>
16#include <asm/page.h>
17#include <asm/prom.h>
18#include <asm/lmb.h>
19
20typedef u32 msChunks_entry;
21struct msChunks {
22 unsigned long num_chunks;
23 unsigned long chunk_size;
24 unsigned long chunk_shift;
25 unsigned long chunk_mask;
26 msChunks_entry *abs;
27};
28
29extern struct msChunks msChunks;
30
31extern unsigned long msChunks_alloc(unsigned long, unsigned long, unsigned long);
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
33#ifdef CONFIG_MSCHUNKS
34
Michael Ellerman38e85dc2005-08-03 20:21:23 +100035static inline unsigned long chunk_to_addr(unsigned long chunk)
Linus Torvalds1da177e2005-04-16 15:20:36 -070036{
Michael Ellerman38e85dc2005-08-03 20:21:23 +100037 return chunk << msChunks.chunk_shift;
Linus Torvalds1da177e2005-04-16 15:20:36 -070038}
39
Michael Ellerman38e85dc2005-08-03 20:21:23 +100040static inline unsigned long addr_to_chunk(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -070041{
Michael Ellerman38e85dc2005-08-03 20:21:23 +100042 return addr >> msChunks.chunk_shift;
Linus Torvalds1da177e2005-04-16 15:20:36 -070043}
44
Michael Ellerman38e85dc2005-08-03 20:21:23 +100045static inline unsigned long chunk_offset(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -070046{
Michael Ellerman38e85dc2005-08-03 20:21:23 +100047 return addr & msChunks.chunk_mask;
Linus Torvalds1da177e2005-04-16 15:20:36 -070048}
49
Michael Ellerman38e85dc2005-08-03 20:21:23 +100050static inline unsigned long abs_chunk(unsigned long pchunk)
Linus Torvalds1da177e2005-04-16 15:20:36 -070051{
Michael Ellerman38e85dc2005-08-03 20:21:23 +100052 if (pchunk >= msChunks.num_chunks)
Linus Torvalds1da177e2005-04-16 15:20:36 -070053 return pchunk;
Michael Ellerman38e85dc2005-08-03 20:21:23 +100054
55 return msChunks.abs[pchunk];
Linus Torvalds1da177e2005-04-16 15:20:36 -070056}
57
58/* A macro so it can take pointers or unsigned long. */
59#define phys_to_abs(pa) \
60 ({ unsigned long _pa = (unsigned long)(pa); \
61 chunk_to_addr(abs_chunk(addr_to_chunk(_pa))) + chunk_offset(_pa); \
62 })
63
64static inline unsigned long
65physRpn_to_absRpn(unsigned long rpn)
66{
67 unsigned long pa = rpn << PAGE_SHIFT;
68 unsigned long aa = phys_to_abs(pa);
69 return (aa >> PAGE_SHIFT);
70}
71
72/* A macro so it can take pointers or unsigned long. */
73#define abs_to_phys(aa) lmb_abs_to_phys((unsigned long)(aa))
74
75#else /* !CONFIG_MSCHUNKS */
76
77#define chunk_to_addr(chunk) ((unsigned long)(chunk))
78#define addr_to_chunk(addr) (addr)
79#define chunk_offset(addr) (0)
80#define abs_chunk(pchunk) (pchunk)
81
82#define phys_to_abs(pa) (pa)
83#define physRpn_to_absRpn(rpn) (rpn)
84#define abs_to_phys(aa) (aa)
85
86#endif /* !CONFIG_MSCHUNKS */
87
88/* Convenience macros */
89#define virt_to_abs(va) phys_to_abs(__pa(va))
90#define abs_to_virt(aa) __va(abs_to_phys(aa))
91
92#endif /* _ABS_ADDR_H */