Exemple #1
0
static int cd(int argc, char *argv[])
{
    errval_t err;

    if (argc != 2) {
        printf("Usage: %s DIR\n", argv[0]);
        return 1;
    }

    char *newcwd = vfs_path_mkabsolute(cwd, argv[1]);

    // ensure directory exists, by attempting to open it
    vfs_handle_t dh;
    err = vfs_opendir(newcwd, &dh);
    if (err_is_fail(err)) {
        printf("cd to %s (-> %s) failed: %s\n",
               argv[1], newcwd, err_getstring(err));
        free(newcwd);
        return 1;
    }
    vfs_closedir(dh);

    // ok!
    free(cwd);
    cwd = newcwd;

    return 0;
}
static void memcpy_req_cb(errval_t err,
                          dma_req_id_t id,
                          void *st)
{
    XDMA_DEBUG("memcpy_req_cb %lx, %s\n", id, err_getstring(err));
    dma_service_send_done(st, err, id);
}
static void
cap_send_request_tx_cont(errval_t err, struct captx_prepare_state *captx_st,
                         intermon_captx_t *captx, void *st_)
{
    DEBUG_CAPOPS("%s: %s [%p]\n", __FUNCTION__, err_getstring(err), __builtin_return_address(0));
    errval_t queue_err;
    struct send_cap_st *send_st = (struct send_cap_st*)st_;

    if (err_is_fail(err)) {
        // XXX: should forward error here
        DEBUG_ERR(err, "preparing cap tx failed");
        free(send_st);
        return;
    }

    send_st->captx = *captx;

    DEBUG_CAPOPS("%s: enqueueing send\n", __FUNCTION__);
    send_st->qe.cont = cap_send_tx_cont;
    struct remote_conn_state *conn = remote_conn_lookup(send_st->my_mon_id);
    struct intermon_binding *binding = conn->mon_binding;
    struct intermon_state *inter_st = (struct intermon_state*)binding->st;
    queue_err = intermon_enqueue_send(binding, &inter_st->queue,
                                      binding->waitset,
                                      (struct msg_queue_elem*)send_st);
    if (err_is_fail(queue_err)) {
        DEBUG_ERR(queue_err, "enqueuing cap_send_request failed");
        free(send_st);
    }
}
Exemple #4
0
static int touch(int argc, char *argv[])
{
    if(argc < 2) {
        printf("Usage: %s [file...]\n", argv[0]);
        return 1;
    }

    vfs_handle_t vh;
    errval_t err;
    int ret = 0;

    for (int i = 1; i < argc; i++) {
        char *path = vfs_path_mkabsolute(cwd, argv[i]);
        err = vfs_create(path, &vh);
        free(path);
        if (err_is_fail(err)) {
            printf("%s: %s\n", argv[i], err_getstring(err));
            DEBUG_ERR(err, "vfs_create failed");
            ret = 1;
            continue;
        }

        err = vfs_close(vh);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

    return ret;
}
errval_t blockdevfs_ata_flush(void *handle)
{
    struct ata_handle *h = handle;
    errval_t err, status;
    err = h->ata_rw28_rpc.vtbl.flush_cache(&h->ata_rw28_rpc, &status);
    if (err_is_fail(err)) {
        printf("failed calling flush_cache\n");
        return err;
    }
    VFS_BLK_DEBUG("status: %s\n", err_getstring(status));
    return err;
}
Exemple #6
0
static int execute_program(coreid_t coreid, int argc, char *argv[],
                           domainid_t *retdomainid)
{
    vfs_handle_t vh;
    errval_t err;

    // if the name contains a directory separator, assume it is relative to PWD
    char *prog = argv[0];
    if (strchr(argv[0], VFS_PATH_SEP) != NULL) {
        prog = vfs_path_mkabsolute(cwd, argv[0]);

        // check it exists
        err = vfs_open(prog, &vh);
        if (err_is_fail(err)) {
            printf("%s: file not found: %s\n", prog, err_getstring(err));
            free(prog);
            return -1;
        }
        vfs_close(vh);
    }

    assert(retdomainid != NULL);

    argv[argc] = NULL;
    err = spawn_program(coreid, prog, argv, NULL, SPAWN_NEW_DOMAIN,
                        retdomainid);

    if (prog != argv[0]) {
        free(prog);
    }

    if (err_is_fail(err)) {
        printf("%s: error spawning: %s\n", argv[0], err_getstring(err));
        DEBUG_ERR(err, "Spawning Error\n");
        return -1;
    }

    return 0;
}
/**
 * \brief XOMP channel connect callback called by the Flounder backend
 *
 * \param st    Supplied worker state
 * \param err   outcome of the connect attempt
 * \param xb    XOMP Flounder binding
 */
static void master_bind_cb(void *st,
                           errval_t err,
                           struct xomp_binding *xb)
{
    XWI_DEBUG("bound to master: %s\n", err_getstring(err));

    txq_init(&txq, xb, xb->waitset, (txq_register_fn_t) xb->register_send,
             sizeof(struct xomp_msg_st));

    xb->rx_vtbl = rx_vtbl;
    xbinding = xb;

    is_bound = 0x1;
}
static void ahci_init_cb(void *st, errval_t err, struct ahci_binding *binding)
{
    struct ahci_handle *h = st;

    if (err_is_fail(err)) {
        printf("ahci_init_cb returned '%s'\n", err_getstring(err));
        h->wait_status = err;
        h->waiting = false;
        return;
    }

    h->binding = binding;
    binding->st = h;
    h->waiting = false;
}
errval_t blockdevfs_ahci_close(void *handle)
{
    struct ahci_handle *h = handle;
    h->waiting = true;
    errval_t err = ahci_close(h->binding, MKCLOSURE(ahci_close_cb, h));
    if (err_is_fail(err)) {
        printf("ahci_init failed: '%s'\n", err_getstring(err));
        h->waiting = false;
        return err;
    }
    while (h->waiting) {
        messages_wait_and_handle_next();
    }
    return SYS_ERR_OK;
}
Exemple #10
0
static int rmdir(int argc, char *argv[])
{
    if(argc != 2) {
        printf("Usage: %s dir\n", argv[0]);
        return 1;
    }

    char *path = vfs_path_mkabsolute(cwd, argv[1]);
    errval_t err = vfs_rmdir(path);
    free(path);
    if (err_is_fail(err)) {
        printf("%s\n", err_getstring(err));
        return 1;
    } else {
        return 0;
    }
}
Exemple #11
0
static void pci_dev_init_manager(struct device_mem *bar_info,
                                 int nr_mapped_bars)
{
    errval_t err;

    DEV_DEBUG("Initialize device @ [%016lx] with %u bars\n", bar_info->paddr,
              nr_mapped_bars);

    if (nr_mapped_bars != 1) {
        DEV_ERR("number of mapped bars is wrong. Skipping initialization\n");
        return;
    }

    err = ioat_mgr_svc_add_device(bar_info->frame_cap);
    if (err_is_fail(err)) {
        DEV_ERR("Device coult not be added to the manager: %s\n",
                err_getstring(err));
    }
}
Exemple #12
0
static int rm(int argc, char *argv[])
{
    if(argc < 2) {
        printf("Usage: %s file...\n", argv[0]);
        return 1;
    }

    int ret = 0;

    for (int i = 1; i < argc; i++) {
        char *path = vfs_path_mkabsolute(cwd, argv[i]);
        errval_t err = vfs_remove(path);
        free(path);
        if (err_is_fail(err)) {
            printf("%s: %s\n", argv[i], err_getstring(err));
            ret = 1;
        }
    }

    return ret;
}
Exemple #13
0
static void pci_dev_init_service(struct device_mem *bar_info,
                                 int nr_mapped_bars)
{
    errval_t err;

    DEV_DEBUG("Initialize device @ [%016lx] with %u bars\n", bar_info->paddr,
              nr_mapped_bars);

    if (nr_mapped_bars != 1) {
        DEV_ERR("number of mapped bars is wrong. Skipping initialization\n");
        return;
    }

    /* initialize the device */
    err = ioat_dma_device_init(*bar_info->frame_cap, &devices[device_count]);
    if (err_is_fail(err)) {
        DEV_ERR("Could not initialize the device: %s\n", err_getstring(err));
        return;
    }

    device_count++;
}
errval_t blockdevfs_ata_open(void *handle)
{
    VFS_BLK_DEBUG("blockdevfs_ata_open: entering\n");
    errval_t err;
    struct ata_handle *h = handle;

    h->wait_status = SYS_ERR_OK;
    h->waiting = true;

    err = ahci_init(h->port_num, ahci_init_cb, h, get_default_waitset());
    if (err_is_fail(err)) {
        printf("ahci_init failed: '%s'\n", err_getstring(err));
        h->waiting = false;
        return err;
    }

    // XXX: block for command completion (broken API!)
    while (h->waiting) {
        err = event_dispatch(get_default_waitset());
        if (err_is_fail(err)) {
            USER_PANIC_ERR(err, "error in event_dispatch for blockdevfs_ata_open");
        }
    }

    struct ahci_ata_rw28_binding *ahci_ata_rw28_binding;
    ahci_ata_rw28_binding = calloc(1, sizeof(struct ahci_ata_rw28_binding));
    ahci_ata_rw28_init(ahci_ata_rw28_binding, get_default_waitset(), h->ahci_binding);
    h->ata_rw28_binding = (struct ata_rw28_binding*)ahci_ata_rw28_binding;
    err = ata_rw28_rpc_client_init(&h->ata_rw28_rpc, h->ata_rw28_binding);
    if (err_is_fail(err)) {
        // TODO: bindings leak
        VFS_BLK_DEBUG("blockdevfs_ata_open: failed to init ata_rw28 rpc client\n");
        return err;
    }
    VFS_BLK_DEBUG("blockdevfs_ata_open: exiting\n");
    return h->wait_status;
}
errval_t blockdevfs_ahci_open(void *handle)
{
    VFS_BLK_DEBUG("blockdevfs_ahci_open: entering\n");
    errval_t err;
    struct ahci_handle *h = handle;

    h->wait_status = SYS_ERR_OK;
    h->waiting = true;

    err = ahci_init(h->port_num, ahci_init_cb, h, get_default_waitset());
    if (err_is_fail(err)) {
        printf("ahci_init failed: '%s'\n", err_getstring(err));
        h->waiting = false;
        return err;
    }

    // XXX: block for command completion (broken API!)
    while (h->waiting) {
        messages_wait_and_handle_next();
    }

    VFS_BLK_DEBUG("blockdevfs_ahci_open: exiting\n");
    return h->wait_status;
}
Exemple #16
0
static int
rand_bench_time(char *target, uint8_t *buffer, size_t filesize, size_t blocksize, size_t count, size_t randval, struct bench_res *result)
{
    size_t randbit;

    size_t rsize = 0;
    size_t wsize = 0;

    int ret = 0;


#define RAND_NEXT do {\
    randbit = ((randval >> 0) ^ (randval >> 3)) & 1;\
    randval = (randval >> 1) | (randbit << (sizeof(size_t) * CHAR_BIT - 1));\
} while (0)

#define RAND_BLOCK ((randval % (filesize / blocksize)) * blocksize)

    if (filesize % blocksize != 0) {
        printf("Please spcifiy the filesize as a multiple of blocksize\n");
        return 0;
    }

    errval_t err;
    vfs_handle_t f = NULL;
    char *path = vfs_path_mkabsolute(cwd, target);
    err = vfs_open(path, &f);

    if (err_is_fail(err)) {
        printf("%s: %s\n", path, err_getstring(err));
        return 1;
    }

#if defined(__x86_64__) || defined(__i386__)
    uint64_t tscperms;
    err = sys_debug_get_tsc_per_ms(&tscperms);
    assert(err_is_ok(err));

    //printf("ticks per millisec: %" PRIu64 "\n", tscperms);
    uint64_t start = rdtsc();
#endif

    size_t count2 = count;
    while (count2--) {
        RAND_NEXT;
        vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK);

        err = vfs_read(f, buffer, blocksize, &rsize);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "error reading file");
            ret = 1;
            goto out;
        }

        assert(rsize == blocksize);
    }
