1/**
2 * \file
3 * \brief memory object that only supports pinned memory.
4 * It does not track the frames that are mapped in so they cannot be unpinned.
5 * This can only be mapped into one vregion.
6 *
7 * This memory region is used for meta data for some lists
8 * maintained by vspace and memobjs.
9 */
10
11/*
12 * Copyright (c) 2010, ETH Zurich.
13 * All rights reserved.
14 *
15 * This file is distributed under the terms in the attached LICENSE file.
16 * If you do not find this file, copies can be found by writing to:
17 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
18 */
19
20#include <barrelfish/barrelfish.h>
21#include "vspace_internal.h"
22
23/**
24 * \brief Map the memory object into a region
25 *
26 * \param memobj   The memory object
27 * \param region  The region to add
28 *
29 * Only one vregion can be mapped
30 */
31static errval_t map_region(struct memobj *memobj, struct vregion *vregion)
32{
33    struct memobj_pinned *pinned = (struct memobj_pinned*)memobj;
34
35    if (pinned->vregion) {
36        return LIB_ERR_MEMOBJ_VREGION_ALREADY_MAPPED;
37    }
38
39    pinned->vregion = vregion;
40    return SYS_ERR_OK;
41}
42
43/**
44 * \brief Unmap the memory object from a region
45 *
46 * \param memobj   The memory object
47 * \param region  The region to remove
48 */
49static errval_t unmap_region(struct memobj *memobj, struct vregion *vregion)
50{
51    USER_PANIC("NYI");
52}
53
54/**
55 * \brief Set the protection on a range
56 *
57 * \param memobj  The memory object
58 * \param region  The vregion to modify the mappings on
59 * \param offset  Offset into the memory object
60 * \param range   The range of space to set the protection for
61 * \param flags   The protection flags
62 */
63static errval_t protect(struct memobj *memobj, struct vregion *vregion,
64                        genvaddr_t offset, size_t range, vs_prot_flags_t flags)
65{
66    USER_PANIC("NYI");
67}
68
69/**
70 * \brief Pin a range
71 *
72 * \param memobj  The memory object
73 * \param region  The vregion to modify the state on
74 * \param offset  Offset into the memory object
75 * \param range   The range of space to pin
76 */
77static errval_t pin(struct memobj *memobj, struct vregion *vregion,
78                    genvaddr_t offset, size_t range)
79{
80    USER_PANIC("NYI");
81}
82
83/**
84 * \brief Unpin a range
85 *
86 * \param memobj  The memory object
87 * \param region  The vregion to modify the state on
88 * \param offset  Offset into the memory object
89 * \param range   The range of space to unpin
90 */
91static errval_t unpin(struct memobj *memobj, struct vregion *vregion,
92                      genvaddr_t offset, size_t range)
93{
94    USER_PANIC("NYI");
95}
96
97/**
98 * \brief Set a frame for an offset into the memobj
99 *
100 * \param memobj  The memory object
101 * \param offset  Offset into the memory object
102 * \param frame   The frame cap for the offset
103 * \param size    The size of frame cap
104 *
105 * Since frames are not tracked, mappings must be created on fill
106 */
107static errval_t fill(struct memobj *memobj, genvaddr_t offset, struct capref frame,
108                     size_t size)
109{
110    errval_t err;
111    struct memobj_pinned *pinned = (struct memobj_pinned*)memobj;
112
113    if (offset + size > memobj->size) {
114        return LIB_ERR_MEMOBJ_WRONG_OFFSET;
115    }
116
117    assert(pinned->vregion);
118    struct vregion *vregion = pinned->vregion;
119    struct vspace *vspace   = vregion_get_vspace(vregion);
120    struct pmap *pmap       = vspace_get_pmap(vspace);
121    genvaddr_t base            = vregion_get_base_addr(vregion);
122    genvaddr_t vregion_off     = vregion_get_offset(vregion);
123    vregion_flags_t flags   = vregion_get_flags(vregion);
124
125    err = pmap->f.map(pmap, base + vregion_off + offset, frame, 0, size, flags,
126                      NULL, NULL);
127    if (err_is_fail(err)) {
128        return err_push(err, LIB_ERR_PMAP_MAP);
129    }
130    return SYS_ERR_OK;
131}
132
133/**
134 * \brief Page fault handler
135 *
136 * \param memobj  The memory object
137 * \param region  The associated vregion
138 * \param offset  Offset into memory object of the page fault
139 * \param type    The fault type
140 */
141static errval_t pagefault(struct memobj *memobj, struct vregion *vregion,
142                          genvaddr_t offset, vm_fault_type_t type)
143{
144    USER_PANIC("NYI");
145}
146
147/**
148 * \brief Free up some pages by placing them in the backing storage
149 *
150 * \param memobj      The memory object
151 * \param size        The amount of space to free up
152 * \param frames      An array of capref frames to return the freed pages
153 * \param num_frames  The number of frames returned
154 *
155 * This will affect all the vregions that are associated with the object
156 */
157static errval_t pager_free(struct memobj *memobj, size_t size,
158                           struct capref *frames, size_t num_frames)
159{
160    USER_PANIC("NYI");
161}
162
163/**
164 * \brief Initialize a memory object of type anon
165 *
166 * \param memobj  The memory object
167 * \param size    Size of the memory region
168 * \param flags   Memory object specific flags
169 *
170 * This object handles multiple frames.
171 * The frames are mapped in on demand.
172 */
173errval_t memobj_create_pinned(struct memobj_pinned *pinned, size_t size,
174                              memobj_flags_t flags)
175{
176    struct memobj *memobj = &pinned->m;
177
178    /* Generic portion */
179    memobj->f.map_region   = map_region;
180    memobj->f.unmap_region = unmap_region;
181    memobj->f.protect      = protect;
182    memobj->f.pin          = pin;
183    memobj->f.unpin        = unpin;
184    memobj->f.fill         = fill;
185    memobj->f.pagefault    = pagefault;
186    memobj->f.pager_free   = pager_free;
187
188    memobj->size  = size;
189    memobj->flags = flags;
190
191    memobj->type = PINNED;
192
193    /* pinned specific portion */
194    pinned->vregion = NULL;
195    return SYS_ERR_OK;
196}
197