Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2306 → Rev 2307

/branches/rcu/contrib/conf/msim.conf
5,7 → 5,7
add dcpu mips1
 
add rwm mainmem 0x0 8M load "/dev/zero"
add rom startmem 0x1fc00000 1024k load "image.boot"
add rom startmem 0x1fc00000 2048k load "image.boot"
 
add dprinter printer 0x10000000
add dkeyboard keyboard 0x10000000 2
/branches/rcu/contrib/conf/ski.conf
6,6 → 6,6
romload HelenOS/uspace/kbd/kbd 0x1400000
romload HelenOS/uspace/tetris/tetris 0x1800000
romload HelenOS/uspace/klog/klog 0x1c00000
romload HelenOS/uspace/ipcc/ipcc 0x2000000
romload HelenOS/uspace/tester/tester 0x2000000
 
 
/branches/rcu/kernel/test/synch/rwlock3.c
45,14 → 45,14
thread_detach(THREAD);
if (!sh_quiet)
printf("cpu%d, tid %d: trying to lock rwlock for reading....\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu: trying to lock rwlock for reading....\n", CPU->id, THREAD->tid);
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
if (!sh_quiet) {
printf("cpu%d, tid %d: success\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %d: trying to lock rwlock for writing....\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu: success\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu: trying to lock rwlock for writing....\n", CPU->id, THREAD->tid);
}
 