#if defined(__x86_64__) || defined(__i386__)
    uint64_t stop = rdtsc();
    uint64_t elapsed_msecs = ((stop - start) / tscperms);
    double elapsed_secs = (double)elapsed_msecs/1000.0;

    result->read = elapsed_secs;

    start = rdtsc();
#endif

    count2 = count;
    while(count2--) {
        RAND_NEXT;
        vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK);

        err = vfs_write(f, buffer, blocksize, &wsize);
        if (err_is_fail(err) || wsize == 0) {
            DEBUG_ERR(err, "error writing file");
            ret = 1;
            goto out;
        }

        assert(wsize == blocksize);
        vfs_flush(f);
    }

#if defined(__x86_64__) || defined(__i386__)
    stop = rdtsc();
    elapsed_msecs = ((stop - start) / tscperms);
    elapsed_secs = (double)elapsed_msecs/1000.0;

    result->write = elapsed_secs;
#endif

out:
    if (f != NULL) {
        err = vfs_close(f);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

    return ret;
}
Exemple #17
0
static double
dd_bench(char *source, char *target, size_t blocksize, size_t count)
{
    vfs_handle_t source_vh = NULL;
    vfs_handle_t target_vh = NULL;

    size_t blocks_written = 0;

    size_t total_bytes_read = 0;
    size_t total_bytes_written = 0;

    errval_t err;
    double ret = 0;
    double kbps = 0.0;

    err = vfs_open(source, &source_vh);
    if (err_is_fail(err)) {
        printf("%s: %s (%ld)\n", source, err_getstring(err), err);
        return -1;
    }

    err = vfs_create(target, &target_vh);
    if (err_is_fail(err)) {
        // close source handle
        if (source_vh != NULL)
            vfs_close(source_vh);
        printf("%s: %s (%ld)\n", target, err_getstring(err), err);
        return -1;
    }

    uint8_t *buffer = malloc(blocksize);

#if defined(__x86_64__) || defined(__i386__)
    uint64_t tscperms;
    err = sys_debug_get_tsc_per_ms(&tscperms);
    assert(err_is_ok(err));

    uint64_t start = rdtsc();
#endif

    if (buffer == NULL) {
        ret = -2;
        printf("failed to allocate buffer of size %zd\n", blocksize);
        goto out;
    }

    size_t rsize, wsize;
    do {
        err = vfs_read(source_vh, buffer, blocksize, &rsize);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "error reading file");
            ret = -1;
            goto out;
        }

        total_bytes_read += rsize;

        size_t wpos = 0;
        while (wpos < rsize) {
            if (wpos > 0)
                printf("was unable to write the whole chunk of size %zd. Now at pos: %zd of buffer\n", rsize, wpos);

            err = vfs_write(target_vh, &buffer[wpos], rsize - wpos, &wsize);
            if (err_is_fail(err) || wsize == 0) {
                DEBUG_ERR(err, "error writing file");
                ret = -1;
                goto out;
            }
            wpos += wsize;
            total_bytes_written += wsize;
        }

        blocks_written++;

    } while (rsize > 0 && !(count > 0 && blocks_written >= count));

