Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2924 → Rev 2925

/branches/tracing/kernel/kernel.config
1,3 → 1,31
#
# 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.
#
 
## General configuration directives
 
# Architecture
/branches/tracing/kernel/generic/include/byteorder.h
35,26 → 35,60
#ifndef KERN_BYTEORDER_H_
#define KERN_BYTEORDER_H_
 
#include <arch/byteorder.h>
 
#if !(defined(ARCH_IS_BIG_ENDIAN) ^ defined(ARCH_IS_LITTLE_ENDIAN))
#error The architecture must be either big-endian or little-endian.
#endif
 
#ifdef ARCH_IS_BIG_ENDIAN
 
#define uint16_t_le2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
 
#define uint16_t_be2host(n) (n)
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#else
 
#define uint16_t_le2host(n) (n)
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#define uint16_t_be2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
 
#endif
 
static inline uint64_t uint64_t_byteorder_swap(uint64_t n)
{
return ((n & 0xff) << 56) |
((n & 0xff00) << 40) |
((n & 0xff0000) << 24) |
((n & 0xff000000LL) << 8) |
((n & 0xff00000000LL) >> 8) |
((n & 0xff0000000000LL) >> 24) |
((n & 0xff000000000000LL) >> 40) |
((n & 0xff00000000000000LL) >> 56);
((n & 0xff00) << 40) |
((n & 0xff0000) << 24) |
((n & 0xff000000LL) << 8) |
((n & 0xff00000000LL) >> 8) |
((n & 0xff0000000000LL) >> 24) |
((n & 0xff000000000000LL) >> 40) |
((n & 0xff00000000000000LL) >> 56);
}
 
static inline uint32_t uint32_t_byteorder_swap(uint32_t n)
{
return ((n & 0xff) << 24) |
((n & 0xff00) << 8) |
((n & 0xff0000) >> 8) |
((n & 0xff000000) >> 24);
((n & 0xff00) << 8) |
((n & 0xff0000) >> 8) |
((n & 0xff000000) >> 24);
}
 
static inline uint16_t uint16_t_byteorder_swap(uint16_t n)
{
return ((n & 0xff) << 8) |
((n & 0xff00) >> 8);
}
 
#endif
 
