1/**
2 * \file
3 * \brief memory object which maintains a single frame that is lazily mapped
4 */
5
6/*
7 * Copyright (c) 2009, 2010, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <barrelfish/barrelfish.h>
16#include "vspace_internal.h"
17
18/**
19 * \brief Map the memory object into a region
20 *
21 * \param memobj  The memory object
22 * \param region  The region to add
23 */
24static errval_t map_region(struct memobj *memobj, struct vregion *vregion)
25{
26    struct memobj_one_frame_lazy *lazy = (struct memobj_one_frame_lazy*)memobj;
27
28    // Allocate and insert
29    struct vregion_list *data = malloc(sizeof(struct vregion_list));
30    if (!data) {
31        return LIB_ERR_MALLOC_FAIL;
32    }
33    data->region = vregion;
34    struct vregion_list *walk = lazy->vregion_list;
35    lazy->vregion_list = data;
36    data->next = walk;
37
38    return SYS_ERR_OK;
39}
40
41/**
42 * \brief Unmap the memory object from a region
43 *
44 * \param memobj   The memory object
45 * \param region  The region to remove
46 */
47static errval_t unmap_region(struct memobj *memobj, struct vregion *vregion)
48{
49    USER_PANIC("NYI");
50
51    return SYS_ERR_OK;
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    return SYS_ERR_OK;
68}
69
70/**
71 * \brief Pin a range
72 *
73 * \param memobj  The memory object
74 * \param region  The vregion to modify the state on
75 * \param offset  Offset into the memory object
76 * \param range   The range of space to pin
77 */
78static errval_t pin(struct memobj *memobj, struct vregion *vregion,
79                    genvaddr_t offset, size_t range)
80{
81    USER_PANIC("NYI");
82    return SYS_ERR_OK;
83}
84
85/**
86 * \brief Unpin a range
87 *
88 * \param memobj  The memory object
89 * \param region  The vregion to modify the state on
90 * \param offset  Offset into the memory object
91 * \param range   The range of space to unpin
92 */
93static errval_t unpin(struct memobj *memobj, struct vregion *vregion,
94                      genvaddr_t offset, size_t range)
95{
96    USER_PANIC("NYI");
97    return SYS_ERR_OK;
98}
99
100/**
101 * \brief Page fault handler
102 *
103 * \param memobj  The memory object
104 * \param region  The associated vregion
105 * \param offset  Offset into memory object of the page fault
106 * \param type    The fault type
107 */
108static errval_t pagefault(struct memobj *memobj, struct vregion *vregion,
109                                 genvaddr_t offset, vm_fault_type_t type)
110{
111    errval_t err;
112    struct memobj_one_frame_lazy *lazy = (struct memobj_one_frame_lazy*)memobj;
113
114    struct vspace *vspace = vregion_get_vspace(vregion);
115    struct pmap *pmap     = vspace_get_pmap(vspace);
116    genvaddr_t vregion_base  = vregion_get_base_addr(vregion);
117    genvaddr_t vregion_off   = vregion_get_offset(vregion);
118    vregion_flags_t flags = vregion_get_flags(vregion);
119
120    // XXX: ugly --> need to revoke lazy->frame in order to clean up
121    //               all the copies that are created here
122    struct capref frame_copy;
123    err = slot_alloc(&frame_copy);
124    if (err_is_fail(err)) {
125        return err;
126    }
127    err = cap_copy(frame_copy, lazy->frame);
128    if (err_is_fail(err)) {
129        return err;
130    }
131
132    err = pmap->f.map(pmap, vregion_base + vregion_off + offset, frame_copy,
133                      offset, lazy->chunk_size, flags, NULL, NULL);
134    if (err_is_fail(err)) {
135        return err_push(err, LIB_ERR_PMAP_MAP);
136    }
137
138    return SYS_ERR_OK;
139}
140
141/**
142 * \brief Free up some pages by placing them in the backing storage
143 *
144 * \param memobj      The memory object
145 * \param size        The amount of space to free up
146 * \param frames      An array of capref frames to return the freed pages
147 * \param num_frames  The number of frames returned
148 *
149 * This will affect all the vregions that are associated with the object
150 */
151static errval_t pager_free(struct memobj *memobj, size_t size,
152                                  struct capref *frames, size_t num_frames)
153{
154    USER_PANIC("NYI");
155    return SYS_ERR_OK;
156}
157
158/**
159 * \brief Initialize a memory object of type one frame
160 *
161 * \param memobj  The memory object
162 * \param size    Size of the memory region
163 * \param flags   Memory object specific flags
164 * \param frame   The frame to use
165 */
166errval_t memobj_create_one_frame_lazy(struct memobj_one_frame_lazy *lazy,
167                                      size_t size, memobj_flags_t flags,
168                                      struct capref frame, size_t chunk_size)
169{
170    struct memobj *memobj = &lazy->m;
171    /* Generic portion */
172    memobj->f.map_region = map_region;
173    memobj->f.unmap_region = unmap_region;
174    memobj->f.protect = protect;
175    memobj->f.pin = pin;
176    memobj->f.unpin = unpin;
177    memobj->f.pagefault = pagefault;
178    memobj->f.pager_free = pager_free;
179
180    memobj->size  = size;
181    memobj->flags = flags;
182
183    memobj->type = ONE_FRAME_LAZY;
184
185    /* lazy specific portion */
186    lazy->vregion_list = NULL;
187    lazy->chunk_size   = chunk_size;
188    lazy->frame        = frame;
189
190    return SYS_ERR_OK;
191}
192