blob: 7121744a80e054965435e5e6efb8d0cdab337f32 [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 Scull18c78fc2018-08-20 12:57:41 +010022#include "hf/arch/addr.h"
Andrew Scull8dce4982018-08-06 13:02:20 +010023
24/* An opaque type for a physical address. */
25typedef struct {
26 uintpaddr_t pa;
27} paddr_t;
28
29/* An opaque type for an intermediate physical address. */
30typedef struct {
31 uintpaddr_t ipa;
32} ipaddr_t;
33
34/* An opaque type for a virtual address. */
35typedef 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/**
56 * Initializes an intermeditate physical address.
57 */
58static inline ipaddr_t ipa_init(uintvaddr_t v)
59{
60 return (ipaddr_t){.ipa = v};
61}
62
63/**
64 * Extracts the absolute intermediate physical address.
65 */
66static inline uintpaddr_t ipa_addr(ipaddr_t ipa)
67{
68 return ipa.ipa;
69}
70
71/**
72 * Initializes a virtual address.
73 */
74static inline vaddr_t va_init(uintvaddr_t v)
75{
76 return (vaddr_t){.va = v};
77}
78
79/**
80 * Extracts the absolute virtual address.
81 */
82static inline uintvaddr_t va_addr(vaddr_t va)
83{
84 return va.va;
85}
86
87/**
Andrew Scull80871322018-08-06 12:04:09 +010088 * Advances a physical address.
Andrew Scull8dce4982018-08-06 13:02:20 +010089 */
Andrew Scull80871322018-08-06 12:04:09 +010090static inline paddr_t pa_add(paddr_t pa, size_t n)
Andrew Scull8dce4982018-08-06 13:02:20 +010091{
Andrew Scull80871322018-08-06 12:04:09 +010092 return pa_init(pa_addr(pa) + n);
Andrew Scull8dce4982018-08-06 13:02:20 +010093}
94
95/**
96 * Casts a physical address to a virtual address.
97 */
98static inline vaddr_t va_from_pa(paddr_t pa)
99{
100 return va_init(pa_addr(pa));
101}
102
103/**
Andrew Scull1b8d0442018-08-06 15:47:04 +0100104 * Casts a physical address to an intermediate physical address.
105 */
106static inline ipaddr_t ipa_from_pa(paddr_t pa)
107{
108 return ipa_init(pa_addr(pa));
109}
110
111/**
Andrew Scull8dce4982018-08-06 13:02:20 +0100112 * Casts a virtual address to a physical address.
113 */
114static inline paddr_t pa_from_va(vaddr_t va)
115{
116 return pa_init(va_addr(va));
117}
118
119/**
120 * Casts a pointer to a virtual address.
121 */
122static inline vaddr_t va_from_ptr(const void *p)
123{
124 return (vaddr_t){.va = (uintvaddr_t)p};
125}
126
127/**
128 * Casts a virtual address to a pointer. Only use when the virtual address is
129 * mapped for the calling context.
130 * TODO: check the mapping for a range and return a memiter?
131 */
132static inline void *ptr_from_va(vaddr_t va)
133{
134 return (void *)va_addr(va);
135}