Compare commits

...

3 Commits

7 changed files with 148 additions and 11 deletions

View File

@@ -5,7 +5,8 @@
#include <kernel/pmap.h> #include <kernel/pmap.h>
#include <kernel/vm.h> #include <kernel/vm.h>
#define ADDRESS_SPACE_COPY_ALL ((size_t)-1) #define ADDRESS_SPACE_COPY_ALL ((size_t) - 1)
#define ADDRESS_SPACE_F_
struct address_space; struct address_space;
struct vm_object; struct vm_object;
@@ -158,6 +159,12 @@ extern kern_status_t address_space_memmove_v(
size_t bytes_to_move, size_t bytes_to_move,
size_t *nr_bytes_moved); size_t *nr_bytes_moved);
extern kern_status_t address_space_translate(
struct address_space *space,
virt_addr_t in,
phys_addr_t *out,
unsigned long *irq_flags);
void address_space_dump(struct address_space *region); void address_space_dump(struct address_space *region);
DEFINE_OBJECT_LOCK_FUNCTION(address_space, s_base) DEFINE_OBJECT_LOCK_FUNCTION(address_space, s_base)

26
include/kernel/futex.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef KERNEL_FUTEX_H_
#define KERNEL_FUTEX_H_
#include <kernel/btree.h>
#include <kernel/wait.h>
#include <mango/types.h>
struct address_space;
typedef phys_addr_t futex_key_t;
struct futex {
struct btree_node f_node;
futex_key_t f_key;
struct waitqueue f_waiters;
};
extern kern_status_t futex_init(void);
extern kern_status_t futex_get(
struct address_space *space,
kern_futex_t *futex,
futex_key_t *out);
extern kern_status_t futex_wait(futex_key_t futex, kern_futex_t new_val);
extern kern_status_t futex_wake(futex_key_t futex, size_t nwaiters);
#endif

70
kernel/futex.c Normal file
View File

@@ -0,0 +1,70 @@
#include <kernel/address-space.h>
#include <kernel/futex.h>
#include <mango/status.h>
enum futex_flags {
FUTEX_CREATE = 0x01u,
};
static struct btree futex_list = {0};
static spin_lock_t futex_list_lock = SPIN_LOCK_INIT;
static struct vm_cache futex_cache = {
.c_name = "futex",
.c_obj_size = sizeof(struct futex),
};
BTREE_DEFINE_SIMPLE_INSERT(struct futex, f_node, f_key, put_futex)
BTREE_DEFINE_SIMPLE_GET(struct futex, futex_key_t, f_node, f_key, get_futex)
kern_status_t futex_init(void)
{
vm_cache_init(&futex_cache);
return KERN_OK;
}
static struct futex *get_data(futex_key_t key, enum futex_flags flags)
{
spin_lock(&futex_list_lock);
struct futex *futex = get_futex(&futex_list, key);
spin_unlock(&futex_list_lock);
if (!futex && !(flags & FUTEX_CREATE)) {
return NULL;
}
futex = vm_cache_alloc(&futex_cache, VM_NORMAL);
futex->f_key = key;
spin_lock(&futex_list_lock);
put_futex(&futex_list, futex);
spin_unlock(&futex_list_lock);
return futex;
}
kern_status_t futex_get(
struct address_space *space,
kern_futex_t *futex,
futex_key_t *out)
{
unsigned long flags;
address_space_lock_irqsave(space, &flags);
kern_status_t status = address_space_translate(
space,
(virt_addr_t)futex,
out,
&flags);
address_space_unlock_irqrestore(space, flags);
return status;
}
kern_status_t futex_wait(futex_key_t futex, kern_futex_t new_val)
{
return KERN_UNIMPLEMENTED;
}
kern_status_t futex_wake(futex_key_t futex, size_t nwaiters)
{
return KERN_UNIMPLEMENTED;
}

View File

View File

