1/*
2 * Copyright (c) 2014, University of Washington.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich.
8 * Attn: Systems Group.
9 */
10
11#ifndef VTD_SL_PAGING_H
12#define VTD_SL_PAGING_H
13
14#include <barrelfish_kpi/types.h>
15#include <target/x86_64/barrelfish_kpi/paging_target.h>
16
17typedef uint64_t paging_sl_flags_t;
18
19#define SL_PML4_BASE(addr)         X86_64_PML4_BASE(addr)
20#define SL_PDPT_BASE(addr)         X86_64_PDPT_BASE(addr)
21#define SL_PDIR_BASE(addr)         X86_64_PDIR_BASE(addr)
22#define SL_PTABLE_BASE(addr)       X86_64_PTABLE_BASE(addr)
23
24#define SL_BASE_PAGE_SIZE          X86_64_BASE_PAGE_SIZE
25#define SL_BASE_PAGE_MASK          X86_64_BASE_PAGE_MASK
26
27#define SL_PTABLE_SIZE             X86_64_PTABLE_SIZE
28
29#define SL_PTABLE_MASK_BITS        9
30#define SL_PTABLE_CLEAR            0
31
32#define SL_PTABLE_TRANS_MAP        (((paging_sl_flags_t)1) << 62)
33#define SL_PTABLE_SNOOP            (((paging_sl_flags_t)1) << 11)
34#define SL_PTABLE_IGNORE_PAT       (((paging_sl_flags_t)1) << 6)
35#define SL_PTABLE_EXECUTE          (((paging_sl_flags_t)1) << 2)
36#define SL_PTABLE_WRITE            (((paging_sl_flags_t)1) << 1)
37#define SL_PTABLE_READ             (((paging_sl_flags_t)1) << 0)
38
39/**
40 * A second-level page directory entry.
41 */
42union sl_pdir_entry {
43    uint64_t raw;
44    struct {
45        uint64_t        read            :1;
46        uint64_t        write           :1;
47        uint64_t        execute         :1;
48        uint64_t        available       :4;
49        // Must be 0 for sl-pdpe to sl-pdt and sl-pde to sl-ptable
50        uint64_t        reserved        :1;
51        uint64_t        available2      :3;
52        uint64_t        reserved2       :1;
53        uint64_t        base_addr       :28;
54        uint64_t        reserved3       :12;
55        uint64_t        available3      :10;
56        uint64_t        reserved4       :1;
57        uint64_t        available4      :1;
58    } d;
59};
60
61/**
62 * A second-level translation page table entry.
63 */
64union sl_ptable_entry {
65    uint64_t raw;
66    struct {
67        uint64_t        read            :1;
68        uint64_t        write           :1;
69        uint64_t        execute         :1;
70        uint64_t        extend_mem_type :3;
71        uint64_t        ignore_pat      :1;
72        uint64_t        always1         :1;
73        uint64_t        available       :3;
74        uint64_t        snoop           :1;
75        uint64_t        reserved        :18;
76        uint64_t        base_addr       :10;
77        uint64_t        reserved2       :12;
78        uint64_t        available2      :10;
79        uint64_t        trans_map       :1;
80        uint64_t        available3      :1;
81    } large30;
82    struct {
83        uint64_t        read            :1;
84        uint64_t        write           :1;
85        uint64_t        execute         :1;
86        uint64_t        extend_mem_type :3;
87        uint64_t        ignore_pat      :1;
88        uint64_t        always1         :1;
89        uint64_t        available       :3;
90        uint64_t        snoop           :1;
91        uint64_t        reserved        :9;
92        uint64_t        base_addr       :19;
93        uint64_t        reserved2       :12;
94        uint64_t        available2      :10;
95        uint64_t        trans_map       :1;
96        uint64_t        available3      :1;
97    } large21;
98    struct {
99        uint64_t        read            :1;
100        uint64_t        write           :1;
101        uint64_t        execute         :1;
102        uint64_t        extend_mem_type :3;
103        uint64_t        ignore_pat      :1;
104        uint64_t        available       :4;
105        uint64_t        snoop           :1;
106        uint64_t        base_addr       :28;
107        uint64_t        reserved        :12;
108        uint64_t        available2      :10;
109        uint64_t        trans_map       :1;
110        uint64_t        available3      :1;
111    } base;
112};
113
114static inline void sl_map_table(union sl_pdir_entry *entry, genpaddr_t base)
115{
116    union sl_pdir_entry tmp;
117    tmp.raw = SL_PTABLE_CLEAR;
118
119    tmp.d.read = 1;
120    tmp.d.write = 1;
121    tmp.d.base_addr = base >> 12;
122
123    *entry = tmp;
124}
125
126static inline void sl_map(union sl_ptable_entry *entry, genpaddr_t base, uint64_t bitmap)
127{
128    union sl_ptable_entry tmp;
129    tmp.raw = SL_PTABLE_CLEAR;
130
131    tmp.base.read = bitmap & SL_PTABLE_READ ? 1 : 0;
132    tmp.base.write = bitmap & SL_PTABLE_WRITE ? 1 : 0;
133    tmp.base.execute = bitmap & SL_PTABLE_EXECUTE ? 1 : 0;
134    tmp.base.ignore_pat = bitmap & SL_PTABLE_IGNORE_PAT ? 1 : 0;
135    tmp.base.snoop = bitmap & SL_PTABLE_SNOOP ? 1 : 0;
136    tmp.base.trans_map = bitmap & SL_PTABLE_TRANS_MAP ? 1 : 0;
137    tmp.base.base_addr = base >> 12;
138
139    *entry = tmp;
140}
141
142static inline void sl_map_large21(union sl_ptable_entry *entry, genpaddr_t base, uint64_t bitmap)
143{
144    union sl_ptable_entry tmp;
145    tmp.raw = SL_PTABLE_CLEAR;
146
147    tmp.large21.read = bitmap & SL_PTABLE_READ ? 1 : 0;
148    tmp.large21.write = bitmap & SL_PTABLE_WRITE ? 1 : 0;
149    tmp.large21.execute = bitmap & SL_PTABLE_EXECUTE ? 1 : 0;
150    tmp.large21.ignore_pat = bitmap & SL_PTABLE_IGNORE_PAT ? 1 : 0;
151    tmp.large21.snoop = bitmap & SL_PTABLE_SNOOP ? 1 : 0;
152    tmp.large21.trans_map = bitmap & SL_PTABLE_TRANS_MAP ? 1 : 0;
153    tmp.large21.always1 = 1;
154    tmp.large21.base_addr = base >> 21;
155
156    *entry = tmp;
157}
158
159static inline void sl_map_large30(union sl_ptable_entry *entry, genpaddr_t base, uint64_t bitmap)
160{
161    union sl_ptable_entry tmp;
162    tmp.raw = SL_PTABLE_CLEAR;
163
164    tmp.large30.read = bitmap & SL_PTABLE_READ ? 1 : 0;
165    tmp.large30.write = bitmap & SL_PTABLE_WRITE ? 1 : 0;
166    tmp.large30.execute = bitmap & SL_PTABLE_EXECUTE ? 1 : 0;
167    tmp.large30.ignore_pat = bitmap & SL_PTABLE_IGNORE_PAT ? 1 : 0;
168    tmp.large30.snoop = bitmap & SL_PTABLE_SNOOP ? 1 : 0;
169    tmp.large30.trans_map = bitmap & SL_PTABLE_TRANS_MAP ? 1 : 0;
170    tmp.large30.always1 = 1;
171    tmp.large30.base_addr = base >> 30;
172
173    *entry = tmp;
174}
175
176#endif //VTD_SL_PAGING_H
177