out:
    if (buffer != NULL)
        free(buffer);

    if (source_vh != NULL) {
        err = vfs_close(source_vh);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

    if (target_vh != NULL) {
        err = vfs_close(target_vh);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

#if defined(__x86_64__) || defined(__i386__)
    uint64_t stop = rdtsc();
    uint64_t elapsed_msecs = ((stop - start) / tscperms);
    double elapsed_secs = (double)elapsed_msecs/1000.0;

    kbps = ((double)total_bytes_written / 1024.0) / elapsed_secs;

    if (ret == 0)
        return kbps;
    else
        return ret;
#else
    return ret;
#endif
}
Exemple #18
0
static int
shuffle_file(int argc, char *argv[])
{
    if (argc != 6) {
        printf("Usage: %s <file> <filesize> <blocksize> <count> <seed>\n", argv[0]);

        return 0;
    }

    size_t filesize = atoi(argv[2]);
    size_t blocksize = atoi(argv[3]);
    size_t count = atoi(argv[4]);
    size_t randval = atoi(argv[5]);
    size_t randbit;
    char * filename = argv[1];

    size_t rsize = 0;
    size_t wsize = 0;

    int ret = 0;


#define RAND_NEXT do {\
    randbit = ((randval >> 0) ^ (randval >> 3)) & 1;\
    randval = (randval >> 1) | (randbit << (sizeof(size_t) * CHAR_BIT - 1));\
} while (0)

#define RAND_BLOCK ((randval % (filesize / blocksize)) * blocksize)

    if (filesize % blocksize != 0) {
        printf("Please spcifiy the filesize as a multiple of blocksize\n");
        return 0;
    }

    uint8_t * buffer = malloc(blocksize);
    
    if (buffer == NULL) {
        printf("failed to allocate buffer of size %zd\n", blocksize);
        return 1;
    }

    errval_t err;
    vfs_handle_t f = NULL;
    char *path = vfs_path_mkabsolute(cwd, filename);
    err = vfs_open(path, &f);

    if (err_is_fail(err)) {
        printf("%s: %s\n", path, err_getstring(err));
        return 1;
    }

#if defined(__x86_64__) || defined(__i386__)
    uint64_t tscperms;
    err = sys_debug_get_tsc_per_ms(&tscperms);
    assert(err_is_ok(err));

    //printf("ticks per millisec: %" PRIu64 "\n", tscperms);
    uint64_t start = rdtsc();
#endif

    size_t count2 = count;
    while (count2--) {
        RAND_NEXT;
        vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK);
        
        err = vfs_read(f, buffer, blocksize, &rsize);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "error reading file");
            ret = 1;
            goto out;
        }

        assert(rsize == blocksize);

        RAND_NEXT;
        vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK);

        err = vfs_write(f, buffer, blocksize, &wsize);
        if (err_is_fail(err) || wsize == 0) {
            DEBUG_ERR(err, "error writing file");
            ret = 1;
            goto out;
        }

        assert(wsize == blocksize);
    }

#if defined(__x86_64__) || defined(__i386__)
    uint64_t stop = rdtsc();
    uint64_t elapsed_msecs = ((stop - start) / tscperms);
    double elapsed_secs = (double)elapsed_msecs/1000.0;

    printf("start: %" PRIu64 " stop: %" PRIu64 "\n", start, stop);

    double kbps = ((double)(count * blocksize) / 1024.0) / elapsed_secs;

    printf("%zu bytes read. %zu bytes written. %f s, %f kB/s\n", count * blocksize, count * blocksize, elapsed_secs, kbps); 
#endif

out:
    if (buffer != NULL)
        free(buffer);
    
    if (f != NULL) {
        err = vfs_close(f);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

    return ret;
}
Exemple #19
0
static errval_t
fill_bench(char *target, uint8_t *buffer, size_t blocksize, size_t count, struct bench_res *result)
{
    vfs_handle_t target_vh = NULL;

    size_t blocks_written = 0;
    size_t blocks_read = 0;

    size_t total_bytes_read = 0;
    size_t total_bytes_written = 0;

    uint64_t start = 0, stop = 0;
    errval_t err;

#if defined(__x86_64__) || defined(__i386__)
    uint64_t tscperms;
    err = sys_debug_get_tsc_per_ms(&tscperms);
    assert(err_is_ok(err));
#endif

    errval_t ret = 0;

    err = vfs_open(target, &target_vh);
    if (err_is_fail(err)) {
        printf("%s: %s (%ld)\n", target, err_getstring(err), err);
        return err;
    }

#if defined(__x86_64__) || defined(__i386__)
    start = rdtsc();
#endif

    if (buffer == NULL) {
        ret = -2;
        printf("failed to allocate buffer of size %zd\n", blocksize);
        goto out;
    }

    size_t wsize;
    do {
        // initialize buffer
        for (size_t i = 0; i < blocksize; i += sizeof(size_t))
            *((size_t *)(buffer + i)) = blocks_written;

        // write to file
        size_t wpos = 0;
        while (wpos < blocksize) {
            if (wpos > 0)
                printf("was unable to write the whole chunk of size %zd. Now at pos: %zd of buffer\n", blocksize, wpos);

            err = vfs_write(target_vh, &buffer[wpos], blocksize - wpos, &wsize);
            if (err_is_fail(err) || wsize == 0) {
                DEBUG_ERR(err, "error writing file");
                ret = err;
                goto out;
            }
            wpos += wsize;
            total_bytes_written += wsize;
        }

        blocks_written++;

    } while (blocksize > 0 && !(count > 0 && blocks_written >= count));

    err = vfs_close(target_vh);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "in vfs_close");
        goto out;
    }


#if defined(__x86_64__) || defined(__i386__)
    stop = rdtsc();
    {
        uint64_t elapsed_msecs = ((stop - start) / tscperms);
        double elapsed_secs = (double)elapsed_msecs/1000.0;

        result->write = ((double)total_bytes_written / 1024.0) / elapsed_secs;
	printf("%lf\n", result->write);
    }

#endif
    err = vfs_open(target, &target_vh);
    if (err_is_fail(err)) {
        printf("%s: %s (%ld)\n", target, err_getstring(err), err);
        goto out;
    }
    err = vfs_seek(target_vh, VFS_SEEK_SET, 0);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "seeking failed");
        ret = err;
        goto out;
    }