/** @}
/branches/tracing/kernel/generic/src/synch/waitq.c
54,13 → 54,13
#include <context.h>
#include <adt/list.h>
 
static void waitq_timeouted_sleep(void *data);
static void waitq_sleep_timed_out(void *data);
 
/** Initialize wait queue
*
* Initialize wait queue.
*
* @param wq Pointer to wait queue to be initialized.
* @param wq Pointer to wait queue to be initialized.
*/
void waitq_initialize(waitq_t *wq)
{
71,7 → 71,7
 
/** Handle timeout during waitq_sleep_timeout() call
*
* This routine is called when waitq_sleep_timeout() timeouts.
* This routine is called when waitq_sleep_timeout() times out.
* Interrupts are disabled.
*
* It is supposed to try to remove 'its' thread from the wait queue;
79,9 → 79,9
* overlap. In that case it behaves just as though there was no
* timeout at all.
*
* @param data Pointer to the thread that called waitq_sleep_timeout().
* @param data Pointer to the thread that called waitq_sleep_timeout().
*/
void waitq_timeouted_sleep(void *data)
void waitq_sleep_timed_out(void *data)
{
thread_t *t = (thread_t *) data;
waitq_t *wq;
123,7 → 123,7
* This routine attempts to interrupt a thread from its sleep in a waitqueue.
* If the thread is not found sleeping, no action is taken.
*
* @param t Thread to be interrupted.
* @param t Thread to be interrupted.
*/
void waitq_interrupt_sleep(thread_t *t)
{
183,9 → 183,9
* This function is really basic in that other functions as waitq_sleep()
* and all the *_timeout() functions use it.
*
* @param wq Pointer to wait queue.
* @param usec Timeout in microseconds.
* @param flags Specify mode of the sleep.
* @param wq Pointer to wait queue.
* @param usec Timeout in microseconds.
* @param flags Specify mode of the sleep.
*
* The sleep can be interrupted only if the
* SYNCH_FLAGS_INTERRUPTIBLE bit is specified in flags.
200,22 → 200,23
* If usec is zero and the SYNCH_FLAGS_NON_BLOCKING bit is set in flags, the
* call will immediately return, reporting either success or failure.
*
* @return One of: ESYNCH_WOULD_BLOCK, ESYNCH_TIMEOUT, ESYNCH_INTERRUPTED,
* ESYNCH_OK_ATOMIC, ESYNCH_OK_BLOCKED.
* @return Returns one of ESYNCH_WOULD_BLOCK, ESYNCH_TIMEOUT,
* ESYNCH_INTERRUPTED, ESYNCH_OK_ATOMIC and
* ESYNCH_OK_BLOCKED.
*
* @li ESYNCH_WOULD_BLOCK means that the sleep failed because at the time of the
* call there was no pending wakeup.
* @li ESYNCH_WOULD_BLOCK means that the sleep failed because at the time of
* the call there was no pending wakeup.
*
* @li ESYNCH_TIMEOUT means that the sleep timed out.
* @li ESYNCH_TIMEOUT means that the sleep timed out.
*
* @li ESYNCH_INTERRUPTED means that somebody interrupted the sleeping thread.
* @li ESYNCH_INTERRUPTED means that somebody interrupted the sleeping thread.
*
* @li ESYNCH_OK_ATOMIC means that the sleep succeeded and that there was
* a pending wakeup at the time of the call. The caller was not put
* asleep at all.
* @li ESYNCH_OK_ATOMIC means that the sleep succeeded and that there was
* a pending wakeup at the time of the call. The caller was not put
* asleep at all.
*
* @li ESYNCH_OK_BLOCKED means that the sleep succeeded; the full sleep was
* attempted.
* @li ESYNCH_OK_BLOCKED means that the sleep succeeded; the full sleep was
* attempted.
*/
int waitq_sleep_timeout(waitq_t *wq, uint32_t usec, int flags)
{
233,9 → 234,9
* This function will return holding the lock of the wait queue
* and interrupts disabled.
*
* @param wq Wait queue.
* @param wq Wait queue.
*
* @return Interrupt level as it existed on entry to this function.
* @return Interrupt level as it existed on entry to this function.
*/
ipl_t waitq_sleep_prepare(waitq_t *wq)
{
271,9 → 272,9
* to the call to waitq_sleep_prepare(). If necessary, the wait queue
* lock is released.
*
* @param wq Wait queue.
* @param rc Return code of waitq_sleep_timeout_unsafe().
* @param ipl Interrupt level returned by waitq_sleep_prepare().
* @param wq Wait queue.
* @param rc Return code of waitq_sleep_timeout_unsafe().
* @param ipl Interrupt level returned by waitq_sleep_prepare().
*/
void waitq_sleep_finish(waitq_t *wq, int rc, ipl_t ipl)
{
291,14 → 292,14
/** Internal implementation of waitq_sleep_timeout().
*
* This function implements logic of sleeping in a wait queue.
* This call must be preceeded by a call to waitq_sleep_prepare()
* and followed by a call to waitq_slee_finish().
* This call must be preceded by a call to waitq_sleep_prepare()
* and followed by a call to waitq_sleep_finish().
*
* @param wq See waitq_sleep_timeout().
* @param usec See waitq_sleep_timeout().
* @param flags See waitq_sleep_timeout().
* @param wq See waitq_sleep_timeout().
* @param usec See waitq_sleep_timeout().
* @param flags See waitq_sleep_timeout().
*
* @return See waitq_sleep_timeout().
* @return See waitq_sleep_timeout().
*/
int waitq_sleep_timeout_unsafe(waitq_t *wq, uint32_t usec, int flags)
{
355,7 → 356,7
}
THREAD->timeout_pending = true;
timeout_register(&THREAD->sleep_timeout, (uint64_t) usec,
waitq_timeouted_sleep, THREAD);
waitq_sleep_timed_out, THREAD);
}
 
list_append(&THREAD->wq_link, &wq->head);
383,8 → 384,8
* Besides its 'normal' wakeup operation, it attempts to unregister possible
* timeout.
*
* @param wq Pointer to wait queue.
* @param mode Wakeup mode.
* @param wq Pointer to wait queue.
* @param mode Wakeup mode.
*/
void waitq_wakeup(waitq_t *wq, wakeup_mode_t mode)
{
404,12 → 405,12
* This is the internal SMP- and IRQ-unsafe version of waitq_wakeup(). It
* assumes wq->lock is already locked and interrupts are already disabled.
*
* @param wq Pointer to wait queue.
* @param mode If mode is WAKEUP_FIRST, then the longest waiting thread,
* if any, is woken up. If mode is WAKEUP_ALL, then all
* waiting threads, if any, are woken up. If there are no
* waiting threads to be woken up, the missed wakeup is
* recorded in the wait queue.
* @param wq Pointer to wait queue.
* @param mode If mode is WAKEUP_FIRST, then the longest waiting
* thread, if any, is woken up. If mode is WAKEUP_ALL, then
* all waiting threads, if any, are woken up. If there are
* no waiting threads to be woken up, the missed wakeup is
* recorded in the wait queue.
*/
void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode)
{
431,7 → 432,7
* Lock the thread prior to removing it from the wq.
* This is not necessary because of mutual exclusion
* (the link belongs to the wait queue), but because
* of synchronization with waitq_timeouted_sleep()
* of synchronization with waitq_sleep_timed_out()
* and thread_interrupt_sleep().
*
* In order for these two functions to work, the following
/branches/tracing/kernel/generic/src/debug/symtab.c
36,7 → 36,7
*/
 
#include <symtab.h>
#include <arch/byteorder.h>
#include <byteorder.h>
#include <func.h>
#include <print.h>
 
53,12 → 53,12
{
count_t i;
 
for (i=1;symbol_table[i].address_le;++i) {
for (i = 1; symbol_table[i].address_le; ++i) {
if (addr < uint64_t_le2host(symbol_table[i].address_le))
break;
}
if (addr >= uint64_t_le2host(symbol_table[i-1].address_le))
return symbol_table[i-1].symbol_name;
if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le))
return symbol_table[i - 1].symbol_name;
return NULL;
}
 
72,19 → 72,19
{
unsigned int namelen = strlen(name);
char *curname;
int i,j;
int i, j;
int colonoffset = -1;
 
for (i=0;name[i];i++)
for (i = 0; name[i]; i++)
if (name[i] == ':') {
colonoffset = i;
break;
}
 
for (i=*startpos;symbol_table[i].address_le;++i) {
for (i = *startpos; symbol_table[i].address_le; ++i) {
/* Find a ':' in name */
curname = symbol_table[i].symbol_name;
for (j=0; curname[j] && curname[j] != ':'; j++)
for (j = 0; curname[j] && curname[j] != ':'; j++)
;
if (!curname[j])
continue;
94,7 → 94,7
continue;
if (strncmp(curname, name, namelen) == 0) {
*startpos = i;
return curname+namelen;
return curname + namelen;
}
}
return NULL;
115,7 → 115,7
int i;
 
i = 0;
while ((hint=symtab_search_one(name, &i))) {
while ((hint = symtab_search_one(name, &i))) {
if (!strlen(hint)) {
addr = uint64_t_le2host(symbol_table[i].address_le);
found++;
151,7 → 151,7
*/
int symtab_compl(char *input)
{
char output[MAX_SYMBOL_NAME+1];
char output[MAX_SYMBOL_NAME + 1];
int startpos = 0;
char *foundtxt;
int found = 0;
172,9 → 172,10
while ((foundtxt = symtab_search_one(name, &startpos))) {
startpos++;
if (!found)
strncpy(output, foundtxt, strlen(foundtxt)+1);
strncpy(output, foundtxt, strlen(foundtxt) + 1);
else {
for (i=0; output[i] && foundtxt[i] && output[i]==foundtxt[i]; i++)
for (i = 0; output[i] && foundtxt[i] &&
output[i] == foundtxt[i]; i++)
;
output[i] = '\0';
}
/branches/tracing/kernel/generic/src/time/timeout.c
32,7 → 32,7
 
/**
* @file
* @brief Timeout management functions.
* @brief Timeout management functions.
*/
 
#include <time/timeout.h>
61,7 → 61,7
*
* Initialize all members except the lock.
*
* @param t Timeout to be initialized.
* @param t Timeout to be initialized.
*
*/
void timeout_reinitialize(timeout_t *t)
78,7 → 78,7
*
* Initialize all members including the lock.
*
* @param t Timeout to be initialized.
* @param t Timeout to be initialized.
*
*/
void timeout_initialize(timeout_t *t)
94,14 → 94,14
* to timeout list and make it execute in
* time microseconds (or slightly more).
*
* @param t Timeout structure.
* @param time Number of usec in the future to execute
* the handler.
* @param f Timeout handler function.
* @param arg Timeout handler argument.
* @param t Timeout structure.
* @param time Number of usec in the future to execute the handler.
* @param f Timeout handler function.
* @param arg Timeout handler argument.
*
*/
void timeout_register(timeout_t *t, uint64_t time, timeout_handler_t f, void *arg)
void
timeout_register(timeout_t *t, uint64_t time, timeout_handler_t f, void *arg)
{
timeout_t *hlp = NULL;
link_t *l, *m;
165,9 → 165,9
*
* Remove timeout from timeout list.
*
* @param t Timeout to unregister.
* @param t Timeout to unregister.
*
* @return true on success, false on failure.
* @return True on success, false on failure.
*/
bool timeout_unregister(timeout_t *t)
{
/branches/tracing/kernel/generic/src/proc/thread.c
87,7 → 87,7
*/
SPINLOCK_INITIALIZE(threads_lock);
 
/** ALV tree of all threads.
/** AVL tree of all threads.
*
* When a thread is found in the threads_tree AVL tree, it is guaranteed to
* exist as long as the threads_lock is held.
267,15 → 267,17
*
* Create a new thread.
*
* @param func Thread's implementing function.
* @param arg Thread's implementing function argument.
* @param task Task to which the thread belongs.
* @param flags Thread flags.
* @param name Symbolic name.
* @param uncounted Thread's accounting doesn't affect accumulated task
* accounting.
* @param func Thread's implementing function.
* @param arg Thread's implementing function argument.
* @param task Task to which the thread belongs. The caller must
* guarantee that the task won't cease to exist during the
* call. The task's lock may not be held.
* @param flags Thread flags.
* @param name Symbolic name.
* @param uncounted Thread's accounting doesn't affect accumulated task
* accounting.
*
* @return New thread's structure on success, NULL on failure.
* @return New thread's structure on success, NULL on failure.
*
*/
thread_t *thread_create(void (* func)(void *), void *arg, task_t *task,
/branches/tracing/kernel/generic/src/lib/rd.c
38,7 → 38,7
*/
 
#include <lib/rd.h>
#include <arch/byteorder.h>
#include <byteorder.h>
#include <mm/frame.h>
#include <sysinfo/sysinfo.h>
#include <ddi/ddi.h>
/branches/tracing/kernel/arch/sparc64/include/context_offset.h
48,4 → 48,60
#define OFFSET_L6 0x80
#define OFFSET_L7 0x88
 
#ifndef KERNEL
# define OFFSET_TP 0x90
#endif
 
#ifdef __ASM__
 
.macro CONTEXT_SAVE_ARCH_CORE ctx:req
stx %sp, [\ctx + OFFSET_SP]
stx %o7, [\ctx + OFFSET_PC]
stx %i0, [\ctx + OFFSET_I0]
stx %i1, [\ctx + OFFSET_I1]
stx %i2, [\ctx + OFFSET_I2]
stx %i3, [\ctx + OFFSET_I3]
stx %i4, [\ctx + OFFSET_I4]
stx %i5, [\ctx + OFFSET_I5]
stx %fp, [\ctx + OFFSET_FP]
stx %i7, [\ctx + OFFSET_I7]
stx %l0, [\ctx + OFFSET_L0]
stx %l1, [\ctx + OFFSET_L1]
stx %l2, [\ctx + OFFSET_L2]
stx %l3, [\ctx + OFFSET_L3]
stx %l4, [\ctx + OFFSET_L4]
stx %l5, [\ctx + OFFSET_L5]
stx %l6, [\ctx + OFFSET_L6]
stx %l7, [\ctx + OFFSET_L7]
#ifndef KERNEL
stx %g7, [\ctx + OFFSET_TP]
#endif
.endm
 
.macro CONTEXT_RESTORE_ARCH_CORE ctx:req
ldx [\ctx + OFFSET_SP], %sp
ldx [\ctx + OFFSET_PC], %o7
ldx [\ctx + OFFSET_I0], %i0
ldx [\ctx + OFFSET_I1], %i1
ldx [\ctx + OFFSET_I2], %i2
ldx [\ctx + OFFSET_I3], %i3
ldx [\ctx + OFFSET_I4], %i4
ldx [\ctx + OFFSET_I5], %i5
ldx [\ctx + OFFSET_FP], %fp
ldx [\ctx + OFFSET_I7], %i7
ldx [\ctx + OFFSET_L0], %l0
ldx [\ctx + OFFSET_L1], %l1
ldx [\ctx + OFFSET_L2], %l2
ldx [\ctx + OFFSET_L3], %l3
ldx [\ctx + OFFSET_L4], %l4
ldx [\ctx + OFFSET_L5], %l5
ldx [\ctx + OFFSET_L6], %l6
ldx [\ctx + OFFSET_L7], %l7
#ifndef KERNEL
ldx [\ctx + OFFSET_TP], %g7
#endif
.endm
 
#endif /* __ASM__ */
 
#endif
/branches/tracing/kernel/arch/sparc64/include/byteorder.h
35,14 → 35,8
#ifndef KERN_sparc64_BYTEORDER_H_
#define KERN_sparc64_BYTEORDER_H_
 
#include <byteorder.h>
#define ARCH_IS_BIG_ENDIAN
 
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
 
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#endif
 
/** @}
/branches/tracing/kernel/arch/sparc64/src/context.S
36,55 → 36,15
* functions.
*/
#include <arch/context_offset.h>
 
.text
 
.global context_save_arch
.global context_restore_arch
 
.macro CONTEXT_STORE r
stx %sp, [\r + OFFSET_SP]
stx %o7, [\r + OFFSET_PC]
stx %i0, [\r + OFFSET_I0]
stx %i1, [\r + OFFSET_I1]
stx %i2, [\r + OFFSET_I2]
stx %i3, [\r + OFFSET_I3]
stx %i4, [\r + OFFSET_I4]
stx %i5, [\r + OFFSET_I5]
stx %fp, [\r + OFFSET_FP]
stx %i7, [\r + OFFSET_I7]
stx %l0, [\r + OFFSET_L0]
stx %l1, [\r + OFFSET_L1]
stx %l2, [\r + OFFSET_L2]
stx %l3, [\r + OFFSET_L3]
stx %l4, [\r + OFFSET_L4]
stx %l5, [\r + OFFSET_L5]
stx %l6, [\r + OFFSET_L6]
stx %l7, [\r + OFFSET_L7]
.endm
 
.macro CONTEXT_LOAD r
ldx [\r + OFFSET_SP], %sp
ldx [\r + OFFSET_PC], %o7
ldx [\r + OFFSET_I0], %i0
ldx [\r + OFFSET_I1], %i1
ldx [\r + OFFSET_I2], %i2
ldx [\r + OFFSET_I3], %i3
ldx [\r + OFFSET_I4], %i4
ldx [\r + OFFSET_I5], %i5
ldx [\r + OFFSET_FP], %fp
ldx [\r + OFFSET_I7], %i7
ldx [\r + OFFSET_L0], %l0
ldx [\r + OFFSET_L1], %l1
ldx [\r + OFFSET_L2], %l2
ldx [\r + OFFSET_L3], %l3
ldx [\r + OFFSET_L4], %l4
ldx [\r + OFFSET_L5], %l5
ldx [\r + OFFSET_L6], %l6
ldx [\r + OFFSET_L7], %l7
.endm
 
context_save_arch:
CONTEXT_STORE %o0
CONTEXT_SAVE_ARCH_CORE %o0
retl
mov 1, %o0 ! context_save_arch returns 1
 
98,6 → 58,6
#
flushw
CONTEXT_LOAD %o0
CONTEXT_RESTORE_ARCH_CORE %o0
retl
xor %o0, %o0, %o0 ! context_restore_arch returns 0
/branches/tracing/kernel/arch/ia64/include/byteorder.h
35,15 → 35,9
#ifndef KERN_ia64_BYTEORDER_H_
#define KERN_ia64_BYTEORDER_H_
 
#include <byteorder.h>
 
/* IA-64 is little-endian */
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
#define ARCH_IS_LITTLE_ENDIAN
 
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
 
#endif
 
/** @}
/branches/tracing/kernel/arch/arm32/include/byteorder.h
36,24 → 36,10
#ifndef KERN_arm32_BYTEORDER_H_
#define KERN_arm32_BYTEORDER_H_
 
#include <byteorder.h>
 
#ifdef BIG_ENDIAN
 
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
 
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#define ARCH_IS_BIG_ENDIAN
#else
 
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
 
#define ARCH_IS_LITTLE_ENDIAN
#endif
 
#endif
/branches/tracing/kernel/arch/ppc32/include/context_offset.h
76,7 → 76,6
#ifdef __ASM__
# include <arch/asm/regname.h>
 
 
# ctx: address of the structure with saved context
.macro CONTEXT_SAVE_ARCH_CORE ctx:req
stw sp, OFFSET_SP(\ctx)
/branches/tracing/kernel/arch/ppc32/include/byteorder.h
35,14 → 35,8
#ifndef KERN_ppc32_BYTEORDER_H_
#define KERN_ppc32_BYTEORDER_H_
 
#include <byteorder.h>
#define ARCH_IS_BIG_ENDIAN
 
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
 
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#endif
 
/** @}
/branches/tracing/kernel/arch/amd64/include/byteorder.h
35,15 → 35,9
#ifndef KERN_amd64_BYTEORDER_H_
#define KERN_amd64_BYTEORDER_H_
 
#include <byteorder.h>
 
/* AMD64 is little-endian */
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
#define ARCH_IS_LITTLE_ENDIAN
 
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
 
#endif
 
/** @}
/branches/tracing/kernel/arch/ppc64/include/context_offset.h
73,4 → 73,60
#define OFFSET_FR31 0x88
#define OFFSET_FPSCR 0x90
 
 
#ifdef __ASM__
# include <arch/asm/regname.h>
 
# ctx: address of the structure with saved context
.macro CONTEXT_SAVE_ARCH_CORE ctx:req
stw sp, OFFSET_SP(\ctx)
stw r2, OFFSET_R2(\ctx)
stw r13, OFFSET_R13(\ctx)
stw r14, OFFSET_R14(\ctx)
stw r15, OFFSET_R15(\ctx)
stw r16, OFFSET_R16(\ctx)
stw r17, OFFSET_R17(\ctx)
stw r18, OFFSET_R18(\ctx)
stw r19, OFFSET_R19(\ctx)
stw r20, OFFSET_R20(\ctx)
stw r21, OFFSET_R21(\ctx)
stw r22, OFFSET_R22(\ctx)
stw r23, OFFSET_R23(\ctx)
stw r24, OFFSET_R24(\ctx)
stw r25, OFFSET_R25(\ctx)
stw r26, OFFSET_R26(\ctx)
stw r27, OFFSET_R27(\ctx)
stw r28, OFFSET_R28(\ctx)
stw r29, OFFSET_R29(\ctx)
stw r30, OFFSET_R30(\ctx)
stw r31, OFFSET_R31(\ctx)
.endm
 
# ctx: address of the structure with saved context
.macro CONTEXT_RESTORE_ARCH_CORE ctx:req
lwz sp, OFFSET_SP(\ctx)
lwz r2, OFFSET_R2(\ctx)
lwz r13, OFFSET_R13(\ctx)
lwz r14, OFFSET_R14(\ctx)
lwz r15, OFFSET_R15(\ctx)
lwz r16, OFFSET_R16(\ctx)
lwz r17, OFFSET_R17(\ctx)
lwz r18, OFFSET_R18(\ctx)
lwz r19, OFFSET_R19(\ctx)
lwz r20, OFFSET_R20(\ctx)
lwz r21, OFFSET_R21(\ctx)
lwz r22, OFFSET_R22(\ctx)
lwz r23, OFFSET_R23(\ctx)
lwz r24, OFFSET_R24(\ctx)
lwz r25, OFFSET_R25(\ctx)
lwz r26, OFFSET_R26(\ctx)
lwz r27, OFFSET_R27(\ctx)
lwz r28, OFFSET_R28(\ctx)
lwz r29, OFFSET_R29(\ctx)
lwz r30, OFFSET_R30(\ctx)
lwz r31, OFFSET_R31(\ctx)
.endm
 
#endif /* __ASM__ */
 
#endif
/branches/tracing/kernel/arch/ppc64/include/byteorder.h
35,14 → 35,8
#ifndef KERN_ppc64_BYTEORDER_H_
#define KERN_ppc64_BYTEORDER_H_
 
#include <byteorder.h>
#define ARCH_IS_BIG_ENDIAN
 
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
 
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#endif
 
/** @}
/branches/tracing/kernel/arch/ppc64/src/context.S
34,56 → 34,8
.global context_save_arch
.global context_restore_arch
 
.macro CONTEXT_STORE r
stw sp, OFFSET_SP(\r)
stw r2, OFFSET_R2(\r)
stw r13, OFFSET_R13(\r)
stw r14, OFFSET_R14(\r)
stw r15, OFFSET_R15(\r)
stw r16, OFFSET_R16(\r)
stw r17, OFFSET_R17(\r)
stw r18, OFFSET_R18(\r)
stw r19, OFFSET_R19(\r)
stw r20, OFFSET_R20(\r)
stw r21, OFFSET_R21(\r)
stw r22, OFFSET_R22(\r)
stw r23, OFFSET_R23(\r)
stw r24, OFFSET_R24(\r)
stw r25, OFFSET_R25(\r)
stw r26, OFFSET_R26(\r)
stw r27, OFFSET_R27(\r)
stw r28, OFFSET_R28(\r)
stw r29, OFFSET_R29(\r)
stw r30, OFFSET_R30(\r)
stw r31, OFFSET_R31(\r)
.endm
 
.macro CONTEXT_LOAD r
lwz sp, OFFSET_SP(\r)
lwz r2, OFFSET_R2(\r)
lwz r13, OFFSET_R13(\r)
lwz r14, OFFSET_R14(\r)
lwz r15, OFFSET_R15(\r)
lwz r16, OFFSET_R16(\r)
lwz r17, OFFSET_R17(\r)
lwz r18, OFFSET_R18(\r)
lwz r19, OFFSET_R19(\r)
lwz r20, OFFSET_R20(\r)
lwz r21, OFFSET_R21(\r)
lwz r22, OFFSET_R22(\r)
lwz r23, OFFSET_R23(\r)
lwz r24, OFFSET_R24(\r)
lwz r25, OFFSET_R25(\r)
lwz r26, OFFSET_R26(\r)
lwz r27, OFFSET_R27(\r)
lwz r28, OFFSET_R28(\r)
lwz r29, OFFSET_R29(\r)
lwz r30, OFFSET_R30(\r)
lwz r31, OFFSET_R31(\r)
.endm
 
context_save_arch:
CONTEXT_STORE r3
CONTEXT_SAVE_ARCH_CORE r3
mflr r4
stw r4, OFFSET_PC(r3)
96,7 → 48,7
blr
context_restore_arch:
CONTEXT_LOAD r3
CONTEXT_RESTORE_ARCH_CORE r3
lwz r4, OFFSET_CR(r3)
mtcr r4
/branches/tracing/kernel/arch/mips32/include/byteorder.h
35,24 → 35,10
#ifndef KERN_mips32_BYTEORDER_H_
#define KERN_mips32_BYTEORDER_H_
 
#include <byteorder.h>
 
#ifdef BIG_ENDIAN
 
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
 
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#define ARCH_IS_BIG_ENDIAN
#else
 
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
 
#define ARCH_IS_LITTLE_ENDIAN
#endif
 
#endif
/branches/tracing/kernel/arch/mips32/src/drivers/arc.c
36,7 → 36,7
#include <arch/mm/page.h>
#include <print.h>
#include <arch.h>
#include <arch/byteorder.h>
#include <byteorder.h>
#include <arch/mm/frame.h>
#include <mm/frame.h>
#include <interrupt.h>
/branches/tracing/kernel/arch/ia32/include/byteorder.h
35,15 → 35,9
#ifndef KERN_ia32_BYTEORDER_H_
#define KERN_ia32_BYTEORDER_H_
 
#include <byteorder.h>
 
/* IA-32 is little-endian */
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
#define ARCH_IS_LITTLE_ENDIAN
 
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
 
#endif
 
/** @}
/branches/tracing/tools/build
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/branches/tracing/tools/config.py
1,4 → 1,31
#!/usr/bin/env python
#
# 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.
#
"""
HelenOS configuration script
"""
/branches/tracing/tools/cygwin_symlink_patch.sh
20,10 → 20,3
ln -s "$linkTarget" "$linkName"
fi
done
 
 
 
 
 
/branches/tracing/uspace/app/tester/tester.c
80,9 → 80,10
static void run_safe_tests(void)
{
test_t *test;
int i = 0, n = 0;
unsigned int i = 0;
unsigned int n = 0;
 
printf("\n*** Running all safe tests\n\n");
printf("\n*** Running all safe tests ***\n\n");
 
for (test = tests; test->name != NULL; test++) {
if (test->safe) {
93,7 → 94,7
}
}
 
printf("\nSafe tests completed, %d tests run, %d passed.\n\n", i + n, i);
printf("\nSafe tests completed, %u tests run, %u passed.\n\n", i + n, i);
}
 
static void list_tests(void)
/branches/tracing/uspace/app/tester/ipc/send_sync.c
38,10 → 38,10
static int msgid = 1;
char c;
 
printf("Select phoneid to send msg: 2-9 (Q to skip)\n");
printf("Select phoneid to send msg: 2-9 (q to skip)\n");
do {
c = getchar();
if (c == 'Q' || c == 'q')
if ((c == 'Q') || (c == 'q'))
return TEST_SKIPPED;
} while (c < '2' || c > '9');
phoneid = c - '0';
/branches/tracing/uspace/app/tester/ipc/send_async.c
41,10 → 41,10
static int msgid = 1;
char c;
 
printf("Select phoneid to send msg: 2-9 (Q to skip)\n");
printf("Select phoneid to send msg: 2-9 (q to skip)\n");
do {
c = getchar();
if (c == 'Q' || c == 'q')
if ((c == 'Q') || (c == 'q'))
return TEST_SKIPPED;
} while (c < '2' || c > '9');
phoneid = c - '0';
/branches/tracing/uspace/app/tester/ipc/connect.c
36,10 → 36,10
int svc;
int phid;
 
printf("Choose one service: 0:10000....9:10009 (Q to skip)\n");
printf("Choose one service: 0:10000....9:10009 (q to skip)\n");
do {
c = getchar();
if (c == 'Q' || c == 'q')
if ((c == 'Q') || (c == 'q'))
return TEST_SKIPPED;
} while (c < '0' || c > '9');
/branches/tracing/uspace/app/tester/vfs/vfs1.c
43,11 → 43,24
 
char *test_vfs1(bool quiet)
{
if (mount("tmpfs", "/", "nulldev0") != EOK)
return "mount() failed.\n";
if (!quiet)
printf("mounted tmpfs on /.\n");
int rc;
 
rc = mount("tmpfs", "/", "nulldev0");
switch (rc) {
case EOK:
if (!quiet)
printf("mounted tmpfs on /\n");
break;
case EBUSY:
if (!quiet)
printf("(INFO) something is already mounted on /\n");
break;
default:
if (!quiet)
printf("(INFO) IPC returned errno %d\n", rc);
return "mount() failed.";
}
 
if (mkdir("/mydir", 0) != 0)
return "mkdir() failed.\n";
if (!quiet)
/branches/tracing/uspace/uspace.config
1,3 → 1,31
#
# 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.
#
 
## General configuration directives
 
# Architecture
/branches/tracing/uspace/lib/libfs/libfs.c
142,42 → 142,38
dev_handle_t dev_handle = IPC_GET_ARG3(*request);
int lflag = IPC_GET_ARG4(*request);
fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */
char component[NAME_MAX + 1];
int len;
 
if (last < next)
last += PLB_SIZE;
 
void *par = NULL;
void *cur = ops->root_get();
void *tmp = ops->child_get(cur);
void *cur = ops->root_get(dev_handle);
void *tmp = NULL;
 
if (ops->plb_get_char(next) == '/')
next++; /* eat slash */
char component[NAME_MAX + 1];
int len = 0;
while (tmp && next <= last) {
 
while (ops->has_children(cur) && next <= last) {
/* collect the component */
if (ops->plb_get_char(next) != '/') {
len = 0;
while ((ops->plb_get_char(next) != '/') && (next <= last)) {
if (len + 1 == NAME_MAX) {
/* comopnent length overflow */
ipc_answer_0(rid, ENAMETOOLONG);
return;
goto out;
}
component[len++] = ops->plb_get_char(next);
next++; /* process next character */
if (next <= last)
continue;
}
 
assert(len);
component[len] = '\0';
next++; /* eat slash */
len = 0;
 
/* match the component */
while (tmp && !ops->match(cur, tmp, component))
tmp = ops->sibling_get(tmp);
tmp = ops->match(cur, component);
 
/* handle miss: match amongst siblings */
if (!tmp) {
184,7 → 180,7
if (next <= last) {
/* there are unprocessed components */
ipc_answer_0(rid, ENOENT);
return;
goto out;
}
/* miss in the last component */
if (lflag & (L_CREATE | L_LINK)) {
191,18 → 187,18
/* request to create a new link */
if (!ops->is_directory(cur)) {
ipc_answer_0(rid, ENOTDIR);
return;
goto out;
}
void *nodep;
if (lflag & L_CREATE)
nodep = ops->create(lflag);
else
nodep = ops->node_get(fs_handle,
dev_handle, index);
nodep = ops->node_get(dev_handle,
index);
if (nodep) {
if (!ops->link(cur, nodep, component)) {
if (lflag & L_CREATE)
ops->destroy(nodep);
(void)ops->destroy(nodep);
ipc_answer_0(rid, ENOSPC);
} else {
ipc_answer_5(rid, EOK,
210,11 → 206,12
ops->index_get(nodep),
ops->size_get(nodep),
ops->lnkcnt_get(nodep));
ops->node_put(nodep);
}
} else {
ipc_answer_0(rid, ENOSPC);
}
return;
goto out;
} else if (lflag & L_PARENT) {
/* return parent */
ipc_answer_5(rid, EOK, fs_handle, dev_handle,
222,34 → 219,38
ops->lnkcnt_get(cur));
}
ipc_answer_0(rid, ENOENT);
return;
goto out;
}
 
if (par)
ops->node_put(par);
 
/* descend one level */
par = cur;
cur = tmp;
tmp = ops->child_get(tmp);
tmp = NULL;
}
 
/* handle miss: excessive components */
if (!tmp && next <= last) {
if (!ops->has_children(cur) && next <= last) {
if (lflag & (L_CREATE | L_LINK)) {
if (!ops->is_directory(cur)) {
ipc_answer_0(rid, ENOTDIR);
return;
goto out;
}
 
/* collect next component */
len = 0;
while (next <= last) {
if (ops->plb_get_char(next) == '/') {
/* more than one component */
ipc_answer_0(rid, ENOENT);
return;
goto out;
}
if (len + 1 == NAME_MAX) {
/* component length overflow */
ipc_answer_0(rid, ENAMETOOLONG);
return;
goto out;
}
component[len++] = ops->plb_get_char(next);
next++; /* process next character */
256,18 → 257,16
}
assert(len);
component[len] = '\0';
len = 0;
void *nodep;
if (lflag & L_CREATE)
nodep = ops->create(lflag);
else
nodep = ops->node_get(fs_handle, dev_handle,
index);
nodep = ops->node_get(dev_handle, index);
if (nodep) {
if (!ops->link(cur, nodep, component)) {
if (lflag & L_CREATE)
ops->destroy(nodep);
(void)ops->destroy(nodep);
ipc_answer_0(rid, ENOSPC);
} else {
ipc_answer_5(rid, EOK,
275,22 → 274,25
ops->index_get(nodep),
ops->size_get(nodep),
ops->lnkcnt_get(nodep));
ops->node_put(nodep);
}
} else {
ipc_answer_0(rid, ENOSPC);
}
return;
goto out;
}
ipc_answer_0(rid, ENOENT);
return;
goto out;
}
 
/* handle hit */
if (lflag & L_PARENT) {
ops->node_put(cur);
cur = par;
par = NULL;
if (!cur) {
ipc_answer_0(rid, ENOENT);
return;
goto out;
}
}
if (lflag & L_UNLINK) {
298,24 → 300,32
int res = ops->unlink(par, cur);
ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle,
ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
return;
goto out;
}
if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
(lflag & L_LINK)) {
ipc_answer_0(rid, EEXIST);
return;
goto out;
}
if ((lflag & L_FILE) && (ops->is_directory(cur))) {
ipc_answer_0(rid, EISDIR);
return;
goto out;
}
if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) {
ipc_answer_0(rid, ENOTDIR);
return;
goto out;
}
 
ipc_answer_5(rid, EOK, fs_handle, dev_handle, ops->index_get(cur),
ops->size_get(cur), ops->lnkcnt_get(cur));
 
out:
if (par)
ops->node_put(par);
if (cur)
ops->node_put(cur);
if (tmp)
ops->node_put(tmp);
}
 
/** @}
/branches/tracing/uspace/lib/libfs/libfs.h
42,18 → 42,18
#include <async.h>
 
typedef struct {
bool (* match)(void *, void *, const char *);
void * (* node_get)(fs_handle_t, dev_handle_t, fs_index_t);
void * (* match)(void *, const char *);
void * (* node_get)(dev_handle_t, fs_index_t);
void (* node_put)(void *);
void * (* create)(int);
void (* destroy)(void *);
int (* destroy)(void *);
bool (* link)(void *, void *, const char *);
int (* unlink)(void *, void *);
fs_index_t (* index_get)(void *);
size_t (* size_get)(void *);
unsigned (* lnkcnt_get)(void *);
void *(* child_get)(void *);
void *(* sibling_get)(void *);
void *(* root_get)(void);
bool (* has_children)(void *);
void *(* root_get)(dev_handle_t);
char (* plb_get_char)(unsigned pos);
bool (* is_directory)(void *);
bool (* is_file)(void *);
67,13 → 67,6
 
extern int fs_register(int, fs_reg_t *, vfs_info_t *, async_client_conn_t);
 
extern int block_read(int, unsigned long, void *);
extern int block_write(int, unsigned long, void *);
 
extern void node_add_mp(int, unsigned long);
extern void node_del_mp(int, unsigned long);
extern bool node_is_mp(int, unsigned long);
 
extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
 
#endif
/branches/tracing/uspace/lib/softfloat/include/sftypes.h
35,7 → 35,7
#ifndef __SFTYPES_H__
#define __SFTYPES_H__
 
#include <endian.h>
#include <byteorder.h>
#include <stdint.h>
 
typedef union {
43,17 → 43,17
uint32_t binary;
 
struct {
#if __BYTE_ORDER == __BIG_ENDIAN
#if defined(ARCH_IS_BIG_ENDIAN)
uint32_t sign:1;
uint32_t exp:8;
uint32_t fraction:23;
#elif __BYTE_ORDER == __LITTLE_ENDIAN
#elif defined(ARCH_IS_LITTLE_ENDIAN)
uint32_t fraction:23;
uint32_t exp:8;
uint32_t sign:1;
#else
#error "Unknown endians."
#endif
#else
#error "Unknown endians."
#endif
} parts __attribute__ ((packed));
} float32;
62,17 → 62,17
uint64_t binary;
struct {
#if __BYTE_ORDER == __BIG_ENDIAN
#if defined(ARCH_IS_BIG_ENDIAN)
uint64_t sign:1;
uint64_t exp:11;
uint64_t fraction:52;
#elif __BYTE_ORDER == __LITTLE_ENDIAN
#elif defined(ARCH_IS_LITTLE_ENDIAN)
uint64_t fraction:52;
uint64_t exp:11;
uint64_t sign:1;
#else
#error "Unknown endians."
#endif
#else
#error "Unknown endians."
#endif
} parts __attribute__ ((packed));
} float64;
 
81,7 → 81,10
#define FLOAT64_MAX
#define FLOAT64_MIN
 
/* For recognizing NaNs or infinity use isFloat32NaN and is Float32Inf, comparing with this constants is not sufficient */
/*
* For recognizing NaNs or infinity use isFloat32NaN and is Float32Inf,
* comparing with these constants is not sufficient.
*/
#define FLOAT32_NAN 0x7FC00001
#define FLOAT32_SIGNAN 0x7F800001
#define FLOAT32_INF 0x7F800000
/branches/tracing/uspace/lib/libc/include/endian.h
File deleted
/branches/tracing/uspace/lib/libc/include/byteorder.h
0,0 → 1,96
/*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_BYTEORDER_H_
#define LIBC_BYTEORDER_H_
 
#include <libarch/byteorder.h>
#include <stdint.h>
 
#if !(defined(ARCH_IS_BIG_ENDIAN) ^ defined(ARCH_IS_LITTLE_ENDIAN))
#error The architecture must be either big-endian or little-endian.
#endif
 
#ifdef ARCH_IS_BIG_ENDIAN
 
#define uint16_t_le2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
 
#define uint16_t_be2host(n) (n)
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#else
 
#define uint16_t_le2host(n) (n)
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#define uint16_t_be2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
 
#endif
 
static inline uint64_t uint64_t_byteorder_swap(uint64_t n)
{
return ((n & 0xff) << 56) |
((n & 0xff00) << 40) |
((n & 0xff0000) << 24) |
((n & 0xff000000LL) << 8) |
((n & 0xff00000000LL) >> 8) |
((n & 0xff0000000000LL) >> 24) |
((n & 0xff000000000000LL) >> 40) |
((n & 0xff00000000000000LL) >> 56);
}
 
static inline uint32_t uint32_t_byteorder_swap(uint32_t n)
{
return ((n & 0xff) << 24) |
((n & 0xff00) << 8) |
((n & 0xff0000) >> 8) |
((n & 0xff000000) >> 24);
}
 
static inline uint16_t uint16_t_byteorder_swap(uint16_t n)
{
return ((n & 0xff) << 8) |
((n & 0xff00) >> 8);
}
 
#endif
 
/** @}
*/
/branches/tracing/uspace/lib/libc/include/libadt/list.h
112,6 → 112,18
head->prev = link;
}
 
/** Insert item before another item in doubly-linked circular list. */
static inline void list_insert_before(link_t *l, link_t *r)
{
list_append(l, r);
}
 
/** Insert item after another item in doubly-linked circular list. */
static inline void list_insert_after(link_t *r, link_t *l)
{
list_prepend(l, r);
}
 
/** Remove item from doubly-linked circular list
*
* Remove item from doubly-linked circular list.
/branches/tracing/uspace/lib/libc/generic/ipc.c
770,7 → 770,7
assert(flags);
 
*callid = async_get_call(&data);
if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE)
if (IPC_GET_METHOD(data) != IPC_M_SHARE_OUT)
return 0;
*size = (size_t) IPC_GET_ARG2(data);
*flags = (int) IPC_GET_ARG3(data);
/branches/tracing/uspace/lib/libc/arch/sparc64/include/context_offset.h
File deleted
/branches/tracing/uspace/lib/libc/arch/sparc64/include/endian.h
File deleted
/branches/tracing/uspace/lib/libc/arch/sparc64/include/byteorder.h
0,0 → 1,43
/*
* 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.
*/
 
/** @addtogroup libcsparc64
* @{
*/
/** @file
*/
 
#ifndef LIBC_sparc64_BYTEORDER_H_
#define LIBC_sparc64_BYTEORDER_H_
 
#define ARCH_IS_BIG_ENDIAN
 
#endif
 
/** @}
*/
/branches/tracing/uspace/lib/libc/arch/sparc64/src/fibril.S
26,7 → 26,7
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
#include <libarch/context_offset.h>
#include <kernel/arch/context_offset.h>
 
.text
 
33,52 → 33,8
.global context_save
.global context_restore
 
.macro CONTEXT_STORE r
stx %sp, [\r + OFFSET_SP]
stx %o7, [\r + OFFSET_PC]
stx %i0, [\r + OFFSET_I0]
stx %i1, [\r + OFFSET_I1]
stx %i2, [\r + OFFSET_I2]
stx %i3, [\r + OFFSET_I3]
stx %i4, [\r + OFFSET_I4]
stx %i5, [\r + OFFSET_I5]
stx %fp, [\r + OFFSET_FP]
stx %i7, [\r + OFFSET_I7]
stx %l0, [\r + OFFSET_L0]
stx %l1, [\r + OFFSET_L1]
stx %l2, [\r + OFFSET_L2]
stx %l3, [\r + OFFSET_L3]
stx %l4, [\r + OFFSET_L4]
stx %l5, [\r + OFFSET_L5]
stx %l6, [\r + OFFSET_L6]
stx %l7, [\r + OFFSET_L7]
stx %g7, [\r + OFFSET_TP]
.endm
 
.macro CONTEXT_LOAD r
ldx [\r + OFFSET_SP], %sp
ldx [\r + OFFSET_PC], %o7
ldx [\r + OFFSET_I0], %i0
ldx [\r + OFFSET_I1], %i1
ldx [\r + OFFSET_I2], %i2
ldx [\r + OFFSET_I3], %i3
ldx [\r + OFFSET_I4], %i4
ldx [\r + OFFSET_I5], %i5
ldx [\r + OFFSET_FP], %fp
ldx [\r + OFFSET_I7], %i7
ldx [\r + OFFSET_L0], %l0
ldx [\r + OFFSET_L1], %l1
ldx [\r + OFFSET_L2], %l2
ldx [\r + OFFSET_L3], %l3
ldx [\r + OFFSET_L4], %l4
ldx [\r + OFFSET_L5], %l5
ldx [\r + OFFSET_L6], %l6
ldx [\r + OFFSET_L7], %l7
ldx [\r + OFFSET_TP], %g7
.endm
 
context_save:
CONTEXT_STORE %o0
CONTEXT_SAVE_ARCH_CORE %o0
retl
mov 1, %o0 ! context_save_arch returns 1
 
92,6 → 48,6
#
flushw
CONTEXT_LOAD %o0
CONTEXT_RESTORE_ARCH_CORE %o0
retl
xor %o0, %o0, %o0 ! context_restore_arch returns 0
/branches/tracing/uspace/lib/libc/arch/ia64/include/endian.h
File deleted
/branches/tracing/uspace/lib/libc/arch/ia64/include/byteorder.h
0,0 → 1,44
/*
* 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.
*/
 
/** @addtogroup libcia64
* @{
*/
/** @file
*/
 
#ifndef LIBC_ia64_BYTEORDER_H_
#define LIBC_ia64_BYTEORDER_H_
 
/* IA-64 is little-endian */
#define ARCH_IS_LITTLE_ENDIAN
 
#endif
 
/** @}
*/
/branches/tracing/uspace/lib/libc/arch/arm32/include/endian.h
File deleted
/branches/tracing/uspace/lib/libc/arch/arm32/include/byteorder.h
0,0 → 1,44
/*
* 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.
*/
 
/** @addtogroup libcarm32
* @{
*/
/** @file
* @brief Endianness definitions.
*/
 
#ifndef LIBC_arm32_BYTEORDER_H_
#define LIBC_arm32_BYTEORDER_H_
 
#define ARCH_IS_BIG_ENDIAN
 
#endif
 
/** @}
*/
/branches/tracing/uspace/lib/libc/arch/mips32eb/include/endian.h
File deleted
/branches/tracing/uspace/lib/libc/arch/mips32eb/include/byteorder.h
0,0 → 1,43
/*
* 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.
*/
 
/** @addtogroup libcmips32
* @{
*/
/** @file
*/
 
#ifndef LIBC_mips32eb_BYTEORDER_H_
#define LIBC_mips32eb_BYTEORDER_H_
 
#define ARCH_IS_BIG_ENDIAN
 
#endif
 
/** @}
*/
/branches/tracing/uspace/lib/libc/arch/ppc32/include/endian.h
File deleted
/branches/tracing/uspace/lib/libc/arch/ppc32/include/byteorder.h
0,0 → 1,43
/*
* 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.
*/
 
/** @addtogroup libcppc32
* @{
*/
/** @file
*/
 
#ifndef LIBC_ppc32_BYTEORDER_H_
#define LIBC_ppc32_BYTEORDER_H_
 
#define ARCH_IS_BIG_ENDIAN
 
#endif
 
/** @}
*/
/branches/tracing/uspace/lib/libc/arch/amd64/include/endian.h
File deleted
/branches/tracing/uspace/lib/libc/arch/amd64/include/byteorder.h
0,0 → 1,44
/*
* 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.
*/
 
/** @addtogroup libcamd64
* @{
*/
/** @file
*/
 
#ifndef LIBC_amd64_BYTEORDER_H_
#define LIBC_amd64_BYTEORDER_H_
 
/* AMD64 is little-endian */
#define ARCH_IS_LITTLE_ENDIAN
 
#endif
 
/** @}
*/
/branches/tracing/uspace/lib/libc/arch/ppc64/include/context_offset.h
File deleted
/branches/tracing/uspace/lib/libc/arch/ppc64/include/endian.h
File deleted
/branches/tracing/uspace/lib/libc/arch/ppc64/include/byteorder.h
0,0 → 1,43
/*
* 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.
*/
 
/** @addtogroup libcppc64
* @{
*/
/** @file
*/
 
#ifndef LIBC_ppc64_BYTEORDER_H_
#define LIBC_ppc64_BYTEORDER_H_
 
#define ARCH_IS_BIG_ENDIAN
 
#endif
 
/** @}
*/
/branches/tracing/uspace/lib/libc/arch/ppc64/src/fibril.S
32,58 → 32,10
.global context_restore
 
#include <libarch/regname.h>
#include <libarch/context_offset.h>
#include <kernel/arch/context_offset.h>
 
.macro CONTEXT_STORE r
stw sp, OFFSET_SP(\r)
stw r2, OFFSET_R2(\r)
stw r13, OFFSET_R13(\r)
stw r14, OFFSET_R14(\r)
stw r15, OFFSET_R15(\r)
stw r16, OFFSET_R16(\r)
stw r17, OFFSET_R17(\r)
stw r18, OFFSET_R18(\r)
stw r19, OFFSET_R19(\r)
stw r20, OFFSET_R20(\r)
stw r21, OFFSET_R21(\r)
stw r22, OFFSET_R22(\r)
stw r23, OFFSET_R23(\r)
stw r24, OFFSET_R24(\r)
stw r25, OFFSET_R25(\r)
stw r26, OFFSET_R26(\r)
stw r27, OFFSET_R27(\r)
stw r28, OFFSET_R28(\r)
stw r29, OFFSET_R29(\r)
stw r30, OFFSET_R30(\r)
stw r31, OFFSET_R31(\r)
.endm
 
.macro CONTEXT_LOAD r
lwz sp, OFFSET_SP(\r)
lwz r2, OFFSET_R2(\r)
lwz r13, OFFSET_R13(\r)
lwz r14, OFFSET_R14(\r)
lwz r15, OFFSET_R15(\r)
lwz r16, OFFSET_R16(\r)
lwz r17, OFFSET_R17(\r)
lwz r18, OFFSET_R18(\r)
lwz r19, OFFSET_R19(\r)
lwz r20, OFFSET_R20(\r)
lwz r21, OFFSET_R21(\r)
lwz r22, OFFSET_R22(\r)
lwz r23, OFFSET_R23(\r)
lwz r24, OFFSET_R24(\r)
lwz r25, OFFSET_R25(\r)
lwz r26, OFFSET_R26(\r)
lwz r27, OFFSET_R27(\r)
lwz r28, OFFSET_R28(\r)
lwz r29, OFFSET_R29(\r)
lwz r30, OFFSET_R30(\r)
lwz r31, OFFSET_R31(\r)
.endm
 
context_save:
CONTEXT_STORE r3
CONTEXT_SAVE_ARCH_CORE r3
mflr r4
stw r4, OFFSET_PC(r3)
97,7 → 49,7
 
 
context_restore:
CONTEXT_LOAD r3
CONTEXT_RESTORE_ARCH_CORE r3
lwz r4, OFFSET_CR(r3)
mtcr r4
/branches/tracing/uspace/lib/libc/arch/mips32/include/endian.h
File deleted
/branches/tracing/uspace/lib/libc/arch/mips32/include/byteorder.h
0,0 → 1,43
/*
* 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.
*/
 
/** @addtogroup libcmips32
* @{
*/
/** @file
*/
 
#ifndef LIBC_mips32_BYTEORDER_H_
#define LIBC_mips32_BYTEORDER_H_
 
#define ARCH_IS_LITTLE_ENDIAN
 
#endif
 
/** @}
*/
/branches/tracing/uspace/lib/libc/arch/ia32/include/endian.h
File deleted
/branches/tracing/uspace/lib/libc/arch/ia32/include/byteorder.h
0,0 → 1,44
/*
* 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.
*/
 
/** @addtogroup libcia32
* @{
*/
/** @file
*/
 
#ifndef LIBC_ia32_BYTEORDER_H_
#define LIBC_ia32_BYTEORDER_H_
 
/* IA-32 is little-endian */
#define ARCH_IS_LITTLE_ENDIAN
 
#endif
 
/** @}
*/
/branches/tracing/uspace/srv/fs/tmpfs/tmpfs_ops.c
69,12 → 69,13
*/
 
/* Forward declarations of static functions. */
static bool tmpfs_match(void *, void *, const char *);
static void *tmpfs_node_get(fs_handle_t, dev_handle_t, fs_index_t);
static void *tmpfs_match(void *, const char *);
static void *tmpfs_node_get(dev_handle_t, fs_index_t);
static void tmpfs_node_put(void *);
static void *tmpfs_create_node(int);
static bool tmpfs_link_node(void *, void *, const char *);
static int tmpfs_unlink_node(void *, void *);
static void tmpfs_destroy_node(void *);
static int tmpfs_destroy_node(void *);
 
/* Implementation of helper functions. */
static fs_index_t tmpfs_index_get(void *nodep)
92,18 → 93,13
return ((tmpfs_dentry_t *) nodep)->lnkcnt;
}
 
static void *tmpfs_child_get(void *nodep)
static bool tmpfs_has_children(void *nodep)
{
return ((tmpfs_dentry_t *) nodep)->child;
return ((tmpfs_dentry_t *) nodep)->child != NULL;
}
 
static void *tmpfs_sibling_get(void *nodep)
static void *tmpfs_root_get(dev_handle_t dev_handle)
{
return ((tmpfs_dentry_t *) nodep)->sibling;
}
 
static void *tmpfs_root_get(void)
{
return root;
}
 
126,6 → 122,7
libfs_ops_t tmpfs_libfs_ops = {
.match = tmpfs_match,
.node_get = tmpfs_node_get,
.node_put = tmpfs_node_put,
.create = tmpfs_create_node,
.destroy = tmpfs_destroy_node,
.link = tmpfs_link_node,
133,8 → 130,7
.index_get = tmpfs_index_get,
.size_get = tmpfs_size_get,
.lnkcnt_get = tmpfs_lnkcnt_get,
.child_get = tmpfs_child_get,
.sibling_get = tmpfs_sibling_get,
.has_children = tmpfs_has_children,
.root_get = tmpfs_root_get,
.plb_get_char = tmpfs_plb_get_char,
.is_directory = tmpfs_is_directory,
243,27 → 239,36
 
/** Compare one component of path to a directory entry.
*
* @param prnt Node from which we descended.
* @param chld Node to compare the path component with.
* @param parentp Pointer to node from which we descended.
* @param childp Pointer to node to compare the path component with.
* @param component Array of characters holding component name.
*
* @return True on match, false otherwise.
*/
bool tmpfs_match(void *prnt, void *chld, const char *component)
static bool
tmpfs_match_one(tmpfs_dentry_t *parentp, tmpfs_dentry_t *childp,
const char *component)
{
tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
tmpfs_dentry_t *childp = (tmpfs_dentry_t *) chld;
 
unsigned long key = (unsigned long) parentp;
link_t *hlp = hash_table_find(&childp->names, &key);
assert(hlp);
tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t, link);
 
return !strcmp(namep->name, component);
}
 
void *tmpfs_match(void *prnt, const char *component)
{
tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
tmpfs_dentry_t *childp = parentp->child;
 
while (childp && !tmpfs_match_one(parentp, childp, component))
childp = childp->sibling;
 
return (void *) childp;
}
 
void *
tmpfs_node_get(fs_handle_t fs_handle, dev_handle_t dev_handle, fs_index_t index)
tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index)
{
unsigned long key = index;
link_t *lnk = hash_table_find(&dentries, &key);
272,6 → 277,11
return hash_table_get_instance(lnk, tmpfs_dentry_t, dh_link);
}
 
void tmpfs_node_put(void *node)
{
/* nothing to do */
}
 
void *tmpfs_create_node(int lflag)
{
assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
364,7 → 374,7
return EOK;
}
 
void tmpfs_destroy_node(void *nodep)
int tmpfs_destroy_node(void *nodep)
{
tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
380,6 → 390,7
if (dentry->type == TMPFS_FILE)
free(dentry->data);
free(dentry);
return EOK;
}
 
void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
568,6 → 579,7
{
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
int rc;
 
link_t *hlp;
unsigned long key = index;
578,8 → 590,8
}
tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
dh_link);
tmpfs_destroy_node(dentry);
ipc_answer_0(rid, EOK);
rc = tmpfs_destroy_node(dentry);
ipc_answer_0(rid, rc);
}
 
/**
/branches/tracing/uspace/srv/fs/fat/fat_idx.c
0,0 → 1,377
/*
* Copyright (c) 2008 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.
*/
 
/** @addtogroup fs
* @{
*/
 
/**
* @file fat_idx.c
* @brief Layer for translating FAT entities to VFS node indices.
*/
 
#include "fat.h"
#include "../../vfs/vfs.h"
#include <errno.h>
#include <string.h>
#include <libadt/hash_table.h>
#include <libadt/list.h>
#include <assert.h>
#include <futex.h>
 
/** Each instance of this type describes one interval of freed VFS indices. */
typedef struct {
link_t link;
fs_index_t first;
fs_index_t last;
} freed_t;
 
/**
* Each instance of this type describes state of all VFS indices that
* are currently unused.
*/
typedef struct {
link_t link;
dev_handle_t dev_handle;
 
/** Next unassigned index. */
fs_index_t next;
/** Number of remaining unassigned indices. */
uint64_t remaining;
 
/** Sorted list of intervals of freed indices. */
link_t freed_head;
} unused_t;
 
static LIST_INITIALIZE(unused_head);
 
/**
* Global hash table of all used fat_idx_t structures.
* The index structures are hashed by the dev_handle, parent node's first
* cluster and index within the parent directory.
*/
static hash_table_t up_hash;
 
#define UPH_BUCKETS_LOG 12
#define UPH_BUCKETS (1 << UPH_BUCKETS_LOG)
 
#define UPH_DH_KEY 0
#define UPH_PFC_KEY 1
#define UPH_PDI_KEY 2
 
static hash_index_t pos_hash(unsigned long key[])
{
dev_handle_t dev_handle = (dev_handle_t)key[UPH_DH_KEY];
fat_cluster_t pfc = (fat_cluster_t)key[UPH_PFC_KEY];
unsigned pdi = (unsigned)key[UPH_PDI_KEY];
 
hash_index_t h;
 
/*
* The least significant half of all bits are the least significant bits
* of the parent node's first cluster.
*
* The least significant half of the most significant half of all bits
* are the least significant bits of the node's dentry index within the
* parent directory node.
*
* The most significant half of the most significant half of all bits
* are the least significant bits of the device handle.
*/
h = pfc & ((1 << (UPH_BUCKETS_LOG / 2)) - 1);
h |= (pdi & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) <<
(UPH_BUCKETS_LOG / 2);
h |= (dev_handle & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) <<
(3 * (UPH_BUCKETS_LOG / 4));
 
return h;
}
 
static int pos_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
dev_handle_t dev_handle = (dev_handle_t)key[UPH_DH_KEY];
fat_cluster_t pfc = (fat_cluster_t)key[UPH_PFC_KEY];
unsigned pdi = (unsigned)key[UPH_PDI_KEY];
fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uph_link);
 
return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) &&
(pdi == fidx->pdi);
}
 
static void pos_remove_callback(link_t *item)
{
/* nothing to do */
}
 
static hash_table_operations_t uph_ops = {
.hash = pos_hash,
.compare = pos_compare,
.remove_callback = pos_remove_callback,
};
 
/**
* Global hash table of all used fat_idx_t structures.
* The index structures are hashed by the dev_handle and index.
*/
static hash_table_t ui_hash;
 
#define UIH_BUCKETS_LOG 12
#define UIH_BUCKETS (1 << UIH_BUCKETS_LOG)
 
#define UIH_DH_KEY 0
#define UIH_INDEX_KEY 1
 
static hash_index_t idx_hash(unsigned long key[])
{
dev_handle_t dev_handle = (dev_handle_t)key[UIH_DH_KEY];
fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY];
 
hash_index_t h;
 
h = dev_handle & ((1 << (UIH_BUCKETS_LOG / 2)) - 1);
h |= (index & ((1 << (UIH_BUCKETS_LOG / 2)) - 1)) <<
(UIH_BUCKETS_LOG / 2);
 
return h;
}
 
static int idx_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
dev_handle_t dev_handle = (dev_handle_t)key[UIH_DH_KEY];
fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY];
fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link);
 
return (dev_handle == fidx->dev_handle) && (index == fidx->index);
}
 
static void idx_remove_callback(link_t *item)
{
/* nothing to do */
}
 
static hash_table_operations_t uih_ops = {
.hash = idx_hash,
.compare = idx_compare,
.remove_callback = idx_remove_callback,
};
 
/** Allocate a VFS index which is not currently in use. */
static bool fat_idx_alloc(dev_handle_t dev_handle, fs_index_t *index)
{
link_t *l;
unused_t *u;
assert(index);
for (l = unused_head.next; l != &unused_head; l = l->next) {
u = list_get_instance(l, unused_t, link);
if (u->dev_handle == dev_handle)
goto hit;
}
 
/* dev_handle not found */
return false;
 
hit:
if (list_empty(&u->freed_head)) {
if (u->remaining) {
/*
* There are no freed indices, allocate one directly
* from the counter.
*/
*index = u->next++;
--u->remaining;
return true;
}
} else {
/* There are some freed indices which we can reuse. */
freed_t *f = list_get_instance(u->freed_head.next, freed_t,
link);
*index = f->first;
if (f->first++ == f->last) {
/* Destroy the interval. */
list_remove(&f->link);
free(f);
}
return true;
}
/*
* We ran out of indices, which is extremely unlikely with FAT16, but
* theoretically still possible (e.g. too many open unlinked nodes or
* too many zero-sized nodes).
*/
return false;
}
 
/** If possible, coalesce two intervals of freed indices. */
static void try_coalesce_intervals(link_t *l, link_t *r, link_t *cur)
{
freed_t *fl = list_get_instance(l, freed_t, link);
freed_t *fr = list_get_instance(r, freed_t, link);
 
if (fl->last + 1 == fr->first) {
if (cur == l) {
fl->last = fr->last;
list_remove(r);
free(r);
} else {
fr->first = fl->first;
list_remove(l);
free(l);
}
}
}
 
/** Free a VFS index, which is no longer in use. */
static void fat_idx_free(dev_handle_t dev_handle, fs_index_t index)
{
link_t *l;
unused_t *u;
 
for (l = unused_head.next; l != &unused_head; l = l->next) {
u = list_get_instance(l, unused_t, link);
if (u->dev_handle == dev_handle)
goto hit;
}
 
/* should not happen */
assert(0);
 
hit:
if (u->next == index + 1) {
/* The index can be returned directly to the counter. */
u->next--;
u->remaining++;
return;
} else {
/*
* The index must be returned either to an existing freed
* interval or a new interval must be created.
*/
link_t *lnk;
freed_t *n;
for (lnk = u->freed_head.next; lnk != &u->freed_head;
lnk = lnk->next) {
freed_t *f = list_get_instance(lnk, freed_t, link);
if (f->first == index + 1) {
f->first--;
if (lnk->prev != &u->freed_head)
try_coalesce_intervals(lnk->prev, lnk,
lnk);
return;
}
if (f->last == index - 1) {
f->last++;
if (lnk->next != &u->freed_head)
try_coalesce_intervals(lnk, lnk->next,
lnk);
return;
}
if (index > f->first) {
n = malloc(sizeof(freed_t));
/* TODO: sleep until allocation succeeds */
assert(n);
link_initialize(&n->link);
n->first = index;
n->last = index;
list_insert_before(&n->link, lnk);
return;
}
 
}
/* The index will form the last interval. */
n = malloc(sizeof(freed_t));
/* TODO: sleep until allocation succeeds */
assert(n);
link_initialize(&n->link);
n->first = index;
n->last = index;
list_append(&n->link, &u->freed_head);
}
}
 
fat_idx_t *
fat_idx_get_by_pos(dev_handle_t dev_handle, fat_cluster_t pfc, unsigned pdi)
{
fat_idx_t *fidx;
link_t *l;
unsigned long pkey[] = {
[UPH_DH_KEY] = dev_handle,
[UPH_PFC_KEY] = pfc,
[UPH_PDI_KEY] = pdi,
};
 
l = hash_table_find(&up_hash, pkey);
if (l) {
fidx = hash_table_get_instance(l, fat_idx_t, uph_link);
} else {
fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t));
if (!fidx) {
return NULL;
}
if (!fat_idx_alloc(dev_handle, &fidx->index)) {
free(fidx);
return NULL;
}
unsigned long ikey[] = {
[UIH_DH_KEY] = dev_handle,
[UIH_INDEX_KEY] = fidx->index,
};
link_initialize(&fidx->uph_link);
link_initialize(&fidx->uih_link);
fidx->dev_handle = dev_handle;
fidx->pfc = pfc;
fidx->pdi = pdi;
fidx->nodep = NULL;
 
hash_table_insert(&up_hash, pkey, &fidx->uph_link);
hash_table_insert(&ui_hash, ikey, &fidx->uih_link);
}
 
return fidx;
}
 
