diff options
author | Zheng Da <zhengda1936@gmail.com> | 2009-12-06 05:14:54 +0100 |
---|---|---|
committer | Zheng Da <zhengda1936@gmail.com> | 2009-12-06 05:14:54 +0100 |
commit | b4bffcfcdf3ab7a55d664e9aa5907f88da503f38 (patch) | |
tree | ea865150eeb64bf519b1660c0624cf8a22931894 | |
parent | d73efeeaba75cbdc5b3c23037f1e9f9f82d2d0c9 (diff) |
The code can be compiled now.
-rw-r--r-- | libddekit/Makefile | 11 | ||||
-rw-r--r-- | libddekit/condvar.c | 4 | ||||
-rw-r--r-- | libddekit/device.defs | 204 | ||||
-rw-r--r-- | libddekit/include/Makefile | 9 | ||||
-rw-r--r-- | libddekit/include/ddekit/assert.h | 4 | ||||
-rw-r--r-- | libddekit/include/ddekit/condvar.h | 1 | ||||
-rw-r--r-- | libddekit/include/ddekit/initcall.h | 42 | ||||
-rw-r--r-- | libddekit/include/ddekit/thread.h | 2 | ||||
-rw-r--r-- | libddekit/init.c | 3 | ||||
-rw-r--r-- | libddekit/initcall.c | 8 | ||||
-rw-r--r-- | libddekit/interrupt.c | 63 | ||||
-rw-r--r-- | libddekit/kmem.c | 5 | ||||
-rw-r--r-- | libddekit/list.c | 4 | ||||
-rw-r--r-- | libddekit/lock.c | 3 | ||||
-rw-r--r-- | libddekit/mach.defs | 779 | ||||
-rw-r--r-- | libddekit/malloc.c | 3 | ||||
-rw-r--r-- | libddekit/memory.c | 5 | ||||
-rw-r--r-- | libddekit/pci.c | 33 | ||||
-rw-r--r-- | libddekit/printf.c | 3 | ||||
-rw-r--r-- | libddekit/thread.c | 68 | ||||
-rw-r--r-- | libddekit/timer.c | 7 | ||||
-rw-r--r-- | libddekit/vm_param.h | 7 |
22 files changed, 1132 insertions, 136 deletions
diff --git a/libddekit/Makefile b/libddekit/Makefile index 1203ca38..67a3b193 100644 --- a/libddekit/Makefile +++ b/libddekit/Makefile @@ -19,22 +19,22 @@ dir := libddekit makemode := library libname = libddekit -SRCS= condvar.c init.c initcall.c interrupt.c lock.c malloc.c memory.c \ - pci.c pgtab-old.c pgtab.c printf.c resources.c list.c \ +SRCS= condvar.c init.c interrupt.c lock.c malloc.c memory.c \ + pci.c pgtab.c printf.c resources.c list.c \ thread.c timer.c kmem.c LCLHDRS = include/ddekit/condvar.h include/ddekit/lock.h \ - include/ddekit/initcall.h include/ddekit/debug.h \ + include/ddekit/semaphore.h include/ddekit/debug.h \ include/ddekit/inline.h include/ddekit/panic.h \ include/ddekit/thread.h include/ddekit/types.h \ include/ddekit/pgtab.h include/ddekit/printf.h \ include/ddekit/pci.h include/ddekit/assert.h \ include/ddekit/interrupt.h include/ddekit/resources.h \ include/ddekit/memory.h include/ddekit/timer.h \ - include/ddekit/semaphore.h include/dde.h \ + include/dde.h \ config.h list.h installhdrs = -MIGSTUBS = +MIGSTUBS = deviceUser.o machUser.o OBJS = $(sort $(SRCS:.c=.o) $(MIGSTUBS)) HURDLIBS = threads ports @@ -44,3 +44,4 @@ MIGCOMSFLAGS = -prefix dde_ include ../Makeconf LDFLAGS += -lpciaccess +CFLAGS += -Iinclude -Iinclude/ddekit diff --git a/libddekit/condvar.c b/libddekit/condvar.c index 96e28c07..bbd49417 100644 --- a/libddekit/condvar.c +++ b/libddekit/condvar.c @@ -13,12 +13,12 @@ struct ddekit_condvar { }; ddekit_condvar_t *ddekit_condvar_init() { - ddekit_condvar_t *cvp; + struct condition *cvp; cvp = condition_alloc (); condition_init (cvp); - return cvp; + return (ddekit_condvar_t *) cvp; } void ddekit_condvar_wait(ddekit_condvar_t *cvp, ddekit_lock_t *mp) { diff --git a/libddekit/device.defs b/libddekit/device.defs new file mode 100644 index 00000000..6a73853a --- /dev/null +++ b/libddekit/device.defs @@ -0,0 +1,204 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * File: device/device.defs + * Author: Douglas Orr + * Feb 10, 1988 + * Abstract: + * Mach device support. Mach devices are accessed through + * block and character device interfaces to the kernel. + */ + +#ifdef MACH_KERNEL +simport <kern/compat_xxx_defs.h>; /* for obsolete routines */ +#endif + +subsystem +#if KERNEL_SERVER + KernelServer +#endif + device 2800; + +#include <mach/std_types.defs> +#include <mach/mach_types.defs> +#include <device/device_types.defs> + +serverprefix ds_; + +type pci_config_data_t = array[*:4] of char; +type reply_port_t = MACH_MSG_TYPE_MAKE_SEND_ONCE | polymorphic + ctype: mach_port_t; + +routine device_open( + master_port : mach_port_t; + sreplyport reply_port : reply_port_t; + mode : dev_mode_t; + name : dev_name_t; + out device : device_t + ); + +routine device_close( + device : device_t + ); + +routine device_write( + device : device_t; + sreplyport reply_port : reply_port_t; + in mode : dev_mode_t; + in recnum : recnum_t; + in data : io_buf_ptr_t; + out bytes_written : int + ); + +routine device_write_inband( + device : device_t; + sreplyport reply_port : reply_port_t; + in mode : dev_mode_t; + in recnum : recnum_t; + in data : io_buf_ptr_inband_t; + out bytes_written : int + ); + +routine device_read( + device : device_t; + sreplyport reply_port : reply_port_t; + in mode : dev_mode_t; + in recnum : recnum_t; + in bytes_wanted : int; + out data : io_buf_ptr_t + ); + +routine device_read_inband( + device : device_t; + sreplyport reply_port : reply_port_t; + in mode : dev_mode_t; + in recnum : recnum_t; + in bytes_wanted : int; + out data : io_buf_ptr_inband_t + ); + +/* obsolete */ +routine xxx_device_set_status( + device : device_t; + in flavor : dev_flavor_t; + in status : dev_status_t, IsLong + ); + +/* obsolete */ +routine xxx_device_get_status( + device : device_t; + in flavor : dev_flavor_t; + out status : dev_status_t, IsLong + ); + +/* obsolete */ +routine xxx_device_set_filter( + device : device_t; + in receive_port : mach_port_send_t; + in priority : int; + in filter : filter_array_t, IsLong + ); + +routine device_map( + device : device_t; + in prot : vm_prot_t; + in offset : vm_offset_t; + in size : vm_size_t; + out pager : memory_object_t; + in unmap : int + ); + +routine device_set_status( + device : device_t; + in flavor : dev_flavor_t; + in status : dev_status_t + ); + +routine device_get_status( + device : device_t; + in flavor : dev_flavor_t; + out status : dev_status_t, CountInOut + ); + +routine device_set_filter( + device : device_t; + in receive_port : mach_port_send_t; + in priority : int; + in filter : filter_array_t + ); + +routine device_intr_notify( + master_port : mach_port_t; + in irq : int; + in id : int; + in receive_port : mach_port_send_t + ); + +/* + * Test whether IPC devices exist. + */ +routine pci_present( + master_port : mach_port_t); + +/* + * Find the specified PCI device. + */ +routine pci_find_device( + master_port : mach_port_t; + vendor : short; + device_id : short; + index : short; + out bus : char; + out device_fn : char); + +/* + * Read the configuration space of a IPC device. + */ +routine pci_read_config( + master_port : mach_port_t; + bus : char; + device_fn : char; + where : char; + bytes_wanted : int; + out result : pci_config_data_t); + +/* + * Write the configuration space of a IPC device. + */ +routine pci_write_config( + master_port : mach_port_t; + bus : char; + device_fn : char; + where : char; + data : pci_config_data_t); + +/* + * enable/disable the specified irq. + */ +routine device_irq_enable( + master_port : mach_port_t; + irq : int; + status : char); diff --git a/libddekit/include/Makefile b/libddekit/include/Makefile deleted file mode 100644 index 8d31023f..00000000 --- a/libddekit/include/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -PKGDIR ?= .. -L4DIR ?= $(PKGDIR)/../.. - -# All haeder files found in this directory tree will be automatically -# installed in a way that they can be included with -# #include <l4/pkgname/yourfile.h> later. -# No need to list them in this Makefile. - -include $(L4DIR)/mk/include.mk diff --git a/libddekit/include/ddekit/assert.h b/libddekit/include/ddekit/assert.h index 5d572b49..5d593662 100644 --- a/libddekit/include/ddekit/assert.h +++ b/libddekit/include/ddekit/assert.h @@ -1,8 +1,8 @@ #ifndef _ddekit_assert_h #define _ddekit_assert_h -#include <l4/dde/ddekit/printf.h> -#include <l4/dde/ddekit/panic.h> +#include "ddekit/printf.h" +#include "ddekit/panic.h" /** \file ddekit/assert.h */ diff --git a/libddekit/include/ddekit/condvar.h b/libddekit/include/ddekit/condvar.h index ba87358d..129a718d 100644 --- a/libddekit/include/ddekit/condvar.h +++ b/libddekit/include/ddekit/condvar.h @@ -2,6 +2,7 @@ #define _ddekit_condvar_h /** \file ddekit/condvar.h */ +#include "ddekit/lock.h" struct ddekit_condvar; typedef struct ddekit_condvar ddekit_condvar_t; diff --git a/libddekit/include/ddekit/initcall.h b/libddekit/include/ddekit/initcall.h deleted file mode 100644 index b503cc6a..00000000 --- a/libddekit/include/ddekit/initcall.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _ddekit_initcall_h -#define _ddekit_initcall_h - -// from l4/sys/compiler.h -#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ >= 4 -#define L4_STICKY(x) __attribute__((used)) x -#else -#define L4_STICKY(x) __attribute__((unused)) x -#endif - -#define l4str(s) #s - -// from dde_linux/ARCH-x86/ctor.h -typedef void (*l4ddekit_initcall_t)(void); - -#define __l4ddekit_initcall(p) \ - __attribute__ ((__section__ (".l4dde_ctors." #p))) - -/** Define a function to be a DDEKit initcall. - * - * Define a function to be a DDEKit initcall. This function will then be placed - * in a separate linker section of the binary (called .l4dde_ctors). The L4Env - * construction mechanism will execute all constructors in this section during - * application startup. - * - * This is the right place to place Linux' module_init functions & Co. - * - * \param fn function - */ -#define DDEKIT_INITCALL(fn) DDEKIT_CTOR(fn, 1) - -#define DDEKIT_CTOR(fn, prio) \ - static l4ddekit_initcall_t \ - L4_STICKY(__l4ddekit_initcall_##fn) \ - __l4ddekit_initcall(prio) = (void *)fn - -/** - * Runs all registered initcalls. - */ -void ddekit_do_initcalls(void); - -#endif diff --git a/libddekit/include/ddekit/thread.h b/libddekit/include/ddekit/thread.h index 6e505818..8ed52013 100644 --- a/libddekit/include/ddekit/thread.h +++ b/libddekit/include/ddekit/thread.h @@ -3,6 +3,8 @@ /** \defgroup DDEKit_threads */ +#include "ddekit/lock.h" + struct ddekit_thread; typedef struct ddekit_thread ddekit_thread_t; diff --git a/libddekit/init.c b/libddekit/init.c index 6bc9d8ff..9114ff46 100644 --- a/libddekit/init.c +++ b/libddekit/init.c @@ -9,8 +9,11 @@ void ddekit_init(void) { extern void linux_kmem_init (); extern int log_init (); + extern void interrupt_init (); + ddekit_init_threads(); linux_kmem_init (); log_init (); + interrupt_init (); } diff --git a/libddekit/initcall.c b/libddekit/initcall.c deleted file mode 100644 index 49e1fec1..00000000 --- a/libddekit/initcall.c +++ /dev/null @@ -1,8 +0,0 @@ -#include <l4/dde/ddekit/initcall.h> - -#include <l4/crtx/crt0.h> - -void ddekit_do_initcalls() { - crt0_dde_construction(); -} - diff --git a/libddekit/interrupt.c b/libddekit/interrupt.c index 6a8b3fd8..5a778f9b 100644 --- a/libddekit/interrupt.c +++ b/libddekit/interrupt.c @@ -8,9 +8,17 @@ * FIXME use consume flag to indicate IRQ was handled */ +#include <stdio.h> +#include <error.h> +#include <mach.h> +#include <hurd.h> + #include "ddekit/interrupt.h" +#include "ddekit/semaphore.h" +#include "ddekit/printf.h" +#include "ddekit/memory.h" -#include <stdio.h> +#include "device_U.h" #define DEBUG_INTERRUPTS 0 @@ -18,6 +26,15 @@ #define BLOCK_IRQ 0 +#define MACH_NOTIFY_IRQ 100 + +typedef struct +{ + mach_msg_header_t irq_header; + mach_msg_type_t irq_type; + int irq; +} mach_irq_notification_t; + /* * Internal type for interrupt loop parameters */ @@ -35,19 +52,14 @@ struct intloop_params static struct { - int handle_irq; /* nested irq disable count */ - ddekit_lock_t *irqlock; + int handle_irq; /* nested irq disable count */ + ddekit_lock_t irqlock; ddekit_thread_t *irq_thread; /* thread ID for detaching from IRQ later on */ boolean_t thread_exit; thread_t mach_thread; } ddekit_irq_ctrl[MAX_INTERRUPTS]; - -static void ddekit_irq_exit_fn(l4thread_t thread, void *data) -{ - // TODO we can remove the port for delivery of interrupt explicitly, - // though it cannot cause any harm even if we don't remove it. -} +static mach_port_t master_device; /** * Interrupt service loop @@ -57,26 +69,25 @@ static void intloop(void *arg) { kern_return_t ret; struct intloop_params *params = arg; - mach_port_t delivery_port; + mach_port_t delivery_port = mach_reply_port (); int my_index; my_index = params->irq; - ddekit_irq_ctrl[my_index]->mach_thread = mach_thread_self (); + ddekit_irq_ctrl[my_index].mach_thread = mach_thread_self (); ret = thread_priority (mach_thread_self (), DDEKIT_IRQ_PRIO, 0); if (ret) error (0, ret, "thread_priority"); // TODO I should give another parameter to show whether // the interrupt can be shared. - ret = device_intr_notify (master_device, dev->irq, - dev->dev_id, delivery_port, + ret = device_intr_notify (master_device, params->irq, + 0, delivery_port, MACH_MSG_TYPE_MAKE_SEND); if (!ret) { /* inform thread creator of error */ /* XXX does omega0 error code have any meaning to DDEKit users? */ params->start_err = ret; ddekit_sem_up(params->started); - return NULL; } #if 0 @@ -104,23 +115,25 @@ static void intloop(void *arg) /* It's an interrupt not for us. It shouldn't happen. */ if (irq_header->irq != params->irq) { - LOG("We get interrupt %d, %d is expected", - irq_header->irq, params->irq); + ddekit_printf ("We get interrupt %d, %d is expected", + irq_header->irq, params->irq); return 1; } /* only call registered handler function, if IRQ is not disabled */ ddekit_lock_lock (&ddekit_irq_ctrl[my_index].irqlock); if (ddekit_irq_ctrl[my_index].handle_irq > 0) { - LOGd(DEBUG_INTERRUPTS, "IRQ %x, handler %p", my_index,params->handler); + ddekit_printf ("IRQ %x, handler %p", + my_index,params->handler); params->handler(params->priv); } else - LOGd(DEBUG_INTERRUPTS, "not handling IRQ %x, because it is disabled.", my_index); + ddekit_printf ("not handling IRQ %x, because it is disabled.", + my_index); // ((mig_reply_header_t *) outp)->RetCode = MIG_NO_REPLY; - if (ddekit_irq_ctrl[irq].thread_exit) { + if (ddekit_irq_ctrl[my_index].thread_exit) { ddekit_lock_unlock (&ddekit_irq_ctrl[my_index].irqlock); ddekit_thread_exit(); return 1; @@ -129,7 +142,7 @@ static void intloop(void *arg) return 1; } - mach_msg_server (int_server, 0, delivery_port); + mach_msg_server (irq_server, 0, delivery_port); } @@ -238,3 +251,13 @@ void ddekit_interrupt_enable(int irq) ddekit_lock_unlock (&ddekit_irq_ctrl[irq].irqlock); } } + +void interrupt_init () +{ + + error_t err; + + err = get_privileged_ports (0, &master_device); + if (err) + error (1, err, "get_privileged_ports"); +} diff --git a/libddekit/kmem.c b/libddekit/kmem.c index 4769190e..2e6f7340 100644 --- a/libddekit/kmem.c +++ b/libddekit/kmem.c @@ -28,9 +28,12 @@ #include <hurd.h> #include <cthreads.h> -#include "util.h" #include "vm_param.h" +#include "ddekit/panic.h" + +#define debug ddekit_debug + extern int printf (const char *, ...); /* Amount of memory to reserve for Linux memory allocator. diff --git a/libddekit/list.c b/libddekit/list.c index 992ea9ad..4f163584 100644 --- a/libddekit/list.c +++ b/libddekit/list.c @@ -48,7 +48,7 @@ struct list *remove_entry_head (struct list *head) { struct list *entry = head->next; - if (EMPTY_ENTRY (entry)) + if (EMPTY_LIST (entry)) return NULL; remove_entry (entry); @@ -59,7 +59,7 @@ struct list *remove_entry_end (struct list *head) { struct list *entry = head->prev; - if (EMPTY_ENTRY (entry)) + if (EMPTY_LIST (entry)) return NULL; remove_entry (entry); diff --git a/libddekit/lock.c b/libddekit/lock.c index bf643e65..4c4cff01 100644 --- a/libddekit/lock.c +++ b/libddekit/lock.c @@ -1,6 +1,7 @@ #include <cthreads.h> #include "ddekit/lock.h" +#include "ddekit/memory.h" #define DDEKIT_DEBUG_LOCKS 0 @@ -48,6 +49,6 @@ int _ddekit_lock_owner(struct ddekit_lock **mtx) { /* The return value is the address of the holder. * I hope it will be OK. At least, it is OK * for the current implementation of DDE Linux/BSD */ - return (int) (*mtx)->holder; + return (int) (*mtx)->helder; } diff --git a/libddekit/mach.defs b/libddekit/mach.defs new file mode 100644 index 00000000..764bd451 --- /dev/null +++ b/libddekit/mach.defs @@ -0,0 +1,779 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University. + * Copyright (c) 1993,1994 The University of Utah and + * the Computer Systems Laboratory (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Matchmaker definitions file for Mach kernel interface. + */ + +#ifdef MACH_KERNEL +simport <kern/compat_xxx_defs.h>; /* for obsolete routines */ +#endif /* MACH_KERNEL */ + +subsystem +#if KERNEL_USER + KernelUser +#endif /* KERNEL_USER */ +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + mach 2000; + +#ifdef KERNEL_USER +userprefix r_; +#endif /* KERNEL_USER */ + +#include <mach/std_types.defs> +#include <mach/mach_types.defs> + +skip; /* old port_allocate */ +skip; /* old port_deallocate */ +skip; /* old port_enable */ +skip; /* old port_disable */ +skip; /* old port_select */ +skip; /* old port_set_backlog */ +skip; /* old port_status */ + +/* + * Create a new task with an empty set of IPC rights, + * and having an address space constructed from the + * target task (or empty, if inherit_memory is FALSE). + */ +routine task_create( + target_task : task_t; + inherit_memory : boolean_t; + out child_task : task_t); + +/* + * Destroy the target task, causing all of its threads + * to be destroyed, all of its IPC rights to be deallocated, + * and all of its address space to be deallocated. + */ +routine task_terminate( + target_task : task_t); + +/* + * Get user-level handler entry points for all + * emulated system calls. + */ +routine task_get_emulation_vector( + task : task_t; + out vector_start : int; + out emulation_vector: emulation_vector_t); + +/* + * Establish user-level handlers for the specified + * system calls. Non-emulated system calls are specified + * with emulation_vector[i] == EML_ROUTINE_NULL. + */ +routine task_set_emulation_vector( + task : task_t; + vector_start : int; + emulation_vector: emulation_vector_t); + + +/* + * Returns the set of threads belonging to the target task. + */ +routine task_threads( + target_task : task_t; + out thread_list : thread_array_t); + +/* + * Returns information about the target task. + */ +routine task_info( + target_task : task_t; + flavor : int; + out task_info_out : task_info_t, CountInOut); + + +skip; /* old task_status */ +skip; /* old task_set_notify */ +skip; /* old thread_create */ + +/* + * Destroy the target thread. + */ +routine thread_terminate( + target_thread : thread_t); + +/* + * Return the selected state information for the target + * thread. If the thread is currently executing, the results + * may be stale. [Flavor THREAD_STATE_FLAVOR_LIST provides a + * list of valid flavors for the target thread.] + */ +routine thread_get_state( + target_thread : thread_t; + flavor : int; + out old_state : thread_state_t, CountInOut); + +/* + * Set the selected state information for the target thread. + * If the thread is currently executing, the state change + * may be ill-defined. + */ +routine thread_set_state( + target_thread : thread_t; + flavor : int; + new_state : thread_state_t); + +/* + * Returns information about the target thread. + */ +routine thread_info( + target_thread : thread_t; + flavor : int; + out thread_info_out : thread_info_t, CountInOut); + +skip; /* old thread_mutate */ + +/* + * Allocate zero-filled memory in the address space + * of the target task, either at the specified address, + * or wherever space can be found (if anywhere is TRUE), + * of the specified size. The address at which the + * allocation actually took place is returned. + */ +#ifdef EMULATOR +skip; /* the emulator redefines vm_allocate using vm_map */ +#else /* EMULATOR */ +routine vm_allocate( + target_task : vm_task_t; + inout address : vm_address_t; + size : vm_size_t; + anywhere : boolean_t); +#endif /* EMULATOR */ + +skip; /* old vm_allocate_with_pager */ + +/* + * Deallocate the specified range from the virtual + * address space of the target task. + */ +routine vm_deallocate( + target_task : vm_task_t; + address : vm_address_t; + size : vm_size_t); + +/* + * Set the current or maximum protection attribute + * for the specified range of the virtual address + * space of the target task. The current protection + * limits the memory access rights of threads within + * the task; the maximum protection limits the accesses + * that may be given in the current protection. + * Protections are specified as a set of {read, write, execute} + * *permissions*. + */ +routine vm_protect( + target_task : vm_task_t; + address : vm_address_t; + size : vm_size_t; + set_maximum : boolean_t; + new_protection : vm_prot_t); + +/* + * Set the inheritance attribute for the specified range + * of the virtual address space of the target task. + * The inheritance value is one of {none, copy, share}, and + * specifies how the child address space should acquire + * this memory at the time of a task_create call. + */ +routine vm_inherit( + target_task : vm_task_t; + address : vm_address_t; + size : vm_size_t; + new_inheritance : vm_inherit_t); + +/* + * Returns the contents of the specified range of the + * virtual address space of the target task. [The + * range must be aligned on a virtual page boundary, + * and must be a multiple of pages in extent. The + * protection on the specified range must permit reading.] + */ +routine vm_read( + target_task : vm_task_t; + address : vm_address_t; + size : vm_size_t; + out data : pointer_t); + +/* + * Writes the contents of the specified range of the + * virtual address space of the target task. [The + * range must be aligned on a virtual page boundary, + * and must be a multiple of pages in extent. The + * protection on the specified range must permit writing.] + */ +routine vm_write( + target_task : vm_task_t; + address : vm_address_t; + data : pointer_t); + +/* + * Copy the contents of the source range of the virtual + * address space of the target task to the destination + * range in that same address space. [Both of the + * ranges must be aligned on a virtual page boundary, + * and must be multiples of pages in extent. The + * protection on the source range must permit reading, + * and the protection on the destination range must + * permit writing.] + */ +routine vm_copy( + target_task : vm_task_t; + source_address : vm_address_t; + size : vm_size_t; + dest_address : vm_address_t); + +/* + * Returns information about the contents of the virtual + * address space of the target task at the specified + * address. The returned protection, inheritance, sharing + * and memory object values apply to the entire range described + * by the address range returned; the memory object offset + * corresponds to the beginning of the address range. + * [If the specified address is not allocated, the next + * highest address range is described. If no addresses beyond + * the one specified are allocated, the call returns KERN_NO_SPACE.] + */ +routine vm_region( + target_task : vm_task_t; + inout address : vm_address_t; + out size : vm_size_t; + out protection : vm_prot_t; + out max_protection : vm_prot_t; + out inheritance : vm_inherit_t; + out is_shared : boolean_t; + /* avoid out-translation of the argument */ + out object_name : memory_object_name_t = + MACH_MSG_TYPE_MOVE_SEND + ctype: mach_port_t; + out offset : vm_offset_t); + +/* + * Return virtual memory statistics for the host + * on which the target task resides. [Note that the + * statistics are not specific to the target task.] + */ +routine vm_statistics( + target_task : vm_task_t; + out vm_stats : vm_statistics_data_t); + +skip; /* old task_by_u*x_pid */ +skip; /* old vm_pageable */ + +/* + * Stash a handful of ports for the target task; child + * tasks inherit this stash at task_create time. + */ +routine mach_ports_register( + target_task : task_t; + init_port_set : mach_port_array_t = + ^array[] of mach_port_t); + +/* + * Retrieve the stashed ports for the target task. + */ +routine mach_ports_lookup( + target_task : task_t; + out init_port_set : mach_port_array_t = + ^array[] of mach_port_t); + +skip; /* old u*x_pid */ +skip; /* old netipc_listen */ +skip; /* old netipc_ignore */ + +/* + * Provide the data contents of a range of the given memory + * object, with the access restriction specified. [Only + * whole virtual pages of data can be accepted; partial pages + * will be discarded. Data should be provided on request, but + * may be provided in advance as desired. When data already + * held by this kernel is provided again, the new data is ignored. + * The access restriction is the subset of {read, write, execute} + * which are prohibited. The kernel may not provide any data (or + * protection) consistency among pages with different virtual page + * alignments within the same object.] + */ +simpleroutine memory_object_data_provided( + memory_control : memory_object_control_t; + offset : vm_offset_t; + data : pointer_t; + lock_value : vm_prot_t); + +/* + * Indicate that a range of the given temporary memory object does + * not exist, and that the backing memory object should be used + * instead (or zero-fill memory be used, if no backing object exists). + * [This call is intended for use only by the default memory manager. + * It should not be used to indicate a real error -- + * memory_object_data_error should be used for that purpose.] + */ +simpleroutine memory_object_data_unavailable( + memory_control : memory_object_control_t; + offset : vm_offset_t; + size : vm_size_t); + +/* + * Retrieves the attributes currently associated with + * a memory object. + */ +routine memory_object_get_attributes( + memory_control : memory_object_control_t; + out object_ready : boolean_t; + out may_cache : boolean_t; + out copy_strategy : memory_object_copy_strategy_t); + +/* + * Sets the default memory manager, the port to which + * newly-created temporary memory objects are delivered. + * [See (memory_object_default)memory_object_create.] + * The old memory manager port is returned. + */ +routine vm_set_default_memory_manager( + host_priv : host_priv_t; + inout default_manager : mach_port_make_send_t); + +skip; /* old pager_flush_request */ + +/* + * Control use of the data associated with the given + * memory object. For each page in the given range, + * perform the following operations, in order: + * 1) restrict access to the page (disallow + * forms specified by "prot"); + * 2) write back modifications (if "should_return" + * is RETURN_DIRTY and the page is dirty, or + * "should_return" is RETURN_ALL and the page + * is either dirty or precious); and, + * 3) flush the cached copy (if "should_flush" + * is asserted). + * The set of pages is defined by a starting offset + * ("offset") and size ("size"). Only pages with the + * same page alignment as the starting offset are + * considered. + * + * A single acknowledgement is sent (to the "reply_to" + * port) when these actions are complete. + * + * There are two versions of this routine because IPC distinguishes + * between booleans and integers (a 2-valued integer is NOT a + * boolean). The new routine is backwards compatible at the C + * language interface. + */ +simpleroutine xxx_memory_object_lock_request( + memory_control : memory_object_control_t; + offset : vm_offset_t; + size : vm_size_t; + should_clean : boolean_t; + should_flush : boolean_t; + lock_value : vm_prot_t; + reply_to : mach_port_t = + MACH_MSG_TYPE_MAKE_SEND_ONCE|polymorphic); + + +simpleroutine memory_object_lock_request( + memory_control : memory_object_control_t; + offset : vm_offset_t; + size : vm_size_t; + should_return : memory_object_return_t; + should_flush : boolean_t; + lock_value : vm_prot_t; + reply_to : mach_port_t = + MACH_MSG_TYPE_MAKE_SEND_ONCE|polymorphic); + +/* obsolete */ +routine xxx_task_get_emulation_vector( + task : task_t; + out vector_start : int; + out emulation_vector: xxx_emulation_vector_t, IsLong); + +/* obsolete */ +routine xxx_task_set_emulation_vector( + task : task_t; + vector_start : int; + emulation_vector: xxx_emulation_vector_t, IsLong); + +/* + * Returns information about the host on which the + * target object resides. [This object may be + * a task, thread, or memory_object_control port.] + */ +routine xxx_host_info( + target_task : mach_port_t; + out info : machine_info_data_t); + +/* + * Returns information about a particular processor on + * the host on which the target task resides. + */ +routine xxx_slot_info( + target_task : task_t; + slot : int; + out info : machine_slot_data_t); + +/* + * Performs control operations (currently only + * turning off or on) on a particular processor on + * the host on which the target task resides. + */ +routine xxx_cpu_control( + target_task : task_t; + cpu : int; + running : boolean_t); + +skip; /* old thread_statistics */ +skip; /* old task_statistics */ +skip; /* old netport_init */ +skip; /* old netport_enter */ +skip; /* old netport_remove */ +skip; /* old thread_set_priority */ + +/* + * Increment the suspend count for the target task. + * No threads within a task may run when the suspend + * count for that task is non-zero. + */ +routine task_suspend( + target_task : task_t); + +/* + * Decrement the suspend count for the target task, + * if the count is currently non-zero. If the resulting + * suspend count is zero, then threads within the task + * that also have non-zero suspend counts may execute. + */ +routine task_resume( + target_task : task_t); + +/* + * Returns the current value of the selected special port + * associated with the target task. + */ +routine task_get_special_port( + task : task_t; + which_port : int; + out special_port : mach_port_t); + +/* + * Set one of the special ports associated with the + * target task. + */ +routine task_set_special_port( + task : task_t; + which_port : int; + special_port : mach_port_t); + +/* obsolete */ +routine xxx_task_info( + target_task : task_t; + flavor : int; + out task_info_out : task_info_t, IsLong); + + +/* + * Create a new thread within the target task, returning + * the port representing that new thread. The + * initial execution state of the thread is undefined. + */ +routine thread_create( + parent_task : task_t; + out child_thread : thread_t); + +/* + * Increment the suspend count for the target thread. + * Once this call has completed, the thread will not + * execute any further user or meta- instructions. + * Once suspended, a thread may not execute again until + * its suspend count is zero, and the suspend count + * for its task is also zero. + */ +routine thread_suspend( + target_thread : thread_t); + +/* + * Decrement the suspend count for the target thread, + * if that count is not already zero. + */ +routine thread_resume( + target_thread : thread_t); + +/* + * Cause any user or meta- instructions currently being + * executed by the target thread to be aborted. [Meta- + * instructions consist of the basic traps for IPC + * (e.g., msg_send, msg_receive) and self-identification + * (e.g., task_self, thread_self, thread_reply). Calls + * described by MiG interfaces are not meta-instructions + * themselves.] + */ +routine thread_abort( + target_thread : thread_t); + +/* obsolete */ +routine xxx_thread_get_state( + target_thread : thread_t; + flavor : int; + out old_state : thread_state_t, IsLong); + +/* obsolete */ +routine xxx_thread_set_state( + target_thread : thread_t; + flavor : int; + new_state : thread_state_t, IsLong); + +/* + * Returns the current value of the selected special port + * associated with the target thread. + */ +routine thread_get_special_port( + thread : thread_t; + which_port : int; + out special_port : mach_port_t); + +/* + * Set one of the special ports associated with the + * target thread. + */ +routine thread_set_special_port( + thread : thread_t; + which_port : int; + special_port : mach_port_t); + +/* obsolete */ +routine xxx_thread_info( + target_thread : thread_t; + flavor : int; + out thread_info_out : thread_info_t, IsLong); + +/* + * Establish a user-level handler for the specified + * system call. + */ +routine task_set_emulation( + target_port : task_t; + routine_entry_pt: vm_address_t; + routine_number : int); + +/* + * Establish restart pc for interrupted atomic sequences. + * This reuses the message number for the old task_get_io_port. + * See task_info.h for description of flavors. + * + */ +routine task_ras_control( + target_task : task_t; + basepc : vm_address_t; + boundspc : vm_address_t; + flavor : int); + + + +skip; /* old host_ipc_statistics */ +skip; /* old port_names */ +skip; /* old port_type */ +skip; /* old port_rename */ +skip; /* old port_allocate */ +skip; /* old port_deallocate */ +skip; /* old port_set_backlog */ +skip; /* old port_status */ +skip; /* old port_set_allocate */ +skip; /* old port_set_deallocate */ +skip; /* old port_set_add */ +skip; /* old port_set_remove */ +skip; /* old port_set_status */ +skip; /* old port_insert_send */ +skip; /* old port_extract_send */ +skip; /* old port_insert_receive */ +skip; /* old port_extract_receive */ + +/* + * Map a user-defined memory object into the virtual address + * space of the target task. If desired (anywhere is TRUE), + * the kernel will find a suitable address range of the + * specified size; else, the specific address will be allocated. + * + * The beginning address of the range will be aligned on a virtual + * page boundary, be at or beyond the address specified, and + * meet the mask requirements (bits turned on in the mask must not + * be turned on in the result); the size of the range, in bytes, + * will be rounded up to an integral number of virtual pages. + * + * The memory in the resulting range will be associated with the + * specified memory object, with the beginning of the memory range + * referring to the specified offset into the memory object. + * + * The mapping will take the current and maximum protections and + * the inheritance attributes specified; see the vm_protect and + * vm_inherit calls for a description of these attributes. + * + * If desired (copy is TRUE), the memory range will be filled + * with a copy of the data from the memory object; this copy will + * be private to this mapping in this target task. Otherwise, + * the memory in this mapping will be shared with other mappings + * of the same memory object at the same offset (in this task or + * in other tasks). [The Mach kernel only enforces shared memory + * consistency among mappings on one host with similar page alignments. + * The user-defined memory manager for this object is responsible + * for further consistency.] + */ +#ifdef EMULATOR +routine htg_vm_map( + target_task : vm_task_t; + ureplyport reply_port : mach_port_make_send_once_t; + inout address : vm_address_t; + size : vm_size_t; + mask : vm_address_t; + anywhere : boolean_t; + memory_object : memory_object_t; + offset : vm_offset_t; + copy : boolean_t; + cur_protection : vm_prot_t; + max_protection : vm_prot_t; + inheritance : vm_inherit_t); +#else /* EMULATOR */ +routine vm_map( + target_task : vm_task_t; + inout address : vm_address_t; + size : vm_size_t; + mask : vm_address_t; + anywhere : boolean_t; + memory_object : memory_object_t; + offset : vm_offset_t; + copy : boolean_t; + cur_protection : vm_prot_t; + max_protection : vm_prot_t; + inheritance : vm_inherit_t); +#endif /* EMULATOR */ + +/* + * Indicate that a range of the specified memory object cannot + * be provided at this time. [Threads waiting for memory pages + * specified by this call will experience a memory exception. + * Only threads waiting at the time of the call are affected.] + */ +simpleroutine memory_object_data_error( + memory_control : memory_object_control_t; + offset : vm_offset_t; + size : vm_size_t; + error_value : kern_return_t); + +/* + * Make decisions regarding the use of the specified + * memory object. + */ +simpleroutine memory_object_set_attributes( + memory_control : memory_object_control_t; + object_ready : boolean_t; + may_cache : boolean_t; + copy_strategy : memory_object_copy_strategy_t); + +/* + */ +simpleroutine memory_object_destroy( + memory_control : memory_object_control_t; + reason : kern_return_t); + +/* + * Provide the data contents of a range of the given memory + * object, with the access restriction specified, optional + * precious attribute, and reply message. [Only + * whole virtual pages of data can be accepted; partial pages + * will be discarded. Data should be provided on request, but + * may be provided in advance as desired. When data already + * held by this kernel is provided again, the new data is ignored. + * The access restriction is the subset of {read, write, execute} + * which are prohibited. The kernel may not provide any data (or + * protection) consistency among pages with different virtual page + * alignments within the same object. The precious value controls + * how the kernel treats the data. If it is FALSE, the kernel treats + * its copy as a temporary and may throw it away if it hasn't been + * changed. If the precious value is TRUE, the kernel treats its + * copy as a data repository and promises to return it to the manager; + * the manager may tell the kernel to throw it away instead by flushing + * and not cleaning the data -- see memory_object_lock_request. The + * reply_to port is for a compeletion message; it will be + * memory_object_supply_completed.] + */ + +simpleroutine memory_object_data_supply( + memory_control : memory_object_control_t; + offset : vm_offset_t; + data : pointer_t, Dealloc[]; + lock_value : vm_prot_t; + precious : boolean_t; + reply_to : mach_port_t = + MACH_MSG_TYPE_MAKE_SEND_ONCE|polymorphic); + +simpleroutine memory_object_ready( + memory_control : memory_object_control_t; + may_cache : boolean_t; + copy_strategy : memory_object_copy_strategy_t); + +simpleroutine memory_object_change_attributes( + memory_control : memory_object_control_t; + may_cache : boolean_t; + copy_strategy : memory_object_copy_strategy_t; + reply_to : mach_port_t = + MACH_MSG_TYPE_MAKE_SEND_ONCE|polymorphic); + +skip; /* old host_callout_statistics_reset */ +skip; /* old port_set_select */ +skip; /* old port_set_backup */ + +/* + * Set/Get special properties of memory associated + * to some virtual address range, such as cachability, + * migrability, replicability. Machine-dependent. + */ +routine vm_machine_attribute( + target_task : vm_task_t; + address : vm_address_t; + size : vm_size_t; + attribute : vm_machine_attribute_t; + inout value : vm_machine_attribute_val_t); + +/*skip;*/ /* old host_fpa_counters_reset */ + +/* + * This routine is created for allocating DMA buffers. + * We are going to get a contiguous physical memory + * and its physical address in addition to the virtual address. + */ +routine vm_dma_buff_alloc( + host_priv : host_priv_t; + target_task : vm_task_t; + size : vm_size_t; + out vaddr : vm_address_t; + out paddr : vm_address_t); + +/* + * There is no more room in this interface for additional calls. + */ diff --git a/libddekit/malloc.c b/libddekit/malloc.c index c3735bdb..a30cd7b7 100644 --- a/libddekit/malloc.c +++ b/libddekit/malloc.c @@ -29,6 +29,9 @@ * * Each chunk stores its size in the first word for free() to work. */ + +#include <stdlib.h> + void *ddekit_simple_malloc(unsigned size) { return malloc (size); diff --git a/libddekit/memory.c b/libddekit/memory.c index 93853e55..27be4eeb 100644 --- a/libddekit/memory.c +++ b/libddekit/memory.c @@ -11,8 +11,10 @@ */ #include "ddekit/memory.h" +#include "ddekit/panic.h" extern void * linux_kmalloc (unsigned int size, int priority); +extern void linux_kfree (void *p); /**************** @@ -110,6 +112,7 @@ void *ddekit_slab_get_data(struct ddekit_slab * slab) #if 0 return l4slab_get_data(&slab->cache); #endif + return NULL; } @@ -154,7 +157,7 @@ struct ddekit_slab * ddekit_slab_init(unsigned size, int contiguous) */ void ddekit_large_free(void *objp) { - return linux_kfree (objp); + linux_kfree (objp); } diff --git a/libddekit/pci.c b/libddekit/pci.c index 32e02b84..5c3f4ef6 100644 --- a/libddekit/pci.c +++ b/libddekit/pci.c @@ -1,4 +1,8 @@ +#include <stdlib.h> #include <pciaccess.h> + +#include "ddekit/assert.h" +#include "ddekit/printf.h" #include "ddekit/pci.h" #include "config.h" @@ -43,8 +47,8 @@ void ddekit_pci_init(void) dev_iter = pci_slot_match_iterator_create (NULL); while ((pci_dev = pci_device_next (dev_iter)) != NULL) { if (slots_found == MAX_PCI_DEVS) { - LOGd(dbg_this, "find more than %d pci devices", - slots_found); + ddekit_printf ("find more than %d pci devices", + slots_found); break; } /* Pretend all our devices are chained to exactly one bus. */ @@ -68,7 +72,7 @@ int ddekit_pci_get_device(int nr, int *bus, int *slot, int *func) { ddekit_pci_dev_t *dev; - LOGd(dbg_this, "searching for dev #%d", nr); + ddekit_printf ("searching for dev #%d", nr); if (nr >= 0 && nr < MAX_PCI_DEVS && !invalid_device(&ddekit_pci_bus[nr])) { dev = &ddekit_pci_bus[nr]; @@ -89,7 +93,8 @@ ddekit_pci_dev_t *ddekit_pci_find_device(int *bus, int *slot, int *func, Assert(slot); Assert(func); - LOGd(dbg_this, "start %p (slot %d)", start, start ? start->slot : -1); + ddekit_printf ("start %p (slot %d)", + start, start ? start->slot : -1); int idx = start ? start->slot + 1 : 0; for ( ; idx < MAX_PCI_DEVS; ++idx) { @@ -214,7 +219,8 @@ int ddekit_pci_writel(int bus, int slot, int func, int pos, ddekit_uint32_t val int ddekit_pci_enable_device(struct ddekit_pci_dev *dev) { - return pci_device_enable (dev->dev); + pci_device_enable (dev->dev); + return 0; } int ddekit_pci_disable_device(struct ddekit_pci_dev *dev) @@ -238,7 +244,7 @@ int ddekit_pci_disable_device(struct ddekit_pci_dev *dev) */ unsigned short ddekit_pci_get_vendor(struct ddekit_pci_dev *dev) { - return dev->dev.vendor_id; + return dev->dev->vendor_id; } @@ -251,7 +257,7 @@ unsigned short ddekit_pci_get_vendor(struct ddekit_pci_dev *dev) */ unsigned short ddekit_pci_get_device_id(struct ddekit_pci_dev *dev) { - return dev->dev.device_id; + return dev->dev->device_id; } @@ -264,7 +270,7 @@ unsigned short ddekit_pci_get_device_id(struct ddekit_pci_dev *dev) */ unsigned short ddekit_pci_get_sub_vendor(struct ddekit_pci_dev *dev) { - return dev->dev.subvendor_id; + return dev->dev->subvendor_id; } @@ -277,7 +283,7 @@ unsigned short ddekit_pci_get_sub_vendor(struct ddekit_pci_dev *dev) */ unsigned short ddekit_pci_get_sub_device(struct ddekit_pci_dev *dev) { - return dev->dev.subdevice_id; + return dev->dev->subdevice_id; } @@ -290,7 +296,7 @@ unsigned short ddekit_pci_get_sub_device(struct ddekit_pci_dev *dev) */ unsigned ddekit_pci_get_dev_class(struct ddekit_pci_dev *dev) { - return dev->dev.device_class; + return dev->dev->device_class; } @@ -303,7 +309,7 @@ unsigned ddekit_pci_get_dev_class(struct ddekit_pci_dev *dev) */ unsigned long ddekit_pci_get_irq(struct ddekit_pci_dev *dev) { - return dev->dev.irq; + return dev->dev->irq; } @@ -345,10 +351,11 @@ char *ddekit_pci_get_slot_name(struct ddekit_pci_dev *dev) */ ddekit_pci_res_t *ddekit_pci_get_resource(struct ddekit_pci_dev *dev, unsigned int idx) { - if (idx > L4IO_PCIDEV_RES) + // TODO +// if (idx > L4IO_PCIDEV_RES) return NULL; - //TODO return (ddekit_pci_res_t *)(&(dev->l4dev.res[idx])); +// return (ddekit_pci_res_t *)(&(dev->l4dev.res[idx])); } diff --git a/libddekit/printf.c b/libddekit/printf.c index bbd58863..72ff5003 100644 --- a/libddekit/printf.c +++ b/libddekit/printf.c @@ -4,7 +4,10 @@ * \date 2006-03-01 */ +#include <error.h> +#include <errno.h> #include <stdio.h> +#include <stdlib.h> #include <unistd.h> #include "ddekit/printf.h" diff --git a/libddekit/thread.c b/libddekit/thread.c index a095db2f..081a4742 100644 --- a/libddekit/thread.c +++ b/libddekit/thread.c @@ -3,14 +3,18 @@ #include <cthreads.h> #include <time.h> #include <error.h> +#include <hurd.h> +#include <sys/time.h> +#include <assert.h> +#include "ddekit/memory.h" #include "ddekit/semaphore.h" #include "list.h" #include "ddekit/thread.h" #define DDEKIT_THREAD_STACK_SIZE 0x2000 /* 8 KB */ -static struct ddekit_slab *ddekit_stack_slab = NULL; +//static struct ddekit_slab *ddekit_stack_slab = NULL; struct _ddekit_private_data { struct list list; @@ -18,8 +22,7 @@ struct _ddekit_private_data { /* point to the thread who has the private data. */ struct ddekit_thread *thread; mach_msg_header_t wakeupmsg; - -} +}; struct ddekit_thread { struct cthread thread; @@ -64,20 +67,20 @@ static error_t _create_wakeupmsg (struct _ddekit_private_data *data) return 0; } -static void setup_thread (cthread_t *t, const char *name) { +static void setup_thread (struct ddekit_thread *t, const char *name) { error_t err; struct _ddekit_private_data *private_data; if (name) { - const char *cpy = NULL; + char *cpy = NULL; - cpy = malloc (strlen (name) + 1); + cpy = ddekit_simple_malloc (strlen (name) + 1); if (cpy == NULL) error (0, 0, "fail to allocate memory"); else strcpy (cpy, name); - cthread_set_name (t, name); + cthread_set_name (&t->thread, name); } /* @@ -92,20 +95,21 @@ static void setup_thread (cthread_t *t, const char *name) { private_data->sleep_cond = condition_alloc (); condition_init (private_data->sleep_cond); - private_data->list = {&private_data->list, &private_data->list}; + private_data->list.prev = &private_data->list; + private_data->list.next = &private_data->list; private_data->thread = t; err = _create_wakeupmsg (private_data); - // TODO I need to change this. - assert_perror (err); + if (err) + error (1, err, "_create_wakeupmsg"); - cthread_set_ldata (t, private_data); + cthread_set_ldata (&t->thread, private_data); } ddekit_thread_t *ddekit_thread_setup_myself(const char *name) { ddekit_thread_t *td = ddekit_thread_myself(); - setup_thread (&td->thread, name); + setup_thread (td, name); return td; } @@ -116,7 +120,7 @@ ddekit_thread_t *ddekit_thread_create(void (*fun)(void *), void *arg, const char // before initialization is completed. td = (ddekit_thread_t *) cthread_fork (fun, arg); cthread_detach (&td->thread); - setup_thread (&td->thread, name); + setup_thread (td, name); return td; } @@ -180,7 +184,7 @@ void ddekit_thread_sleep(ddekit_lock_t *lock) { // TODO condition_wait cannot guarantee that the thread is // woke up by another thread, maybe by signals. // Does it matter here? - condition_wait (data->sleep_cond, lock); + condition_wait (data->sleep_cond, (struct mutex *) *lock); } void dekit_thread_wakeup(ddekit_thread_t *td) { @@ -205,7 +209,7 @@ void ddekit_thread_exit() { name = cthread_name (t); cthread_set_name (t, NULL); - free (name); + ddekit_simple_free ((char *) name); cthread_exit (0); } @@ -225,10 +229,18 @@ void ddekit_yield(void) } void ddekit_init_threads() { + char *str = "main"; + char *name = ddekit_simple_malloc (strlen (str) + 1); + + strcpy (name, str); // TODO maybe the name has already been set. - cthread_set_name (cthread_self (), "main"); + cthread_set_name (cthread_self (), name); } +/********************************************************************** + * semaphore + **********************************************************************/ + /* Block THREAD. */ static error_t _timedblock (struct _ddekit_private_data *data, const struct timespec *abstime) @@ -281,16 +293,16 @@ static void _block (struct _ddekit_private_data *data) assert_perror (err); } -static int _sem_timedwait_internal (sem_t *restrict sem, +static int _sem_timedwait_internal (ddekit_sem_t *restrict sem, const struct timespec *restrict timeout) { - struct ddekit_private_data *self_private_data; + struct _ddekit_private_data *self_private_data; spin_lock (&sem->lock); if (sem->value > 0) { /* Successful down. */ sem->value --; - spin_unlock (&sem->__lock); + spin_unlock (&sem->lock); return 0; } @@ -350,13 +362,14 @@ ddekit_sem_t *ddekit_sem_init(int value) { (ddekit_sem_t *) ddekit_simple_malloc (sizeof (*sem)); sem->lock = SPIN_LOCK_INITIALIZER; - sem->head = {&sem->head, &sem->head}; + sem->head.prev = &sem->head; + sem->head.next = &sem->head; sem->value = value; return sem; } void ddekit_sem_deinit(ddekit_sem_t *sem) { - if (!EMPTY_ENTRY (&sem->head)) { + if (!EMPTY_LIST (&sem->head)) { error (0, EBUSY, "ddekit_sem_deinit"); } else @@ -388,11 +401,11 @@ int ddekit_sem_down_timed(ddekit_sem_t *sem, int timo) { timeout.tv_sec = timo / 1000; timeout.tv_nsec = (timo % 1000) * 1000 * 1000; - return __sem_timedwait_internal (sem, &timeout); + return _sem_timedwait_internal (sem, &timeout); } void ddekit_sem_up(ddekit_sem_t *sem) { - struct _ddekit_thread_data *wakeup; + struct _ddekit_private_data *wakeup; spin_lock (&sem->lock); if (sem->value > 0) { @@ -400,26 +413,25 @@ void ddekit_sem_up(ddekit_sem_t *sem) { assert (EMPTY_LIST (&sem->head)); sem->value ++; spin_unlock (&sem->lock); - return 0; + return; } if (EMPTY_LIST (&sem->head)) { /* No one waiting. */ sem->value = 1; spin_unlock (&sem->lock); - return 0; + return; } /* Wake someone up. */ /* First dequeue someone. */ - wakeup = (struct _ddekit_private_data *) remove_entry_end (&sem->head); + wakeup = LIST_ENTRY (remove_entry_end (&sem->head), + struct _ddekit_private_data, list); /* Then drop the lock and transfer control. */ spin_unlock (&sem->lock); if (wakeup) _thread_wakeup (wakeup); - - return 0; } diff --git a/libddekit/timer.c b/libddekit/timer.c index d0a6ccc0..f8bfc7a1 100644 --- a/libddekit/timer.c +++ b/libddekit/timer.c @@ -2,6 +2,9 @@ #include <maptime.h> #include <cthreads.h> +#include "ddekit/memory.h" +#include "ddekit/assert.h" +#include "ddekit/semaphore.h" #include "ddekit/timer.h" #define __DEBUG 0 @@ -118,7 +121,7 @@ int ddekit_add_timer(void (*fn)(void *), void *args, unsigned long timeout) * necessary to notify the timer thread. */ if (t == timer_list) { - Assert(!l4_is_nil_id(timer_thread)); + Assert(timer_thread); __notify_timer_thread(); } @@ -329,6 +332,6 @@ void ddekit_init_timers(void) root_jiffies = (long long) tp.tv_sec * HZ + ((long long) tp.tv_usec * HZ) / 1000000; - timer_thread = cthread_fork ((cthread_fn_t) timer_function, 0); + timer_thread = cthread_fork ((cthread_fn_t) ddekit_timer_thread, 0); cthread_detach (timer_thread); } diff --git a/libddekit/vm_param.h b/libddekit/vm_param.h new file mode 100644 index 00000000..7b615c8a --- /dev/null +++ b/libddekit/vm_param.h @@ -0,0 +1,7 @@ +#ifndef __VM_PARAM_H__ +#define __VM_PARAM_H__ + +#define PAGE_SIZE __vm_page_size +#define PAGE_MASK (PAGE_SIZE-1) + +#endif |