#if defined(__x86_64__) || defined(__i386__)
    start = rdtsc();
#endif

    size_t rsize;
    do {
        // read
        size_t rpos = 0;
        while (rpos < blocksize) {
            if (rpos > 0)
                printf("was unable to read whole chunk of size %zd. Now at pos: %zd of buffer\n", blocksize, rpos);

            err = vfs_read(target_vh, &buffer[rpos], blocksize - rpos, &rsize);
            if (err_is_fail(err) || wsize == 0) {
                DEBUG_ERR(err, "error reading file");
                ret = err;
                goto out;
            }
            rpos += rsize;
            total_bytes_read += rsize;
        }

        // verify data
        for (size_t i = 0; i < blocksize; i += sizeof(size_t)) {
            if (*((size_t *)(buffer + i)) != blocks_read) {
                printf("Verification failed! Block %zd, value %zd\n", blocks_read, *((size_t *)(buffer + i)) );
                ret = err;
                goto out;
            }
        }

        blocks_read++;
    } while (blocksize > 0 && !(count > 0 && blocks_read >= count));

out:
    if (target_vh != NULL) {
        err = vfs_close(target_vh);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
            ret = err;
        }
    }

#if defined(__x86_64__) || defined(__i386__)
    stop = rdtsc();
    {
        uint64_t elapsed_msecs = ((stop - start) / tscperms);
        double elapsed_secs = (double)elapsed_msecs/1000.0;

        result->read = ((double)total_bytes_read / 1024.0) / elapsed_secs;
	printf("%lf\n", result->read);
    }
#endif

    return ret;
}
Exemple #20
0
void remove_empty_vnodes(struct pmap_x86 *pmap, struct vnode *root,
                         uint32_t entry, size_t len)
{
    errval_t err;
    uint32_t end_entry = entry + len;
    for (struct vnode *n = root->u.vnode.children; n; n = n->next) {
        if (n->entry >= entry && n->entry < end_entry) {
            // sanity check and skip leaf entries
            if (!n->is_vnode) {
                continue;
            }
            // here we know that all vnodes we're interested in are
            // page tables
            assert(n->is_vnode);
            if (n->u.vnode.children) {
                remove_empty_vnodes(pmap, n, 0, PTABLE_SIZE);
            }

            // unmap
            err = vnode_unmap(root->u.vnode.cap, n->mapping);
            if (err_is_fail(err)) {
                debug_printf("remove_empty_vnodes: vnode_unmap: %s\n",
                        err_getstring(err));
            }

            // delete mapping cap first: underlying cap needs to exist for
            // this to work properly!
            err = cap_delete(n->mapping);
            if (err_is_fail(err)) {
                debug_printf("remove_empty_vnodes: cap_delete (mapping): %s\n",
                        err_getstring(err));
            }
            err = pmap->p.slot_alloc->free(pmap->p.slot_alloc, n->mapping);
            if (err_is_fail(err)) {
                debug_printf("remove_empty_vnodes: slot_free (mapping): %s\n",
                        err_getstring(err));
            }
            // delete capability
            err = cap_delete(n->u.vnode.cap);
            if (err_is_fail(err)) {
                debug_printf("remove_empty_vnodes: cap_delete (vnode): %s\n",
                        err_getstring(err));
            }
            if (!capcmp(n->u.vnode.cap, n->u.vnode.invokable)) {
                // invokable is always allocated in our cspace
                err = cap_destroy(n->u.vnode.invokable);
                if (err_is_fail(err)) {
                    debug_printf("remove_empty_vnodes: cap_delete (vnode.invokable): %s\n",
                        err_getstring(err));

                }
            }
            err = pmap->p.slot_alloc->free(pmap->p.slot_alloc, n->u.vnode.cap);
            if (err_is_fail(err)) {
                debug_printf("remove_empty_vnodes: slot_free (vnode): %s\n",
                        err_getstring(err));
            }

            // remove vnode from list
            remove_vnode(root, n);
            slab_free(&pmap->slab, n);
        }
    }
}
Exemple #21
0
static int cp(int argc, char *argv[])
{
    if(argc != 3) {
        printf("Usage: %s src dest\n", argv[0]);
        return 1;
    }

    static uint8_t buf[32768];
    size_t rsize, wsize;
    vfs_handle_t src = NULL, dst = NULL;
    errval_t err;
    int ret = 0;

    char *path = vfs_path_mkabsolute(cwd, argv[1]);
    err = vfs_open(path, &src);
    free(path);
    if (err_is_fail(err)) {
        printf("%s: %s\n", argv[1], err_getstring(err));
        return 1;
    }

    path = vfs_path_mkabsolute(cwd, argv[2]);
    err = vfs_create(path, &dst);
    free(path);
    if (err_is_fail(err)) {
        printf("%s: %s\n", argv[2], err_getstring(err));
        ret = 1;
        goto out;
    }

    err = vfs_truncate(dst, 0);
    if (err_is_fail(err)) {
        printf("truncate %s: %s\n", argv[2], err_getstring(err));
        ret = 1;
        goto out;
    }

    do {
        err = vfs_read(src, buf, sizeof(buf), &rsize);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "error reading file");
            ret = 1;
            goto out;
        }

        size_t wpos = 0;
        while (wpos < rsize) {
            err = vfs_write(dst, &buf[wpos], rsize - wpos, &wsize);
            if (err_is_fail(err) || wsize == 0) {
                DEBUG_ERR(err, "error writing file");
                ret = 1;
                goto out;
            }
            wpos += wsize;
        }
    } while(rsize > 0);

out:
    if (src != NULL) {
        err = vfs_close(src);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

    if (dst != NULL) {
        err = vfs_close(dst);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

    return ret;
}
Exemple #22
0
int main (int argc, char *argv[])
{
    errval_t err;
    char *cardName = NULL;

    const char *imagefile = IMAGEFILE;

    vfs_init();
    
    err = timer_init();
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "error initialising timer client library\n");
    }

    if (argc < 3) {
        printf("Usage: %s <Network card Name> <vfs mount URI> [disk image path]\n",
               argv[0]);
        printf("<Network card Name> value is ignored in this version\n");
        return 1;
    }

    if(argc > 3) {
        imagefile = argv[3];
    }

    cardName = argv[1];
    printf("vmkitmon: start\n");
    printf("Ignoring the cardname [%s], and using the default one from vfs_mount\n",
            cardName);
    vfs_mkdir(VFS_MOUNTPOINT);
    err = vfs_mount(VFS_MOUNTPOINT, argv[2]);
    if (err_is_fail(err)) {
        printf("vmkitmon: error mounting %s: %s\n", argv[2], err_getstring(err));
        return 1;
    }

    /* Initialization */
    err = realmode_init();
    assert_err(err, "realmode_init");
    // fetch all relevant multiboot data
    //load_multiboot_files();

    // aquire the standard input
#if 1
    err = terminal_want_stdin(TERMINAL_SOURCE_SERIAL);
    assert_err(err, "terminal_want_stdin");