fat_idx_t *
fat_idx_get_by_index(dev_handle_t dev_handle, fs_index_t index)
{
fat_idx_t *fidx = NULL;
link_t *l;
unsigned long ikey[] = {
[UIH_DH_KEY] = dev_handle,
[UIH_INDEX_KEY] = index,
};
 
l = hash_table_find(&ui_hash, ikey);
if (l) {
fidx = hash_table_get_instance(l, fat_idx_t, uih_link);
}
 
return fidx;
}
 
/branches/tracing/uspace/srv/fs/fat/fat.h
1,5 → 1,5
/*
* Copyright (c) 2007 Jakub Jermar
* Copyright (c) 2008 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
38,6 → 38,7
#include <atomic.h>
#include <sys/types.h>
#include <bool.h>
#include "../../vfs/vfs.h"
 
#define dprintf(...) printf(__VA_ARGS__)
 
47,17 → 48,17
/* BIOS Parameter Block */
uint16_t bps; /**< Bytes per sector. */
uint8_t spc; /**< Sectors per cluster. */
uint16_t rsc; /**< Reserved sector count. */
uint16_t rscnt; /**< Reserved sector count. */
uint8_t fatcnt; /**< Number of FATs. */
uint16_t root_ent_max; /**< Maximum number of root directory
entries. */
uint16_t totsec; /**< Total sectors. */
uint16_t totsec16; /**< Total sectors. 16-bit version. */
uint8_t mdesc; /**< Media descriptor. */
uint16_t sec_per_fat; /**< Sectors per FAT12/FAT16. */
uint16_t sec_per_track; /**< Sectors per track. */
uint16_t headcnt; /**< Number of heads. */
uint32_t hidden_sec; /**< Hidden sectors. */
uint32_t total_sec; /**< Total sectors. */
uint32_t totsec32; /**< Total sectors. 32-bit version. */
 