rwlock_write_lock(&rwlock);
59,7 → 59,7
rwlock_write_unlock(&rwlock);
if (!sh_quiet)
printf("cpu%d, tid %d: success\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu: success\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
}
/branches/rcu/kernel/test/synch/rwlock4.c
74,18 → 74,18
to = random(40000);
if (!sh_quiet)
printf("cpu%d, tid %d w+ (%d)\n", CPU->id, THREAD->tid, to);
printf("cpu%d, tid %llu w+ (%d)\n", CPU->id, THREAD->tid, to);
rc = rwlock_write_lock_timeout(&rwlock, to);
if (SYNCH_FAILED(rc)) {
if (!sh_quiet)
printf("cpu%d, tid %d w!\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu w!\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
return;
}
if (!sh_quiet)
printf("cpu%d, tid %d w=\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu w=\n", CPU->id, THREAD->tid);
 
if (rwlock.readers_in) {
if (!sh_quiet)
106,7 → 106,7
rwlock_write_unlock(&rwlock);
if (!sh_quiet)
printf("cpu%d, tid %d w-\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu w-\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
}
 
119,24 → 119,24
to = random(2000);
if (!sh_quiet)
printf("cpu%d, tid %d r+ (%d)\n", CPU->id, THREAD->tid, to);
printf("cpu%d, tid %llu r+ (%d)\n", CPU->id, THREAD->tid, to);
rc = rwlock_read_lock_timeout(&rwlock, to);
if (SYNCH_FAILED(rc)) {
if (!sh_quiet)
printf("cpu%d, tid %d r!\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu r!\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
return;
}
if (!sh_quiet)
printf("cpu%d, tid %d r=\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu r=\n", CPU->id, THREAD->tid);
thread_usleep(30000);
rwlock_read_unlock(&rwlock);
if (!sh_quiet)
printf("cpu%d, tid %d r-\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu r-\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
}
 
/branches/rcu/kernel/test/synch/semaphore2.c
67,18 → 67,18
waitq_sleep(&can_start);
to = random(20000);
printf("cpu%d, tid %d down+ (%d)\n", CPU->id, THREAD->tid, to);
printf("cpu%d, tid %llu down+ (%d)\n", CPU->id, THREAD->tid, to);
rc = semaphore_down_timeout(&sem, to);
if (SYNCH_FAILED(rc)) {
printf("cpu%d, tid %d down!\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu down!\n", CPU->id, THREAD->tid);
return;
}
printf("cpu%d, tid %d down=\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu down=\n", CPU->id, THREAD->tid);
thread_usleep(random(30000));
semaphore_up(&sem);
printf("cpu%d, tid %d up\n", CPU->id, THREAD->tid);
printf("cpu%d, tid %llu up\n", CPU->id, THREAD->tid);
}
 
char * test_semaphore2(bool quiet)
/branches/rcu/kernel/test/tasklet/tasklet1.c
43,6 → 43,7
}
 
bool gquiet;
#ifdef CONFIG_SMP
 
static void running_tasklet(void * data)
{
102,7 → 103,7
if (!gquiet)
printf("Done!\n");
}
 
#endif
char * test_tasklet1(bool quiet)
{
gquiet = quiet;
109,8 → 110,8
waitq_t wq;
waitq_initialize(&wq);
tasklet_descriptor_t *tasklet_desc;
#ifdef CONFIG_SMP
thread_t* second_thread = NULL;
#ifdef CONFIG_SMP
if (!quiet)
printf("cpus:%d\n", config.cpu_active);
 
/branches/rcu/kernel/test/thread/thread1.c
48,8 → 48,8
 
while (atomic_get(&finish)) {
if (!sh_quiet)
printf("%d\n", (int) (THREAD->tid));
thread_usleep(100);
printf("%llu ", THREAD->tid);
thread_usleep(100000);
}
atomic_inc(&threads_finished);
}
/branches/rcu/kernel/test/mm/falloc2.c
58,7 → 58,7
uintptr_t * frames = (uintptr_t *) malloc(MAX_FRAMES * sizeof(uintptr_t), FRAME_ATOMIC);
if (frames == NULL) {
if (!sh_quiet)
printf("Thread #%d (cpu%d): Unable to allocate frames\n", THREAD->tid, CPU->id);
printf("Thread #%llu (cpu%d): Unable to allocate frames\n", THREAD->tid, CPU->id);
atomic_inc(&thread_fail);
atomic_dec(&thread_count);
return;
69,7 → 69,7
for (run = 0; run < THREAD_RUNS; run++) {
for (order = 0; order <= MAX_ORDER; order++) {
if (!sh_quiet)
printf("Thread #%d (cpu%d): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order);
printf("Thread #%llu (cpu%d): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order);
allocated = 0;
for (i = 0; i < (MAX_FRAMES >> order); i++) {
82,16 → 82,16
}
if (!sh_quiet)
printf("Thread #%d (cpu%d): %d blocks allocated.\n", THREAD->tid, CPU->id, allocated);
printf("Thread #%llu (cpu%d): %d blocks allocated.\n", THREAD->tid, CPU->id, allocated);
if (!sh_quiet)
printf("Thread #%d (cpu%d): Deallocating ... \n", THREAD->tid, CPU->id);
printf("Thread #%llu (cpu%d): Deallocating ... \n", THREAD->tid, CPU->id);
for (i = 0; i < allocated; i++) {
for (k = 0; k <= ((FRAME_SIZE << order) - 1); k++) {
if (((uint8_t *) frames[i])[k] != val) {
if (!sh_quiet)
printf("Thread #%d (cpu%d): Unexpected data (%d) in block %p offset %#zx\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k);
printf("Thread #%llu (cpu%d): Unexpected data (%d) in block %p offset %#zx\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k);
atomic_inc(&thread_fail);
goto cleanup;
}
100,7 → 100,7
}
if (!sh_quiet)
printf("Thread #%d (cpu%d): Finished run.\n", THREAD->tid, CPU->id);
printf("Thread #%llu (cpu%d): Finished run.\n", THREAD->tid, CPU->id);
}
}
 
108,7 → 108,7
free(frames);
if (!sh_quiet)
printf("Thread #%d (cpu%d): Exiting\n", THREAD->tid, CPU->id);
printf("Thread #%llu (cpu%d): Exiting\n", THREAD->tid, CPU->id);
atomic_dec(&thread_count);
}
 
/branches/rcu/kernel/test/mm/slab1.c
137,7 → 137,7
thread_detach(THREAD);
if (!sh_quiet)
printf("Starting thread #%d...\n", THREAD->tid);
printf("Starting thread #%llu...\n", THREAD->tid);
for (j = 0; j < 10; j++) {
for (i = 0; i < THR_MEM_COUNT; i++)
151,7 → 151,7
}
if (!sh_quiet)
printf("Thread #%d finished\n", THREAD->tid);
printf("Thread #%llu finished\n", THREAD->tid);
semaphore_up(&thr_sem);
}
/branches/rcu/kernel/test/mm/slab2.c
150,11 → 150,11
mutex_unlock(&starter_mutex);
if (!sh_quiet)
printf("Starting thread #%d...\n",THREAD->tid);
printf("Starting thread #%llu...\n",THREAD->tid);
 
/* Alloc all */
if (!sh_quiet)
printf("Thread #%d allocating...\n", THREAD->tid);
printf("Thread #%llu allocating...\n", THREAD->tid);
while (1) {
/* Call with atomic to detect end of memory */
166,7 → 166,7
}
if (!sh_quiet)
printf("Thread #%d releasing...\n", THREAD->tid);
printf("Thread #%llu releasing...\n", THREAD->tid);
while (data) {
new = *((void **)data);
176,7 → 176,7
}
if (!sh_quiet)
printf("Thread #%d allocating...\n", THREAD->tid);
printf("Thread #%llu allocating...\n", THREAD->tid);
while (1) {
/* Call with atomic to detect end of memory */
188,7 → 188,7
}
if (!sh_quiet)
printf("Thread #%d releasing...\n", THREAD->tid);
printf("Thread #%llu releasing...\n", THREAD->tid);
while (data) {
new = *((void **)data);
198,7 → 198,7
}
if (!sh_quiet)
printf("Thread #%d finished\n", THREAD->tid);
printf("Thread #%llu finished\n", THREAD->tid);
slab_print_list();
semaphore_up(&thr_sem);
/branches/rcu/kernel/test/fpu/mips2.c
72,7 → 72,7
if (arg != after_arg) {
if (!sh_quiet)
printf("General reg tid%d: arg(%d) != %d\n", THREAD->tid, arg, after_arg);
printf("General reg tid%llu: arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
104,7 → 104,7
if (arg != after_arg) {
if (!sh_quiet)
printf("General reg tid%d: arg(%d) != %d\n", THREAD->tid, arg, after_arg);
printf("General reg tid%llu: arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
/branches/rcu/kernel/test/fpu/fpu1.c
126,7 → 126,7
 
if ((int) (100000000 * e) != E_10e8) {
if (!sh_quiet)
printf("tid%d: e*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000 * e), (unative_t) E_10e8);
printf("tid%llu: e*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000 * e), (unative_t) E_10e8);
atomic_inc(&threads_fault);
break;
}
161,7 → 161,7
#ifdef KERN_ia64_ARCH_H_
if ((int) (1000000 * pi) != PI_10e8) {
if (!sh_quiet)
printf("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (1000000 * pi), (unative_t) (PI_10e8 / 100));
printf("tid%llu: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (1000000 * pi), (unative_t) (PI_10e8 / 100));
atomic_inc(&threads_fault);
break;
}
168,7 → 168,7
#else
if ((int) (100000000 * pi) != PI_10e8) {
if (!sh_quiet)
printf("tid%d: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000 * pi), (unative_t) PI_10e8);
printf("tid%llu: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000 * pi), (unative_t) PI_10e8);
atomic_inc(&threads_fault);
break;
}
/branches/rcu/kernel/test/fpu/sse1.c
72,7 → 72,7
if (arg != after_arg) {
if (!sh_quiet)
printf("tid%d: arg(%d) != %d\n", THREAD->tid, arg, after_arg);
printf("tid%llu: arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
104,7 → 104,7
if (arg != after_arg) {
if (!sh_quiet)
printf("tid%d: arg(%d) != %d\n", THREAD->tid, arg, after_arg);
printf("tid%llu: arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
/branches/rcu/kernel/test/print/print1.c
25,6 → 25,7
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <print.h>
#include <test.h>
 
/branches/rcu/kernel/kernel.config
92,9 → 92,6
# Lazy FPU context switching
! [(ARCH=mips32&MACHINE!=msim&MACHINE!=simics)|ARCH=amd64|ARCH=ia32|ARCH=ia64|ARCH=sparc64|ARCH=ia32xen] CONFIG_FPU_LAZY (y/n)
 
# Power off on halt
! [ARCH=ppc32] CONFIG_POWEROFF (n/y)
 
# Use VHPT
! [ARCH=ia64] CONFIG_VHPT (n/y)
 
/branches/rcu/kernel/genarch/src/acpi/acpi.c
88,7 → 88,7
 
static void map_sdt(struct acpi_sdt_header *sdt)
{
page_mapping_insert(AS_KERNEL, (uintptr_t) sdt, (uintptr_t) sdt, PAGE_NOT_CACHEABLE);
page_mapping_insert(AS_KERNEL, (uintptr_t) sdt, (uintptr_t) sdt, PAGE_NOT_CACHEABLE | PAGE_WRITE);
map_structure((uintptr_t) sdt, sdt->length);
}
 
/branches/rcu/kernel/generic/include/print.h
40,7 → 40,7
#include <arch/arg.h>
 
/* We need this address in spinlock to avoid deadlock in deadlock detection */
SPINLOCK_EXTERN(printflock);
SPINLOCK_EXTERN(printf_lock);
 
#define EOF (-1)
 
/branches/rcu/kernel/generic/include/time/clock.h
35,8 → 35,19
#ifndef KERN_CLOCK_H_
#define KERN_CLOCK_H_
 
#include <arch/types.h>
 
#define HZ 100
 
/** Uptime structure */
typedef struct {
unative_t seconds1;
unative_t useconds;
unative_t seconds2;
} uptime_t;
 
extern uptime_t *uptime;
 
extern void clock(void);
extern void clock_counter_init(void);
 
/branches/rcu/kernel/generic/include/proc/task.h
90,10 → 90,10
* Active asynchronous messages. It is used for limiting uspace to
* certain extent.
*/
atomic_t active_calls;
atomic_t active_calls;
/** Architecture specific task data. */
task_arch_t arch;
task_arch_t arch;
/**
* Serializes access to the B+tree of task's futexes. This mutex is
111,6 → 111,7
extern btree_t tasks_btree;
 
extern void task_init(void);
extern void task_done(void);
extern task_t *task_create(as_t *as, char *name);
extern void task_destroy(task_t *t);
extern task_t *task_run_program(void *program_addr, char *name);
/branches/rcu/kernel/generic/include/proc/thread.h
53,7 → 53,11
 
/* Thread flags */
 
/** Thread cannot be migrated to another CPU. */
/** Thread cannot be migrated to another CPU.
*
* When using this flag, the caller must set cpu in the thread_t
* structure manually before calling thread_ready (even on uniprocessor).
*/
#define THREAD_FLAG_WIRED (1 << 0)
/** Thread was migrated to another CPU and has not run yet. */
#define THREAD_FLAG_STOLEN (1 << 1)
193,7 → 197,7
/** Thread's priority. Implemented as index to CPU->rq */
int priority;
/** Thread ID. */
uint32_t tid;
thread_id_t tid;
/** Architecture-specific data. */
thread_arch_t arch;
248,8 → 252,9
extern slab_cache_t *fpu_context_slab;
 
/* Thread syscall prototypes. */
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name);
unative_t sys_thread_exit(int uspace_status);
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name, thread_id_t *uspace_thread_id);
extern unative_t sys_thread_exit(int uspace_status);
extern unative_t sys_thread_get_id(thread_id_t *uspace_thread_id);
 
#endif
 
/branches/rcu/kernel/generic/include/interrupt.h
48,7 → 48,7
#define fault_if_from_uspace(istate, cmd, ...) \
{ \
if (istate_from_uspace(istate)) { \
klog_printf("Task %lld killed due to an exception at %p.", TASK->taskid, istate_get_pc(istate)); \
klog_printf("Task %llu killed due to an exception at %p.", TASK->taskid, istate_get_pc(istate)); \
klog_printf(" " cmd, ##__VA_ARGS__); \
task_kill(TASK->taskid); \
thread_exit(); \
/branches/rcu/kernel/generic/include/synch/mutex.h
44,13 → 44,11
} mutex_t;
 
#define mutex_lock(mtx) \
_mutex_lock_timeout((mtx),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NONE)
_mutex_lock_timeout((mtx), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
#define mutex_trylock(mtx) \
_mutex_lock_timeout((mtx),SYNCH_NO_TIMEOUT,SYNCH_FLAGS_NON_BLOCKING)
#define mutex_lock_timeout(mtx,usec) \
_mutex_lock_timeout((mtx),(usec),SYNCH_FLAGS_NON_BLOCKING)
#define mutex_lock_active(mtx) \
while (mutex_trylock((mtx)) != ESYNCH_OK_ATOMIC)
_mutex_lock_timeout((mtx), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING)
#define mutex_lock_timeout(mtx, usec) \
_mutex_lock_timeout((mtx), (usec), SYNCH_FLAGS_NON_BLOCKING)
 
extern void mutex_initialize(mutex_t *mtx);
extern int _mutex_lock_timeout(mutex_t *mtx, uint32_t usec, int flags);
/branches/rcu/kernel/generic/include/synch/spinlock.h
101,8 → 101,26
preemption_enable();
}
 
#ifdef CONFIG_DEBUG_SPINLOCK
 
extern int printf(const char *, ...);
 
#define DEADLOCK_THRESHOLD 100000000
#define DEADLOCK_PROBE_INIT(pname) count_t pname = 0
#define DEADLOCK_PROBE(pname, value) \
if ((pname)++ > (value)) { \
(pname) = 0; \
printf("Deadlock probe %s: exceeded threshold %d\n", \
"cpu%d: function=%s, line=%d\n", \
#pname, (value), CPU->id, __FUNCTION__, __LINE__); \
}
#else
#define DEADLOCK_PROBE_INIT(pname)
#define DEADLOCK_PROBE(pname, value)
#endif
 
#else
 
/* On UP systems, spinlocks are effectively left out. */
#define SPINLOCK_DECLARE(name)
#define SPINLOCK_EXTERN(name)
113,6 → 131,9
#define spinlock_trylock(x) (preemption_disable(), 1)
#define spinlock_unlock(x) preemption_enable()
 
#define DEADLOCK_PROBE_INIT(pname)
#define DEADLOCK_PROBE(pname, value)
 
#endif
 
#endif
/branches/rcu/kernel/generic/include/ddi/irq.h
121,6 → 121,14
* this lock must not be taken first.
*/
SPINLOCK_DECLARE(lock);
/** Send EOI before processing the interrupt.
* This is essential for timer interrupt which
* has to be acknowledged before doing preemption
* to make sure another timer interrupt will
* be eventually generated.
*/
bool preack;
 
/** Unique device number. -1 if not yet assigned. */
devno_t devno;
127,7 → 135,7
 
/** Actual IRQ number. -1 if not yet assigned. */
inr_t inr;
/** Trigger level of the IRQ.*/
/** Trigger level of the IRQ. */
irq_trigger_t trigger;
/** Claim ownership of the IRQ. */
irq_ownership_t (* claim)(void);
/branches/rcu/kernel/generic/include/printf/printf_core.h
47,7 → 47,7
 
};
 
int printf_core(const char *fmt, struct printf_spec *ps ,va_list ap);
int printf_core(const char *fmt, struct printf_spec *ps, va_list ap);
 
#endif
 
/branches/rcu/kernel/generic/include/arch.h
74,8 → 74,12
extern void arch_post_cpu_init(void);
extern void arch_pre_smp_init(void);
extern void arch_post_smp_init(void);
 
extern void calibrate_delay_loop(void);
 
extern void reboot(void);
extern void arch_reboot(void);
 
#endif
 
/** @}
/branches/rcu/kernel/generic/include/mm/as.h
101,11 → 101,11
*/
asid_t asid;
/** Number of references (i.e tasks that reference this as). */
atomic_t refcount;
 
mutex_t lock;
/** Number of references (i.e tasks that reference this as). */
count_t refcount;
/** B+tree of address space areas. */
btree_t as_area_btree;
147,11 → 147,11
*/
asid_t asid;
 
/** Number of references (i.e tasks that reference this as). */
atomic_t refcount;
 
mutex_t lock;
 
/** Number of references (i.e tasks that reference this as). */
count_t refcount;
 
/** B+tree of address space areas. */
btree_t as_area_btree;
/branches/rcu/kernel/generic/include/syscall/syscall.h
40,6 → 40,7
SYS_TLS_SET = 1, /* Hardcoded in AMD64, IA32 uspace - psthread.S */
SYS_THREAD_CREATE,
SYS_THREAD_EXIT,
SYS_THREAD_GET_ID,
SYS_TASK_GET_ID,
SYS_FUTEX_SLEEP,
SYS_FUTEX_WAKEUP,
/branches/rcu/kernel/generic/src/synch/spinlock.c
73,7 → 73,6
* @param sl Pointer to spinlock_t structure.
*/
#ifdef CONFIG_DEBUG_SPINLOCK
#define DEADLOCK_THRESHOLD 100000000
void spinlock_lock_debug(spinlock_t *sl)
{
count_t i = 0;
84,7 → 83,7
while (test_and_set(&sl->val)) {
 
/*
* We need to be careful about printflock and fb_lock.
* We need to be careful about printf_lock and fb_lock.
* Both of them are used to report deadlocks via
* printf() and fb_putchar().
*
94,13 → 93,13
* However, we encountered false positives caused by very
* slow VESA framebuffer interaction (especially when
* run in a simulator) that caused problems with both
* printflock and fb_lock.
* printf_lock and fb_lock.
*
* Possible deadlocks on both printflock and fb_lock
* Possible deadlocks on both printf_lock and fb_lock
* are therefore not reported as they would cause an
* infinite recursion.
*/
if (sl == &printflock)
if (sl == &printf_lock)
continue;
#ifdef CONFIG_FB
if (sl == &fb_lock)
/branches/rcu/kernel/generic/src/main/kinit.c
118,7 → 118,7
 
#ifdef CONFIG_SMP
if (config.cpu_count > 1) {
unsigned int i;
count_t i;
/*
* For each CPU, create its load balancing thread.
/branches/rcu/kernel/generic/src/main/main.c
82,6 → 82,7
#include <smp/smp.h>
#include <ddi/ddi.h>
#include <proc/tasklet.h>
#include <synch/rcu.h>
 
/** Global configuration structure. */
config_t config;
275,6 → 276,8
tasklet_run_tasklet_thread(k);
 
rcu_init();
 
/*
* This call to scheduler() will return to kinit,
* starting the thread of kernel threads.
/branches/rcu/kernel/generic/src/time/timeout.c
45,7 → 45,6
#include <arch/asm.h>
#include <arch.h>
 
 
/** Initialize timeouts
*
* Initialize kernel timeouts.
175,6 → 174,7
timeout_t *hlp;
link_t *l;
ipl_t ipl;
DEADLOCK_PROBE_INIT(p_tolock);
 
grab_locks:
ipl = interrupts_disable();
186,7 → 186,8
}
if (!spinlock_trylock(&t->cpu->timeoutlock)) {
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
interrupts_restore(ipl);
DEADLOCK_PROBE(p_tolock, DEADLOCK_THRESHOLD);
goto grab_locks;
}
/branches/rcu/kernel/generic/src/time/clock.c
41,7 → 41,6
#include <time/clock.h>
#include <time/timeout.h>
#include <arch/types.h>
#include <config.h>
#include <synch/spinlock.h>
#include <synch/waitq.h>
57,16 → 56,12
#include <mm/frame.h>
#include <ddi/ddi.h>
 
/** Physical memory area of the real time clock. */
/* Pointer to variable with uptime */
uptime_t *uptime;
 
/** Physical memory area of the real time clock */
static parea_t clock_parea;
 
/* Pointers to public variables with time */
struct ptime {
unative_t seconds1;
unative_t useconds;
unative_t seconds2;
};
struct ptime *public_time;
/* Variable holding fragment of second, so that we would update
* seconds correctly
*/
86,15 → 81,14
if (!faddr)
panic("Cannot allocate page for clock");
public_time = (struct ptime *) PA2KA(faddr);
uptime = (uptime_t *) PA2KA(faddr);
uptime->seconds1 = 0;
uptime->seconds2 = 0;
uptime->useconds = 0;
 
/* TODO: We would need some arch dependent settings here */
public_time->seconds1 = 0;
public_time->seconds2 = 0;
public_time->useconds = 0;
 
clock_parea.pbase = (uintptr_t) faddr;
clock_parea.vbase = (uintptr_t) public_time;
clock_parea.vbase = (uintptr_t) uptime;
clock_parea.frames = 1;
clock_parea.cacheable = true;
ddi_parea_register(&clock_parea);
116,16 → 110,16
static void clock_update_counters(void)
{
if (CPU->id == 0) {
secfrag += 1000000/HZ;
secfrag += 1000000 / HZ;
if (secfrag >= 1000000) {
secfrag -= 1000000;
public_time->seconds1++;
uptime->seconds1++;
write_barrier();
public_time->useconds = secfrag;
uptime->useconds = secfrag;
write_barrier();
public_time->seconds2 = public_time->seconds1;
uptime->seconds2 = uptime->seconds1;
} else
public_time->useconds += 1000000/HZ;
uptime->useconds += 1000000 / HZ;
}
}
 
/branches/rcu/kernel/generic/src/ddi/irq.c
138,6 → 138,7
{
link_initialize(&irq->link);
spinlock_initialize(&irq->lock, "irq.lock");
irq->preack = false;
irq->inr = -1;
irq->devno = -1;
irq->trigger = (irq_trigger_t) 0;
/branches/rcu/kernel/generic/src/printf/snprintf.c
50,4 → 50,3
 
/** @}
*/
 
/branches/rcu/kernel/generic/src/printf/vprintf.c
35,7 → 35,11
#include <print.h>
#include <printf/printf_core.h>
#include <putchar.h>
#include <synch/spinlock.h>
#include <arch/asm.h>
 
SPINLOCK_INITIALIZE(printf_lock); /**< vprintf spinlock */
 
static int vprintf_write(const char *str, size_t count, void *unused)
{
size_t i;
55,8 → 59,16
int vprintf(const char *fmt, va_list ap)
{
struct printf_spec ps = {(int(*)(void *, size_t, void *)) vprintf_write, NULL};
return printf_core(fmt, &ps, ap);
 
int irqpri = interrupts_disable();
spinlock_lock(&printf_lock);
int ret = printf_core(fmt, &ps, ap);
spinlock_unlock(&printf_lock);
interrupts_restore(irqpri);
return ret;
}
 
/** @}
/branches/rcu/kernel/generic/src/printf/vsnprintf.c
42,8 → 42,6
char *string; /* destination string */
};
 
int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data);
 
/** Write string to given buffer.
* Write at most data->size characters including trailing zero. According to C99, snprintf() has to return number
* of characters that would have been written if enough space had been available. Hence the return value is not
54,7 → 52,7
* @param data structure with destination string, counter of used space and total string size.
* @return number of characters to print (not characters really printed!)
*/
int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data)
static int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data)
{
size_t i;
i = data->size - data->len;
/branches/rcu/kernel/generic/src/printf/printf_core.c
38,14 → 38,9
#include <printf/printf_core.h>
#include <putchar.h>
#include <print.h>
#include <synch/spinlock.h>
#include <arch/arg.h>
#include <arch/asm.h>
 
#include <arch.h>
 
SPINLOCK_INITIALIZE(printflock); /**< printf spinlock */
 
#define __PRINTF_FLAG_PREFIX 0x00000001 /**< show prefixes 0x or 0*/
#define __PRINTF_FLAG_SIGNED 0x00000002 /**< signed / unsigned number */
#define __PRINTF_FLAG_ZEROPADDED 0x00000004 /**< print leading zeroes */
458,7 → 453,6
*/
int printf_core(const char *fmt, struct printf_spec *ps, va_list ap)
{
int irqpri;
int i = 0, j = 0; /**< i is index of currently processed char from fmt, j is index to the first not printed nonformating character */
int end;
int counter; /**< counter of printed characters */
472,10 → 466,7
uint64_t flags;
counter = 0;
irqpri = interrupts_disable();
spinlock_lock(&printflock);
 
while ((c = fmt[i])) {
/* control character */
if (c == '%' ) {
712,8 → 703,6
}
 
out:
spinlock_unlock(&printflock);
interrupts_restore(irqpri);
return counter;
}
/branches/rcu/kernel/generic/src/printf/vsprintf.c
36,7 → 36,7
 
int vsprintf(char *str, const char *fmt, va_list ap)
{
return vsnprintf(str, (size_t)-1, fmt, ap);
return vsnprintf(str, (size_t) - 1, fmt, ap);
}
 
/** @}
/branches/rcu/kernel/generic/src/console/cmd.c
48,6 → 48,7
#include <arch/types.h>
#include <adt/list.h>
#include <arch.h>
#include <config.h>
#include <func.h>
#include <macros.h>
#include <debug.h>
79,10 → 80,26
 
static cmd_info_t exit_info = {
.name = "exit",
.description = "Exit kconsole",
.description = "Exit kconsole.",
.argc = 0
};
 
static int cmd_reboot(cmd_arg_t *argv);
static cmd_info_t reboot_info = {
.name = "reboot",
.description = "Reboot.",
.func = cmd_reboot,
.argc = 0
};
 
static int cmd_uptime(cmd_arg_t *argv);
static cmd_info_t uptime_info = {
.name = "uptime",
.description = "Print uptime information.",
.func = cmd_uptime,
.argc = 0
};
 
static int cmd_continue(cmd_arg_t *argv);
static cmd_info_t continue_info = {
.name = "continue",
192,10 → 209,10
};
 
/* Data and methods for 'call0' command. */
static char call0_buf[MAX_CMDLINE+1];
static char carg1_buf[MAX_CMDLINE+1];
static char carg2_buf[MAX_CMDLINE+1];
static char carg3_buf[MAX_CMDLINE+1];
static char call0_buf[MAX_CMDLINE + 1];
static char carg1_buf[MAX_CMDLINE + 1];
static char carg2_buf[MAX_CMDLINE + 1];
static char carg3_buf[MAX_CMDLINE + 1];
 
static int cmd_call0(cmd_arg_t *argv);
static cmd_arg_t call0_argv = {
211,6 → 228,21
.argv = &call0_argv
};
 
/* Data and methods for 'mcall0' command. */
static int cmd_mcall0(cmd_arg_t *argv);
static cmd_arg_t mcall0_argv = {
.type = ARG_TYPE_STRING,
.buffer = call0_buf,
.len = sizeof(call0_buf)
};
static cmd_info_t mcall0_info = {
.name = "mcall0",
.description = "mcall0 <function> -> call function() on each CPU.",
.func = cmd_mcall0,
.argc = 1,
.argv = &mcall0_argv
};
 
/* Data and methods for 'call1' command. */
static int cmd_call1(cmd_arg_t *argv);
static cmd_arg_t call1_argv[] = {
406,6 → 438,7
 
static cmd_info_t *basic_commands[] = {
&call0_info,
&mcall0_info,
&call1_info,
&call2_info,
&call3_info,
413,6 → 446,8
&cpus_info,
&desc_info,
&exit_info,
&reboot_info,
&uptime_info,
&halt_info,
&help_info,
&ipc_task_info,
488,6 → 523,41
return 1;
}
 
 
/** Reboot the system.
*
* @param argv Argument vector.
*
* @return 0 on failure, 1 on success.
*/
int cmd_reboot(cmd_arg_t *argv)
{
reboot();
/* Not reached */
return 1;
}
 
 
/** Print system uptime information.
*
* @param argv Argument vector.
*
* @return 0 on failure, 1 on success.
*/
int cmd_uptime(cmd_arg_t *argv)
{
ASSERT(uptime);
/* This doesn't have to be very accurate */
unative_t sec = uptime->seconds1;
printf("Up %u days, %u hours, %u minutes, %u seconds\n",
sec / 86400, (sec % 86400) / 3600, (sec % 3600) / 60, sec % 60);
return 1;
}
 
/** Describe specified command.
*
* @param argv Argument vector.
540,7 → 610,7
struct {
unative_t f;
unative_t gp;
}fptr;
} fptr;
#endif
 
symaddr = get_symbol_addr((char *) argv->buffer);
551,7 → 621,7
printf("Duplicate symbol, be more specific.\n");
} else {
symbol = get_symtab_entry(symaddr);
printf("Calling f(): %.*p: %s\n", sizeof(uintptr_t) * 2, symaddr, symbol);
printf("Calling %s() (%.*p)\n", symbol, sizeof(uintptr_t) * 2, symaddr);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
565,6 → 635,32
return 1;
}
 
/** Call function with zero parameters on each CPU */
int cmd_mcall0(cmd_arg_t *argv)
{
/*
* For each CPU, create a thread which will
* call the function.
*/
count_t i;
for (i = 0; i < config.cpu_count; i++) {
thread_t *t;
if ((t = thread_create((void (*)(void *)) cmd_call0, (void *) argv, TASK, THREAD_FLAG_WIRED, "call0", false))) {
spinlock_lock(&t->lock);
t->cpu = &cpus[i];
spinlock_unlock(&t->lock);
printf("cpu%u: ", i);
thread_ready(t);
thread_join(t);
thread_detach(t);
} else
printf("Unable to create thread for cpu%u\n", i);
}
return 1;
}
 
/** Call function with one parameter */
int cmd_call1(cmd_arg_t *argv)
{
713,7 → 809,7
/** Write 4 byte value to address */
int cmd_set4(cmd_arg_t *argv)
{
uint32_t *addr ;
uint32_t *addr;
uint32_t arg1 = argv[1].intval;
bool pointer = false;
 
/branches/rcu/kernel/generic/src/proc/scheduler.c
61,6 → 61,7
#include <cpu.h>
#include <print.h>
#include <debug.h>
#include <synch/rcu.h>
 
static void before_task_runs(void);
static void before_thread_runs(void);
115,6 → 116,7
void after_thread_ran(void)
{
after_thread_ran_arch();
rcu_run_callbacks();
}
 
#ifdef CONFIG_FPU_LAZY
207,7 → 209,7
 
interrupts_disable();
for (i = 0; i<RQ_COUNT; i++) {
for (i = 0; i < RQ_COUNT; i++) {
r = &CPU->rq[i];
spinlock_lock(&r->lock);
if (r->n == 0) {
377,7 → 379,8
void scheduler_separated_stack(void)
{
int priority;
DEADLOCK_PROBE_INIT(p_joinwq);
 
ASSERT(CPU != NULL);
if (THREAD) {
406,6 → 409,8
spinlock_unlock(&THREAD->lock);
delay(10);
spinlock_lock(&THREAD->lock);
DEADLOCK_PROBE(p_joinwq,
DEADLOCK_THRESHOLD);
goto repeat;
}
_waitq_wakeup_unsafe(&THREAD->join_wq, false);
447,8 → 452,8
/*
* Entering state is unexpected.
*/
panic("tid%d: unexpected state %s\n", THREAD->tid,
thread_states[THREAD->state]);
panic("tid%llu: unexpected state %s\n", THREAD->tid,
thread_states[THREAD->state]);
break;
}
 
500,7 → 505,7
THREAD->state = Running;
 
#ifdef SCHEDULER_VERBOSE
printf("cpu%d: tid %d (priority=%d, ticks=%lld, nrdy=%ld)\n",
printf("cpu%d: tid %llu (priority=%d, ticks=%llu, nrdy=%ld)\n",
CPU->id, THREAD->tid, THREAD->priority, THREAD->ticks,
atomic_get(&CPU->nrdy));
#endif
568,7 → 573,7
* Searching least priority queues on all CPU's first and most priority
* queues on all CPU's last.
*/
for (j= RQ_COUNT - 1; j >= 0; j--) {
for (j = RQ_COUNT - 1; j >= 0; j--) {
for (i = 0; i < config.cpu_active; i++) {
link_t *l;
runq_t *r;
609,8 → 614,8
*/
spinlock_lock(&t->lock);
if ((!(t->flags & (THREAD_FLAG_WIRED |
THREAD_FLAG_STOLEN))) &&
(!(t->fpu_context_engaged)) ) {
THREAD_FLAG_STOLEN))) &&
(!(t->fpu_context_engaged))) {
/*
* Remove t from r.
*/
636,7 → 641,7
*/
spinlock_lock(&t->lock);
#ifdef KCPULB_VERBOSE
printf("kcpulb%d: TID %d -> cpu%d, nrdy=%ld, "
printf("kcpulb%d: TID %llu -> cpu%d, nrdy=%ld, "
"avg=%nd\n", CPU->id, t->tid, CPU->id,
atomic_get(&CPU->nrdy),
atomic_get(&nrdy) / config.cpu_active);
719,7 → 724,7
for (cur = r->rq_head.next; cur != &r->rq_head;
cur = cur->next) {
t = list_get_instance(cur, thread_t, rq_link);
printf("%d(%s) ", t->tid,
printf("%llu(%s) ", t->tid,
thread_states[t->state]);
}
printf("\n");
/branches/rcu/kernel/generic/src/proc/task.c
41,6 → 41,7
#include <proc/uarg.h>
#include <mm/as.h>
#include <mm/slab.h>
#include <atomic.h>
#include <synch/spinlock.h>
#include <synch/waitq.h>
#include <arch.h>
92,6 → 93,49
btree_create(&tasks_btree);
}
 
/** Kill all tasks except the current task.
*
*/
void task_done(void)
{
task_t *t;
do { /* Repeat until there are any tasks except TASK */
/* Messing with task structures, avoid deadlock */
ipl_t ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
t = NULL;
link_t *cur;
for (cur = tasks_btree.leaf_head.next; cur != &tasks_btree.leaf_head; cur = cur->next) {
btree_node_t *node = list_get_instance(cur, btree_node_t, leaf_link);
unsigned int i;
for (i = 0; i < node->keys; i++) {
if ((task_t *) node->value[i] != TASK) {
t = (task_t *) node->value[i];
break;
}
}
}
if (t != NULL) {
task_id_t id = t->taskid;
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
#ifdef CONFIG_DEBUG
printf("Killing task %llu\n", id);
#endif
task_kill(id);
} else {
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
}
} while (t != NULL);
}
 
/** Create new task
*
140,11 → 184,8
 
/*
* Increment address space reference count.
* TODO: Reconsider the locking scheme.
*/
mutex_lock(&as->lock);
as->refcount++;
mutex_unlock(&as->lock);
atomic_inc(&as->refcount);
 
spinlock_lock(&tasks_lock);
 
166,15 → 207,8
task_destroy_arch(t);
btree_destroy(&t->futexes);
 
mutex_lock_active(&t->as->lock);
if (--t->as->refcount == 0) {
mutex_unlock(&t->as->lock);
if (atomic_predec(&t->as->refcount) == 0)
as_destroy(t->as);
/*
* t->as is destroyed.
*/
} else
mutex_unlock(&t->as->lock);
free(t);
TASK = NULL;
382,7 → 416,7
link_t *cur;
ipl_t ipl;
/* Messing with thread structures, avoid deadlock */
/* Messing with task structures, avoid deadlock */
ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
408,7 → 442,7
char suffix;
order(task_get_accounting(t), &cycles, &suffix);
printf("%-6lld %-10s %-3ld %#10zx %#10zx %9llu%c %7zd "
printf("%-6llu %-10s %-3ld %#10zx %#10zx %9llu%c %7zd "
"%6zd", t->taskid, t->name, t->context, t, t->as,
cycles, suffix, t->refcount,
atomic_get(&t->active_calls));
495,7 → 529,7
 
ipc_cleanup();
futex_cleanup();
klog_printf("Cleanup of task %lld completed.", TASK->taskid);
klog_printf("Cleanup of task %llu completed.", TASK->taskid);
}
 
/** Kernel thread used to kill the userspace task when its main thread exits.
/branches/rcu/kernel/generic/src/proc/thread.c
94,7 → 94,7
btree_t threads_btree;
 
SPINLOCK_INITIALIZE(tidlock);
uint32_t last_tid = 0;
thread_id_t last_tid = 0;
 
static slab_cache_t *thread_slab;
#ifdef ARCH_HAS_FPU
238,6 → 238,7
cpu = CPU;
if (t->flags & THREAD_FLAG_WIRED) {
ASSERT(t->cpu != NULL);
cpu = t->cpu;
}
t->state = Ready;
496,7 → 497,7
ipl_t ipl;
 
/*
* Since the thread is expected to not be already detached,
* Since the thread is expected not to be already detached,
* pointer to it must be still valid.
*/
ipl = interrupts_disable();
580,7 → 581,7
char suffix;
order(t->cycles, &cycles, &suffix);
printf("%-6zd %-10s %#10zx %-8s %#10zx %-3ld %#10zx "
printf("%-6llu %-10s %#10zx %-8s %#10zx %-3ld %#10zx "
"%#10zx %9llu%c ", t->tid, t->name, t,
thread_states[t->state], t->task, t->task->context,
t->thread_code, t->kstack, cycles, suffix);
636,12 → 637,11
/** Process syscall to create new thread.
*
*/
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name)
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name, thread_id_t *uspace_thread_id)
{
thread_t *t;
char namebuf[THREAD_NAME_BUFLEN];
uspace_arg_t *kernel_uarg;
uint32_t tid;
int rc;
 
rc = copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN);
658,12 → 658,14
t = thread_create(uinit, kernel_uarg, TASK, THREAD_FLAG_USPACE, namebuf,
false);
if (t) {
tid = t->tid;
thread_ready(t);
return (unative_t) tid;
} else {
if (uspace_thread_id != NULL)
return (unative_t) copy_to_uspace(uspace_thread_id, &t->tid,
sizeof(t->tid));
else
return 0;
} else
free(kernel_uarg);
}
 
return (unative_t) ENOMEM;
}
678,6 → 680,22
return 0;
}
 
/** Syscall for getting TID.
*
* @param uspace_thread_id Userspace address of 8-byte buffer where to store
* current thread ID.
*
* @return 0 on success or an error code from @ref errno.h.
*/
unative_t sys_thread_get_id(thread_id_t *uspace_thread_id)
{
/*
* No need to acquire lock on THREAD because tid
* remains constant for the lifespan of the thread.
*/
return (unative_t) copy_to_uspace(uspace_thread_id, &THREAD->tid,
sizeof(THREAD->tid));
}
 
/** @}
*/
 
/branches/rcu/kernel/generic/src/lib/memstr.c
130,7 → 130,8
{
char *orig = dest;
while ((*(dest++) = *(src++)));
while ((*(dest++) = *(src++)))
;
return orig;
}
 
/branches/rcu/kernel/generic/src/lib/func.c
223,20 → 223,23
 
void order(const uint64_t val, uint64_t *rv, char *suffix)
{
if (val > 1000000000000000000LL) {
*rv = val / 1000000000000000LL;
if (val > 10000000000000000000ULL) {
*rv = val / 1000000000000000000ULL;
*suffix = 'Z';
} else if (val > 1000000000000000000ULL) {
*rv = val / 1000000000000000ULL;
*suffix = 'E';
} else if (val > 1000000000000000LL) {
*rv = val / 1000000000000LL;
} else if (val > 1000000000000000ULL) {
*rv = val / 1000000000000ULL;
*suffix = 'T';
} else if (val > 1000000000000LL) {
*rv = val / 1000000000LL;
} else if (val > 1000000000000ULL) {
*rv = val / 1000000000ULL;
*suffix = 'G';
} else if (val > 1000000000LL) {
*rv = val / 1000000LL;
} else if (val > 1000000000ULL) {
*rv = val / 1000000ULL;
*suffix = 'M';
} else if (val > 1000000LL) {
*rv = val / 1000LL;
} else if (val > 1000000ULL) {
*rv = val / 1000ULL;
*suffix = 'k';
} else {
*rv = val;
/branches/rcu/kernel/generic/src/lib/objc.c
49,7 → 49,7
return class_create_instance(self);
}
 
- (id) free
- (id) dispose
{
return object_dispose(self);
}
/branches/rcu/kernel/generic/src/adt/btree.c
970,7 → 970,7
 
printf("(");
for (i = 0; i < node->keys; i++) {
printf("%lld%s", node->key[i], i < node->keys - 1 ? "," : "");
printf("%llu%s", node->key[i], i < node->keys - 1 ? "," : "");
if (node->depth && node->subtree[i]) {
list_append(&node->subtree[i]->bfs_link, &head);
}
992,7 → 992,7
 
printf("(");
for (i = 0; i < node->keys; i++)
printf("%lld%s", node->key[i], i < node->keys - 1 ? "," : "");
printf("%llu%s", node->key[i], i < node->keys - 1 ? "," : "");
printf(")");
}
printf("\n");
/branches/rcu/kernel/generic/src/mm/as.c
57,6 → 57,7
#include <genarch/mm/page_ht.h>
#include <mm/asid.h>
#include <arch/mm/asid.h>
#include <preemption.h>
#include <synch/spinlock.h>
#include <synch/mutex.h>
#include <adt/list.h>
181,7 → 182,7
else
as->asid = ASID_INVALID;
as->refcount = 0;
atomic_set(&as->refcount, 0);
as->cpu_refcount = 0;
#ifdef AS_PAGE_TABLE
as->genarch.page_table = page_table_create(flags);
196,13 → 197,16
*
* When there are no tasks referencing this address space (i.e. its refcount is
* zero), the address space can be destroyed.
*
* We know that we don't hold any spinlock.
*/
void as_destroy(as_t *as)
{
ipl_t ipl;
bool cond;
DEADLOCK_PROBE_INIT(p_asidlock);
 
ASSERT(as->refcount == 0);
ASSERT(atomic_get(&as->refcount) == 0);
/*
* Since there is no reference to this area,
209,8 → 213,23
* it is safe not to lock its mutex.
*/
 
ipl = interrupts_disable();
spinlock_lock(&asidlock);
/*
* We need to avoid deadlock between TLB shootdown and asidlock.
* We therefore try to take asid conditionally and if we don't succeed,
* we enable interrupts and try again. This is done while preemption is
* disabled to prevent nested context switches. We also depend on the
* fact that so far no spinlocks are held.
*/
preemption_disable();
ipl = interrupts_read();
retry:
interrupts_disable();
if (!spinlock_trylock(&asidlock)) {
interrupts_enable();
DEADLOCK_PROBE(p_asidlock, DEADLOCK_THRESHOLD);
goto retry;
}
preemption_enable(); /* Interrupts disabled, enable preemption */
if (as->asid != ASID_INVALID && as != AS_KERNEL) {
if (as != AS && as->cpu_refcount == 0)
list_remove(&as->inactive_as_with_asid_link);
472,15 → 491,16
/*
* Finish TLB shootdown sequence.
*/
 
tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE,
area->pages - pages);
tlb_shootdown_finalize();
/*
* Invalidate software translation caches (e.g. TSB on sparc64).
*/
as_invalidate_translation_cache(as, area->base +
pages * PAGE_SIZE, area->pages - pages);
tlb_shootdown_finalize();
} else {
/*
* Growing the area.
568,14 → 588,14
/*
* Finish TLB shootdown sequence.
*/
 
tlb_invalidate_pages(as->asid, area->base, area->pages);
tlb_shootdown_finalize();
/*
* Invalidate potential software translation caches (e.g. TSB on
* sparc64).
*/
as_invalidate_translation_cache(as, area->base, area->pages);
tlb_shootdown_finalize();
btree_destroy(&area->used_space);
 
867,12 → 887,29
* scheduling. Sleeping here would lead to deadlock on wakeup. Another
* thing which is forbidden in this context is locking the address space.
*
* When this function is enetered, no spinlocks may be held.
*
* @param old Old address space or NULL.
* @param new New address space.
*/
void as_switch(as_t *old_as, as_t *new_as)
{
spinlock_lock(&asidlock);
DEADLOCK_PROBE_INIT(p_asidlock);
preemption_disable();
retry:
(void) interrupts_disable();
if (!spinlock_trylock(&asidlock)) {
/*
* Avoid deadlock with TLB shootdown.
* We can enable interrupts here because
* preemption is disabled. We should not be
* holding any other lock.
*/
(void) interrupts_enable();
DEADLOCK_PROBE(p_asidlock, DEADLOCK_THRESHOLD);
goto retry;
}
preemption_enable();
 
/*
* First, take care of the old address space.
/branches/rcu/kernel/generic/src/mm/page.c
76,7 → 76,7
cnt = length / PAGE_SIZE + (length % PAGE_SIZE > 0);
 
for (i = 0; i < cnt; i++)
page_mapping_insert(AS_KERNEL, s + i * PAGE_SIZE, s + i * PAGE_SIZE, PAGE_NOT_CACHEABLE);
page_mapping_insert(AS_KERNEL, s + i * PAGE_SIZE, s + i * PAGE_SIZE, PAGE_NOT_CACHEABLE | PAGE_WRITE);
 
}
 
/branches/rcu/kernel/generic/src/syscall/syscall.c
100,7 → 100,7
if (id < SYSCALL_END)
rc = syscall_table[id](a1, a2, a3, a4);
else {
klog_printf("TASK %lld: Unknown syscall id %d",TASK->taskid,id);
klog_printf("TASK %llu: Unknown syscall id %d",TASK->taskid,id);
task_kill(TASK->taskid);
thread_exit();
}
118,6 → 118,7
/* Thread and task related syscalls. */
(syshandler_t) sys_thread_create,
(syshandler_t) sys_thread_exit,
(syshandler_t) sys_thread_get_id,
(syshandler_t) sys_task_get_id,
/* Synchronization related syscalls. */
/branches/rcu/kernel/generic/src/ipc/ipc.c
374,6 → 374,7
int i;
call_t *call;
phone_t *phone;
DEADLOCK_PROBE_INIT(p_phonelck);
 
/* Disconnect all our phones ('ipc_phone_hangup') */
for (i=0;i < IPC_MAX_PHONES; i++)
387,9 → 388,10
spinlock_lock(&TASK->answerbox.lock);
while (!list_empty(&TASK->answerbox.connected_phones)) {
phone = list_get_instance(TASK->answerbox.connected_phones.next,
phone_t, link);
phone_t, link);
if (! spinlock_trylock(&phone->lock)) {
spinlock_unlock(&TASK->answerbox.lock);
DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);
goto restart_phones;
}
500,7 → 502,7
printf("ABOX - CALLS:\n");
for (tmp=task->answerbox.calls.next; tmp != &task->answerbox.calls;tmp = tmp->next) {
call = list_get_instance(tmp, call_t, link);
printf("Callid: %p Srctask:%lld M:%d A1:%d A2:%d A3:%d Flags:%x\n",call,
printf("Callid: %p Srctask:%llu M:%d A1:%d A2:%d A3:%d Flags:%x\n",call,
call->sender->taskid, IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data),
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), call->flags);
}
510,7 → 512,7
tmp != &task->answerbox.dispatched_calls;
tmp = tmp->next) {
call = list_get_instance(tmp, call_t, link);
printf("Callid: %p Srctask:%lld M:%d A1:%d A2:%d A3:%d Flags:%x\n",call,
printf("Callid: %p Srctask:%llu M:%d A1:%d A2:%d A3:%d Flags:%x\n",call,
call->sender->taskid, IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data),
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), call->flags);
}
/branches/rcu/kernel/generic/src/ipc/irq.c
336,6 → 336,7
while (box->irq_head.next != &box->irq_head) {
link_t *cur = box->irq_head.next;
irq_t *irq;
DEADLOCK_PROBE_INIT(p_irqlock);
irq = list_get_instance(cur, irq_t, notif_cfg.link);
if (!spinlock_trylock(&irq->lock)) {
344,6 → 345,7
*/
spinlock_unlock(&box->irq_lock);
interrupts_restore(ipl);
DEADLOCK_PROBE(p_irqlock, DEADLOCK_THRESHOLD);
goto loop;
}
/branches/rcu/kernel/Makefile
156,6 → 156,7
generic/src/main/kinit.c \
generic/src/main/uinit.c \
generic/src/main/version.c \
generic/src/main/shutdown.c \
generic/src/proc/scheduler.c \
generic/src/proc/thread.c \
generic/src/proc/task.c \
227,6 → 228,7
test/mm/slab1.c \
test/mm/slab2.c \
test/mm/purge1.c \
test/synch/rcu1.c \
test/synch/rwlock1.c \
test/synch/rwlock2.c \
test/synch/rwlock3.c \
235,9 → 237,9
test/synch/semaphore1.c \
test/synch/semaphore2.c \
test/print/print1.c \
test/tasklet/tasklet1.c \
test/thread/thread1.c \
test/sysinfo/sysinfo1.c \
test/tasklet/tasklet1.c
test/sysinfo/sysinfo1.c
endif
 
## Experimental features
/branches/rcu/kernel/arch/sparc64/include/types.h
62,6 → 62,7
typedef int64_t native_t;
 
typedef uint8_t bool;
typedef uint64_t thread_id_t;
typedef uint64_t task_id_t;
typedef uint32_t context_id_t;
 
/branches/rcu/kernel/arch/sparc64/include/trap/mmu.h
129,7 → 129,21
wrpr %g0, 1, %tl
.endif
 
/*
* Switch from the MM globals.
*/
wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
 
/*
* Read the Tag Access register for the higher-level handler.
* This is necessary to survive nested DTLB misses.
*/
mov VA_DMMU_TAG_ACCESS, %g2
ldxa [%g2] ASI_DMMU, %g2
 
/*
* g2 will be passed as an argument to fast_data_access_mmu_miss().
*/
PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
.endm
 
142,7 → 156,21
wrpr %g0, 1, %tl
.endif
 
/*
* Switch from the MM globals.
*/
wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
 
/*
* Read the Tag Access register for the higher-level handler.
* This is necessary to survive nested DTLB misses.
*/
mov VA_DMMU_TAG_ACCESS, %g2
ldxa [%g2] ASI_DMMU, %g2
 
/*
* g2 will be passed as an argument to fast_data_access_mmu_miss().
*/
PREEMPTIBLE_HANDLER fast_data_access_protection
.endm
 
/branches/rcu/kernel/arch/sparc64/include/mm/tlb.h
428,9 → 428,9
membar();
}
 
extern void fast_instruction_access_mmu_miss(int n, istate_t *istate);
extern void fast_data_access_mmu_miss(int n, istate_t *istate);
extern void fast_data_access_protection(int n, istate_t *istate);
extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate);
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate);
extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate);
 
extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
 
/branches/rcu/kernel/arch/sparc64/include/barrier.h
39,12 → 39,12
* Our critical section barriers are prepared for the weakest RMO memory model.
*/
#define CS_ENTER_BARRIER() \
asm volatile ( \
asm volatile ( \
"membar #LoadLoad | #LoadStore\n" \
::: "memory" \
)
#define CS_LEAVE_BARRIER() \
asm volatile ( \
asm volatile ( \
"membar #StoreStore\n" \
"membar #LoadStore\n" \
::: "memory" \
/branches/rcu/kernel/arch/sparc64/src/smp/smp.c
100,7 → 100,7
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT)
printf("%s: waiting for processor (mid = %d) timed out\n",
__FUNCTION__, mid);
__FUNCTION__, mid);
}
}
 
/branches/rcu/kernel/arch/sparc64/src/smp/ipi.c
74,8 → 74,8
panic("Interrupt Dispatch Status busy bit set\n");
do {
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_0, (uintptr_t)
func);
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_0,
(uintptr_t) func);
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_1, 0);
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_2, 0);
asi_u64_write(ASI_UDB_INTR_W,
/branches/rcu/kernel/arch/sparc64/src/asm.S
273,7 → 273,7
flushw
wrpr %g0, 0, %cleanwin ! avoid information leak
 
mov %i3, %o0 ! uarg
mov %i2, %o0 ! uarg
 
clr %i2
clr %i3
/branches/rcu/kernel/arch/sparc64/src/proc/scheduler.c
62,9 → 62,8
* - preemptible trap handler switches to alternate globals
* before it explicitly uses %g7.
*/
uint64_t sp = (uintptr_t) THREAD->kstack + STACK_SIZE
- (STACK_BIAS + ALIGN_UP(STACK_ITEM_SIZE,
STACK_ALIGNMENT));
uint64_t sp = (uintptr_t) THREAD->kstack + STACK_SIZE -
(STACK_BIAS + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT));
write_to_ig_g6(sp);
write_to_ag_g6(sp);
write_to_ag_g7((uintptr_t) THREAD->arch.uspace_window_buffer);
/branches/rcu/kernel/arch/sparc64/src/proc/thread.c
55,7 → 55,7
* belonging to a killed thread.
*/
frame_free(KA2PA(ALIGN_DOWN((uintptr_t)
t->arch.uspace_window_buffer, PAGE_SIZE)));
t->arch.uspace_window_buffer, PAGE_SIZE)));
}
}
 
75,8 → 75,8
* Mind the possible alignment of the userspace window buffer
* belonging to a killed thread.
*/
t->arch.uspace_window_buffer = (uint8_t *) ALIGN_DOWN(uw_buf,
PAGE_SIZE);
t->arch.uspace_window_buffer = (uint8_t *) ALIGN_DOWN(uw_buf,
PAGE_SIZE);
}
}
 
/branches/rcu/kernel/arch/sparc64/src/sparc64.c
155,5 → 155,11
/* not reached */
}
 
void arch_reboot(void)
{
// TODO
while (1);
}
 
/** @}
*/
/branches/rcu/kernel/arch/sparc64/src/cpu/cpu.c
63,10 → 63,10
mid = *((uint32_t *) prop->value);
if (mid == CPU->arch.mid) {
prop = ofw_tree_getprop(node,
"clock-frequency");
"clock-frequency");
if (prop && prop->value)
clock_frequency = *((uint32_t *)
prop->value);
prop->value);
}
}
node = ofw_tree_find_peer_by_device_type(node, "cpu");
/branches/rcu/kernel/arch/sparc64/src/mm/tlb.c
198,7 → 198,7
}
 
/** ITLB miss handler. */
void fast_instruction_access_mmu_miss(int n, istate_t *istate)
void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate)
{
uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
index_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
234,15 → 234,18
*
* Note that some faults (e.g. kernel faults) were already resolved by the
* low-level, assembly language part of the fast_data_access_mmu_miss handler.
*
* @param tag Content of the TLB Tag Access register as it existed when the
* trap happened. This is to prevent confusion created by clobbered
* Tag Access register during a nested DTLB miss.
* @param istate Interrupted state saved on the stack.
*/
void fast_data_access_mmu_miss(int n, istate_t *istate)
void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
{
tlb_tag_access_reg_t tag;
uintptr_t va;
index_t index;
pte_t *t;
 
tag.value = dtlb_tag_access_read();
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
index = tag.vpn % MMU_PAGES_PER_PAGE;
 
282,15 → 285,19
}
}
 
/** DTLB protection fault handler. */
void fast_data_access_protection(int n, istate_t *istate)
/** DTLB protection fault handler.
*
* @param tag Content of the TLB Tag Access register as it existed when the
* trap happened. This is to prevent confusion created by clobbered
* Tag Access register during a nested DTLB miss.
* @param istate Interrupted state saved on the stack.
*/
void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
{
tlb_tag_access_reg_t tag;
uintptr_t va;
index_t index;
pte_t *t;
 
tag.value = dtlb_tag_access_read();
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
index = tag.vpn % MMU_PAGES_PER_PAGE; /* 16K-page emulation */
 
371,9 → 378,10
uintptr_t va;
 
va = tag.vpn << MMU_PAGE_WIDTH;
 
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
tag.context);
if (tag.context) {
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
tag.context);
}
dump_istate(istate);
printf("Faulting page: %p, ASID=%d\n", va, tag.context);
panic("%s\n", str);
386,8 → 394,10
 
va = tag.vpn << MMU_PAGE_WIDTH;
 
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
tag.context);
if (tag.context) {
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
tag.context);
}
printf("Faulting page: %p, ASID=%d\n", va, tag.context);
dump_istate(istate);
panic("%s\n", str);
/branches/rcu/kernel/arch/sparc64/src/mm/as.c
66,6 → 66,7
*/
int order = fnzb32(((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
sizeof(tsb_entry_t)) >> FRAME_WIDTH);
 
uintptr_t tsb = (uintptr_t) frame_alloc(order, flags | FRAME_KA);
 
if (!tsb)
74,6 → 75,7
as->arch.itsb = (tsb_entry_t *) tsb;
as->arch.dtsb = (tsb_entry_t *) (tsb + ITSB_ENTRY_COUNT *
sizeof(tsb_entry_t));
 
memsetb((uintptr_t) as->arch.itsb,
(ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * sizeof(tsb_entry_t), 0);
#endif
/branches/rcu/kernel/arch/sparc64/src/mm/cache.S
45,8 → 45,10
subcc %g1, DCACHE_LINE_SIZE, %g1
bnz,pt %xcc, 0b
stxa %g0, [%g1] ASI_DCACHE_TAG
membar #Sync
retl
membar #Sync
! beware SF Erratum #51, do not put the MEMBAR here
nop
 
/** Flush only D-cache lines of one virtual color.
*
/branches/rcu/kernel/arch/sparc64/src/mm/tsb.c
61,6 → 61,8
ASSERT(as->arch.itsb && as->arch.dtsb);
i0 = (page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
ASSERT(i0 < ITSB_ENTRY_COUNT && i0 < DTSB_ENTRY_COUNT);
 
if (pages == (count_t) -1 || (pages * 2) > ITSB_ENTRY_COUNT)
cnt = ITSB_ENTRY_COUNT;
else
84,9 → 86,12
as_t *as;
tsb_entry_t *tsb;
index_t entry;
 
ASSERT(index <= 1);
as = t->as;
entry = ((t->page >> MMU_PAGE_WIDTH) + index) & TSB_INDEX_MASK;
ASSERT(entry < ITSB_ENTRY_COUNT);
tsb = &as->arch.itsb[entry];
 
/*
102,8 → 107,8
write_barrier();
 
tsb->tag.context = as->asid;
tsb->tag.va_tag = (t->page + (index << MMU_PAGE_WIDTH)) >>
VA_TAG_PAGE_SHIFT;
/* the shift is bigger than PAGE_WIDTH, do not bother with index */
tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
tsb->data.value = 0;
tsb->data.size = PAGESIZE_8K;
tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
128,8 → 133,11
tsb_entry_t *tsb;
index_t entry;
ASSERT(index <= 1);
 
as = t->as;
entry = ((t->page >> MMU_PAGE_WIDTH) + index) & TSB_INDEX_MASK;
ASSERT(entry < DTSB_ENTRY_COUNT);
tsb = &as->arch.dtsb[entry];
 
/*
145,8 → 153,8
write_barrier();
 
tsb->tag.context = as->asid;
tsb->tag.va_tag = (t->page + (index << MMU_PAGE_WIDTH)) >>
VA_TAG_PAGE_SHIFT;
/* the shift is bigger than PAGE_WIDTH, do not bother with index */
tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
tsb->data.value = 0;
tsb->data.size = PAGESIZE_8K;
tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
/branches/rcu/kernel/arch/sparc64/src/mm/frame.c
65,10 → 65,10
if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0))))
confdata = ADDR2PFN(KA2PA(PFN2ADDR(2)));
zone_create(ADDR2PFN(start),
SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),
confdata, 0);
SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),
confdata, 0);
last_frame = max(last_frame, start + ALIGN_UP(size,
FRAME_SIZE));
FRAME_SIZE));
}
 
