blob: efb184441df74af66331965d029e815d41a4d903 [file] [log] [blame]
Andrew Scull18834872018-10-12 11:48:09 +01001/*
Andrew Walbran692b3252019-03-07 15:51:31 +00002 * Copyright 2018 The Hafnium Authors.
Andrew Scull18834872018-10-12 11:48:09 +01003 *
Andrew Walbrane959ec12020-06-17 15:01:09 +01004 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/BSD-3-Clause.
Andrew Scull18834872018-10-12 11:48:09 +01007 */
8
Andrew Scullfbc938a2018-08-20 14:09:28 +01009#pragma once
Andrew Scull8dce4982018-08-06 13:02:20 +010010
11#include <stddef.h>
12#include <stdint.h>
13
Andrew Scull11a4a0c2018-12-29 11:38:31 +000014#include "hf/arch/types.h"
Andrew Scull8dce4982018-08-06 13:02:20 +010015
Fuad Tabba50469e02020-06-30 15:14:28 +010016#include "hf/check.h"
17
Andrew Walbranc3910f72018-11-27 14:24:36 +000018/** An opaque type for a physical address. */
Andrew Scull8dce4982018-08-06 13:02:20 +010019typedef struct {
20 uintpaddr_t pa;
21} paddr_t;
22
Andrew Walbranc3910f72018-11-27 14:24:36 +000023/** An opaque type for an intermediate physical address. */
Andrew Scull8dce4982018-08-06 13:02:20 +010024typedef struct {
25 uintpaddr_t ipa;
26} ipaddr_t;
27
Andrew Walbranc3910f72018-11-27 14:24:36 +000028/** An opaque type for a virtual address. */
Andrew Scull8dce4982018-08-06 13:02:20 +010029typedef struct {
30 uintvaddr_t va;
31} vaddr_t;
32
33/**
34 * Initializes a physical address.
35 */
36static inline paddr_t pa_init(uintpaddr_t p)
37{
38 return (paddr_t){.pa = p};
39}
40
41/**
42 * Extracts the absolute physical address.
43 */
44static inline uintpaddr_t pa_addr(paddr_t pa)
45{
46 return pa.pa;
47}
48
49/**
Andrew Scull81e85092018-12-12 12:56:20 +000050 * Advances a physical address.
51 */
52static inline paddr_t pa_add(paddr_t pa, size_t n)
53{
54 return pa_init(pa_addr(pa) + n);
55}
56
57/**
Andrew Walbran2cb43392019-04-17 12:52:45 +010058 * Returns the difference between two physical addresses.
59 */
60static inline size_t pa_difference(paddr_t start, paddr_t end)
61{
62 return pa_addr(end) - pa_addr(start);
63}
64
65/**
Andrew Scull8dce4982018-08-06 13:02:20 +010066 * Initializes an intermeditate physical address.
67 */
Alfredo Mazzinghi8cc983e2019-02-22 15:12:36 +000068static inline ipaddr_t ipa_init(uintpaddr_t ipa)
Andrew Scull8dce4982018-08-06 13:02:20 +010069{
Alfredo Mazzinghi8cc983e2019-02-22 15:12:36 +000070 return (ipaddr_t){.ipa = ipa};
Andrew Scull8dce4982018-08-06 13:02:20 +010071}
72
73/**
Fuad Tabba50469e02020-06-30 15:14:28 +010074 * Subtract from a physical address.
75 */
76static inline paddr_t pa_sub(paddr_t pa, size_t n)
77{
78 CHECK((uintptr_t)pa_addr(pa) >= n);
79 return pa_init(pa_addr(pa) - n);
80}
81
82/**
Andrew Scull8dce4982018-08-06 13:02:20 +010083 * Extracts the absolute intermediate physical address.
84 */
85static inline uintpaddr_t ipa_addr(ipaddr_t ipa)
86{
87 return ipa.ipa;
88}
89
90/**
Andrew Scull81e85092018-12-12 12:56:20 +000091 * Advances an intermediate physical address.
92 */
93static inline ipaddr_t ipa_add(ipaddr_t ipa, size_t n)
94{
95 return ipa_init(ipa_addr(ipa) + n);
96}
97
98/**
Andrew Scull8dce4982018-08-06 13:02:20 +010099 * Initializes a virtual address.
100 */
101static inline vaddr_t va_init(uintvaddr_t v)
102{
103 return (vaddr_t){.va = v};
104}
105
106/**
107 * Extracts the absolute virtual address.
108 */
109static inline uintvaddr_t va_addr(vaddr_t va)
110{
111 return va.va;
112}
113
114/**
Andrew Scull8dce4982018-08-06 13:02:20 +0100115 * Casts a physical address to a virtual address.
116 */
117static inline vaddr_t va_from_pa(paddr_t pa)
118{
119 return va_init(pa_addr(pa));
120}
121
122/**
Andrew Scull1b8d0442018-08-06 15:47:04 +0100123 * Casts a physical address to an intermediate physical address.
124 */
125static inline ipaddr_t ipa_from_pa(paddr_t pa)
126{
127 return ipa_init(pa_addr(pa));
128}
129
130/**
Andrew Scull8dce4982018-08-06 13:02:20 +0100131 * Casts a virtual address to a physical address.
132 */
133static inline paddr_t pa_from_va(vaddr_t va)
134{
135 return pa_init(va_addr(va));
136}
137
138/**
Andrew Scullc2eb6a32018-12-13 16:54:24 +0000139 * Casts an intermediate physical address to a physical address.
140 */
141static inline paddr_t pa_from_ipa(ipaddr_t ipa)
142{
143 return pa_init(ipa_addr(ipa));
144}
145
146/**
Andrew Scull8dce4982018-08-06 13:02:20 +0100147 * Casts a pointer to a virtual address.
148 */
149static inline vaddr_t va_from_ptr(const void *p)
150{
151 return (vaddr_t){.va = (uintvaddr_t)p};
152}
153
154/**
155 * Casts a virtual address to a pointer. Only use when the virtual address is
156 * mapped for the calling context.
157 * TODO: check the mapping for a range and return a memiter?
158 */
159static inline void *ptr_from_va(vaddr_t va)
160{
161 return (void *)va_addr(va);
162}