blob: 14e21c045a9a5edbe3afdaa01f52cdd01604efce [file] [log] [blame]
Andrew Scullfbc938a2018-08-20 14:09:28 +01001#pragma once
Andrew Scull8dce4982018-08-06 13:02:20 +01002
3#include <stddef.h>
4#include <stdint.h>
5
Andrew Scull18c78fc2018-08-20 12:57:41 +01006#include "hf/arch/addr.h"
Andrew Scull8dce4982018-08-06 13:02:20 +01007
8/* An opaque type for a physical address. */
9typedef struct {
10 uintpaddr_t pa;
11} paddr_t;
12
13/* An opaque type for an intermediate physical address. */
14typedef struct {
15 uintpaddr_t ipa;
16} ipaddr_t;
17
18/* An opaque type for a virtual address. */
19typedef struct {
20 uintvaddr_t va;
21} vaddr_t;
22
23/**
24 * Initializes a physical address.
25 */
26static inline paddr_t pa_init(uintpaddr_t p)
27{
28 return (paddr_t){.pa = p};
29}
30
31/**
32 * Extracts the absolute physical address.
33 */
34static inline uintpaddr_t pa_addr(paddr_t pa)
35{
36 return pa.pa;
37}
38
39/**
40 * Initializes an intermeditate physical address.
41 */
42static inline ipaddr_t ipa_init(uintvaddr_t v)
43{
44 return (ipaddr_t){.ipa = v};
45}
46
47/**
48 * Extracts the absolute intermediate physical address.
49 */
50static inline uintpaddr_t ipa_addr(ipaddr_t ipa)
51{
52 return ipa.ipa;
53}
54
55/**
56 * Initializes a virtual address.
57 */
58static inline vaddr_t va_init(uintvaddr_t v)
59{
60 return (vaddr_t){.va = v};
61}
62
63/**
64 * Extracts the absolute virtual address.
65 */
66static inline uintvaddr_t va_addr(vaddr_t va)
67{
68 return va.va;
69}
70
71/**
Andrew Scull80871322018-08-06 12:04:09 +010072 * Advances a physical address.
Andrew Scull8dce4982018-08-06 13:02:20 +010073 */
Andrew Scull80871322018-08-06 12:04:09 +010074static inline paddr_t pa_add(paddr_t pa, size_t n)
Andrew Scull8dce4982018-08-06 13:02:20 +010075{
Andrew Scull80871322018-08-06 12:04:09 +010076 return pa_init(pa_addr(pa) + n);
Andrew Scull8dce4982018-08-06 13:02:20 +010077}
78
79/**
80 * Casts a physical address to a virtual address.
81 */
82static inline vaddr_t va_from_pa(paddr_t pa)
83{
84 return va_init(pa_addr(pa));
85}
86
87/**
Andrew Scull1b8d0442018-08-06 15:47:04 +010088 * Casts a physical address to an intermediate physical address.
89 */
90static inline ipaddr_t ipa_from_pa(paddr_t pa)
91{
92 return ipa_init(pa_addr(pa));
93}
94
95/**
Andrew Scull8dce4982018-08-06 13:02:20 +010096 * Casts a virtual address to a physical address.
97 */
98static inline paddr_t pa_from_va(vaddr_t va)
99{
100 return pa_init(va_addr(va));
101}
102
103/**
104 * Casts a pointer to a virtual address.
105 */
106static inline vaddr_t va_from_ptr(const void *p)
107{
108 return (vaddr_t){.va = (uintvaddr_t)p};
109}
110
111/**
112 * Casts a virtual address to a pointer. Only use when the virtual address is
113 * mapped for the calling context.
114 * TODO: check the mapping for a range and return a memiter?
115 */
116static inline void *ptr_from_va(vaddr_t va)
117{
118 return (void *)va_addr(va);
119}