union {
struct {
101,7 → 102,7
/** Serial number. */
uint32_t id;
/** Volume label. */
uint8_t label;
uint8_t label[11];
/** FAT type. */
uint8_t type[8];
/** Boot code. */
112,6 → 113,10
};
} __attribute__ ((packed)) fat_bs_t;
 
#define FAT_ATTR_RDONLY (1 << 0)
#define FAT_ATTR_VOLLABEL (1 << 3)
#define FAT_ATTR_SUBDIR (1 << 4)
 
typedef struct {
uint8_t name[8];
uint8_t ext[3];
134,10 → 139,87
uint32_t size;
} __attribute__ ((packed)) fat_dentry_t;
 
typedef uint16_t fat_cluster_t;
 
typedef enum {
FAT_INVALID,
FAT_DIRECTORY,
FAT_FILE
} fat_node_type_t;
 
struct fat_node;
 
/** FAT index structure.
*
* This structure exists to help us to overcome certain limitations of the FAT
* file system design. The problem with FAT is that it is hard to find
* an entity which could represent a VFS index. There are two candidates:
*
* a) number of the node's first cluster
* b) the pair of the parent directory's first cluster and the dentry index
* within the parent directory
*
* We need VFS indices to be:
* A) unique
* B) stable in time, at least until the next mount
*
* Unfortunately a) does not meet the A) criterion because zero-length files
* will have the first cluster field cleared. And b) does not meet the B)
* criterion because unlink() and rename() will both free up the original
* dentry, which contains all the essential info about the file.
*
* Therefore, a completely opaque indices are used and the FAT server maintains
* a mapping between them and otherwise nice b) variant. On rename(), the VFS
* index stays unaltered, while the internal FAT "physical tree address"
* changes. The unlink case is also handled this way thanks to an in-core node
* pointer embedded in the index structure.
*/
typedef struct {
/** Used indices (position) hash table link. */
link_t uph_link;
/** Used indices (index) hash table link. */
link_t uih_link;
 
dev_handle_t dev_handle;
fs_index_t index;
/**
* Parent node's first cluster.
* Zero is used if this node is not linked, in which case nodep must
* contain a pointer to the in-core node structure.
* One is used when the parent is the root directory.
*/
fat_cluster_t pfc;
/** Directory entry index within the parent node. */
unsigned pdi;
/** Pointer to in-core node instance. */
struct fat_node *nodep;
} fat_idx_t;
 
