/*
* Copyright (c) 2007, 2008, 2009, ETH Zurich.
+ * Copyright (c) 2014, HP Labs.
* All rights reserved.
*
* This file is distributed under the terms in the attached LICENSE file.
* If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
*/
#ifndef BARRELFISH_MORECORE_H
errval_t morecore_init(void);
void morecore_use_optimal(void);
+errval_t morecore_reinit(void);
__END_DECLS
errval_t vspace_mmu_aware_init_aligned(struct vspace_mmu_aware *state,
size_t size, size_t alignment,
vregion_flags_t flags);
+errval_t vspace_mmu_aware_reset(struct vspace_mmu_aware *state,
+ struct capref frame, size_t size);
errval_t vspace_mmu_aware_map(struct vspace_mmu_aware *state,
struct capref frame, size_t req_size,
void **retbuf, size_t *retsize);
*/
/*
- * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, ETH Zurich.
+ * Copyright (c) 2007-2012, ETH Zurich.
+ * Copyright (c) 2014, HP Labs.
* All rights reserved.
*
* This file is distributed under the terms in the attached LICENSE file.
return err_push(err, LIB_ERR_RAM_ALLOC_SET);
}
+ // switch morecore to intended configuration
+ err = morecore_reinit();
+ if (err_is_fail(err)) {
+ return err_push(err, LIB_ERR_MORECORE_INIT);
+ }
+
#ifdef CONFIG_TRACE
err = trace_my_setup();
if (err_is_fail(err)) {
return SYS_ERR_OK;
}
+
+errval_t morecore_reinit(void)
+{
+ errval_t err;
+ struct morecore_state *state = get_morecore_state();
+
+ size_t mapoffset = state->mmu_state.mapoffset;
+ size_t remapsize = ROUND_UP(mapoffset, state->mmu_state.alignment);
+ if (remapsize == mapoffset) {
+ // don't need to do anything if we only recreate the exact same
+ // mapping
+ return SYS_ERR_OK;
+ }
+ struct capref frame;
+ size_t retsize;
+ err = frame_alloc(&frame, remapsize, &retsize);
+ if (err_is_fail(err)) {
+ return err;
+ }
+ return vspace_mmu_aware_reset(&state->mmu_state, frame, remapsize);
+}
#include <barrelfish/barrelfish.h>
#include <barrelfish/vspace_mmu_aware.h>
#include <barrelfish/core_state.h>
+#include <string.h>
/// Minimum free memory before we return it to memory server
#define MIN_MEM_FOR_FREE (1 * 1024 * 1024)
return SYS_ERR_OK;
}
+errval_t vspace_mmu_aware_reset(struct vspace_mmu_aware *state,
+ struct capref frame, size_t size)
+{
+ errval_t err;
+ struct vregion *vregion;
+ struct capref oldframe;
+ void *vbuf;
+ // create copy of new region
+ err = slot_alloc(&oldframe);
+ if (err_is_fail(err)) {
+ return err;
+ }
+ err = cap_copy(oldframe, frame);
+ if (err_is_fail(err)) {
+ return err;
+ }
+ err = vspace_map_one_frame_attr_aligned(&vbuf, size, oldframe,
+ VREGION_FLAGS_READ_WRITE | VREGION_FLAGS_LARGE, LARGE_PAGE_SIZE,
+ NULL, &vregion);
+ if (err_is_fail(err)) {
+ return err;
+ }
+ // copy over data to new frame
+ genvaddr_t gen_base = vregion_get_base_addr(&state->vregion);
+ memcpy(vbuf, (void*)gen_base, state->mapoffset);
+
+ err = vregion_destroy(vregion);
+ if (err_is_fail(err)) {
+ return err;
+ }
+
+ size_t offset = 0;
+ // Unmap backing frames for [0, size) in state.vregion
+ do {
+ err = state->memobj.m.f.unfill(&state->memobj.m, 0, &oldframe,
+ &offset);
+ if (err_is_fail(err) &&
+ err_no(err) != LIB_ERR_MEMOBJ_UNFILL_TOO_HIGH_OFFSET)
+ {
+ return err_push(err, LIB_ERR_MEMOBJ_UNMAP_REGION);
+ }
+ struct frame_identity fi;
+ // increase address
+ err = invoke_frame_identify(oldframe, &fi);
+ if (err_is_fail(err)) {
+ return err;
+ }
+ offset += (1UL<<fi.bits);
+ err = cap_destroy(oldframe);
+ if (err_is_fail(err)) {
+ return err;
+ }
+ } while(offset < state->mapoffset);
+
+ // Map new frame in
+ err = state->memobj.m.f.fill(&state->memobj.m, 0, frame, size);
+ if (err_is_fail(err)) {
+ return err_push(err, LIB_ERR_MEMOBJ_FILL);
+ }
+ err = state->memobj.m.f.pagefault(&state->memobj.m, &state->vregion, 0, 0);
+ if (err_is_fail(err)) {
+ return err_push(err, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER);
+ }
+
+ state->mapoffset = size;
+ return SYS_ERR_OK;
+}
+
errval_t vspace_mmu_aware_unmap(struct vspace_mmu_aware *state,
lvaddr_t base, size_t bytes)
{