#endif

    // load files
    // FIXME: use a dynamic way to specify those arguments
    printf("Loading file [%s]\n", GRUB_IMG_PATH);
    vfs_load_file_to_memory(GRUB_IMG_PATH, &grub_image, &grub_image_size);
    printf("Loading file [%s]\n", imagefile);
    vfs_load_file_to_memory(imagefile, &hdd0_image, &hdd0_image_size);
    printf("Done with file loading\n");

    /* Guest execution */
    // perform some sanity checks
    if (grub_image == NULL) {
        printf("vmkitmon: no grub image available, abort\n");
        return 1;
    }

    guest = guest_create ();
    assert(guest != NULL);
    err = guest_make_runnable(guest, true);
    assert_err(err, "guest_make_runnable");

    printf("vmkitmon: end\n");

    messages_handler_loop();
}
int invalid_mappings(void)
{
    // outline:
    // get pml4, pdpt, pdir, ptable, and frame
    // check all combinations to make sure that restrictions are implemented
    // correctly in kernel space
    // VALID:
    // map pdpt in pml4
    // map pdir in pdpt
    // map pt   in pdir
    // map frame in {pt, pdir, pdpt}
    // INVALID:
    // all other combinations

    errval_t err;
    struct capref caps[7];
    struct capref mapping;

    // allocate slot for mapping cap: can reuse`
    err = slot_alloc(&mapping);
    if (err_is_fail(err)) {
        debug_printf("slot_alloc: %s (%ld)\n", err_getstring(err), err);
        return 1;
    }

    // allocate caps
    for (int i = 0; i < 5; i++) {
        // get 4k block
        struct capref mem;
        err = ram_alloc(&mem, BASE_PAGE_BITS);
        if (err_is_fail(err)) {
            debug_printf("ram_alloc: %s (%ld)\n", err_getstring(err), err);
            return 1;
        }

        // get slot for retype dest
        err = slot_alloc(&caps[i]);
        if (err_is_fail(err)) {
            debug_printf("slot_alloc: %s (%ld)\n", err_getstring(err), err);
            return 1;
        }
        // retype to selected type
        err = cap_retype(caps[i], mem, types[i], BASE_PAGE_BITS);
        if (err_is_fail(err)) {
            debug_printf("cap_retype: %s (%ld)\n", err_getstring(err), err);
            return 1;
        }

        // cleanup source cap
        DEBUG_INVALID_MAPPINGS("delete ram cap\n");
        err = cap_destroy(mem);
        if (err_is_fail(err)) {
            debug_printf("cap_delete(mem): %s (%ld)\n", err_getstring(err), err);
            return 1;
        }
    }
    // cap 6: 2M frame
    size_t rb = 0;
    err = frame_alloc(&caps[5], X86_64_LARGE_PAGE_SIZE, &rb);
    if (err_is_fail(err) || rb != X86_64_LARGE_PAGE_SIZE) {
        debug_printf("frame_alloc: %s (%ld)\n", err_getstring(err), err);
        return 1;
    }
    // cap 7: 1G frame
    err = frame_alloc(&caps[6], X86_64_HUGE_PAGE_SIZE, &rb);
    if (err_is_fail(err) || rb != X86_64_HUGE_PAGE_SIZE) {
        debug_printf("frame_alloc: %s (%ld)\n", err_getstring(err), err);
        return 1;
    }

    paging_x86_64_flags_t attr = 0;
    // select dest (ignore frame, asserts)
    for (int i = 0; i < 4; i++) {
        // select source
        for (int j = 0; j < 7; j++) {
            if (j >= 4) {
                // frame
                attr = FRAME_ACCESS_DEFAULT;
            } else {
                // ptable
                attr = PTABLE_ACCESS_DEFAULT;
            }
            // try mapping
            err = vnode_map(caps[i], caps[j], /*slot*/0, attr, /*off*/0,
                            /*count*/1, mapping);
            check_result(err, i, j);
            // unmap if mapping succeeded
            if (err_is_ok(err)) {
                err = vnode_unmap(caps[i], mapping);
                if (err_is_fail(err)) {
                    DEBUG_ERR(err, "vnode_unmap");
                }
                assert(err_is_ok(err));
                // XXX: better API?
                err = cap_delete(mapping);
                assert(err_is_ok(err));
            }
        }
    }

    printf("All tests executed: %d PASSED, %d FAILED\n", pass, fail);

    return 0;
}
Exemple #24
0
static void impl_test(void)
{
    errval_t err;

    debug_printf("Doing an implementation test\n");

    struct capref frame;
    err = frame_alloc(&frame, 2 * BUFFER_SIZE, NULL);
    assert(err_is_ok(err));

    struct frame_identity id;
    err = invoke_frame_identify(frame, &id);
    assert(err_is_ok(err));

    void *buf;
    err = vspace_map_one_frame(&buf, 1UL << id.bits, frame, NULL, NULL);
    assert(err_is_ok(err));

    memset(buf, 0, 1UL << id.bits);
    memset(buf, 0xA5, BUFFER_SIZE);

    struct ioat_dma_req_setup setup = {
        .type = IOAT_DMA_REQ_TYPE_MEMCPY,
        .src = id.base,
        .dst = id.base + BUFFER_SIZE,
        .bytes = BUFFER_SIZE,
        .done_cb = impl_test_cb,
        .arg = buf
    };
    int reps = 10;
    do {
        debug_printf("!!!!!! NEW ROUND\n");
        err = ioat_dma_request_memcpy(dma_ctrl.devices, &setup);
        assert(err_is_ok(err));

        uint32_t i = 10;
        while(i--) {
            ioat_dma_device_poll_channels(dma_ctrl.devices);
        }
    }while(reps--);
}
#endif

int main(int argc,
         char *argv[])
{
    errval_t err;

    debug_printf("I/O AT DMA driver started\n");

    /*
     * Parsing of cmdline arguments.
     *
     * When started by Kaluga, the last element of the cmdline will contain
     * the basic PCI information of the device.
     * VENDORID:DEVICEID:BUS:DEV:FUN
     */
    uint32_t vendor_id, device_id;

    struct pci_addr addr = {
        .bus = PCI_ADDR_DONT_CARE,
        .device = PCI_ADDR_DONT_CARE,
        .device = PCI_ADDR_DONT_CARE
    };

    enum device_type devtype = IOAT_DEVICE_INVAL;

    if (argc > 1) {
        uint32_t parsed = sscanf(argv[argc - 1], "%x:%x:%x:%x:%x", &vendor_id,
                                 &device_id, &addr.bus, &addr.device,
                                 &addr.function);
        if (parsed != 5) {
            DEBUGPRINT("WARNING: cmdline parsing failed. Using PCI Address [0,0,0]");
        } else {
            if (vendor_id != 0x8086) {
                USER_PANIC("unexpected vendor [%x]", vendor_id);
            }
            switch ((device_id & 0xFFF0)) {
                case PCI_DEVICE_IOAT_IVB0:
                    devtype = IOAT_DEVICE_IVB;
                    break;
                case PCI_DEVICE_IOAT_HSW0:
                    devtype = IOAT_DEVICE_HSW;
                    break;
                default:
                    USER_PANIC("unexpected device [%x]", device_id)
                    ;
                    break;
            }

            DEBUGPRINT("Initializing I/O AT DMA device with PCI address [%u,%u,%u]\n",
                       addr.bus, addr.device, addr.function);
        }
    } else {
        DEBUGPRINT("WARNING: Initializing I/O AT DMA device with unknown PCI address "
                   "[0,0,0]\n");
    }

    err = ioat_device_discovery(addr, devtype, IOAT_DMA_OPERATION);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "DMA Device discovery failed");
    }

