Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1187 → Rev 1191

/kernel/trunk/generic/include/ddi/ddi_arg.h
36,6 → 36,13
void *virt_base; /** Virtual address of starting page. */
unsigned long pages; /** Number of pages to map. */
int writable; /** True if the mapping should be writable. */
} ddi_arg_t;
} ddi_memarg_t;
 
/** Structure encapsulating arguments for SYS_ENABLE_IOSPACE syscall. */
typedef struct {
unsigned long long task_id; /** ID of the destination task. */
void *ioaddr; /** Starting I/O space address. */
unsigned long size; /** Number of bytes. */
} ddi_ioarg_t;
 
#endif
/kernel/trunk/generic/include/ddi/ddi.h
31,7 → 31,14
 
#include <ddi/ddi_arg.h>
#include <arch/types.h>
#include <typedefs.h>
 
extern __native sys_map_physmem(ddi_arg_t *uspace_ddi_arg);
extern __native sys_map_physmem(ddi_memarg_t *uspace_mem_arg);
extern __native sys_enable_iospace(ddi_ioarg_t *uspace_io_arg);
 
/*
* Interface to be implemented by all architectures.
*/
extern int ddi_enable_iospace_arch(task_t *task, __address ioaddr, size_t size);
 
#endif
/kernel/trunk/generic/include/syscall/syscall.h
49,6 → 49,7
SYS_IPC_WAIT,
SYS_IPC_HANGUP,
SYS_MAP_PHYSMEM,
SYS_ENABLE_IOSPACE,
SYSCALL_END
} syscall_t;
 
/kernel/trunk/generic/src/ddi/ddi.c
111,18 → 111,86
return 0;
}
 
/** Enable range of I/O space for task.
*
* @param id Task ID of the destination task.
* @param ioaddr Starting I/O address.
* @param size Size of the enabled I/O space..
*
* @return 0 on success, EPERM if the caller lacks capabilities to use this syscall,
* ENOENT if there is no task matching the specified ID.
*/
static int ddi_enable_iospace(task_id_t id, __address ioaddr, size_t size)
{
ipl_t ipl;
cap_t caps;
task_t *t;
int rc;
/*
* Make sure the caller is authorised to make this syscall.
*/
caps = cap_get(TASK);
if (!(caps & CAP_IO_MANAGER))
return EPERM;
ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
t = task_find_by_id(id);
if (!t) {
/*
* There is no task with the specified ID.
*/
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
/*
* TODO: We are currently lacking support for task destroying.
* Once it is added to the kernel, we must take care to
* synchronize in a way that prevents race conditions here.
*/
/* Lock the task and release the lock protecting tasks_btree. */
spinlock_lock(&t->lock);
spinlock_unlock(&tasks_lock);
 
rc = ddi_enable_iospace_arch(t, ioaddr, size);
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
return rc;
}
 
/** Wrapper for SYS_MAP_PHYSMEM syscall.
*
* @param User space address of DDI argument structure.
* @param User space address of memory DDI argument structure.
*
* @return 0 on success, otherwise it returns error code found in errno.h
*/
__native sys_map_physmem(ddi_arg_t *uspace_ddi_arg)
__native sys_map_physmem(ddi_memarg_t *uspace_mem_arg)
{
ddi_arg_t arg;
ddi_memarg_t arg;
copy_from_uspace(&arg, uspace_ddi_arg, sizeof(ddi_arg_t));
copy_from_uspace(&arg, uspace_mem_arg, sizeof(ddi_memarg_t));
return (__native) ddi_map_physmem((task_id_t) arg.task_id, ALIGN_DOWN((__address) arg.phys_base, FRAME_SIZE),
ALIGN_DOWN((__address) arg.virt_base, PAGE_SIZE), (count_t) arg.pages,
(bool) arg.writable);
}
 
/** Wrapper for SYS_ENABLE_IOSPACE syscall.
*
* @param User space address of DDI argument structure.
*
* @return 0 on success, otherwise it returns error code found in errno.h
*/
__native sys_enable_iospace(ddi_ioarg_t *uspace_io_arg)
{
ddi_ioarg_t arg;
copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
return (__native) ddi_enable_iospace((task_id_t) arg.task_id, (__address) arg.ioaddr, (size_t) arg.size);
}
/kernel/trunk/generic/src/syscall/syscall.c
93,5 → 93,6
sys_ipc_forward_fast,
sys_ipc_wait_for_call,
sys_ipc_hangup,
sys_map_physmem
sys_map_physmem,
sys_enable_iospace
};