@@ -46,20 +46,16 @@
#define IOVEC(p, len) \ #define IOVEC(p, len) \
{ \ { \
.io_base = (virt_addr_t)(p), \ .io_base = (virt_addr_t)(p), .io_len = (len), \
.io_len = (len), \
} }
#define MSG_HANDLE(mode, value) \ #define MSG_HANDLE(mode, value) \
{ \ { \
.hnd_mode = (mode), \ .hnd_mode = (mode), .hnd_value = (value), \
.hnd_value = (value), \
} }
#define MSG(data, data_count, handles, handles_len) \ #define MSG(data, data_count, handles, handles_len) \
{ \ { \
.msg_data = (data), \ .msg_data = (data), .msg_data_count = (data_count), \
.msg_data_count = (data_count), \ .msg_handles = (handles), .msg_handles_count = (handles_len), \
.msg_handles = (handles), \
.msg_handles_count = (handles_len), \
} }
typedef uintptr_t phys_addr_t; typedef uintptr_t phys_addr_t;
@@ -75,6 +71,7 @@ typedef uint32_t kern_handle_t;
typedef uint32_t kern_config_key_t; typedef uint32_t kern_config_key_t;
typedef uint32_t vm_prot_t; typedef uint32_t vm_prot_t;
typedef int64_t ssize_t; typedef int64_t ssize_t;
typedef uint32_t kern_futex_t;
typedef unsigned short equeue_packet_type_t; typedef unsigned short equeue_packet_type_t;

View File

@@ -110,9 +110,9 @@ static struct vm_area *get_entry(
enum get_entry_flags flags) enum get_entry_flags flags)
{ {
/* `x` must be to the left of `y` */ /* `x` must be to the left of `y` */
#define LEFT_DIFF(x, y) ((y) ? ((y)->vma_base - (x)) : ((size_t)-1)) #define LEFT_DIFF(x, y) ((y) ? ((y)->vma_base - (x)) : ((size_t) - 1))
/* `x` must be to the right of `y` */ /* `x` must be to the right of `y` */
#define RIGHT_DIFF(x, y) ((y) ? ((y)->vma_limit - (x)) : ((size_t)-1)) #define RIGHT_DIFF(x, y) ((y) ? ((y)->vma_limit - (x)) : ((size_t) - 1))
struct btree_node *cur = region->s_mappings.b_root; struct btree_node *cur = region->s_mappings.b_root;
if (!cur) { if (!cur) {
@@ -1413,6 +1413,42 @@ extern kern_status_t address_space_memmove_v(
return KERN_OK; return KERN_OK;
} }
kern_status_t address_space_translate(
struct address_space *space,
virt_addr_t in,
phys_addr_t *out,
unsigned long *irq_flags)
{
if (in >= VM_KERNEL_BASE) {
return vm_virt_to_phys((const void *)in);
}
struct vm_area *area = get_entry(space, in, GET_ENTRY_EXACT);
if (!area || !area->vma_object) {
return KERN_NO_ENTRY;
}
off_t offset = in - area->vma_base + area->vma_object_offset;
struct vm_object *vmo = area->vma_object;
vm_object_lock(vmo);
address_space_unlock(space);
struct vm_page *pg = vm_object_get_page(
vmo,
offset,
VMO_ALLOCATE_MISSING_PAGE | VMO_REQUEST_MISSING_PAGE,
irq_flags);
if (!pg) {
return KERN_NO_ENTRY;
}
phys_addr_t paddr = vm_page_get_paddr(pg);
paddr += (in & VM_PAGE_MASK);
vm_object_unlock(vmo);
address_space_lock(space);
return paddr;
}
#ifdef TRACE #ifdef TRACE
void address_space_dump(struct address_space *region) void address_space_dump(struct address_space *region)
{ {

View File

@@ -1,4 +1,5 @@
#include <kernel/address-space.h> #include <kernel/address-space.h>
#include <kernel/printk.h>
#include <kernel/sched.h> #include <kernel/sched.h>
#include <kernel/util.h> #include <kernel/util.h>
#include <kernel/vm-controller.h> #include <kernel/vm-controller.h>