/** FAT in-core node. */
typedef struct fat_node {
fat_node_type_t type;
fat_idx_t *idx;
/**
* Node's first cluster.
* Zero is used for zero-length nodes.
* One is used to mark root directory.
*/
fat_cluster_t firstc;
/** FAT in-core node free list link. */
link_t ffn_link;
size_t size;
unsigned lnkcnt;
unsigned refcnt;
bool dirty;
} fat_node_t;
 
extern fs_reg_t fat_reg;
 
extern void fat_lookup(ipc_callid_t, ipc_call_t *);
 
extern fat_idx_t *fat_idx_get_by_pos(dev_handle_t, fat_cluster_t, unsigned);
extern fat_idx_t *fat_idx_get_by_index(dev_handle_t, fs_index_t);
 
#endif
 
/**
/branches/tracing/uspace/srv/fs/fat/fat_ops.c
1,5 → 1,5
/*
* Copyright (c) 2007 Jakub Jermar
* Copyright (c) 2008 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
37,12 → 37,22
 
#include "fat.h"
#include "../../vfs/vfs.h"
#include <libfs.h>
#include <ipc/ipc.h>
#include <async.h>
#include <errno.h>
#include <string.h>
#include <byteorder.h>
#include <libadt/hash_table.h>
#include <libadt/list.h>
#include <assert.h>
#include <futex.h>
 
#define PLB_GET_CHAR(i) (fat_reg.plb_ro[(i) % PLB_SIZE])
#define BS_BLOCK 0
 
/** List of free FAT nodes that still contain valid data. */
LIST_INITIALIZE(ffn_head);
 