#if DMA_BENCH_RUN_BENCHMARK
    struct ioat_dma_device *dev = ioat_device_get_next();
    dma_bench_run_default(dev);
#endif

#if IOAT_DMA_OPERATION == IOAT_DMA_OPERATION_SERVICE

    iref_t svc_iref;
    char svc_name[30];
    uint8_t numa_node = (disp_get_core_id() >= 20);
    snprintf(svc_name, 30, "%s.%u", IOAT_DMA_SERVICE_NAME, numa_node);
    err = dma_service_init_with_name(svc_name, &dma_svc_cb, NULL, &svc_iref);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Failed to start the DMA service");
    }

    err = dma_manager_register_driver(0, 1ULL << 40, DMA_DEV_TYPE_IOAT, svc_iref);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Failed to register with the DMA manager\n");
    }

    DEBUGPRINT("Driver registered with DMA manager. Serving requests now.\n");

#endif

#if IOAT_DMA_OPERATION == IOAT_DMA_OPERATION_LIBRARY

#endif
    uint8_t idle = 0x1;
    uint32_t idle_counter = 0xFF;
    while (1) {
        err = ioat_device_poll();
        switch (err_no(err)) {
            case DMA_ERR_DEVICE_IDLE:
                idle = idle && 0x1;
                break;
            case SYS_ERR_OK:
                idle = 0;
                break;
            default:
                debug_printf("I/O AT DMA driver terminated: in poll, %s\n",
                             err_getstring(err));
                return err;
        }
        err = event_dispatch_non_block(get_default_waitset());
        switch (err_no(err)) {
            case SYS_ERR_OK:
                idle = 0;
                break;
            case LIB_ERR_NO_EVENT:
                idle &= 1;
                break;
            default:
                debug_printf("I/O AT DMA driver terminated in dispatch,  %s\n",
                             err_getstring(err));
                return err;
        }
        if (idle) {
            idle_counter--;
        }
        if (idle_counter == 0) {
            idle_counter = 0xFF;
            thread_yield();
        }
    }

    return 0;
}
Exemple #25
0
static int dd(int argc, char *argv[])
{
    // parse options
    char *source = NULL;
    char *target = NULL;

    vfs_handle_t source_vh = NULL;
    vfs_handle_t target_vh = NULL;
    
    size_t blocksize = 512;
    size_t count = 0;
    size_t skip = 0;
    size_t seek = 0;

    size_t rsize = 0;
    size_t wsize = 0;
    size_t blocks_written = 0;

    size_t total_bytes_read = 0;
    size_t total_bytes_written = 0;

    size_t progress = 0;

    errval_t err;
    int ret = 0;

    for (int i = 1; i < argc; i++)
    {
        if (!strncmp(argv[i], "bs=", 3))
            blocksize = atoi(argv[i] + 3);

        else if (!strncmp(argv[i], "count=", 6))
            count = atoi(argv[i] + 6);

        else if (!strncmp(argv[i], "skip=", 5))
            skip = atoi(argv[i] + 5);

        else if (!strncmp(argv[i], "seek=", 5))
            seek = atoi(argv[i] + 5);

        else if (!strncmp(argv[i], "if=", 3))
            source = (argv[i] + 3);

        else if (!strncmp(argv[i], "of=", 3))
            target = (argv[i] + 3);
        else if (!strncmp(argv[i], "progress", 8))
            progress = 1;
    }

    size_t one_per_cent = (blocksize * count) / 100;

    printf("from: %s to: %s bs=%zd count=%zd seek=%zd skip=%zd\n", source, target, blocksize, count, seek, skip);

    if (source != NULL)
    {
        char *path = vfs_path_mkabsolute(cwd, source);
        err = vfs_open(path, &source_vh);
        free(path);
        if (err_is_fail(err)) {
            printf("%s: %s\n", source, err_getstring(err));
            return 1;
        }

        if (skip != 0)
        {
            // TODO: skip
        }
    }

    if (target != NULL)
    {
        char *path = vfs_path_mkabsolute(cwd, target);
        err = vfs_create(path, &target_vh);
        free(path);
        if (err_is_fail(err)) {
            // close source handle
            if (source_vh != NULL)
                vfs_close(source_vh);
            printf("%s: %s\n", target, err_getstring(err));
            return 1;
        }

        if (seek != 0)
        {
            // TODO: seek
        }
    }

    uint8_t * buffer = malloc(blocksize);

#if defined(__x86_64__) || defined(__i386__)
    uint64_t tscperms;
    err = sys_debug_get_tsc_per_ms(&tscperms);
    assert(err_is_ok(err));

    //printf("ticks per millisec: %" PRIu64 "\n", tscperms);
    uint64_t start = rdtsc();
#endif

    if (buffer == NULL)
    {
        ret = 2;
        printf("failed to allocate buffer of size %zd\n", blocksize);
        goto out;
    }

    do
    {
        //printf("copying block\n");
        size_t read_bytes = 0;
        do {
            err = vfs_read(source_vh, buffer, blocksize, &rsize);
            if (err_is_fail(err)) {
                DEBUG_ERR(err, "error reading file");
                ret = 1;
                goto out;
            }

            total_bytes_read += rsize;
            read_bytes += rsize;

            size_t wpos = 0;
            while (wpos < rsize) {
                if (wpos > 0)
                    printf("was unable to write the whole chunk of size %zd. Now at pos: %zd of buffer\n", rsize, wpos);

                err = vfs_write(target_vh, &buffer[wpos], rsize - wpos, &wsize);
                if (err_is_fail(err) || wsize == 0) {
                    DEBUG_ERR(err, "error writing file");
                    ret = 1;
                    goto out;
                }
                wpos += wsize;
                total_bytes_written += wsize;
            }
        } while(read_bytes < blocksize);

        blocks_written++;

        if (progress && one_per_cent && total_bytes_written % one_per_cent == 0) {
            printf(".");
        }

        //printf("block successfully copied. read: %zd. blocks written: %zd\n", rsize, blocks_written);
    } while (rsize > 0 && !(count > 0 && blocks_written >= count));

    if (progress) printf("\n");

out:
    if (buffer != NULL)
        free(buffer);
    
    if (source_vh != NULL) {
        err = vfs_close(source_vh);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

    if (target_vh != NULL) {
        err = vfs_close(target_vh);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

#if defined(__x86_64__) || defined(__i386__)
    uint64_t stop = rdtsc();
    uint64_t elapsed_msecs = ((stop - start) / tscperms);
    double elapsed_secs = (double)elapsed_msecs/1000.0;

    printf("start: %" PRIu64 " stop: %" PRIu64 "\n", start, stop);

    double kbps = ((double)total_bytes_written / 1024.0) / elapsed_secs;

    printf("%zd bytes read. %zd bytes written. %f s, %f kB/s\n", total_bytes_read, total_bytes_written, elapsed_secs, kbps); 
#else
    printf("%zd bytes read. %zd bytes written.\n", total_bytes_read, total_bytes_written); 
#endif

    return ret;
}
/**
 * \brief initializes a DMA client device with the giving capability
 *
 * \param info stores information how to find the device driver service
 * \param dev  returns a pointer to the device structure
 *
 * \returns SYS_ERR_OK on success
 *          errval on error
 */
errval_t dma_client_device_init(struct dma_client_info *info,
                                struct dma_client_device **dev)
{
    errval_t err;

    struct dma_client_device *cdev = calloc(1, sizeof(*cdev));
    if (cdev == NULL) {
        return LIB_ERR_MALLOC_FAIL;
    }

#if DMA_BENCH_ENABLED
     bench_init();
#endif

    struct dma_device *dma_dev = (struct dma_device *) cdev;

    CLIENTDEV_DEBUG("initialzing new client device\n", device_id);

    iref_t service_iref = 0;

    switch (info->type) {
        case DMA_CLIENT_INFO_TYPE_ADDR:
            assert(!"NYI: lookup based on physical address range");
            break;
        case DMA_CLIENT_INFO_TYPE_IREF:
            service_iref = info->args.iref;
            break;
        case DMA_CLIENT_INFO_TYPE_NAME:
            CLIENTDEV_DEBUG("looking up iref for name {%s}\n", device_id,
                            info->args.name);
            err = nameservice_blocking_lookup(info->args.name, &service_iref);
            if (err_is_fail(err)) {
                free(cdev);
                return err;
            }
            CLIENTDEV_DEBUG("driver service {%s} @ iref:%"PRIxIREF"\n", device_id,
                            info->args.name, service_iref);
            break;
        default:
            return DMA_ERR_DEVICE_UNSUPPORTED;
            break;
    }

    if (cdev->info.iref == 0) {
        err = dma_manager_lookup_by_iref(service_iref, &cdev->info);
        if (err_is_fail(err)) {
            CLIENTDEV_DEBUG("ERROR: obtaining driver info from DMA manager: %s\n",
                            device_id, err_getstring(err));
            free(cdev);
            return err;
        }
    }

    assert(service_iref != 0);
    dma_dev->type = DMA_DEV_TYPE_CLIENT;
    dma_dev->id = device_id++;
    dma_dev->channels.count = DMA_CLIENT_DEVICE_CONNECTIONS;
    dma_dev->channels.c = calloc(dma_dev->channels.count,
                                 sizeof(*dma_dev->channels.c));
    if (dma_dev->channels.c == NULL) {
        free(cdev);
        return LIB_ERR_MALLOC_FAIL;
    }

    /* channel enumeration */

    CLIENTDEV_DEBUG("doing channel enumeration. discovered %u channels\n",
                    cdev->common.id, cdev->common.channels.count);

    for (uint8_t i = 0; i < dma_dev->channels.count; ++i) {
        struct dma_channel **chan = &dma_dev->channels.c[i];
        err = dma_client_channel_init(cdev, i, service_iref,
                                      (struct dma_client_channel **) chan);
        if (err_is_fail(err)) {
            free(cdev->common.channels.c);
            free(cdev);
            return err;
        }
    }

    dma_dev->f.deregister_memory = dma_client_deregister_memory;
    dma_dev->f.register_memory = dma_client_register_memory;
    dma_dev->f.poll = dma_client_device_poll;

    *dev = cdev;

    return SYS_ERR_OK;
}
Exemple #27
0
static int
ahci_read_write(int argc, char *argv[])
{
    if (argc != 4) {
        printf("usage: %s <block device> <blocksize> <count>\n", argv[0]);
        return 1;
    }

    char *dev = argv[1];
    size_t blocksize = atoi(argv[2]);
    size_t count = atoi(argv[3]);
    printf("malloc buf\n");
    uint8_t *buf = malloc(blocksize);
    int ret = 0;

    errval_t err;
    vfs_handle_t f = NULL;
    char *path = vfs_path_mkabsolute(cwd, dev);
    printf("open\n");
    err = vfs_open(path, &f);

    if (err_is_fail(err)) {
        printf("%s: %s\n", path, err_getstring(err));
        ret = 1;
        goto out;
    }

    for (int i = 0; i < count; i++) {
        size_t read = 0;
        size_t rsize;
        while(read < blocksize) {
            printf("read\n");
            err = vfs_read(f, &buf[read], blocksize, &rsize);
            if (err_is_fail(err)) {
                DEBUG_ERR(err, "error reading file");
                ret = 1;
                goto out;
            }
            read += rsize;
        }

        size_t written = 0;
        size_t wsize;
        while(written < blocksize) {
            printf("write\n");
            err = vfs_write(f, &buf[written], blocksize, &wsize);
            if (err_is_fail(err)) {
                DEBUG_ERR(err, "error writing file");
                ret = 1;
                goto out;
            }
            written += wsize;
        }
    }

out:
    if (buf)
        printf("free\n");
        free(buf);
    if (f) {
        printf("close\n");
        err = vfs_close(f);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in vfs_close");
        }
    }

    return ret;
}
Exemple #28
0
int map_unmap(void)
{
    errval_t err;
    struct capref mem;

    DEBUG_MAP_UNMAP("ram_alloc\n");
    err = ram_alloc(&mem, BASE_PAGE_BITS);
    if (err_is_fail(err)) {
        printf("ram_alloc: %s (%"PRIuERRV")\n", err_getstring(err), err);
        return 1;
    }

    struct capref frame;
    DEBUG_MAP_UNMAP("retype\n");
    err = slot_alloc(&frame);
    if (err_is_fail(err)) {
        printf("slot_alloc: %s (%"PRIuERRV")\n", err_getstring(err), err);
        return 1;
    }
    err = cap_retype(frame, mem, ObjType_Frame, BASE_PAGE_BITS);
    if (err_is_fail(err)) {
        printf("cap_retype: %s (%"PRIuERRV")\n", err_getstring(err), err);
        return 1;
    }

    DEBUG_MAP_UNMAP("delete ram cap\n");
    err = cap_destroy(mem);
    if (err_is_fail(err)) {
        printf("cap_delete(mem): %s (%"PRIuERRV")\n", err_getstring(err), err);
        return 1;
    }

    struct frame_identity fi;
    err = invoke_frame_identify(frame, &fi);
    if (err_is_fail(err)) {
        printf("frame_identify: %s (%"PRIuERRV")\n", err_getstring(err), err);
        return 1;
    }
    DEBUG_MAP_UNMAP("frame: base = 0x%"PRIxGENPADDR", bits = %d\n", fi.base, fi.bits);

#ifdef NKMTEST_DEBUG_MAP_UNMAP
    dump_pmap(get_current_pmap());
#endif

    struct vregion *vr;
    struct memobj *memobj;
    void *vaddr;
    DEBUG_MAP_UNMAP("map\n");
    err = vspace_map_one_frame(&vaddr, BASE_PAGE_SIZE, frame, &memobj, &vr);
    if (err_is_fail(err)) {
        printf("vspace_map_one_frame: %s (%"PRIuERRV")\n", err_getstring(err), err);
    }
    char *memory = vaddr;
    DEBUG_MAP_UNMAP("vaddr = %p\n", vaddr);

#ifdef NKMTEST_DEBUG_MAP_UNMAP
    dump_pmap(get_current_pmap());
#endif

    DEBUG_MAP_UNMAP("write 1\n");
    int i;
    for (i = 0; i < BASE_PAGE_SIZE; i++) {
        memory[i] = i % INT8_MAX;
    }
    DEBUG_MAP_UNMAP("verify 1\n");
    for (i = 0; i < BASE_PAGE_SIZE; i++) {
        assert(memory[i] == i % INT8_MAX);
    }

    DEBUG_MAP_UNMAP("delete frame cap\n");
    err = cap_destroy(frame);
    if (err_is_fail(err)) {
        printf("cap_delete(frame): %s (%"PRIuERRV")\n", err_getstring(err), err);
        return 1;
    }

#ifdef NKMTEST_DEBUG_MAP_UNMAP
    // no mapping should remain here
    dump_pmap(get_current_pmap());
    err = debug_dump_hw_ptables();
    if (err_is_fail(err)) {
        printf("kernel dump ptables: %s (%"PRIuERRV")\n", err_getstring(err), err);
        return 1;
    }
#endif

    printf("%s: done\n", __FUNCTION__);
    return 0;
}
Exemple #29
0
static errval_t cow_init(size_t bufsize, size_t granularity,
        struct cnoderef *cow_cn, size_t *frame_count)
{
    assert(cow_cn);
    assert(frame_count);

    errval_t err;
    struct capref frame, cncap;
    struct cnoderef cnode;

    // get RAM cap bufsize = (bufsize / granularity + 1) * granularity;
    err = slot_alloc(&frame);
    assert(err_is_ok(err));
    size_t rambits = log2floor(bufsize);
    debug_printf("bits = %zu\n", rambits);
    err = ram_alloc(&frame, rambits);
    assert(err_is_ok(err));
    // calculate #slots
    cslot_t cap_count = bufsize / granularity;
    cslot_t slots;
    // get CNode
    err = cnode_create(&cncap, &cnode, cap_count, &slots);
    assert(err_is_ok(err));
    assert(slots >= cap_count);
    // retype RAM into Frames
    struct capref first_frame = (struct capref) { .cnode = cnode, .slot = 0 };
    err = cap_retype(first_frame, frame, ObjType_Frame, log2floor(granularity));
    assert(err_is_ok(err));
    err = cap_destroy(frame);
    assert(err_is_ok(err));
    *frame_count = slots;
    *cow_cn = cnode;
    return SYS_ERR_OK;
}

// create cow-enabled vregion & backing
// Can copy-on-write in granularity-sized chunks
static errval_t vspace_map_one_frame_cow(void **buf, size_t size,
        struct capref frame, vregion_flags_t flags,
        struct memobj **memobj, struct vregion **vregion,
        size_t granularity)
{
    errval_t err;
    if (!memobj) {
        memobj = malloc(sizeof(*memobj));
    }
    assert(memobj);
    if (!vregion) {
        vregion = malloc(sizeof(*vregion));
    }
    assert(vregion);
    err = vspace_map_anon_attr(buf, memobj, vregion, size, &size, flags);
    assert(err_is_ok(err));
    size_t chunks = size / granularity;
    cslot_t slots;
    struct capref cncap;
    struct cnoderef cnode;
    err = cnode_create(&cncap, &cnode, chunks, &slots);
    assert(err_is_ok(err));
    assert(slots >= chunks);
    struct capref fc = (struct capref) { .cnode = cnode, .slot = 0 };
    for (int i = 0; i < chunks; i++) {
        err = cap_copy(fc, frame);
        assert(err_is_ok(err));
        err = (*memobj)->f.fill_foff(*memobj, i * granularity, fc, granularity, i*granularity);
        assert(err_is_ok(err));
        err = (*memobj)->f.pagefault(*memobj, *vregion, i * granularity, 0);
        assert(err_is_ok(err));
        fc.slot++;
    }
    return SYS_ERR_OK;
}

int main(int argc, char *argv[])
{
    errval_t err;
    struct capref frame;
    size_t retsize;
    void *vbuf;
    struct vregion *vregion;
    uint8_t *buf;

    debug_printf("%s:%d\n", __FUNCTION__, __LINE__);
    err = frame_alloc(&frame, BUFSIZE, &retsize);
    assert(retsize >= BUFSIZE);
    if (err_is_fail(err)) {
        debug_printf("frame_alloc: %s\n", err_getstring(err));
        return 1;
    }
    debug_printf("%s:%d: %zu\n", __FUNCTION__, __LINE__, retsize);
    // setup region
    err = vspace_map_one_frame_attr(&vbuf, retsize, frame,
            VREGION_FLAGS_READ_WRITE, NULL, &vregion);
    if (err_is_fail(err)) {
        debug_printf("vspace_map: %s\n", err_getstring(err));
        return 1;
    }
    debug_printf("vaddr: %p\n", vbuf);

    // write stuff to region
    buf = vbuf;
    debug_printf("%s:%d: %p, %lu pages\n", __FUNCTION__, __LINE__, buf, BUFSIZE / BASE_PAGE_SIZE);
    memset(buf, 0xAA, BUFSIZE);

    debug_printf("%s:%d\n", __FUNCTION__, __LINE__);
    // create cow copy
    //  setup exception handler
    thread_set_exception_handler(handler, NULL, ex_stack,
            ex_stack+EX_STACK_SIZE, NULL, NULL);
    assert(err_is_ok(err));
    debug_printf("%s:%d\n", __FUNCTION__, __LINE__);
    err = cow_init(BUFSIZE, BASE_PAGE_SIZE, &cow_frames, &cow_frame_count);
    assert(err_is_ok(err));
    //  create r/o copy of region and tell exception handler bounds
    debug_printf("%s:%d\n", __FUNCTION__, __LINE__);
    err = vspace_map_one_frame_cow(&cow_vbuf, retsize, frame,
            VREGION_FLAGS_READ, NULL, &cow_vregion, BASE_PAGE_SIZE);
    if (err_is_fail(err)) {
        debug_printf("vspace_map: %s\n", err_getstring(err));
        return 1;
    }
    debug_printf("cow_vaddr: %p\n", cow_vbuf);

    // do stuff cow copy
    uint8_t *cbuf = cow_vbuf;
    for (int i = 0; i < BUFSIZE / BASE_PAGE_SIZE; i+=2) {
        cbuf[i * BASE_PAGE_SIZE + 1] = 0x55;
    }
    // verify results
    for (int i = 0; i < BUFSIZE / BASE_PAGE_SIZE; i++) {
        printf("page %d\n", i);
        printf("buf[0] = %d; cbuf[0] = %d\n", buf[i*BASE_PAGE_SIZE],
                cbuf[i*BASE_PAGE_SIZE]);
        printf("buf[1] = %d; cbuf[1] = %d\n", buf[i*BASE_PAGE_SIZE+1],
                cbuf[i*BASE_PAGE_SIZE+1]);
    }
    debug_dump_hw_ptables();
    return EXIT_SUCCESS;
}