1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/libipc/lib/src/mem_ipc.c Wed Aug 25 01:28:08 2021 +0200
1.3 @@ -0,0 +1,116 @@
1.4 +/*
1.5 + * Memory sharing abstractions.
1.6 + *
1.7 + * Copyright (C) 2018, 2019, 2021 Paul Boddie <paul@boddie.org.uk>
1.8 + *
1.9 + * This program is free software; you can redistribute it and/or
1.10 + * modify it under the terms of the GNU General Public License as
1.11 + * published by the Free Software Foundation; either version 2 of
1.12 + * the License, or (at your option) any later version.
1.13 + *
1.14 + * This program is distributed in the hope that it will be useful,
1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.17 + * GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License
1.20 + * along with this program; if not, write to the Free Software
1.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
1.22 + * Boston, MA 02110-1301, USA
1.23 + */
1.24 +
1.25 +#include <l4/re/c/mem_alloc.h>
1.26 +#include <l4/re/c/rm.h>
1.27 +#include <l4/sys/err.h>
1.28 +#include <l4/sys/types.h>
1.29 +
1.30 +#include "cap_alloc.h"
1.31 +#include "mem_ipc.h"
1.32 +#include "semaphore.h"
1.33 +
1.34 +
1.35 +
1.36 +/* Semaphore used if threading has been initialised by ipc_mem_init. */
1.37 +
1.38 +l4_cap_idx_t ipc_mem_semaphore = L4_INVALID_CAP;
1.39 +
1.40 +
1.41 +
1.42 +/* Generic memory allocation. */
1.43 +
1.44 +long ipc_allocate(unsigned long size, void **addr, l4re_ds_t *ds)
1.45 +{
1.46 + /* Allocate a capability for the dataspace. */
1.47 +
1.48 + *ds = ipc_cap_alloc();
1.49 +
1.50 + if (l4_is_invalid_cap(*ds))
1.51 + return -L4_ENOENT;
1.52 +
1.53 + /* Allocate and attach the memory for the dataspace. */
1.54 +
1.55 + if (ipc_new_dataspace(*ds, size, 0, 0))
1.56 + {
1.57 + ipc_cap_free_um(*ds);
1.58 + return -L4_ENOMEM;
1.59 + }
1.60 +
1.61 + if (ipc_attach_dataspace(*ds, size, addr))
1.62 + {
1.63 + ipc_cap_free_um(*ds);
1.64 + return -L4_ENOMEM;
1.65 + }
1.66 +
1.67 + return L4_EOK;
1.68 +}
1.69 +
1.70 +/* Create a dataspace. Equivalent to l4re_ma_alloc_align. */
1.71 +
1.72 +long ipc_new_dataspace(l4_cap_idx_t cap, l4_mword_t size, l4_umword_t flags, l4_umword_t align)
1.73 +{
1.74 + return l4re_ma_alloc_align(size, cap, flags, align);
1.75 +}
1.76 +
1.77 +/* Attach a dataspace region. Similar to l4re_rm_attach. */
1.78 +
1.79 +long ipc_attach_dataspace(l4re_ds_t ds, unsigned long size, void **addr)
1.80 +{
1.81 + long err;
1.82 +
1.83 + err = ipc_semaphore_down(ipc_mem_semaphore);
1.84 + if (err)
1.85 + return err;
1.86 +
1.87 + err = l4re_rm_attach(addr, size, L4RE_RM_SEARCH_ADDR, ds, 0, L4_PAGESHIFT);
1.88 +
1.89 + ipc_semaphore_up(ipc_mem_semaphore);
1.90 +
1.91 + return err;
1.92 +}
1.93 +
1.94 +/* Detach a dataspace region. Equivalent to l4re_rm_detach_unmap. */
1.95 +
1.96 +long ipc_detach_dataspace(void *addr)
1.97 +{
1.98 + long err;
1.99 +
1.100 + err = ipc_semaphore_down(ipc_mem_semaphore);
1.101 + if (err)
1.102 + return err;
1.103 +
1.104 + err = l4re_rm_detach_unmap((l4_addr_t) addr, L4RE_THIS_TASK_CAP);
1.105 +
1.106 + ipc_semaphore_up(ipc_mem_semaphore);
1.107 +
1.108 + return err;
1.109 +}
1.110 +
1.111 +/* Obtain a dataspace size. Equivalent to l4re_ds_size. */
1.112 +
1.113 +long ipc_dataspace_size(l4_cap_idx_t cap, unsigned long *size)
1.114 +{
1.115 + *size = l4re_ds_size(cap);
1.116 + return L4_EOK;
1.117 +}
1.118 +
1.119 +// vim: tabstop=2 expandtab shiftwidth=2