/*
/branches/rcu/kernel/arch/ia64/include/types.h
70,6 → 70,7
typedef int64_t native_t;
 
typedef uint8_t bool;
typedef uint64_t thread_id_t;
typedef uint64_t task_id_t;
typedef uint32_t context_id_t;
 
/branches/rcu/kernel/arch/ia64/src/ia64.c
176,5 → 176,11
#endif
}
 
void arch_reboot(void)
{
// TODO
while (1);
}
 
/** @}
*/
/branches/rcu/kernel/arch/arm32/include/types.h
62,6 → 62,7
typedef int32_t native_t;
 
typedef uint8_t bool;
typedef uint64_t thread_id_t;
typedef uint64_t task_id_t;
typedef uint32_t context_id_t;
 
/branches/rcu/kernel/arch/arm32/src/arm32.c
82,5 → 82,11
/* TODO */
}
 
void arch_reboot(void)
{
// TODO
while (1);
}
 
/** @}
*/
/branches/rcu/kernel/arch/ppc32/include/types.h
62,6 → 62,7
typedef int32_t native_t;
 
typedef uint8_t bool;
typedef uint64_t thread_id_t;
typedef uint64_t task_id_t;
typedef uint32_t context_id_t;
 
/branches/rcu/kernel/arch/ppc32/src/mm/page.c
53,7 → 53,7
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE);
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE);
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
/branches/rcu/kernel/arch/ppc32/src/interrupt.c
60,11 → 60,19
int inum;
while ((inum = pic_get_pending()) != -1) {
bool ack = false;
irq_t *irq = irq_dispatch_and_lock(inum);
if (irq) {
/*
* The IRQ handler was found.
*/
if (irq->preack) {
/* Acknowledge the interrupt before processing */
pic_ack_interrupt(inum);
ack = true;
}
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
75,7 → 83,9
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum);
#endif
}
pic_ack_interrupt(inum);
if (!ack)
pic_ack_interrupt(inum);
}
}
 
