Files
codezero/conts/posix/libposix/mmap.c
2010-03-25 01:12:40 +02:00

135 lines
2.9 KiB
C

/*
* Glue logic between posix mmap/munmap functions
* and their L4 implementation.
*
* Copyright (C) 2007 Bahadir Balban
*/
#include <errno.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <l4lib/ipcdefs.h>
#include <libposix.h>
/* FIXME: Implement the same separation that is in read.c write.c etc. such that
* l4_syscall returns negative value and then the actual posix glue sets the errno
* rather than the l4_syscall sets it itself
*/
struct mmap_descriptor {
void *start;
size_t length;
int prot;
int flags;
int fd;
off_t offset;
};
static inline void *l4_mmap(void *start, size_t length, int prot, int flags, int fd, off_t pgoffset)
{
/* Not enough MRs for all arguments, therefore we fill in a structure */
struct mmap_descriptor desc = {
.start = start,
.length = length,
.prot = prot,
.flags = flags,
.fd = fd,
.offset = pgoffset,
};
int ret;
write_mr(L4SYS_ARG0, (unsigned long)&desc);
/* Call pager with MMAP request. Check ipc error. */
if ((ret = l4_sendrecv(pagerid, pagerid, L4_IPC_TAG_MMAP)) < 0) {
print_err("%s: IPC Error: %d.\n", __FUNCTION__, ret);
return PTR_ERR(ret);
}
if (IS_ERR(ret = l4_get_retval()))
print_err("%s: MMAP Error: %d.\n", __FUNCTION__, ret);
return (void *)ret;
}
void *mmap2(void *start, size_t length, int prot, int flags, int fd, off_t pgoffset)
{
void *ret = l4_mmap(start, length, prot, flags, fd, pgoffset);
if (IS_ERR(ret)) {
errno = -(int)ret;
return MAP_FAILED;
}
return ret;
}
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
{
return mmap2(start, length, prot, flags, fd, __pfn(offset));
}
int l4_munmap(void *start, size_t length)
{
int err;
write_mr(L4SYS_ARG0, (unsigned long)start);
write_mr(L4SYS_ARG1, length);
/* Call pager with MMAP request. */
if ((err = l4_sendrecv(pagerid, pagerid, L4_IPC_TAG_MUNMAP)) < 0) {
print_err("%s: IPC Error: %d.\n", __FUNCTION__, err);
return err;
}
/* Check if syscall itself was successful */
if ((err = l4_get_retval()) < 0) {
print_err("%s: MUNMAP Error: %d.\n", __FUNCTION__, err);
return err;
}
return 0;
}
int munmap(void *start, size_t length)
{
int ret = l4_munmap(start, length);
/* If error, return positive error code */
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}
int l4_msync(void *start, size_t length, int flags)
{
write_mr(L4SYS_ARG0, (unsigned long)start);
write_mr(L4SYS_ARG1, length);
write_mr(L4SYS_ARG2, flags);
/* Call pager with MMAP request. */
if ((errno = l4_sendrecv(pagerid, pagerid, L4_IPC_TAG_MSYNC)) < 0) {
print_err("%s: IPC Error: %d.\n", __FUNCTION__, errno);
return -1;
}
/* Check if syscall itself was successful */
if ((errno = l4_get_retval()) < 0) {
print_err("%s: MSYNC Error: %d.\n", __FUNCTION__, errno);
return -1;
}
return 0;
}
int msync(void *start, size_t length, int flags)
{
int ret = l4_msync(start, length, flags);
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}