#define FAT_NAME_LEN 8
#define FAT_EXT_LEN 3
 
53,90 → 63,454
#define FAT_DENTRY_DOT 0x2e
#define FAT_DENTRY_ERASED 0xe5
 
/** Compare one component of path to a directory entry.
*
* @param dentry Directory entry to compare the path component with.
* @param start Index into PLB where the path component starts.
* @param last Index of the last character of the path in PLB.
*
* @return Zero on failure or delta such that (index + delta) %
* PLB_SIZE points to a new path component in PLB.
*/
static unsigned match_path_component(fat_dentry_t *dentry, unsigned start,
unsigned last)
static void dentry_name_canonify(fat_dentry_t *d, char *buf)
{
unsigned cur; /* current position in PLB */
int pos; /* current position in dentry->name or dentry->ext */
bool name_processed = false;
bool dot_processed = false;
bool ext_processed = false;
int i;
 
if (last < start)
last += PLB_SIZE;
for (pos = 0, cur = start; (cur <= last) && (PLB_GET_CHAR(cur) != '/');
pos++, cur++) {
if (!name_processed) {
if ((pos == FAT_NAME_LEN - 1) ||
(dentry->name[pos + 1] == FAT_PAD)) {
/* this is the last character in name */
name_processed = true;
}
if (dentry->name[0] == FAT_PAD) {
/* name is empty */
name_processed = true;
} else if ((pos == 0) && (dentry->name[pos] ==
FAT_DENTRY_E5_ESC)) {
if (PLB_GET_CHAR(cur) == 0xe5)
continue;
else
return 0; /* character mismatch */
} else {
if (PLB_GET_CHAR(cur) == dentry->name[pos])
continue;
else
return 0; /* character mismatch */
}
for (i = 0; i < FAT_NAME_LEN; i++) {
if (d->name[i] == FAT_PAD) {
buf++;
break;
}
if (!dot_processed) {
dot_processed = true;
pos = -1;
if (PLB_GET_CHAR(cur) != '.')
return 0;
continue;
if (d->name[i] == FAT_DENTRY_E5_ESC)
*buf++ = 0xe5;
else
*buf++ = d->name[i];
}
if (d->ext[0] != FAT_PAD)
*buf++ = '.';
for (i = 0; i < FAT_EXT_LEN; i++) {
if (d->ext[i] == FAT_PAD) {
*buf = '\0';
return;
}
if (!ext_processed) {
if ((pos == FAT_EXT_LEN - 1) ||
(dentry->ext[pos + 1] == FAT_PAD)) {
/* this is the last character in ext */
ext_processed = true;
}
if (dentry->ext[0] == FAT_PAD) {
/* ext is empty; the match will fail */
ext_processed = true;
} else if (PLB_GET_CHAR(cur) == dentry->ext[pos]) {
if (d->ext[i] == FAT_DENTRY_E5_ESC)
*buf++ = 0xe5;
else
*buf++ = d->ext[i];
}
}
 
/* TODO move somewhere else */
typedef struct {
void *data;
} block_t;
 
static block_t *block_get(dev_handle_t dev_handle, off_t offset)
{
return NULL; /* TODO */
}
 
static void block_put(block_t *block)
{
/* TODO */
}
 
#define FAT_BS(b) ((fat_bs_t *)((b)->data))
 
#define FAT_CLST_RES0 0x0000
#define FAT_CLST_RES1 0x0001 /* internally used to mark root directory */
#define FAT_CLST_FIRST 0x0002
#define FAT_CLST_BAD 0xfff7
#define FAT_CLST_LAST1 0xfff8
#define FAT_CLST_LAST8 0xffff
 
#define fat_block_get(np, off) \
_fat_block_get((np)->idx->dev_handle, (np)->firstc, (off))
 
static block_t *
_fat_block_get(dev_handle_t dev_handle, fat_cluster_t firstc, off_t offset)
{
block_t *bb;
block_t *b;
unsigned bps;
unsigned spc;
unsigned rscnt; /* block address of the first FAT */
unsigned fatcnt;
unsigned rde;
unsigned rds; /* root directory size */
unsigned sf;
unsigned ssa; /* size of the system area */
unsigned clusters;
fat_cluster_t clst = firstc;
unsigned i;
 
bb = block_get(dev_handle, BS_BLOCK);
bps = uint16_t_le2host(FAT_BS(bb)->bps);
spc = FAT_BS(bb)->spc;
rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);
fatcnt = FAT_BS(bb)->fatcnt;
rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max);
sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat);
block_put(bb);
 
rds = (sizeof(fat_dentry_t) * rde) / bps;
rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
ssa = rscnt + fatcnt * sf + rds;
 
if (firstc == FAT_CLST_RES1) {
/* root directory special case */
assert(offset < rds);
b = block_get(dev_handle, rscnt + fatcnt * sf + offset);
return b;
}
 
clusters = offset / spc;
for (i = 0; i < clusters; i++) {
unsigned fsec; /* sector offset relative to FAT1 */
unsigned fidx; /* FAT1 entry index */
 
assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD);
fsec = (clst * sizeof(fat_cluster_t)) / bps;
fidx = clst % (bps / sizeof(fat_cluster_t));
/* read FAT1 */
b = block_get(dev_handle, rscnt + fsec);
clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
assert(clst != FAT_CLST_BAD);
assert(clst < FAT_CLST_LAST1);
block_put(b);
}
 
b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc +
offset % spc);
 
return b;
}
 
