1d8efc6caSAlex Smith/*
2d8efc6caSAlex Smith * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
3d8efc6caSAlex Smith * Distributed under the terms of the MIT License.
4d8efc6caSAlex Smith */
5d8efc6caSAlex Smith#ifndef KERNEL_UTIL_FIXED_WIDTH_POINTER_H
6d8efc6caSAlex Smith#define KERNEL_UTIL_FIXED_WIDTH_POINTER_H
7d8efc6caSAlex Smith
8d8efc6caSAlex Smith
9d8efc6caSAlex Smith#include <SupportDefs.h>
10d8efc6caSAlex Smith
11d8efc6caSAlex Smith
12d8efc6caSAlex Smith/*!
13d8efc6caSAlex Smith	\class FixedWidthPointer
14d8efc6caSAlex Smith	\brief Pointer class with fixed size (64-bit) storage.
15d8efc6caSAlex Smith
16d8efc6caSAlex Smith	This class is a pointer-like class that uses a fixed size 64-bit storage.
17d8efc6caSAlex Smith	This is used to make kernel_args compatible (i.e. the same size) for both
18d8efc6caSAlex Smith	32-bit and 64-bit kernels.
19d8efc6caSAlex Smith*/
20d8efc6caSAlex Smithtemplate<typename Type>
21d8efc6caSAlex Smithclass FixedWidthPointer {
22d8efc6caSAlex Smithpublic:
2369a8b954SIngo Weinhold	Type * Pointer() const
24d8efc6caSAlex Smith	{
253a2a3367SAlex Smith		return (Type*)(addr_t)fValue;
263a2a3367SAlex Smith	}
273a2a3367SAlex Smith
2869a8b954SIngo Weinhold	operator Type*() const
293a2a3367SAlex Smith	{
3069a8b954SIngo Weinhold		return Pointer();
31d8efc6caSAlex Smith	}
32d8efc6caSAlex Smith
336b87898aSAlex Smith	Type& operator*() const
34d8efc6caSAlex Smith	{
3569a8b954SIngo Weinhold		return *Pointer();
36d8efc6caSAlex Smith	}
37d8efc6caSAlex Smith
386b87898aSAlex Smith	Type* operator->() const
39d8efc6caSAlex Smith	{
4069a8b954SIngo Weinhold		return Pointer();
413a2a3367SAlex Smith	}
423a2a3367SAlex Smith
433a2a3367SAlex Smith	Type& operator[](size_t i) const
443a2a3367SAlex Smith	{
4569a8b954SIngo Weinhold		return Pointer()[i];
46d8efc6caSAlex Smith	}
47d8efc6caSAlex Smith
486b87898aSAlex Smith	FixedWidthPointer& operator=(const FixedWidthPointer& p)
49d8efc6caSAlex Smith	{
50d8efc6caSAlex Smith		fValue = p.fValue;
51d8efc6caSAlex Smith		return *this;
52d8efc6caSAlex Smith	}
53d8efc6caSAlex Smith
546b87898aSAlex Smith	FixedWidthPointer& operator=(Type* p)
55d8efc6caSAlex Smith	{
56d8efc6caSAlex Smith		fValue = (addr_t)p;
57d8efc6caSAlex Smith		return *this;
58d8efc6caSAlex Smith	}
59d8efc6caSAlex Smith
60d8efc6caSAlex Smith	/*!
61d8efc6caSAlex Smith		Get the 64-bit pointer value.
62d8efc6caSAlex Smith		\return Pointer address.
63d8efc6caSAlex Smith	*/
64d8efc6caSAlex Smith	uint64 Get() const
65d8efc6caSAlex Smith	{
66d8efc6caSAlex Smith		return fValue;
67d8efc6caSAlex Smith	}
68d8efc6caSAlex Smith
69d8efc6caSAlex Smith	/*!
70d8efc6caSAlex Smith		Set the 64-bit pointer value.
71d8efc6caSAlex Smith		\param addr New address for the pointer.
72d8efc6caSAlex Smith	*/
73d8efc6caSAlex Smith	void SetTo(uint64 addr)
74d8efc6caSAlex Smith	{
75d8efc6caSAlex Smith		fValue = addr;
76d8efc6caSAlex Smith	}
776b87898aSAlex Smith
78d8efc6caSAlex Smithprivate:
79d8efc6caSAlex Smith	uint64 fValue;
80d8efc6caSAlex Smith} _PACKED;
81d8efc6caSAlex Smith
82d8efc6caSAlex Smith
83d8efc6caSAlex Smith// Specialization for void pointers, can be converted to another pointer type.
84d8efc6caSAlex Smithtemplate<>
85d8efc6caSAlex Smithclass FixedWidthPointer<void> {
86d8efc6caSAlex Smithpublic:
8769a8b954SIngo Weinhold	void * Pointer() const
88d8efc6caSAlex Smith	{
896b87898aSAlex Smith		return (void*)(addr_t)fValue;
90d8efc6caSAlex Smith	}
91d8efc6caSAlex Smith
9269a8b954SIngo Weinhold	operator void*() const
93d8efc6caSAlex Smith	{
9469a8b954SIngo Weinhold		return Pointer();
95d8efc6caSAlex Smith	}
96d8efc6caSAlex Smith
976b87898aSAlex Smith	FixedWidthPointer& operator=(const FixedWidthPointer& p)
98d8efc6caSAlex Smith	{
99d8efc6caSAlex Smith		fValue = p.fValue;
100d8efc6caSAlex Smith		return *this;
101d8efc6caSAlex Smith	}
102d8efc6caSAlex Smith
1036b87898aSAlex Smith	FixedWidthPointer& operator=(void* p)
104d8efc6caSAlex Smith	{
105d8efc6caSAlex Smith		fValue = (addr_t)p;
106d8efc6caSAlex Smith		return *this;
107d8efc6caSAlex Smith	}
108d8efc6caSAlex Smith
109d8efc6caSAlex Smith	uint64 Get() const
110d8efc6caSAlex Smith	{
111d8efc6caSAlex Smith		return fValue;
112d8efc6caSAlex Smith	}
113d8efc6caSAlex Smith
114d8efc6caSAlex Smith	void SetTo(uint64 addr)
115d8efc6caSAlex Smith	{
116d8efc6caSAlex Smith		fValue = addr;
117d8efc6caSAlex Smith	}
1186b87898aSAlex Smith
119d8efc6caSAlex Smithprivate:
120d8efc6caSAlex Smith	uint64 fValue;
121d8efc6caSAlex Smith} _PACKED;
122d8efc6caSAlex Smith
12369a8b954SIngo Weinhold
12462d36f98SAlex Smithtemplate<typename Type>
12562d36f98SAlex Smithinline bool
12669a8b954SIngo Weinholdoperator==(const FixedWidthPointer<Type>& a, const Type* b)
12762d36f98SAlex Smith{
12862d36f98SAlex Smith	return a.Get() == (addr_t)b;
12962d36f98SAlex Smith}
13062d36f98SAlex Smith
13169a8b954SIngo Weinhold
13269a8b954SIngo Weinholdtemplate<typename Type>
13369a8b954SIngo Weinholdinline bool
13469a8b954SIngo Weinholdoperator!=(const FixedWidthPointer<Type>& a, const Type* b)
13569a8b954SIngo Weinhold{
13669a8b954SIngo Weinhold	return a.Get() != (addr_t)b;
13769a8b954SIngo Weinhold}
13869a8b954SIngo Weinhold
13969a8b954SIngo Weinhold
14069a8b954SIngo Weinholdtemplate<typename Type>
14169a8b954SIngo Weinholdinline bool
14269a8b954SIngo Weinholdoperator==(const FixedWidthPointer<Type>& a, Type* b)
14369a8b954SIngo Weinhold{
14469a8b954SIngo Weinhold	return a.Get() == (addr_t)b;
14569a8b954SIngo Weinhold}
14669a8b954SIngo Weinhold
14769a8b954SIngo Weinhold
14862d36f98SAlex Smithtemplate<typename Type>
14962d36f98SAlex Smithinline bool
15069a8b954SIngo Weinholdoperator!=(const FixedWidthPointer<Type>& a, Type* b)
15162d36f98SAlex Smith{
15262d36f98SAlex Smith	return a.Get() != (addr_t)b;
15362d36f98SAlex Smith}
15462d36f98SAlex Smith
155d8efc6caSAlex Smith
156d8efc6caSAlex Smith#endif	/* KERNEL_UTIL_FIXED_WIDTH_POINTER_H */
157