blob: 4dc342d289b42dbb8fb49421bd32761057e9a661 [file] [log] [blame]
Andrew Scull18834872018-10-12 11:48:09 +01001/*
2 * Copyright 2018 Google LLC
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andrew Scullfbc938a2018-08-20 14:09:28 +010017#pragma once
Andrew Scull8dce4982018-08-06 13:02:20 +010018
19#include <stddef.h>
20#include <stdint.h>
21
Andrew Scull11a4a0c2018-12-29 11:38:31 +000022#include "hf/arch/types.h"
Andrew Scull8dce4982018-08-06 13:02:20 +010023
Andrew Walbranc3910f72018-11-27 14:24:36 +000024/** An opaque type for a physical address. */
Andrew Scull8dce4982018-08-06 13:02:20 +010025typedef struct {
26 uintpaddr_t pa;
27} paddr_t;
28
Andrew Walbranc3910f72018-11-27 14:24:36 +000029/** An opaque type for an intermediate physical address. */
Andrew Scull8dce4982018-08-06 13:02:20 +010030typedef struct {
31 uintpaddr_t ipa;
32} ipaddr_t;
33
Andrew Walbranc3910f72018-11-27 14:24:36 +000034/** An opaque type for a virtual address. */
Andrew Scull8dce4982018-08-06 13:02:20 +010035typedef struct {
36 uintvaddr_t va;
37} vaddr_t;
38
39/**
40 * Initializes a physical address.
41 */
42static inline paddr_t pa_init(uintpaddr_t p)
43{
44 return (paddr_t){.pa = p};
45}
46
47/**
48 * Extracts the absolute physical address.
49 */
50static inline uintpaddr_t pa_addr(paddr_t pa)
51{
52 return pa.pa;
53}
54
55/**
Andrew Scull81e85092018-12-12 12:56:20 +000056 * Advances a physical address.
57 */
58static inline paddr_t pa_add(paddr_t pa, size_t n)
59{
60 return pa_init(pa_addr(pa) + n);
61}
62
63/**
Andrew Scull8dce4982018-08-06 13:02:20 +010064 * Initializes an intermeditate physical address.
65 */
Alfredo Mazzinghi8cc983e2019-02-22 15:12:36 +000066static inline ipaddr_t ipa_init(uintpaddr_t ipa)
Andrew Scull8dce4982018-08-06 13:02:20 +010067{
Alfredo Mazzinghi8cc983e2019-02-22 15:12:36 +000068 return (ipaddr_t){.ipa = ipa};
Andrew Scull8dce4982018-08-06 13:02:20 +010069}
70
71/**
72 * Extracts the absolute intermediate physical address.
73 */
74static inline uintpaddr_t ipa_addr(ipaddr_t ipa)
75{
76 return ipa.ipa;
77}
78
79/**
Andrew Scull81e85092018-12-12 12:56:20 +000080 * Advances an intermediate physical address.
81 */
82static inline ipaddr_t ipa_add(ipaddr_t ipa, size_t n)
83{
84 return ipa_init(ipa_addr(ipa) + n);
85}
86
87/**
Andrew Scull8dce4982018-08-06 13:02:20 +010088 * Initializes a virtual address.
89 */
90static inline vaddr_t va_init(uintvaddr_t v)
91{
92 return (vaddr_t){.va = v};
93}
94
95/**
96 * Extracts the absolute virtual address.
97 */
98static inline uintvaddr_t va_addr(vaddr_t va)
99{
100 return va.va;
101}
102
103/**
Andrew Scull8dce4982018-08-06 13:02:20 +0100104 * Casts a physical address to a virtual address.
105 */
106static inline vaddr_t va_from_pa(paddr_t pa)
107{
108 return va_init(pa_addr(pa));
109}
110
111/**
Andrew Scull1b8d0442018-08-06 15:47:04 +0100112 * Casts a physical address to an intermediate physical address.
113 */
114static inline ipaddr_t ipa_from_pa(paddr_t pa)
115{
116 return ipa_init(pa_addr(pa));
117}
118
119/**
Andrew Scull8dce4982018-08-06 13:02:20 +0100120 * Casts a virtual address to a physical address.
121 */
122static inline paddr_t pa_from_va(vaddr_t va)
123{
124 return pa_init(va_addr(va));
125}
126
127/**
Andrew Scullc2eb6a32018-12-13 16:54:24 +0000128 * Casts an intermediate physical address to a physical address.
129 */
130static inline paddr_t pa_from_ipa(ipaddr_t ipa)
131{
132 return pa_init(ipa_addr(ipa));
133}
134
135/**
Andrew Scull8dce4982018-08-06 13:02:20 +0100136 * Casts a pointer to a virtual address.
137 */
138static inline vaddr_t va_from_ptr(const void *p)
139{
140 return (vaddr_t){.va = (uintvaddr_t)p};
141}
142
143/**
144 * Casts a virtual address to a pointer. Only use when the virtual address is
145 * mapped for the calling context.
146 * TODO: check the mapping for a range and return a memiter?
147 */
148static inline void *ptr_from_va(vaddr_t va)
149{
150 return (void *)va_addr(va);
151}