static void fat_node_initialize(fat_node_t *node)
{
node->idx = NULL;
node->type = 0;
link_initialize(&node->ffn_link);
node->size = 0;
node->lnkcnt = 0;
node->refcnt = 0;
node->dirty = false;
}
 
static uint16_t fat_bps_get(dev_handle_t dev_handle)
{
block_t *bb;
uint16_t bps;
bb = block_get(dev_handle, BS_BLOCK);
assert(bb != NULL);
bps = uint16_t_le2host(FAT_BS(bb)->bps);
block_put(bb);
 
return bps;
}
 
typedef enum {
FAT_DENTRY_SKIP,
FAT_DENTRY_LAST,
FAT_DENTRY_VALID
} fat_dentry_clsf_t;
 
static fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *d)
{
if (d->attr & FAT_ATTR_VOLLABEL) {
/* volume label entry */
return FAT_DENTRY_SKIP;
}
if (d->name[0] == FAT_DENTRY_ERASED) {
/* not-currently-used entry */
return FAT_DENTRY_SKIP;
}
if (d->name[0] == FAT_DENTRY_UNUSED) {
/* never used entry */
return FAT_DENTRY_LAST;
}
if (d->name[0] == FAT_DENTRY_DOT) {
/*
* Most likely '.' or '..'.
* It cannot occur in a regular file name.
*/
return FAT_DENTRY_SKIP;
}
return FAT_DENTRY_VALID;
}
 
