Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2306 → Rev 2307

/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;