/branches/rcu/kernel/arch/ppc32/src/drivers/cuda.c
48,7 → 48,8
#define PACKET_ADB 0x00
#define PACKET_CUDA 0x01
 
#define CUDA_POWERDOWN 0x0a
#define CUDA_POWERDOWN 0x0a
#define CUDA_RESET 0x11
 
#define RS 0x200
#define B (0 * RS)
191,9 → 192,6
};
 
 
void send_packet(const uint8_t kind, index_t count, ...);
 
 
static void receive_packet(uint8_t *kind, index_t count, uint8_t data[])
{
cuda[B] = cuda[B] & ~TIP;
316,7 → 314,7
}
 
 
void send_packet(const uint8_t kind, index_t count, ...)
static void send_packet(const uint8_t kind, count_t count, ...)
{
index_t i;
va_list va;
341,13 → 339,17
 
 
void cpu_halt(void) {
#ifdef CONFIG_POWEROFF
send_packet(PACKET_CUDA, 1, CUDA_POWERDOWN);
#endif
asm volatile (
"b 0\n"
);
}
 
void arch_reboot(void) {
send_packet(PACKET_CUDA, 1, CUDA_RESET);
asm volatile (
"b 0\n"
);
}
 
/** @}
*/
/branches/rcu/kernel/arch/ia32xen/include/types.h
62,6 → 62,7
typedef int32_t native_t;
 
typedef uint8_t bool;
typedef uint64_t thread_id_t;
typedef uint64_t task_id_t;
typedef uint32_t context_id_t;
 
/branches/rcu/kernel/arch/ia32xen/src/ia32xen.c
211,5 → 211,11
{
}
 
void arch_reboot(void)
{
// TODO
while (1);
}
 
/** @}
*/
/branches/rcu/kernel/arch/ia32xen/src/smp/smp.c
80,13 → 80,13
 
if (config.cpu_count > 1) {
page_mapping_insert(AS_KERNEL, l_apic_address, (uintptr_t) l_apic,
PAGE_NOT_CACHEABLE);
PAGE_NOT_CACHEABLE | PAGE_WRITE);
page_mapping_insert(AS_KERNEL, io_apic_address, (uintptr_t) io_apic,
PAGE_NOT_CACHEABLE);
PAGE_NOT_CACHEABLE | PAGE_WRITE);
l_apic = (uint32_t *) l_apic_address;
io_apic = (uint32_t *) io_apic_address;
}
}
}
 
/*
/branches/rcu/kernel/arch/ia32xen/src/interrupt.c
176,14 → 176,21
ASSERT(n >= IVT_IRQBASE);
int inum = n - IVT_IRQBASE;
bool ack = false;
ASSERT(inum < IRQ_COUNT);
ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
 
irq_t *irq = irq_dispatch_and_lock(inum);
if (irq) {
/*
* The IRQ handler was found.
*/
if (irq->preack) {
/* Send EOI before processing the interrupt */
trap_virtual_eoi();
ack = true;
}
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
194,7 → 201,9
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum);
#endif
}
trap_virtual_eoi();
if (!ack)
trap_virtual_eoi();
}
 
void interrupt_init(void)
/branches/rcu/kernel/arch/amd64/include/types.h
62,6 → 62,7
typedef int64_t native_t;
 
typedef uint8_t bool;
typedef uint64_t thread_id_t;
typedef uint64_t task_id_t;
typedef uint32_t context_id_t;
 
/branches/rcu/kernel/arch/amd64/include/asm.h
55,10 → 55,17
return v;
}
 
static inline void cpu_sleep(void) { __asm__ volatile ("hlt\n"); };
static inline void cpu_halt(void) { __asm__ volatile ("hlt\n"); };
static inline void cpu_sleep(void)
{
asm volatile ("hlt\n");
};
 
static inline void cpu_halt(void)
{
asm volatile ("hlt\n");
};
 
 
/** Byte from port
*
* Get byte from port
/branches/rcu/kernel/arch/amd64/src/pm.c
33,6 → 33,7
/** @file
*/
 
#include <arch.h>
#include <arch/pm.h>
#include <arch/asm.h>
#include <mm/as.h>
227,5 → 228,24
tr_load(gdtselector(TSS_DES));
}
 
/* Reboot the machine by initiating
* a triple fault
*/
void arch_reboot(void)
{
preemption_disable();
ipl_t ipl = interrupts_disable();
memsetb((uintptr_t) idt, sizeof(idt), 0);
idtr_load(&idtr);
interrupts_restore(ipl);
asm volatile (
"int $0x03\n"
"cli\n"
"hlt\n"
);
}
 
/** @}
*/
/branches/rcu/kernel/arch/amd64/src/boot/vga323.pal
0,0 → 1,0
link ../../../ia32/src/boot/vga323.pal
/branches/rcu/kernel/arch/amd64/src/boot/boot.S
72,8 → 72,26
movl %eax, grub_eax # save parameters from GRUB
movl %ebx, grub_ebx
# Protected 32-bit. We want to reuse the code-seg descriptor,
# the Default operand size must not be 1 when entering long mode
movl $0x80000000, %eax
cpuid
cmp $0x80000000, %eax # any function > 80000000h?
jbe long_mode_unsupported
movl $(AMD_CPUID_EXTENDED), %eax # Extended function code 80000001
cpuid
bt $29, %edx # Test if long mode is supported.
jc long_mode_supported
 
long_mode_unsupported:
movl $long_mode_msg, %esi
jmp error_halt
long_mode_supported:
#ifdef CONFIG_FB
mov $vesa_init, %esi;
mov $vesa_init, %esi
mov $VESA_INIT_SEGMENT << 4, %edi
mov $e_vesa_init - vesa_init, %ecx
cld
92,25 → 110,7
shr $16, %ebx
mov %bx, KA2PA(vesa_bpp)
#endif
 
# Protected 32-bit. We want to reuse the code-seg descriptor,
# the Default operand size must not be 1 when entering long mode
movl $0x80000000, %eax
cpuid
cmp $0x80000000, %eax # any function > 80000000h?
jbe long_mode_unsupported
movl $(AMD_CPUID_EXTENDED), %eax # Extended function code 80000001
cpuid
bt $29, %edx # Test if long mode is supported.
jc long_mode_supported
 