static void fat_node_sync(fat_node_t *node)
{
/* TODO */
}
 
/** Instantiate a FAT in-core node. */
static void *fat_node_get(dev_handle_t dev_handle, fs_index_t index)
{
fat_idx_t *idx;
block_t *b;
fat_dentry_t *d;
fat_node_t *nodep;
unsigned bps;
unsigned dps;
 
idx = fat_idx_get_by_index(dev_handle, index);
if (!idx)
return NULL;
 
if (idx->nodep) {
/*
* We are lucky.
* The node is already instantiated in memory.
*/
if (!idx->nodep->refcnt++)
list_remove(&nodep->ffn_link);
return idx->nodep;
}
 
/*
* We must instantiate the node from the file system.
*/
assert(idx->pfc);
 
if (!list_empty(&ffn_head)) {
/* Try to use a cached unused node structure. */
nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link);
if (nodep->dirty)
fat_node_sync(nodep);
list_remove(&nodep->ffn_link);
nodep->idx->nodep = NULL;
} else {
/* Try to allocate a new node structure. */
nodep = (fat_node_t *)malloc(sizeof(fat_node_t));
if (!nodep)
return NULL;
}
fat_node_initialize(nodep);
 
bps = fat_bps_get(dev_handle);
dps = bps / sizeof(fat_dentry_t);
 
/* Read the block that contains the dentry of interest. */
b = _fat_block_get(dev_handle, idx->pfc,
(idx->pdi * sizeof(fat_dentry_t)) / bps);
assert(b);
 
d = ((fat_dentry_t *)b->data) + (idx->pdi % dps);
if (d->attr & FAT_ATTR_SUBDIR) {
/*
* The only directory which does not have this bit set is the
* root directory itself. The root directory node is handled
* and initialized elsewhere.
*/
nodep->type = FAT_DIRECTORY;
} else {
nodep->type = FAT_FILE;
}
nodep->firstc = uint16_t_le2host(d->firstc);
nodep->size = uint32_t_le2host(d->size);
nodep->lnkcnt = 1;
nodep->refcnt = 1;
 
block_put(b);
 
/* Link the idx structure with the node structure. */
nodep->idx = idx;
idx->nodep = nodep;
 
return nodep;
}
 
static void fat_node_put(void *node)
{
fat_node_t *nodep = (fat_node_t *)node;
 
if (!--nodep->refcnt) {
list_append(&nodep->ffn_link, &ffn_head);
}
}
 
static void *fat_create(int flags)
{
return NULL; /* not supported at the moment */
}
 
static int fat_destroy(void *node)
{
return ENOTSUP; /* not supported at the moment */
}
 
static bool fat_link(void *prnt, void *chld, const char *name)
{
return false; /* not supported at the moment */
}
 
static int fat_unlink(void *prnt, void *chld)
{
return ENOTSUP; /* not supported at the moment */
}
 
static void *fat_match(void *prnt, const char *component)
{
fat_node_t *parentp = (fat_node_t *)prnt;
char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
unsigned i, j;
unsigned bps; /* bytes per sector */
unsigned dps; /* dentries per sector */
unsigned blocks;
fat_dentry_t *d;
block_t *b;
 
bps = fat_bps_get(parentp->idx->dev_handle);
dps = bps / sizeof(fat_dentry_t);
blocks = parentp->size / bps + (parentp->size % bps != 0);
for (i = 0; i < blocks; i++) {
unsigned dentries;
b = fat_block_get(parentp, i);
dentries = (i == blocks - 1) ?
parentp->size % sizeof(fat_dentry_t) :
dps;
for (j = 0; j < dentries; j++) {
d = ((fat_dentry_t *)b->data) + j;
switch (fat_classify_dentry(d)) {
case FAT_DENTRY_SKIP:
continue;
} else {
/* character mismatch */
return 0;
case FAT_DENTRY_LAST:
block_put(b);
return NULL;
default:
case FAT_DENTRY_VALID:
dentry_name_canonify(d, name);
break;
}
if (strcmp(name, component) == 0) {
/* hit */
fat_idx_t *idx = fat_idx_get_by_pos(
parentp->idx->dev_handle, parentp->firstc,
i * dps + j);
if (!idx) {
/*
* Can happen if memory is low or if we
* run out of 32-bit indices.
*/
block_put(b);
return NULL;
}
void *node = fat_node_get(idx->dev_handle,
idx->index);
block_put(b);
return node;
}
}
return 0; /* extra characters in the component */
block_put(b);
}
if (ext_processed || (name_processed && dentry->ext[0] == FAT_PAD))
return cur - start;
else
 
return NULL;
}
 
static fs_index_t fat_index_get(void *node)
{
fat_node_t *fnodep = (fat_node_t *)node;
if (!fnodep)
return 0;
return fnodep->idx->index;
}
 
void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
static size_t fat_size_get(void *node)
{
int first = IPC_GET_ARG1(*request);
int second = IPC_GET_ARG2(*request);
int dev_handle = IPC_GET_ARG3(*request);
return ((fat_node_t *)node)->size;
}
 
static unsigned fat_lnkcnt_get(void *node)
{
return ((fat_node_t *)node)->lnkcnt;
}
 
static bool fat_has_children(void *node)
{
fat_node_t *nodep = (fat_node_t *)node;
unsigned bps;
unsigned dps;
unsigned blocks;
block_t *b;
unsigned i, j;
 
if (nodep->type != FAT_DIRECTORY)
return false;
 
bps = fat_bps_get(nodep->idx->dev_handle);
dps = bps / sizeof(fat_dentry_t);
 
blocks = nodep->size / bps + (nodep->size % bps != 0);
 
for (i = 0; i < blocks; i++) {
unsigned dentries;
fat_dentry_t *d;
b = fat_block_get(nodep, i);
dentries = (i == blocks - 1) ?
nodep->size % sizeof(fat_dentry_t) :
dps;
for (j = 0; j < dentries; j++) {
d = ((fat_dentry_t *)b->data) + j;
switch (fat_classify_dentry(d)) {
case FAT_DENTRY_SKIP:
continue;
case FAT_DENTRY_LAST:
block_put(b);
return false;
default:
case FAT_DENTRY_VALID:
block_put(b);
return true;
}
block_put(b);
return true;
}
block_put(b);
}
 
return false;
}
 
static void *fat_root_get(dev_handle_t dev_handle)
{
return NULL; /* TODO */
}
 
static char fat_plb_get_char(unsigned pos)
{
return fat_reg.plb_ro[pos % PLB_SIZE];
}
 
static bool fat_is_directory(void *node)
{
return ((fat_node_t *)node)->type == FAT_DIRECTORY;
}
 
static bool fat_is_file(void *node)
{
return ((fat_node_t *)node)->type == FAT_FILE;
}
 
/** libfs operations */
libfs_ops_t fat_libfs_ops = {
.match = fat_match,
.node_get = fat_node_get,
.node_put = fat_node_put,
.create = fat_create,
.destroy = fat_destroy,
.link = fat_link,
.unlink = fat_unlink,
.index_get = fat_index_get,
.size_get = fat_size_get,
.lnkcnt_get = fat_lnkcnt_get,
.has_children = fat_has_children,
.root_get = fat_root_get,
.plb_get_char = fat_plb_get_char,
.is_directory = fat_is_directory,
.is_file = fat_is_file
};
 
void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
{
libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
}
 
/**
* @}
*/
/branches/tracing/uspace/srv/fs/fat/Makefile
44,7 → 44,8
OUTPUT = fat
SOURCES = \
fat.c \
fat_ops.c
fat_ops.c \
fat_idx.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
/branches/tracing/uspace/srv/vfs/vfs_ops.c
188,6 → 188,15
if (rootfs.fs_handle) {
/* We already have the root FS. */
rwlock_write_lock(&namespace_rwlock);
if ((size == 1) && (buf[0] == '/')) {
/* Trying to mount root FS over root FS */
rwlock_write_unlock(&namespace_rwlock);
futex_up(&rootfs_futex);
vfs_node_put(mr_node);
free(buf);
ipc_answer_0(rid, EBUSY);
return;
}
rc = vfs_lookup_internal(buf, L_DIRECTORY, &mp_res, NULL);
if (rc != EOK) {
/* The lookup failed for some reason. */
/branches/tracing/uspace/srv/vfs/vfs.h
209,7 → 209,7
unsigned lnkcnt;
 
link_t nh_link; /**< Node hash-table link. */
size_t size; /**< Cached size of the file. */
size_t size; /**< Cached size if the node is a file. */
 
/**
* Holding this rwlock prevents modifications of the node's contents.
/branches/tracing/HelenOS.config
1,3 → 1,31
#
# 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.
#
 
## General configuration directives
 
# Platform
/branches/tracing/boot/boot.config
1,3 → 1,31
#
# 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.
#
 
## General configuration directives
 
# Architecture