long_mode_unsupported:
cli
hlt
long_mode_supported:
# Enable 64-bit page transaltion entries - CR4.PAE = 1.
# Paging is not enabled until after long mode is enabled
303,11 → 303,12
#define VESA_INFO_SIZE 1024
 
#define VESA_MODE_ATTRIBUTES_OFFSET 0
#define VESA_MODE_LIST_PTR_OFFSET 14
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_WIDTH_OFFSET 18
#define VESA_MODE_HEIGHT_OFFSET 20
#define VESA_MODE_BPP_OFFSET 25
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_PHADDR_OFFSET 40
 
#define VESA_END_OF_MODES 0xffff
317,14 → 318,14
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
#define VESA_SET_PALETTE 0x4f09
 
#define CONFIG_VESA_BPP_a 255
 
#if CONFIG_VESA_BPP == 24
#undef CONFIG_VESA_BPP_a
#define CONFIG_VESA_BPP_a 32
#define CONFIG_VESA_BPP_VARIANT 32
#endif
 
mov $VESA_GET_INFO, %ax
mov $e_vesa_init - vesa_init, %di
push %di
339,7 → 340,7
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
add $VESA_INFO_SIZE, %di
 
1:# Try next mode
mov %gs:(%si), %cx
cmp $VESA_END_OF_MODES, %cx
369,10 → 370,13
mov $CONFIG_VESA_BPP, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
 
#ifdef CONFIG_VESA_BPP_VARIANT
jz 2f
mov $CONFIG_VESA_BPP_a, %al
mov $CONFIG_VESA_BPP_VARIANT, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
#endif
jnz 1b
2:
386,7 → 390,60
pop %di
cmp $VESA_OK, %al
jnz 0f
 
#if CONFIG_VESA_BPP == 8
# Set 3:2:3 VGA palette
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
push %di
mov $vga323 - vesa_init, %di
mov $0x100, %ecx
bt $5, %ax # Test if VGA compatible registers are present
jnc vga_compat
# Try VESA routine to set palette
mov $VESA_SET_PALETTE, %ax
xor %bl, %bl
xor %dx, %dx
int $0x10
jmp vga_not_compat
vga_compat:
# Try VGA registers to set palette
movw $0x3c6, %dx # Set palette mask
movb $0xff, %al
outb %al, %dx
movw $0x3c8, %dx # First index to set
xor %al, %al
outb %al, %dx
movw $0x3c9, %dx # Data port
vga_loop:
movb %es:2(%di), %al
outb %al, %dx
movb %es:1(%di), %al
outb %al, %dx
movb %es:(%di), %al
outb %al, %dx
addw $4, %di
loop vga_loop
vga_not_compat:
pop %di
#endif
mov VESA_MODE_PHADDR_OFFSET(%di), %esi
mov VESA_MODE_WIDTH_OFFSET(%di), %ax
shl $16, %eax
427,8 → 484,10
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA
xor %ax, %ax
jz 8b # Force relative jump
 
vga323:
#include "vga323.pal"
.code32
vesa_init_protect:
movw $gdtselector(KDATA_DES), %cx
441,11 → 500,73
movw %cx, %fs
movw %cx, %gs
movl $START_STACK, %esp # initialize stack pointer
jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
.align 4
e_vesa_init:
#endif
#endif
 
# Print string from %esi to EGA display (in red) and halt
error_halt:
movl $0xb8000, %edi # base of EGA text mode memory
xorl %eax, %eax
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
cmp $1920, %ax
jbe cursor_ok
movw $1920, %ax # sanity check for the cursor on the last line
cursor_ok:
movw %ax, %bx
shl $1, %eax
addl %eax, %edi
movw $0x0c00, %ax # black background, light red foreground
cld
ploop:
lodsb
cmp $0, %al
je ploop_end
stosw
inc %bx
jmp ploop
ploop_end:
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
cli
hlt
.section K_DATA_START, "aw", @progbits
.align 4096
513,3 → 634,6
 
grub_ebx:
.long 0
 
long_mode_msg:
.asciz "64 bit long mode not supported. System halted."
/branches/rcu/kernel/arch/amd64/src/mm/page.c
83,7 → 83,7
{
uintptr_t cur;
int i;
int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL;
int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;
 
if (config.cpu_active == 1) {
page_mapping_operations = &pt_mapping_operations;
112,10 → 112,8
 
exc_register(14, "page_fault", (iroutine) page_fault);
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
}
else {
} else
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
}
}
 
 
208,7 → 206,7
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE);
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE);
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
/branches/rcu/kernel/arch/amd64/src/interrupt.c
156,14 → 156,21
ASSERT(n >= IVT_IRQBASE);
int inum = n - IVT_IRQBASE;
bool ack = false;
ASSERT(inum < IRQ_COUNT);
ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
 
irq_t *irq = irq_dispatch_and_lock(inum);
if (irq) {
/*
* The IRQ handler was found.
*/
if (irq->preack) {
/* Send EOI before processing the interrupt */
trap_virtual_eoi();
ack = true;
}
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
174,7 → 181,9
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum);
#endif
}
trap_virtual_eoi();
if (!ack)
trap_virtual_eoi();
}
 
void interrupt_init(void)
/branches/rcu/kernel/arch/ppc64/include/types.h
62,6 → 62,7
typedef int64_t native_t;
 
typedef uint8_t bool;
typedef uint64_t thread_id_t;
typedef uint64_t task_id_t;
typedef uint32_t context_id_t;
 
/branches/rcu/kernel/arch/ppc64/src/mm/page.c
264,10 → 264,8
uintptr_t cur;
int flags;
/* Frames below 128 MB are mapped using BAT,
map rest of the physical memory */
for (cur = 128 << 20; cur < last_frame; cur += FRAME_SIZE) {
flags = PAGE_CACHEABLE;
flags = PAGE_CACHEABLE | PAGE_WRITE;
if ((PA2KA(cur) >= config.base) && (PA2KA(cur) < config.base + config.kernel_size))
flags |= PAGE_GLOBAL;
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
296,7 → 294,7
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE);
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE);
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
/branches/rcu/kernel/arch/ppc64/src/interrupt.c
60,11 → 60,19
int inum;
while ((inum = pic_get_pending()) != -1) {
bool ack = false;
irq_t *irq = irq_dispatch_and_lock(inum);
if (irq) {
/*
* The IRQ handler was found.
*/
if (irq->preack) {
/* Acknowledge the interrupt before processing */
pic_ack_interrupt(inum);
ack = true;
}
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
75,7 → 83,9
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum);
#endif
}
pic_ack_interrupt(inum);
if (!ack)
pic_ack_interrupt(inum);
}
}
 
/branches/rcu/kernel/arch/ppc64/src/ppc64.c
128,6 → 128,7
void arch_grab_console(void)
{
}
 
/** Return console to userspace
*
*/
135,5 → 136,11
{
}
 
void arch_reboot(void)
{
// TODO
while (1);
}
 
/** @}
*/
/branches/rcu/kernel/arch/mips32/_link.ld.in
10,7 → 10,7
 
OUTPUT_ARCH(mips)
 
ENTRY(kernel_image_start)
ENTRY(kernel_image_start)
 
SECTIONS {
. = KERNEL_LOAD_ADDRESS;
31,9 → 31,10
*(.rodata*);
*(.sdata);
*(.reginfo);
/* Unfortunately IRIX does not allow us
* to include this as a last section :-(
* BSS/SBSS addresses will be wrong */
*(.sbss);
*(.scommon);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
symbol_table = .;
*(symtab.*);
}
40,14 → 41,6
_gp = . + 0x8000;
.lit8 : { *(.lit8) }
.lit4 : { *(.lit4) }
.sbss : {
*(.sbss);
*(.scommon);
}
.bss : {
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
}
 
kdata_end = .;
 
/branches/rcu/kernel/arch/mips32/include/types.h
62,6 → 62,7
typedef int32_t native_t;
 
typedef uint8_t bool;
typedef uint64_t thread_id_t;
typedef uint64_t task_id_t;
typedef uint32_t context_id_t;
 
/branches/rcu/kernel/arch/mips32/src/mips32.c
178,5 → 178,11
return 0;
}
 
void arch_reboot(void)
{
___halt();
while (1);
}
 
/** @}
*/
/branches/rcu/kernel/arch/ia32/include/types.h
62,6 → 62,7
typedef int32_t native_t;
 
typedef uint8_t bool;
typedef uint64_t thread_id_t;
typedef uint64_t task_id_t;
typedef uint32_t context_id_t;
 
/branches/rcu/kernel/arch/ia32/include/asm.h
59,12 → 59,12
*/
static inline void cpu_halt(void)
{
asm("hlt\n");
asm volatile ("hlt\n");
};
 
static inline void cpu_sleep(void)
{
asm("hlt\n");
asm volatile ("hlt\n");
};
 
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
/branches/rcu/kernel/arch/ia32/src/pm.c
121,7 → 121,7
void idt_init(void)
{
idescriptor_t *d;
int i;
unsigned int i;
 
for (i = 0; i < IDT_ITEMS; i++) {
d = &idt[i];
230,5 → 230,28
gdtr_load(&cpugdtr);
}
 
/* Reboot the machine by initiating
* a triple fault
*/
void arch_reboot(void)
{
preemption_disable();
ipl_t ipl = interrupts_disable();
memsetb((uintptr_t) idt, sizeof(idt), 0);
ptr_16_32_t idtr;
idtr.limit = sizeof(idt);
idtr.base = (uintptr_t) idt;
idtr_load(&idtr);
interrupts_restore(ipl);
asm volatile (
"int $0x03\n"
"cli\n"
"hlt\n"
);
}
 
/** @}
*/
/branches/rcu/kernel/arch/ia32/src/smp/smp.c
82,13 → 82,13
 
if (config.cpu_count > 1) {
page_mapping_insert(AS_KERNEL, l_apic_address, (uintptr_t) l_apic,
PAGE_NOT_CACHEABLE);
PAGE_NOT_CACHEABLE | PAGE_WRITE);
page_mapping_insert(AS_KERNEL, io_apic_address, (uintptr_t) io_apic,
PAGE_NOT_CACHEABLE);
PAGE_NOT_CACHEABLE | PAGE_WRITE);
l_apic = (uint32_t *) l_apic_address;
io_apic = (uint32_t *) io_apic_address;
}
}
}
 
/*
/branches/rcu/kernel/arch/ia32/src/smp/apic.c
139,7 → 139,14
 
static void l_apic_timer_irq_handler(irq_t *irq, void *arg, ...)
{
/*
* Holding a spinlock could prevent clock() from preempting
* the current thread. In this case, we don't need to hold the
* irq->lock so we just unlock it and then lock it again.
*/
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
}
 
/** Initialize APIC on BSP. */
162,6 → 169,7
io_apic_disable_irqs(0xffff);
irq_initialize(&l_apic_timer_irq);
l_apic_timer_irq.preack = true;
l_apic_timer_irq.devno = device_assign_devno();
l_apic_timer_irq.inr = IRQ_CLK;
l_apic_timer_irq.claim = l_apic_timer_claim;
/branches/rcu/kernel/arch/ia32/src/boot/vga323.pal
0,0 → 1,256
.byte 0x00, 0x00, 0x00, 0x00
.byte 0x09, 0x00, 0x00, 0x00
.byte 0x12, 0x00, 0x00, 0x00
.byte 0x1b, 0x00, 0x00, 0x00
.byte 0x24, 0x00, 0x00, 0x00
.byte 0x2d, 0x00, 0x00, 0x00
.byte 0x36, 0x00, 0x00, 0x00
.byte 0x3f, 0x00, 0x00, 0x00
.byte 0x00, 0x15, 0x00, 0x00
.byte 0x09, 0x15, 0x00, 0x00
.byte 0x12, 0x15, 0x00, 0x00
.byte 0x1b, 0x15, 0x00, 0x00
.byte 0x24, 0x15, 0x00, 0x00
.byte 0x2d, 0x15, 0x00, 0x00
.byte 0x36, 0x15, 0x00, 0x00
.byte 0x3f, 0x15, 0x00, 0x00
.byte 0x00, 0x2a, 0x00, 0x00
.byte 0x09, 0x2a, 0x00, 0x00
.byte 0x12, 0x2a, 0x00, 0x00
.byte 0x1b, 0x2a, 0x00, 0x00
.byte 0x24, 0x2a, 0x00, 0x00
.byte 0x2d, 0x2a, 0x00, 0x00
.byte 0x36, 0x2a, 0x00, 0x00
.byte 0x3f, 0x2a, 0x00, 0x00
.byte 0x00, 0x3f, 0x00, 0x00
.byte 0x09, 0x3f, 0x00, 0x00
.byte 0x12, 0x3f, 0x00, 0x00
.byte 0x1b, 0x3f, 0x00, 0x00
.byte 0x24, 0x3f, 0x00, 0x00
.byte 0x2d, 0x3f, 0x00, 0x00
.byte 0x36, 0x3f, 0x00, 0x00
.byte 0x3f, 0x3f, 0x00, 0x00
.byte 0x00, 0x00, 0x09, 0x00
.byte 0x09, 0x00, 0x09, 0x00
.byte 0x12, 0x00, 0x09, 0x00
.byte 0x1b, 0x00, 0x09, 0x00
.byte 0x24, 0x00, 0x09, 0x00
.byte 0x2d, 0x00, 0x09, 0x00
.byte 0x36, 0x00, 0x09, 0x00
.byte 0x3f, 0x00, 0x09, 0x00
.byte 0x00, 0x15, 0x09, 0x00
.byte 0x09, 0x15, 0x09, 0x00
.byte 0x12, 0x15, 0x09, 0x00
.byte 0x1b, 0x15, 0x09, 0x00
.byte 0x24, 0x15, 0x09, 0x00
.byte 0x2d, 0x15, 0x09, 0x00
.byte 0x36, 0x15, 0x09, 0x00
.byte 0x3f, 0x15, 0x09, 0x00
.byte 0x00, 0x2a, 0x09, 0x00
.byte 0x09, 0x2a, 0x09, 0x00
.byte 0x12, 0x2a, 0x09, 0x00
.byte 0x1b, 0x2a, 0x09, 0x00
.byte 0x24, 0x2a, 0x09, 0x00
.byte 0x2d, 0x2a, 0x09, 0x00
.byte 0x36, 0x2a, 0x09, 0x00
.byte 0x3f, 0x2a, 0x09, 0x00
.byte 0x00, 0x3f, 0x09, 0x00
.byte 0x09, 0x3f, 0x09, 0x00
.byte 0x12, 0x3f, 0x09, 0x00
.byte 0x1b, 0x3f, 0x09, 0x00
.byte 0x24, 0x3f, 0x09, 0x00
.byte 0x2d, 0x3f, 0x09, 0x00
.byte 0x36, 0x3f, 0x09, 0x00
.byte 0x3f, 0x3f, 0x09, 0x00
.byte 0x00, 0x00, 0x12, 0x00
.byte 0x09, 0x00, 0x12, 0x00
.byte 0x12, 0x00, 0x12, 0x00
.byte 0x1b, 0x00, 0x12, 0x00
.byte 0x24, 0x00, 0x12, 0x00
.byte 0x2d, 0x00, 0x12, 0x00
.byte 0x36, 0x00, 0x12, 0x00
.byte 0x3f, 0x00, 0x12, 0x00
.byte 0x00, 0x15, 0x12, 0x00
.byte 0x09, 0x15, 0x12, 0x00
.byte 0x12, 0x15, 0x12, 0x00
.byte 0x1b, 0x15, 0x12, 0x00
.byte 0x24, 0x15, 0x12, 0x00
.byte 0x2d, 0x15, 0x12, 0x00
.byte 0x36, 0x15, 0x12, 0x00
.byte 0x3f, 0x15, 0x12, 0x00
.byte 0x00, 0x2a, 0x12, 0x00
.byte 0x09, 0x2a, 0x12, 0x00
.byte 0x12, 0x2a, 0x12, 0x00
.byte 0x1b, 0x2a, 0x12, 0x00
.byte 0x24, 0x2a, 0x12, 0x00
.byte 0x2d, 0x2a, 0x12, 0x00
.byte 0x36, 0x2a, 0x12, 0x00
.byte 0x3f, 0x2a, 0x12, 0x00
.byte 0x00, 0x3f, 0x12, 0x00
.byte 0x09, 0x3f, 0x12, 0x00
.byte 0x12, 0x3f, 0x12, 0x00
.byte 0x1b, 0x3f, 0x12, 0x00
.byte 0x24, 0x3f, 0x12, 0x00
.byte 0x2d, 0x3f, 0x12, 0x00
.byte 0x36, 0x3f, 0x12, 0x00
.byte 0x3f, 0x3f, 0x12, 0x00
.byte 0x00, 0x00, 0x1b, 0x00
.byte 0x09, 0x00, 0x1b, 0x00
.byte 0x12, 0x00, 0x1b, 0x00
.byte 0x1b, 0x00, 0x1b, 0x00
.byte 0x24, 0x00, 0x1b, 0x00
.byte 0x2d, 0x00, 0x1b, 0x00
.byte 0x36, 0x00, 0x1b, 0x00
.byte 0x3f, 0x00, 0x1b, 0x00
.byte 0x00, 0x15, 0x1b, 0x00
.byte 0x09, 0x15, 0x1b, 0x00
.byte 0x12, 0x15, 0x1b, 0x00
.byte 0x1b, 0x15, 0x1b, 0x00
.byte 0x24, 0x15, 0x1b, 0x00
.byte 0x2d, 0x15, 0x1b, 0x00
.byte 0x36, 0x15, 0x1b, 0x00
.byte 0x3f, 0x15, 0x1b, 0x00
.byte 0x00, 0x2a, 0x1b, 0x00
.byte 0x09, 0x2a, 0x1b, 0x00
.byte 0x12, 0x2a, 0x1b, 0x00
.byte 0x1b, 0x2a, 0x1b, 0x00
.byte 0x24, 0x2a, 0x1b, 0x00
.byte 0x2d, 0x2a, 0x1b, 0x00
.byte 0x36, 0x2a, 0x1b, 0x00
.byte 0x3f, 0x2a, 0x1b, 0x00
.byte 0x00, 0x3f, 0x1b, 0x00
.byte 0x09, 0x3f, 0x1b, 0x00
.byte 0x12, 0x3f, 0x1b, 0x00
.byte 0x1b, 0x3f, 0x1b, 0x00
.byte 0x24, 0x3f, 0x1b, 0x00
.byte 0x2d, 0x3f, 0x1b, 0x00
.byte 0x36, 0x3f, 0x1b, 0x00
.byte 0x3f, 0x3f, 0x1b, 0x00
.byte 0x00, 0x00, 0x24, 0x00
.byte 0x09, 0x00, 0x24, 0x00
.byte 0x12, 0x00, 0x24, 0x00
.byte 0x1b, 0x00, 0x24, 0x00
.byte 0x24, 0x00, 0x24, 0x00
.byte 0x2d, 0x00, 0x24, 0x00
.byte 0x36, 0x00, 0x24, 0x00
.byte 0x3f, 0x00, 0x24, 0x00
.byte 0x00, 0x15, 0x24, 0x00
.byte 0x09, 0x15, 0x24, 0x00
.byte 0x12, 0x15, 0x24, 0x00
.byte 0x1b, 0x15, 0x24, 0x00
.byte 0x24, 0x15, 0x24, 0x00
.byte 0x2d, 0x15, 0x24, 0x00
.byte 0x36, 0x15, 0x24, 0x00
.byte 0x3f, 0x15, 0x24, 0x00
.byte 0x00, 0x2a, 0x24, 0x00
.byte 0x09, 0x2a, 0x24, 0x00
.byte 0x12, 0x2a, 0x24, 0x00
.byte 0x1b, 0x2a, 0x24, 0x00
.byte 0x24, 0x2a, 0x24, 0x00
.byte 0x2d, 0x2a, 0x24, 0x00
.byte 0x36, 0x2a, 0x24, 0x00
.byte 0x3f, 0x2a, 0x24, 0x00
.byte 0x00, 0x3f, 0x24, 0x00
.byte 0x09, 0x3f, 0x24, 0x00
.byte 0x12, 0x3f, 0x24, 0x00
.byte 0x1b, 0x3f, 0x24, 0x00
.byte 0x24, 0x3f, 0x24, 0x00
.byte 0x2d, 0x3f, 0x24, 0x00
.byte 0x36, 0x3f, 0x24, 0x00
.byte 0x3f, 0x3f, 0x24, 0x00
.byte 0x00, 0x00, 0x2d, 0x00
.byte 0x09, 0x00, 0x2d, 0x00
.byte 0x12, 0x00, 0x2d, 0x00
.byte 0x1b, 0x00, 0x2d, 0x00
.byte 0x24, 0x00, 0x2d, 0x00
.byte 0x2d, 0x00, 0x2d, 0x00
.byte 0x36, 0x00, 0x2d, 0x00
.byte 0x3f, 0x00, 0x2d, 0x00
.byte 0x00, 0x15, 0x2d, 0x00
.byte 0x09, 0x15, 0x2d, 0x00
.byte 0x12, 0x15, 0x2d, 0x00
.byte 0x1b, 0x15, 0x2d, 0x00
.byte 0x24, 0x15, 0x2d, 0x00
.byte 0x2d, 0x15, 0x2d, 0x00
.byte 0x36, 0x15, 0x2d, 0x00
.byte 0x3f, 0x15, 0x2d, 0x00
.byte 0x00, 0x2a, 0x2d, 0x00
.byte 0x09, 0x2a, 0x2d, 0x00
.byte 0x12, 0x2a, 0x2d, 0x00
.byte 0x1b, 0x2a, 0x2d, 0x00
.byte 0x24, 0x2a, 0x2d, 0x00
.byte 0x2d, 0x2a, 0x2d, 0x00
.byte 0x36, 0x2a, 0x2d, 0x00
.byte 0x3f, 0x2a, 0x2d, 0x00
.byte 0x00, 0x3f, 0x2d, 0x00
.byte 0x09, 0x3f, 0x2d, 0x00
.byte 0x12, 0x3f, 0x2d, 0x00
.byte 0x1b, 0x3f, 0x2d, 0x00
.byte 0x24, 0x3f, 0x2d, 0x00
.byte 0x2d, 0x3f, 0x2d, 0x00
.byte 0x36, 0x3f, 0x2d, 0x00
.byte 0x3f, 0x3f, 0x2d, 0x00
.byte 0x00, 0x00, 0x36, 0x00
.byte 0x09, 0x00, 0x36, 0x00
.byte 0x12, 0x00, 0x36, 0x00
.byte 0x1b, 0x00, 0x36, 0x00
.byte 0x24, 0x00, 0x36, 0x00
.byte 0x2d, 0x00, 0x36, 0x00
.byte 0x36, 0x00, 0x36, 0x00
.byte 0x3f, 0x00, 0x36, 0x00
.byte 0x00, 0x15, 0x36, 0x00
.byte 0x09, 0x15, 0x36, 0x00
.byte 0x12, 0x15, 0x36, 0x00
.byte 0x1b, 0x15, 0x36, 0x00
.byte 0x24, 0x15, 0x36, 0x00
.byte 0x2d, 0x15, 0x36, 0x00
.byte 0x36, 0x15, 0x36, 0x00
.byte 0x3f, 0x15, 0x36, 0x00
.byte 0x00, 0x2a, 0x36, 0x00
.byte 0x09, 0x2a, 0x36, 0x00
.byte 0x12, 0x2a, 0x36, 0x00
.byte 0x1b, 0x2a, 0x36, 0x00
.byte 0x24, 0x2a, 0x36, 0x00
.byte 0x2d, 0x2a, 0x36, 0x00
.byte 0x36, 0x2a, 0x36, 0x00
.byte 0x3f, 0x2a, 0x36, 0x00
.byte 0x00, 0x3f, 0x36, 0x00
.byte 0x09, 0x3f, 0x36, 0x00
.byte 0x12, 0x3f, 0x36, 0x00
.byte 0x1b, 0x3f, 0x36, 0x00
.byte 0x24, 0x3f, 0x36, 0x00
.byte 0x2d, 0x3f, 0x36, 0x00
.byte 0x36, 0x3f, 0x36, 0x00
.byte 0x3f, 0x3f, 0x36, 0x00
.byte 0x00, 0x00, 0x3f, 0x00
.byte 0x09, 0x00, 0x3f, 0x00
.byte 0x12, 0x00, 0x3f, 0x00
.byte 0x1b, 0x00, 0x3f, 0x00
.byte 0x24, 0x00, 0x3f, 0x00
.byte 0x2d, 0x00, 0x3f, 0x00
.byte 0x36, 0x00, 0x3f, 0x00
.byte 0x3f, 0x00, 0x3f, 0x00
.byte 0x00, 0x15, 0x3f, 0x00
.byte 0x09, 0x15, 0x3f, 0x00
.byte 0x12, 0x15, 0x3f, 0x00
.byte 0x1b, 0x15, 0x3f, 0x00
.byte 0x24, 0x15, 0x3f, 0x00
.byte 0x2d, 0x15, 0x3f, 0x00
.byte 0x36, 0x15, 0x3f, 0x00
.byte 0x3f, 0x15, 0x3f, 0x00
.byte 0x00, 0x2a, 0x3f, 0x00
.byte 0x09, 0x2a, 0x3f, 0x00
.byte 0x12, 0x2a, 0x3f, 0x00
.byte 0x1b, 0x2a, 0x3f, 0x00
.byte 0x24, 0x2a, 0x3f, 0x00
.byte 0x2d, 0x2a, 0x3f, 0x00
.byte 0x36, 0x2a, 0x3f, 0x00
.byte 0x3f, 0x2a, 0x3f, 0x00
.byte 0x00, 0x3f, 0x3f, 0x00
.byte 0x09, 0x3f, 0x3f, 0x00
.byte 0x12, 0x3f, 0x3f, 0x00
.byte 0x1b, 0x3f, 0x3f, 0x00
.byte 0x24, 0x3f, 0x3f, 0x00
.byte 0x2d, 0x3f, 0x3f, 0x00
.byte 0x36, 0x3f, 0x3f, 0x00
.byte 0x3f, 0x3f, 0x3f, 0x00
/branches/rcu/kernel/arch/ia32/src/boot/boot.S
63,9 → 63,24
jmpl $selector(KTEXT_DES), $multiboot_meeting_point
multiboot_meeting_point:
pushl %ebx # save parameters from GRUB
pushl %eax
movl %eax, grub_eax # save parameters from GRUB
movl %ebx, grub_ebx
xorl %eax, %eax
cpuid
cmp $0x0, %eax # any function > 0?
jbe pse_unsupported
movl $0x1, %eax # Basic function code 1
cpuid
bt $3, %edx # Test if PSE is supported
jc pse_supported
 
pse_unsupported:
movl $pse_msg, %esi
jmp error_halt
pse_supported:
#ifdef CONFIG_FB
mov $vesa_init, %esi
mov $VESA_INIT_SEGMENT << 4, %edi
89,8 → 104,8
call map_kernel # map kernel and turn paging on
popl %eax
popl %ebx
movl grub_eax, %eax
movl grub_ebx, %ebx
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature
je valid_boot
209,7 → 224,7
rep movsb
#endif
 
call main_bsp # never returns
 
cli
222,19 → 237,20
# For simplicity, we map the entire 4G space.
#
movl %cr4, %ecx
orl $(1<<4), %ecx
movl %ecx, %cr4 # turn PSE on
orl $(1 << 4), %ecx # turn PSE on
andl $(~(1 << 5)), %ecx # turn PAE off
movl %ecx, %cr4
movl $(page_directory+0), %esi
movl $(page_directory+2048), %edi
movl $(page_directory + 0), %esi
movl $(page_directory + 2048), %edi
xorl %ecx, %ecx
xorl %ebx, %ebx
0:
movl $((1<<7)|(1<<0)), %eax
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
orl %ebx, %eax
movl %eax, (%esi,%ecx,4) # mapping 0x00000000+%ecx*4M => 0x00000000+%ecx*4M
movl %eax, (%edi,%ecx,4) # mapping 0x80000000+%ecx*4M => 0x00000000+%ecx*4M
addl $(4*1024*1024), %ebx
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
addl $(4 * 1024 * 1024), %ebx
 
incl %ecx
cmpl $512, %ecx
242,12 → 258,71
 
movl %esi, %cr3
# turn paging on
movl %cr0, %ebx
orl $(1<<31), %ebx
orl $(1 << 31), %ebx # turn paging on
movl %ebx, %cr0
ret
 
# Print string from %esi to EGA display (in red) and halt
error_halt:
movl $0xb8000, %edi # base of EGA text mode memory
xorl %eax, %eax
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
cmp $1920, %ax
jbe cursor_ok
movw $1920, %ax # sanity check for the cursor on the last line
cursor_ok:
movw %ax, %bx
shl $1, %eax
addl %eax, %edi
movw $0x0c00, %ax # black background, light red foreground
cld
ploop:
lodsb
cmp $0, %al
je ploop_end
stosw
inc %bx
jmp ploop
ploop_end:
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
cli
hlt
 
#ifdef CONFIG_FB
vesa_init:
jmp $selector(VESA_INIT_DES), $vesa_init_real - vesa_init
278,11 → 353,12
#define VESA_INFO_SIZE 1024
 
#define VESA_MODE_ATTRIBUTES_OFFSET 0
#define VESA_MODE_LIST_PTR_OFFSET 14
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_WIDTH_OFFSET 18
#define VESA_MODE_HEIGHT_OFFSET 20
#define VESA_MODE_BPP_OFFSET 25
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_PHADDR_OFFSET 40
 
#define VESA_END_OF_MODES 0xffff
292,12 → 368,10
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
#define VESA_SET_PALETTE 0x4f09
 
#define CONFIG_VESA_BPP_a 255
 
#if CONFIG_VESA_BPP == 24
#undef CONFIG_VESA_BPP_a
#define CONFIG_VESA_BPP_a 32
#define CONFIG_VESA_BPP_VARIANT 32
#endif
 
mov $VESA_GET_INFO, %ax
338,18 → 412,21
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_HEIGHT,%ax
mov $CONFIG_VESA_HEIGHT, %ax
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_BPP, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
 
#ifdef CONFIG_VESA_BPP_VARIANT
jz 2f
mov $CONFIG_VESA_BPP_a, %al
mov $CONFIG_VESA_BPP_VARIANT, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
#endif
jnz 1b
 
2:
mov %cx, %bx
361,7 → 438,60
pop %di
cmp $VESA_OK, %al
jnz 0f
 
#if CONFIG_VESA_BPP == 8
# Set 3:2:3 VGA palette
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
push %di
mov $vga323 - vesa_init, %di
mov $0x100, %ecx
bt $5, %ax # Test if VGA compatible registers are present
jnc vga_compat
# Try VESA routine to set palette
mov $VESA_SET_PALETTE, %ax
xor %bl, %bl
xor %dx, %dx
int $0x10
jmp vga_not_compat
vga_compat:
# Try VGA registers to set palette
movw $0x3c6, %dx # Set palette mask
movb $0xff, %al
outb %al, %dx
movw $0x3c8, %dx # First index to set
xor %al, %al
outb %al, %dx
movw $0x3c9, %dx # Data port
vga_loop:
movb %es:2(%di), %al
outb %al, %dx
movb %es:1(%di), %al
outb %al, %dx
movb %es:(%di), %al
outb %al, %dx
addw $4, %di
loop vga_loop
vga_not_compat:
pop %di
#endif
mov VESA_MODE_PHADDR_OFFSET(%di), %esi
mov VESA_MODE_WIDTH_OFFSET(%di), %ax
shl $16, %eax
402,12 → 532,12
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA
xor %ax, %ax
jz 8b # Force relative jump
 
vga323:
#include "vga323.pal"
 
.code32
vesa_init_protect:
popl %esp
 
movw $selector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %fs
415,6 → 545,8
movw %cx, %ds # kernel data + stack
movw %cx, %ss
movl $START_STACK, %esp # initialize stack pointer
 
jmpl $selector(KTEXT_DES), $vesa_meeting_point
 
.align 4
426,3 → 558,12
.align 4096
page_directory:
.space 4096, 0
 
grub_eax:
.long 0
 
grub_ebx:
.long 0
 
pse_msg:
.asciz "Page Size Extension not supported. System halted."
/branches/rcu/kernel/arch/ia32/src/mm/page.c
61,7 → 61,7
* PA2KA(identity) mapping for all frames until last_frame.
*/
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
flags = PAGE_CACHEABLE;
flags = PAGE_CACHEABLE | PAGE_WRITE;
if ((PA2KA(cur) >= config.base) && (PA2KA(cur) < config.base + config.kernel_size))
flags |= PAGE_GLOBAL;
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
69,10 → 69,8
 
exc_register(14, "page_fault", (iroutine) page_fault);
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
}
else {
} else
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
}
 
paging_on();
}
86,7 → 84,7
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE);
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE);
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
95,12 → 93,12
 
void page_fault(int n, istate_t *istate)
{
uintptr_t page;
uintptr_t page;
pf_access_t access;
page = read_cr2();
page = read_cr2();
if (istate->error_word & PFERR_CODE_RSVD)
if (istate->error_word & PFERR_CODE_RSVD)
panic("Reserved bit set in page directory.\n");
 
if (istate->error_word & PFERR_CODE_RW)
107,14 → 105,14
access = PF_ACCESS_WRITE;
else
access = PF_ACCESS_READ;
 
if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate, "Page fault: %#x", page);
 
decode_istate(istate);
printf("page fault address: %#x\n", page);
panic("page fault\n");
}
decode_istate(istate);
printf("page fault address: %#x\n", page);
panic("page fault\n");
}
}
 
/** @}
/branches/rcu/kernel/arch/ia32/src/interrupt.c
176,14 → 176,21
ASSERT(n >= IVT_IRQBASE);
int inum = n - IVT_IRQBASE;
bool ack = false;
ASSERT(inum < IRQ_COUNT);
ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
 
irq_t *irq = irq_dispatch_and_lock(inum);
if (irq) {
/*
* The IRQ handler was found.
*/
if (irq->preack) {
/* Send EOI before processing the interrupt */
trap_virtual_eoi();
ack = true;
}
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
194,7 → 201,9
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum);
#endif
}
trap_virtual_eoi();
if (!ack)
trap_virtual_eoi();
}
 
void interrupt_init(void)
/branches/rcu/kernel/arch/ia32/src/drivers/i8254.c
82,6 → 82,7
void i8254_init(void)
{
irq_initialize(&i8254_irq);
i8254_irq.preack = true;
i8254_irq.devno = device_assign_devno();
i8254_irq.inr = IRQ_CLK;
i8254_irq.claim = i8254_claim;
/branches/rcu/uspace/fb/fb.c
833,23 → 833,27
copy_vp_to_pixmap(viewport_t *vport, pixmap_t *pmap)
{
int y;
int rowsize;
int tmp;
int tmp, srcrowsize;
int realwidth, realheight, realrowsize;
int width = vport->width;
int height = vport->height;
 
if (width + vport->x > screen.xres)
width = screen.xres - vport->x;
if (height + vport->y > screen.yres)
if (height + vport->y > screen.yres)
height = screen.yres - vport->y;
realwidth = pmap->width <= width ? pmap->width : width;
realheight = pmap->height <= height ? pmap->height : height;
 
rowsize = width * screen.pixelbytes;
 
for (y = 0; y < height; y++) {
srcrowsize = vport->width * screen.pixelbytes;
realrowsize = realwidth * screen.pixelbytes;
for (y = 0; y < realheight; y++) {
tmp = (vport->y + y) * screen.scanline +
vport->x * screen.pixelbytes;
memcpy(pmap->data + rowsize * y, screen.fbaddress + tmp,
rowsize);
memcpy(pmap->data + srcrowsize * y, screen.fbaddress + tmp,
realrowsize);
}
}
 
/branches/rcu/uspace/kbd/generic/key_buffer.c
111,4 → 111,3
/**
* @}
*/
 
/branches/rcu/uspace/tester/tester.c
0,0 → 1,121
/*
* Copyright (c) 2006 Ondrej Palkovsky
* Copyright (c) 2007 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup tester User space Tester
* @brief User space testing infrastructure.
* @{
*/
/**
* @file
*/
 
#include <unistd.h>
#include <stdio.h>
#include "tester.h"
 
int myservice = 0;
int phones[MAX_PHONES];
int connections[MAX_CONNECTIONS];
ipc_callid_t callids[MAX_CONNECTIONS];
 
test_t tests[] = {
#include "thread/thread1.def"
#include "print/print1.def"
#include "fault/fault1.def"
#include "fault/fault2.def"
#include "ipc/register.def"
#include "ipc/connect.def"
#include "ipc/send_async.def"
#include "ipc/send_sync.def"
#include "ipc/answer.def"
#include "ipc/hangup.def"
{NULL, NULL, NULL}
};
 
static bool run_test(test_t *test)
{
printf("%s\t\t%s\n", test->name, test->desc);
/* Execute the test */
char * ret = test->entry(false);
if (ret == NULL) {
printf("Test passed\n\n");
return true;
}
 
printf("%s\n\n", ret);
return false;
}
 
static void run_safe_tests(void)
{
}
 
static void list_tests(void)
{
test_t *test;
char c = 'a';
for (test = tests; test->name != NULL; test++, c++)
printf("%c\t%s\t\t%s%s\n", c, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
printf("*\t\t\tRun all safe tests\n");
}
 
int main(void)
{
while (1) {
char c;
test_t *test;
list_tests();
printf("> ");
c = getchar();
printf("%c\n", c);
if ((c >= 'a') && (c <= 'z')) {
for (test = tests; test->name != NULL; test++, c--)
if (c == 'a')
break;
if (c > 'a')
printf("Unknown test\n\n");
else
run_test(test);
} else if (c == '*')
run_safe_tests();
else
printf("Invalid test\n\n");
}
}
 
/** @}
*/
/branches/rcu/uspace/tester/thread/thread1.def
0,0 → 1,6
{
"thread1",
"Thread test",
&test_thread1,
true
},
/branches/rcu/uspace/tester/thread/thread1.c
0,0 → 1,83
/*
* Copyright (c) 2005 Jakub Vana
* Copyright (c) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#define THREADS 5
 
#include <atomic.h>
#include <thread.h>
#include <stdio.h>
#include <unistd.h>
#include "../tester.h"
 
static atomic_t finish;
static atomic_t threads_finished;
static bool sh_quiet;
 
static void threadtest(void *data)
{
thread_detach(thread_get_id());
 
while (atomic_get(&finish)) {
if (!sh_quiet)
printf("%llu ", thread_get_id());
usleep(100000);
}
atomic_inc(&threads_finished);
}
 
char * test_thread1(bool quiet)
{
unsigned int i, total = 0;
sh_quiet = quiet;
atomic_set(&finish, 1);
atomic_set(&threads_finished, 0);
 
for (i = 0; i < THREADS; i++) {
if (thread_create(threadtest, NULL, "threadtest", NULL) < 0) {
if (!quiet)
printf("Could not create thread %d\n", i);
break;
}
total++;
}
if (!quiet)
printf("Running threads for 10 seconds...\n");
sleep(10);
atomic_set(&finish, 0);
while (atomic_get(&threads_finished) < total) {
if (!quiet)
printf("Threads left: %d\n", total - atomic_get(&threads_finished));
sleep(1);
}
return NULL;
}
/branches/rcu/uspace/tester/fault/fault1.def
0,0 → 1,6
{
"fault1",
"Write to NULL",
&test_fault1,
false
},
/branches/rcu/uspace/tester/fault/fault2.def
0,0 → 1,6
{
"fault2",
"Unaligned read",
&test_fault2,
false
},
/branches/rcu/uspace/tester/fault/fault1.c
0,0 → 1,37
/*
* Copyright (c) 2005 Jakub Vana
* Copyright (c) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include "../tester.h"
 
char * test_fault1(bool quiet)
{
((int *)(0))[1] = 0;
return "Survived write to NULL";
}
/branches/rcu/uspace/tester/fault/fault2.c
0,0 → 1,40
/*
* Copyright (c) 2005 Jakub Vana
* Copyright (c) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include "../tester.h"
 
char * test_fault2(bool quiet)
{
volatile long long var;
volatile int var1;
var1 = *((int *) (((char *) (&var)) + 1));
return "Survived unaligned read";
}
/branches/rcu/uspace/tester/ipc/hangup.def
0,0 → 1,6
{
"hangup",
"IPC hangup test",
&test_hangup,
true
},
/branches/rcu/uspace/tester/ipc/answer.c
0,0 → 1,76
/*
* Copyright (c) 2006 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include "../tester.h"
 
char * test_answer(bool quiet)
{
int i,cnt, errn = 0;
char c;
 
cnt = 0;
for (i = 0;i < 50; i++) {
if (callids[i]) {
printf("%d: %P\n", cnt, callids[i]);
cnt++;
}
if (cnt >= 10)
break;
}
if (!cnt)
return;
printf("Choose message:\n");
do {
c = getchar();
} while (c < '0' || (c-'0') >= cnt);
cnt = c - '0' + 1;
for (i = 0; cnt; i++)
if (callids[i])
cnt--;
i -= 1;
 
printf("Normal (n) or hangup (h) or error(e) message?\n");
do {
c = getchar();
} while (c != 'n' && c != 'h' && c != 'e');
if (c == 'n')
errn = 0;
else if (c == 'h')
errn = EHANGUP;
else if (c == 'e')
errn = ENOENT;
printf("Answering %P\n", callids[i]);
ipc_answer_fast(callids[i], errn, 0, 0);
callids[i] = 0;
return NULL;
}
/branches/rcu/uspace/tester/ipc/register.def
0,0 → 1,6
{
"register",
"IPC registration test",
&test_register,
true
},
/branches/rcu/uspace/tester/ipc/send_sync.def
0,0 → 1,6
{
"send_sync",
"IPC send sync message test",
&test_send_sync,
true
},
/branches/rcu/uspace/tester/ipc/hangup.c
0,0 → 1,51
/*
* Copyright (c) 2006 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include "../tester.h"
 
char * test_hangup(bool quiet)
{
char c;
int res;
int phoneid;
 
printf("Select phoneid to hangup: 2-9\n");
do {
c = getchar();
} while (c < '2' || c > '9');
phoneid = c - '0';
printf("Hanging up...");
res = ipc_hangup(phoneid);
printf("done: %d\n", phoneid);
return NULL;
}
/branches/rcu/uspace/tester/ipc/send_async.def
0,0 → 1,6
{
"send_async",
"IPC send async message test",
&test_send_async,
true
},
/branches/rcu/uspace/tester/ipc/register.c
0,0 → 1,87
/*
* Copyright (c) 2006 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <stdio.h>
#include <unistd.h>
#include <async.h>
#include "../tester.h"
 
static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
ipcarg_t phonehash = icall->in_phone_hash;
int retval;
int i;
 
printf("Connected phone: %P, accepting\n", icall->in_phone_hash);
ipc_answer_fast(iid, 0, 0, 0);
for (i = 0; i < 1024; i++)
if (!connections[i]) {
connections[i] = phonehash;
break;
}
while (1) {
callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
printf("Phone (%P) hung up.\n", phonehash);
retval = 0;
break;
default:
printf("Received message from %P: %X\n", phonehash,callid);
for (i = 0; i < 1024; i++)
if (!callids[i]) {
callids[i] = callid;
break;
}
continue;
}
ipc_answer_fast(callid, retval, 0, 0);
}
}
 
char * test_register(bool quiet)
{
int i;
async_set_client_connection(client_connection);
 
for (i = IPC_TEST_START; i < IPC_TEST_START + 10; i++) {
ipcarg_t phonead;
int res = ipc_connect_to_me(PHONE_NS, i, 0, &phonead);
if (!res)
break;
printf("Failed registering as %d..:%d\n", i, res);
}
printf("Registered as service: %d\n", i);
myservice = i;
return NULL;
}
/branches/rcu/uspace/tester/ipc/connect.def
0,0 → 1,6
{
"connect",
"IPC connection test (connect to other service)",
&test_connect,
true
},
/branches/rcu/uspace/tester/ipc/send_sync.c
0,0 → 1,51
/*
* Copyright (c) 2006 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <stdio.h>
#include <unistd.h>
#include "../tester.h"
 
char * test_send_sync(bool quiet)
{
int phoneid;
int res;
static int msgid = 1;
char c;
 
printf("Select phoneid to send msg: 2-9\n");
do {
c = getchar();
} while (c < '2' || c > '9');
phoneid = c - '0';
printf("Sending msg...");
res = ipc_call_sync_2(phoneid, 2000, 0, 0, NULL, NULL);
printf("done: %d\n", res);
return NULL;
}
/branches/rcu/uspace/tester/ipc/send_async.c
0,0 → 1,56
/*
* Copyright (c) 2006 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <stdio.h>
#include <unistd.h>
#include "../tester.h"
 
static void callback(void *_private, int retval, ipc_call_t *data)
{
printf("Received response to msg %d - retval: %d.\n", _private, retval);
}
 
char * test_send_async(bool quiet)
{
int phoneid;
int res;
static int msgid = 1;
char c;
 
printf("Select phoneid to send msg: 2-9\n");
do {
c = getchar();
} while (c < '2' || c > '9');
phoneid = c - '0';
 
ipc_call_async(phoneid, 2000, 0, (void *) msgid, callback, 1);
printf("Async sent - msg %d\n", msgid);
msgid++;
return NULL;
}
/branches/rcu/uspace/tester/ipc/connect.c
0,0 → 1,57
/*
* Copyright (c) 2006 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <stdio.h>
#include <unistd.h>
#include "../tester.h"
 
char * test_connect(bool quiet)
{
char c;
int svc;
int phid;
 
printf("Choose one service: 0:10000....9:10009\n");
do {
c = getchar();
} while (c < '0' || c > '9');
svc = IPC_TEST_START + c - '0';
if (svc == myservice)
return "Currently cannot connect to myself, update test";
printf("Connecting to %d..", svc);
phid = ipc_connect_me_to(PHONE_NS, svc, 0);
if (phid > 0) {
printf("phoneid: %d\n", phid);
phones[phid] = 1;
} else
return "Error";
return NULL;
}
/branches/rcu/uspace/tester/ipc/answer.def
0,0 → 1,6
{
"answer",
"IPC answer message test",
&test_answer,
true
},
/branches/rcu/uspace/tester/print/print1.def
0,0 → 1,6
{
"print1",
"Printf test",
&test_print1,
true
},
/branches/rcu/uspace/tester/print/print1.c
0,0 → 1,73
/*
* Copyright (c) 2005 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <stdio.h>
#include <unistd.h>
#include "../tester.h"
 
#define BUFFER_SIZE 32
 
char * test_print1(bool quiet)
{
if (!quiet) {
int retval;
unsigned int nat = 0x12345678u;
char buffer[BUFFER_SIZE];
printf(" text 10.8s %*.*s \n", 5, 3, "text");
printf(" very long text 10.8s %10.8s \n", "very long text");
printf(" text 8.10s %8.10s \n", "text");
printf(" very long text 8.10s %8.10s \n", "very long text");
printf(" char: c '%c', 3.2c '%3.2c', -3.2c '%-3.2c', 2.3c '%2.3c', -2.3c '%-2.3c' \n",'a', 'b', 'c', 'd', 'e' );
printf(" int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",1, 1, 1, 1, 1 );
printf(" -int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",-1, -1, -1, -1, -1 );
printf(" 0xint: x '%#x', 5.3x '%#5.3x', -5.3x '%#-5.3x', 3.5x '%#3.5x', -3.5x '%#-3.5x' \n",17, 17, 17, 17, 17 );
printf("'%#llx' 64bit, '%#x' 32bit, '%#hhx' 8bit, '%#hx' 16bit, unative_t '%#zx'. '%#llx' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, nat, 0x1234567887654321ull, "Lovely string" );
printf(" Print to NULL '%s'\n", NULL);
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print short text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Short %s", "text");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print long text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text`s length is more than %d. We are interested in the result.", "text" , BUFFER_SIZE);
printf("Result is: '%s', retval = %d\n", buffer, retval);
}
return NULL;
}
/branches/rcu/uspace/tester/tester.h
0,0 → 1,76
/*
* Copyright (c) 2007 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup tester
* @{
*/
/** @file
*/
 
#ifndef TESTER_H_
#define TESTER_H_
 
#include <types.h>
#include <bool.h>
#include <ipc/ipc.h>
 
#define IPC_TEST_START 10000
#define MAX_PHONES 20
#define MAX_CONNECTIONS 50
 
extern int myservice;
extern int phones[MAX_PHONES];
extern int connections[MAX_CONNECTIONS];
extern ipc_callid_t callids[MAX_CONNECTIONS];
 
typedef char * (* test_entry_t)(bool);
 
typedef struct {
char * name;
char * desc;
test_entry_t entry;
bool safe;
} test_t;
 
extern char * test_thread1(bool quiet);
extern char * test_print1(bool quiet);
extern char * test_fault1(bool quiet);
extern char * test_fault2(bool quiet);
extern char * test_register(bool quiet);
extern char * test_connect(bool quiet);
extern char * test_send_async(bool quiet);
extern char * test_send_sync(bool quiet);
extern char * test_answer(bool quiet);
extern char * test_hangup(bool quiet);
 
extern test_t tests[];
 
#endif
 
/** @}
*/
/branches/rcu/uspace/tester/Makefile
0,0 → 1,83
#
# Copyright (c) 2005 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
## Setup toolchain
#
 
LIBC_PREFIX = ../libc
SOFTINT_PREFIX = ../softint
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I../kbd/include
 
LIBS = $(LIBC_PREFIX)/libc.a
 
## Sources
#
 
OUTPUT = tester
SOURCES = tester.c \
thread/thread1.c \
print/print1.c \
fault/fault1.c \
fault/fault2.c \
ipc/register.c \
ipc/connect.c \
ipc/send_async.c \
ipc/send_sync.c \
ipc/answer.c \
ipc/hangup.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
.PHONY: all clean depend disasm
 
all: $(OUTPUT) disasm
 
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm:
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/rcu/uspace/libc/include/async.h
116,12 → 116,13
void async_msg_3(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
ipcarg_t arg3);
void async_msg_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2);
#define async_msg(ph,m,a1) async_msg_2(ph,m,a1,0)
#define async_msg(ph, m, a1) async_msg_2(ph, m, a1, 0)
 
static inline void async_serialize_start(void)
{
psthread_inc_sercount();
}
 
static inline void async_serialize_end(void)
{
psthread_dec_sercount();
/branches/rcu/uspace/libc/include/unistd.h
44,8 → 44,9
extern ssize_t write(int fd, const void * buf, size_t count);
extern ssize_t read(int fd, void * buf, size_t count);
extern void _exit(int status);
void *sbrk(ssize_t incr);
void usleep(unsigned long usec);
extern void *sbrk(ssize_t incr);
extern void usleep(unsigned long usec);
extern unsigned int sleep(unsigned int seconds);
 
#endif
 
/branches/rcu/uspace/libc/include/thread.h
39,11 → 39,16
#include <libarch/thread.h>
#include <types.h>
 
typedef uint64_t thread_id_t;
 
extern void __thread_entry(void);
extern void __thread_main(uspace_arg_t *uarg);
 
extern int thread_create(void (* function)(void *arg), void *arg, char *name);
extern int thread_create(void (* function)(void *), void *arg, char *name, thread_id_t *tid);
extern void thread_exit(int status);
extern void thread_detach(thread_id_t thread);
extern int thread_join(thread_id_t thread);
extern thread_id_t thread_get_id(void);
extern tcb_t * __make_tls(void);
extern tcb_t * __alloc_tls(void **data, size_t size);
extern void __free_tls(tcb_t *);
/branches/rcu/uspace/libc/generic/time.c
108,14 → 108,31
return 0;
}
 
/** Wait unconditionally for specified microseconds */
/** Wait unconditionally for specified number of microseconds */
void usleep(unsigned long usec)
{
atomic_t futex = FUTEX_INITIALIZER;
 
futex_initialize(&futex,0);
futex_initialize(&futex, 0);
futex_down_timeout(&futex, usec, 0);
}
 
/** Wait unconditionally for specified number of seconds */
unsigned int sleep(unsigned int seconds)
{
atomic_t futex = FUTEX_INITIALIZER;
 
futex_initialize(&futex, 0);
/* Sleep in 1000 second steps to support
full argument range */
while (seconds > 0) {
unsigned int period = (seconds > 1000) ? 1000 : seconds;
futex_down_timeout(&futex, period * 1000000, 0);
seconds -= period;
}
}
 
/** @}
*/
/branches/rcu/uspace/libc/generic/thread.c
124,10 → 124,11
* @param function Function implementing the thread.
* @param arg Argument to be passed to thread.
* @param name Symbolic name of the thread.
* @param tid Thread ID of the newly created thread.
*
* @return TID of the new thread on success or -1 on failure.
* @return Zero on success or a code from @ref errno.h on failure.
*/
int thread_create(void (* function)(void *), void *arg, char *name)
int thread_create(void (* function)(void *), void *arg, char *name, thread_id_t *tid)
{
char *stack;
uspace_arg_t *uarg;
148,7 → 149,7
uarg->uspace_thread_arg = arg;
uarg->uspace_uarg = uarg;
return __SYSCALL2(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name);
return __SYSCALL3(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name, (sysarg_t) tid);
}
 
/** Terminate current thread.
160,5 → 161,40
__SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status);
}
 
/** Detach thread.
*
* Currently not implemented.
*
* @param thread TID.
*/
void thread_detach(thread_id_t thread)
{
}
 
/** Join thread.
*
* Currently not implemented.
*
* @param thread TID.
*
* @return Thread exit status.
*/
int thread_join(thread_id_t thread)
{
}
 
/** Get current thread ID.
*
* @return Current thread ID.
*/
thread_id_t thread_get_id(void)
{
thread_id_t thread_id;
 
(void) __SYSCALL1(SYS_THREAD_GET_ID, (sysarg_t) &thread_id);
 
return thread_id;
}
 
/** @}
*/
/branches/rcu/uspace/libc/generic/io/printf.c
56,5 → 56,3
 
/** @}
*/
/branches/rcu/uspace/libc/generic/io/io.c
37,18 → 37,17
#include <stdio.h>
#include <io/io.h>
 
static char nl = '\n';
const static char nl = '\n';
 
int puts(const char * str)
int puts(const char *str)
{
size_t count;
if (str == NULL) {
return putnchars("(NULL)",6 );
}
if (str == NULL)
return putnchars("(NULL)", 6);
for (count = 0; str[count] != 0; count++);
if (write(1, (void * ) str, count) == count) {
if (write(1, (void *) str, count) == count) {
if (write(1, &nl, 1) == 1)
return 0;
}
61,11 → 60,10
* @param count
* @return 0 on succes, EOF on fail
*/
int putnchars(const char * buf, size_t count)
int putnchars(const char *buf, size_t count)
{
if (write(1, (void * ) buf, count) == count) {
if (write(1, (void *) buf, count) == count)
return 0;
}
return EOF;
}
73,18 → 71,16
/** Same as puts, but does not print newline at end
*
*/
int putstr(const char * str)
int putstr(const char *str)
{
size_t count;
if (str == NULL) {
return putnchars("(NULL)",6 );
}
if (str == NULL)
return putnchars("(NULL)", 6);
 
for (count = 0; str[count] != 0; count++);
if (write(1, (void * ) str, count) == count) {
if (write(1, (void *) str, count) == count)
return 0;
}
return EOF;
}
92,9 → 88,8
int putchar(int c)
{
unsigned char ch = c;
if (write(1, (void *)&ch , 1) == 1) {
if (write(1, (void *) &ch, 1) == 1)
return c;
}
return EOF;
}
102,9 → 97,8
int getchar(void)
{
unsigned char c;
if (read(0, (void *)&c , 1) == 1) {
if (read(0, (void *) &c, 1) == 1)
return c;
}
return EOF;
}
/branches/rcu/uspace/libc/generic/io/vprintf.c
36,10 → 36,12
#include <stdio.h>
#include <unistd.h>
#include <io/printf_core.h>
#include <futex.h>
#include <async.h>
 
int vprintf_write(const char *str, size_t count, void *unused);
static atomic_t printf_futex = FUTEX_INITIALIZER;
 
int vprintf_write(const char *str, size_t count, void *unused)
static int vprintf_write(const char *str, size_t count, void *unused)
{
return write(1, str, count);
}
51,9 → 53,23
*/
int vprintf(const char *fmt, va_list ap)
{
struct printf_spec ps = {(int(*)(void *, size_t, void *))vprintf_write, NULL};
return printf_core(fmt, &ps, ap);
 
struct printf_spec ps = {
(int (*)(void *, size_t, void *)) vprintf_write,
NULL
};
/*
* Prevent other threads to execute printf_core()
*/
futex_down(&printf_futex);
/*
* Prevent other pseudo threads of the same thread
* to execute printf_core()
*/
async_serialize_start();
int ret = printf_core(fmt, &ps, ap);
async_serialize_end();
futex_up(&printf_futex);
return ret;
}
 
/** @}
/branches/rcu/uspace/libc/generic/io/vsnprintf.c
43,8 → 43,6
char *string; /* destination string */
};
 
int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data);
 
/** Write string to given buffer.
* Write at most data->size characters including trailing zero. According to C99 has snprintf to return number
* of characters that would have been written if enough space had been available. Hence the return value is not
55,7 → 53,7
* @param data structure with destination string, counter of used space and total string size.
* @return number of characters to print (not characters really printed!)
*/
int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data)
static int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data)
{
size_t i;
i = data->size - data->len;
97,7 → 95,7
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
{
struct vsnprintf_data data = {size, 0, str};
struct printf_spec ps = {(int(*)(void *, size_t, void *))vsnprintf_write, &data};
struct printf_spec ps = {(int(*)(void *, size_t, void *)) vsnprintf_write, &data};
 
/* Print 0 at end of string - fix the case that nothing will be printed */
if (size > 0)
/branches/rcu/uspace/libc/generic/io/printf_core.c
40,8 → 40,6
#include <io/printf_core.h>
#include <ctype.h>
#include <string.h>
/* For serialization */
#include <async.h>
 
#define __PRINTF_FLAG_PREFIX 0x00000001 /**< show prefixes 0x or 0*/
#define __PRINTF_FLAG_SIGNED 0x00000002 /**< signed / unsigned number */
92,15 → 90,13
{
size_t count;
if (str == NULL) {
if (str == NULL)
return printf_putnchars("(NULL)", 6, ps);
}
 
for (count = 0; str[count] != 0; count++);
 
if (ps->write((void *) str, count, ps->data) == count) {
if (ps->write((void *) str, count, ps->data) == count)
return 0;
}
return EOF;
}
447,9 → 443,6
int width, precision;
uint64_t flags;
/* Don't let other threads interfere */
async_serialize_start();
 
counter = 0;
while ((c = fmt[i])) {
681,10 → 674,8
counter += retval;
}
async_serialize_end();
return counter;
minus_out:
async_serialize_end();
return -counter;
}
 
/branches/rcu/uspace/libc/generic/io/vsprintf.c
44,7 → 44,7
*/
int vsprintf(char *str, const char *fmt, va_list ap)
{
return vsnprintf(str, (size_t)-1, fmt, ap);
return vsnprintf(str, (size_t) - 1, fmt, ap);
}
 
/** @}
/branches/rcu/uspace/libc/arch/sparc64/include/atomic.h
51,9 → 51,11
uint64_t a, b;
 
do {
a = val->count;
volatile uintptr_t x = (uint64_t) &val->count;
 
a = *((uint64_t *) x);
b = a + i;
asm volatile ("casx %0, %2, %1\n" : "+m" (*val), "+r" (b) : "r" (a));
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *)x)), "+r" (b) : "r" (a));
} while (a != b);
 
return a;
/branches/rcu/uspace/libc/arch/sparc64/src/thread_entry.s
34,7 → 34,7
#
#
__thread_entry:
sethi %hi(_gp), %l7
sethi %hi(_gp), %l7
call __thread_main ! %o0 contains address of uarg
or %l7, %lo(_gp), %l7
/branches/rcu/uspace/Makefile
41,7 → 41,7
kbd \
console \
tetris \
ipcc \
tester \
klog \
rd \
fs
/branches/rcu/boot/tools/ia32/gen_vga323.c
0,0 → 1,14
#include <stdio.h>
 
#define RED(i) ((i >> 5) & ((1 << 3) - 1))
#define GREEN(i) ((i >> 3) & ((1 << 2) - 1))
#define BLUE(i) (i & ((1 << 3) - 1))
 
int main(int argc, char *argv[]) {
unsigned int i;
for (i = 0; i < 256; i++)
printf("\t.byte 0x%02x, 0x%02x, 0x%02x, 0x00\n", BLUE(i) * 9, GREEN(i) * 21, RED(i) * 9);
return 0;
}
/branches/rcu/boot/genarch/ofw.h
117,7 → 117,8
extern unsigned int ofw_get_size_cells(const phandle device);
extern void *ofw_translate(const void *virt);
extern int ofw_translate_failed(ofw_arg_t flag);
extern void *ofw_claim(const void *virt, const int len);
extern void *ofw_claim_virt(const void *virt, const int len);
extern void *ofw_claim_phys(const void *virt, const int len);
extern int ofw_map(const void *phys, const void *virt, const int size, const int mode);
extern int ofw_memmap(memmap_t *map);
extern int ofw_screen(screen_t *screen);
/branches/rcu/boot/genarch/balloc.h
31,6 → 31,8
 
#include <types.h>
 
#define BALLOC_MAX_SIZE (1024 * 1024)
 
typedef struct {
uintptr_t base;
size_t size;
/branches/rcu/boot/genarch/ofw.c
38,6 → 38,7
ihandle ofw_stdout;
phandle ofw_root;
ihandle ofw_mmu;
ihandle ofw_memory_prop;
phandle ofw_memory;
phandle ofw_aliases;
 
47,7 → 48,7
if (ofw_chosen == -1)
halt();
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0)
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0)
ofw_stdout = 0;
ofw_root = ofw_find_device("/");
56,10 → 57,14
halt();
}
if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, sizeof(ofw_mmu)) <= 0) {
if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, sizeof(ofw_mmu)) <= 0) {
puts("\r\nError: Unable to get mmu property, halted.\r\n");
halt();
}
if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop, sizeof(ofw_memory_prop)) <= 0) {
puts("\r\nError: Unable to get memory property, halted.\r\n");
halt();
}
 
ofw_memory = ofw_find_device("/memory");
if (ofw_memory == -1) {
200,13 → 205,12
else
shift = 0;
 
return (void *) ((result[2]<<shift)|result[3]);
return (void *) ((result[2] << shift) | result[3]);
}
 
void *ofw_claim(const void *virt, const int len)
void *ofw_claim_virt(const void *virt, const int len)
{
ofw_arg_t retaddr;
int shift;
 
if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len, virt) != 0) {
puts("Error: MMU method claim() failed, halting.\n");
216,6 → 220,42
return (void *) retaddr;
}
 
void *ofw_claim_phys(const void *phys, const int len)
{
ofw_arg_t retaddr[2];
int shift;
 
if (sizeof(unative_t) == 8) {
shift = 32;
if (ofw_call("call-method", 6, 3, retaddr, "claim",
ofw_memory_prop, 0, len, ((uintptr_t) phys) >> shift,
((uintptr_t) phys) & ((uint32_t) -1)) != 0) {
/*
* Note that this will help us to discover
* conflicts between OpenFirmware allocations
* and our use of physical memory.
* It is better to detect collisions here
* than to cope with weird errors later.
*
* So this is really not to make the loader
* more generic; it is here for debugging
* purposes.
*/
puts("Error: memory method claim() failed, halting.\n");
halt();
}
} else {
shift = 0;
/*
* FIXME: the number of arguments is probably different...
*/
puts("Error: 32-bit ofw_claim_phys not implemented.\n");
halt();
}
 
return (void *) ((retaddr[0] << shift) | retaddr[1]);
}
 
int ofw_map(const void *phys, const void *virt, const int size, const int mode)
{
uintptr_t phys_hi, phys_lo;
230,7 → 270,7
}
 
return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size, virt,
phys_hi, phys_lo);
phys_hi, phys_lo);
}
 
/** Save OpenFirmware physical memory map.
252,8 → 292,8
int pos;
map->total = 0;
map->count = 0;
for (pos = 0; (pos < ret / sizeof(uint32_t)) && (map->count <
MEMMAP_MAX_RECORDS); pos += ac + sc) {
for (pos = 0; (pos < ret / sizeof(uint32_t)) &&
(map->count < MEMMAP_MAX_RECORDS); pos += ac + sc) {
void * start = (void *) ((uintptr_t) buf[pos + ac - 1]);
unsigned int size = buf[pos + ac + sc - 1];
/branches/rcu/boot/genarch/balloc.c
47,7 → 47,10
alignment = ALIGN_UP(alignment, 4);
addr = ballocs->base + ALIGN_UP(ballocs->size, alignment);
 
if (ALIGN_UP(ballocs->size, alignment) + size > BALLOC_MAX_SIZE)
return NULL;
ballocs->size = ALIGN_UP(ballocs->size, alignment) + size;
return (void *) addr;
/branches/rcu/boot/arch/sparc64/loader/main.c
92,7 → 92,7
unsigned int i;
for (i = 0; i < COMPONENTS; i++)
printf(" %P: %s image (size %d bytes)\n", components[i].start,
components[i].name, components[i].size);
components[i].name, components[i].size);
 
void * base = (void *) KERNEL_VIRTUAL_ADDRESS;
unsigned int top = 0;
102,10 → 102,24
for (i = 0; i < COMPONENTS; i++) {
printf(" %s...", components[i].name);
top = ALIGN_UP(top, PAGE_SIZE);
 
/*
* At this point, we claim the physical memory that we are
* going to use. We should be safe in case of the virtual
* address space because the OpenFirmware, according to its
* SPARC binding, should restrict its use of virtual memory
* to addresses from [0xffd00000; 0xffefffff] and
* [0xfe000000; 0xfeffffff].
*/
(void) ofw_claim_phys(bootinfo.physmem_start + base + top,
ALIGN_UP(components[i].size, PAGE_SIZE));
memcpy(base + top, components[i].start, components[i].size);
if (i > 0) {
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = base + top;
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size;
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr =
base + top;
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size =
components[i].size;
bootinfo.taskmap.count++;
}
top += components[i].size;
112,7 → 126,14
printf("done.\n");
}
 
balloc_init(&bootinfo.ballocs, ALIGN_UP(((uintptr_t) base) + top, PAGE_SIZE));
/*
* Claim the physical memory for the boot allocator.
* Initialize the boot allocator.
*/
(void) ofw_claim_phys(bootinfo.physmem_start +
base + ALIGN_UP(top, PAGE_SIZE), BALLOC_MAX_SIZE);
balloc_init(&bootinfo.ballocs, ALIGN_UP(((uintptr_t) base) + top,
PAGE_SIZE));
 
printf("\nCanonizing OpenFirmware device tree...");
bootinfo.ofw_root = ofw_tree_build();
127,5 → 148,7
 
printf("\nBooting the kernel...\n");
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS,
bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo, sizeof(bootinfo));
bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo,
sizeof(bootinfo));
}
 
/branches/rcu/boot/arch/sparc64/loader/Makefile
78,7 → 78,7
$(USPACEDIR)/kbd/kbd \
$(USPACEDIR)/console/console \
$(USPACEDIR)/tetris/tetris \
$(USPACEDIR)/ipcc/ipcc \
$(USPACEDIR)/tester/tester \
$(USPACEDIR)/klog/klog
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
/branches/rcu/boot/arch/sparc64/silo/silo.tar.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/rcu/boot/arch/ppc32/loader/Makefile
75,7 → 75,7
$(USPACEDIR)/kbd/kbd \
$(USPACEDIR)/console/console \
$(USPACEDIR)/tetris/tetris \
$(USPACEDIR)/ipcc/ipcc \
$(USPACEDIR)/tester/tester \
$(USPACEDIR)/klog/klog
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
/branches/rcu/boot/arch/ia32xen/grub/menu.lst
12,5 → 12,5
module /boot/kbd
module /boot/console
module /boot/tetris
module /boot/ipcc
module /boot/tester
module /boot/klog
/branches/rcu/boot/arch/ia32xen/grub/menu.debug.lst
12,5 → 12,5
module /boot/kbd
module /boot/console
module /boot/tetris
module /boot/ipcc
module /boot/tester
module /boot/klog
/branches/rcu/boot/arch/ia32xen/Makefile.inc
34,7 → 34,7
$(USPACEDIR)/kbd/kbd \
$(USPACEDIR)/console/console \
$(USPACEDIR)/tetris/tetris \
$(USPACEDIR)/ipcc/ipcc \
$(USPACEDIR)/tester/tester \
$(USPACEDIR)/klog/klog
 
build: $(BASE)/image.iso
/branches/rcu/boot/arch/amd64/grub/menu.lst
11,5 → 11,5
module /boot/kbd
module /boot/console
module /boot/tetris
module /boot/ipcc
module /boot/tester
module /boot/klog
/branches/rcu/boot/arch/amd64/Makefile.inc
34,7 → 34,7
$(USPACEDIR)/kbd/kbd \
$(USPACEDIR)/console/console \
$(USPACEDIR)/tetris/tetris \
$(USPACEDIR)/ipcc/ipcc \
$(USPACEDIR)/tester/tester \
$(USPACEDIR)/klog/klog
 
build: $(BASE)/image.iso
/branches/rcu/boot/arch/ppc64/loader/Makefile
75,7 → 75,7
$(USPACEDIR)/kbd/kbd \
$(USPACEDIR)/console/console \
$(USPACEDIR)/tetris/tetris \
$(USPACEDIR)/ipcc/ipcc \
$(USPACEDIR)/tester/tester \
$(USPACEDIR)/klog/klog
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
/branches/rcu/boot/arch/mips32/loader/Makefile
74,7 → 74,7
$(USPACEDIR)/kbd/kbd \
$(USPACEDIR)/console/console \
$(USPACEDIR)/tetris/tetris \
$(USPACEDIR)/ipcc/ipcc \
$(USPACEDIR)/tester/tester \
$(USPACEDIR)/klog/klog
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
/branches/rcu/boot/arch/ia32/grub/menu.lst
11,5 → 11,5
module /boot/kbd
module /boot/console
module /boot/tetris
module /boot/ipcc
module /boot/tester
module /boot/klog
/branches/rcu/boot/arch/ia32/Makefile.inc
34,7 → 34,7
$(USPACEDIR)/kbd/kbd \
$(USPACEDIR)/console/console \
$(USPACEDIR)/tetris/tetris \
$(USPACEDIR)/ipcc/ipcc \
$(USPACEDIR)/tester/tester \
$(USPACEDIR)/klog/klog
 
build: $(BASE)/image.iso