Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 3492 → Rev 3489

/branches/sparc/kernel/arch/sparc64/include/trap/syscall.h
31,14 → 31,26
*/
/**
* @file
* @brief
* @brief This file contains the trap_instruction handler.
*
* The trap_instruction trap is used to implement syscalls.
*/
 
#ifndef KERN_sparc64_SYSCALL_TRAP_H_
#define KERN_sparc64_SYSCALL_TRAP_H_
 
#define TT_TRAP_INSTRUCTION_0 0x100
#define TT_TRAP_INSTRUCTION(n) (0x100 + (n))
#define TT_TRAP_INSTRUCTION_LAST TT_TRAP_INSTRUCTION(127)
 
#ifdef __ASM__
 
.macro TRAP_INSTRUCTION n
ba trap_instruction_handler
mov TT_TRAP_INSTRUCTION(\n) - TT_TRAP_INSTRUCTION(0), %g2
.endm
 
#endif /* __ASM__ */
 
#endif
 
/** @}
/branches/sparc/kernel/arch/sparc64/include/trap/regwin.h
39,7 → 39,6
 
#include <arch/stack.h>
#include <arch/arch.h>
#include <align.h>
 
#define TT_CLEAN_WINDOW 0x24
#define TT_SPILL_0_NORMAL 0x80 /* kernel spills */
73,11 → 72,6
#define I6_OFFSET 112
#define I7_OFFSET 120
 
/* Uspace Window Buffer constants. */
#define UWB_SIZE ((NWINDOWS - 1) * STACK_WINDOW_SAVE_AREA_SIZE)
#define UWB_ALIGNMENT 1024
#define UWB_ASIZE ALIGN_UP(UWB_SIZE, UWB_ALIGNMENT)
 
#ifdef __ASM__
 
/*
/branches/sparc/kernel/arch/sparc64/src/trap/trap_table.S
329,22 → 329,198
fill_1_normal_tl0:
FILL_NORMAL_HANDLER_USERSPACE
 
/* TT = 0x100 - 0x17f, TL = 0, trap_instruction_0 - trap_instruction_7f */
.irp cur, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,\
58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\
77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,\
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,\
127
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE
.global trap_instruction_\cur\()_tl0
trap_instruction_\cur\()_tl0:
ba trap_instruction_handler
mov \cur, %g2
.endr
/* TT = 0x100, TL = 0, trap_instruction_0 */
.org trap_table + TT_TRAP_INSTRUCTION(0)*ENTRY_SIZE
.global trap_instruction_0_tl0
trap_instruction_0_tl0:
TRAP_INSTRUCTION 0
 
/* TT = 0x101, TL = 0, trap_instruction_1 */
.org trap_table + TT_TRAP_INSTRUCTION(1)*ENTRY_SIZE
.global trap_instruction_1_tl0
trap_instruction_1_tl0:
TRAP_INSTRUCTION 1
 
/* TT = 0x102, TL = 0, trap_instruction_2 */
.org trap_table + TT_TRAP_INSTRUCTION(2)*ENTRY_SIZE
.global trap_instruction_2_tl0
trap_instruction_2_tl0:
TRAP_INSTRUCTION 2
 
/* TT = 0x103, TL = 0, trap_instruction_3 */
.org trap_table + TT_TRAP_INSTRUCTION(3)*ENTRY_SIZE
.global trap_instruction_3_tl0
trap_instruction_3_tl0:
TRAP_INSTRUCTION 3
 
/* TT = 0x104, TL = 0, trap_instruction_4 */
.org trap_table + TT_TRAP_INSTRUCTION(4)*ENTRY_SIZE
.global trap_instruction_4_tl0
trap_instruction_4_tl0:
TRAP_INSTRUCTION 4
 
/* TT = 0x105, TL = 0, trap_instruction_5 */
.org trap_table + TT_TRAP_INSTRUCTION(5)*ENTRY_SIZE
.global trap_instruction_5_tl0
trap_instruction_5_tl0:
TRAP_INSTRUCTION 5
 
/* TT = 0x106, TL = 0, trap_instruction_6 */
.org trap_table + TT_TRAP_INSTRUCTION(6)*ENTRY_SIZE
.global trap_instruction_6_tl0
trap_instruction_6_tl0:
TRAP_INSTRUCTION 6
 
/* TT = 0x107, TL = 0, trap_instruction_7 */
.org trap_table + TT_TRAP_INSTRUCTION(7)*ENTRY_SIZE
.global trap_instruction_7_tl0
trap_instruction_7_tl0:
TRAP_INSTRUCTION 7
 
/* TT = 0x108, TL = 0, trap_instruction_8 */
.org trap_table + TT_TRAP_INSTRUCTION(8)*ENTRY_SIZE
.global trap_instruction_8_tl0
trap_instruction_8_tl0:
TRAP_INSTRUCTION 8
 
/* TT = 0x109, TL = 0, trap_instruction_9 */
.org trap_table + TT_TRAP_INSTRUCTION(9)*ENTRY_SIZE
.global trap_instruction_9_tl0
trap_instruction_9_tl0:
TRAP_INSTRUCTION 9
 
/* TT = 0x10a, TL = 0, trap_instruction_10 */
.org trap_table + TT_TRAP_INSTRUCTION(10)*ENTRY_SIZE
.global trap_instruction_10_tl0
trap_instruction_10_tl0:
TRAP_INSTRUCTION 10
 
/* TT = 0x10b, TL = 0, trap_instruction_11 */
.org trap_table + TT_TRAP_INSTRUCTION(11)*ENTRY_SIZE
.global trap_instruction_11_tl0
trap_instruction_11_tl0:
TRAP_INSTRUCTION 11
 
/* TT = 0x10c, TL = 0, trap_instruction_12 */
.org trap_table + TT_TRAP_INSTRUCTION(12)*ENTRY_SIZE
.global trap_instruction_12_tl0
trap_instruction_12_tl0:
TRAP_INSTRUCTION 12
 
/* TT = 0x10d, TL = 0, trap_instruction_13 */
.org trap_table + TT_TRAP_INSTRUCTION(13)*ENTRY_SIZE
.global trap_instruction_13_tl0
trap_instruction_13_tl0:
TRAP_INSTRUCTION 13
 
/* TT = 0x10e, TL = 0, trap_instruction_14 */
.org trap_table + TT_TRAP_INSTRUCTION(14)*ENTRY_SIZE
.global trap_instruction_14_tl0
trap_instruction_14_tl0:
TRAP_INSTRUCTION 14
 
/* TT = 0x10f, TL = 0, trap_instruction_15 */
.org trap_table + TT_TRAP_INSTRUCTION(15)*ENTRY_SIZE
.global trap_instruction_15_tl0
trap_instruction_15_tl0:
TRAP_INSTRUCTION 15
 
/* TT = 0x110, TL = 0, trap_instruction_16 */
.org trap_table + TT_TRAP_INSTRUCTION(16)*ENTRY_SIZE
.global trap_instruction_16_tl0
trap_instruction_16_tl0:
TRAP_INSTRUCTION 16
 
/* TT = 0x111, TL = 0, trap_instruction_17 */
.org trap_table + TT_TRAP_INSTRUCTION(17)*ENTRY_SIZE
.global trap_instruction_17_tl0
trap_instruction_17_tl0:
TRAP_INSTRUCTION 17
 
/* TT = 0x112, TL = 0, trap_instruction_18 */
.org trap_table + TT_TRAP_INSTRUCTION(18)*ENTRY_SIZE
.global trap_instruction_18_tl0
trap_instruction_18_tl0:
TRAP_INSTRUCTION 18
 
/* TT = 0x113, TL = 0, trap_instruction_19 */
.org trap_table + TT_TRAP_INSTRUCTION(19)*ENTRY_SIZE
.global trap_instruction_19_tl0
trap_instruction_19_tl0:
TRAP_INSTRUCTION 19
 
/* TT = 0x114, TL = 0, trap_instruction_20 */
.org trap_table + TT_TRAP_INSTRUCTION(20)*ENTRY_SIZE
.global trap_instruction_20_tl0
trap_instruction_20_tl0:
TRAP_INSTRUCTION 20
 
/* TT = 0x115, TL = 0, trap_instruction_21 */
.org trap_table + TT_TRAP_INSTRUCTION(21)*ENTRY_SIZE
.global trap_instruction_21_tl0
trap_instruction_21_tl0:
TRAP_INSTRUCTION 21
 
/* TT = 0x116, TL = 0, trap_instruction_22 */
.org trap_table + TT_TRAP_INSTRUCTION(22)*ENTRY_SIZE
.global trap_instruction_22_tl0
trap_instruction_22_tl0:
TRAP_INSTRUCTION 22
 
/* TT = 0x117, TL = 0, trap_instruction_23 */
.org trap_table + TT_TRAP_INSTRUCTION(23)*ENTRY_SIZE
.global trap_instruction_23_tl0
trap_instruction_23_tl0:
TRAP_INSTRUCTION 23
 
/* TT = 0x118, TL = 0, trap_instruction_24 */
.org trap_table + TT_TRAP_INSTRUCTION(24)*ENTRY_SIZE
.global trap_instruction_24_tl0
trap_instruction_24_tl0:
TRAP_INSTRUCTION 24
 
/* TT = 0x119, TL = 0, trap_instruction_25 */
.org trap_table + TT_TRAP_INSTRUCTION(25)*ENTRY_SIZE
.global trap_instruction_25_tl0
trap_instruction_25_tl0:
TRAP_INSTRUCTION 25
 
/* TT = 0x11a, TL = 0, trap_instruction_26 */
.org trap_table + TT_TRAP_INSTRUCTION(26)*ENTRY_SIZE
.global trap_instruction_26_tl0
trap_instruction_26_tl0:
TRAP_INSTRUCTION 26
 
/* TT = 0x11b, TL = 0, trap_instruction_27 */
.org trap_table + TT_TRAP_INSTRUCTION(27)*ENTRY_SIZE
.global trap_instruction_27_tl0
trap_instruction_27_tl0:
TRAP_INSTRUCTION 27
 
/* TT = 0x11c, TL = 0, trap_instruction_28 */
.org trap_table + TT_TRAP_INSTRUCTION(28)*ENTRY_SIZE
.global trap_instruction_28_tl0
trap_instruction_28_tl0:
TRAP_INSTRUCTION 28
 
/* TT = 0x11d, TL = 0, trap_instruction_29 */
.org trap_table + TT_TRAP_INSTRUCTION(29)*ENTRY_SIZE
.global trap_instruction_29_tl0
trap_instruction_29_tl0:
TRAP_INSTRUCTION 29
 
/* TT = 0x11e, TL = 0, trap_instruction_30 */
.org trap_table + TT_TRAP_INSTRUCTION(30)*ENTRY_SIZE
.global trap_instruction_30_tl0
trap_instruction_30_tl0:
TRAP_INSTRUCTION 30
 
/* TT = 0x11f, TL = 0, trap_instruction_31 */
.org trap_table + TT_TRAP_INSTRUCTION(31)*ENTRY_SIZE
.global trap_instruction_31_tl0
trap_instruction_31_tl0:
TRAP_INSTRUCTION 31
 
/*
* Handlers for TL>0.
*/
748,8 → 924,9
* Fill all windows stored in the buffer.
*/
clr %g4
0: andcc %g7, UWB_ALIGNMENT - 1, %g0 ! alignment check
bz 0f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill
set PAGE_SIZE - 1, %g5
0: andcc %g7, %g5, %g0 ! PAGE_SIZE alignment check
bz 0f ! %g7 is page-aligned, no more windows to refill
nop
 
add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7
/branches/sparc/kernel/arch/sparc64/src/proc/thread.c
34,8 → 34,9
 
#include <proc/thread.h>
#include <arch/proc/thread.h>
#include <mm/slab.h>
#include <arch/trap/regwin.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <arch/mm/page.h>
#include <align.h>
 
void thr_constructor_arch(thread_t *t)
49,12 → 50,12
void thr_destructor_arch(thread_t *t)
{
if (t->arch.uspace_window_buffer) {
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
/*
* Mind the possible alignment of the userspace window buffer
* belonging to a killed thread.
*/
free((uint8_t *) ALIGN_DOWN(uw_buf, UWB_ALIGNMENT));
frame_free(KA2PA(ALIGN_DOWN((uintptr_t)
t->arch.uspace_window_buffer, PAGE_SIZE)));
}
}
 
66,7 → 67,7
* The thread needs userspace window buffer and the object
* returned from the slab allocator doesn't have any.
*/
t->arch.uspace_window_buffer = malloc(UWB_ASIZE, 0);
t->arch.uspace_window_buffer = frame_alloc(ONE_FRAME, FRAME_KA);
} else {
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
 
75,7 → 76,7
* belonging to a killed thread.
*/
t->arch.uspace_window_buffer = (uint8_t *) ALIGN_DOWN(uw_buf,
UWB_ASIZE);
PAGE_SIZE);
}
}
 
/branches/sparc/kernel/arch/ia64/include/asm.h
44,50 → 44,21
 
static inline void outb(uint64_t port,uint8_t v)
{
*((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
*((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
static inline void outw(uint64_t port,uint16_t v)
{
*((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
static inline void outl(uint64_t port,uint32_t v)
{
*((uint32_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
 
 
static inline uint8_t inb(uint64_t port)
{
asm volatile ("mf\n" ::: "memory");
 
return *((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 ))));
return *((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 ))));
}
 
static inline uint16_t inw(uint64_t port)
{
asm volatile ("mf\n" ::: "memory");
 
return *((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xffE) | ( (port >> 2) << 12 ))));
}
 
static inline uint32_t inl(uint64_t port)
{
asm volatile ("mf\n" ::: "memory");
 
return *((uint32_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 ))));
}
 
 
 
/** Return base address of current stack
*
* Return the base address of the current stack.
/branches/sparc/kernel/arch/arm32/include/interrupt.h
37,7 → 37,6
#define KERN_arm32_INTERRUPT_H_
 
#include <arch/types.h>
#include <arch/exception.h>
 
/** Initial size of exception dispatch table. */
#define IVT_ITEMS 6
/branches/sparc/kernel/arch/ppc32/include/regutils.h
File deleted
/branches/sparc/kernel/arch/ppc32/include/exception.h
36,7 → 36,6
#define KERN_ppc32_EXCEPTION_H_
 
#include <arch/types.h>
#include <arch/regutils.h>
 
typedef struct {
uint32_t r0;
85,10 → 84,11
}
 
/** Return true if exception happened while in userspace */
#include <panic.h>
static inline int istate_from_uspace(istate_t *istate)
{
/* true if privilege level PR (copied from MSR) == 1 */
return (istate->srr1 & MSR_PR) != 0;
panic("istate_from_uspace not yet implemented");
return 0;
}
 
static inline unative_t istate_get_pc(istate_t *istate)
/branches/sparc/kernel/arch/ppc32/include/asm/regname.h
214,8 → 214,8
#define hid0 1008
 
/* MSR bits */
#define msr_dr (1 << 4)
#define msr_ir (1 << 5)
#define msr_ir (1 << 4)
#define msr_dr (1 << 5)
#define msr_pr (1 << 14)
#define msr_ee (1 << 15)
 
/branches/sparc/kernel/arch/amd64/include/syscall.h
35,6 → 35,8
#ifndef KERN_amd64_SYSCALL_H_
#define KERN_amd64_SYSCALL_H_
 
#include <arch/types.h>
 
extern void syscall_setup_cpu(void);
 
#endif
/branches/sparc/kernel/arch/ia32/include/syscall.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/sparc/kernel/arch/ia32/include/asm.h
247,22 → 247,6
return v;
}
 
/** Write to MSR */
static inline void write_msr(uint32_t msr, uint64_t value)
{
asm volatile ("wrmsr" : : "c" (msr), "a" ((uint32_t)(value)),
"d" ((uint32_t)(value >> 32)));
}
 
static inline uint64_t read_msr(uint32_t msr)
{
uint32_t ax, dx;
 
asm volatile ("rdmsr" : "=a"(ax), "=d"(dx) : "c" (msr));
return ((uint64_t)dx << 32) | ax;
}
 
 
/** Return base address of current stack
*
* Return the base address of the current stack.
/branches/sparc/kernel/arch/ia32/include/cpu.h
35,21 → 35,12
#ifndef KERN_ia32_CPU_H_
#define KERN_ia32_CPU_H_
 
#include <arch/pm.h>
#include <arch/asm.h>
 
#define EFLAGS_IF (1 << 9)
#define EFLAGS_RF (1 << 16)
 
#define CR4_OSFXSR_MASK (1<<9)
 
/* Support for SYSENTER and SYSEXIT */
#define IA32_MSR_SYSENTER_CS 0x174
#define IA32_MSR_SYSENTER_ESP 0x175
#define IA32_MSR_SYSENTER_EIP 0x176
 
#ifndef __ASM__
 
#include <arch/pm.h>
#include <arch/asm.h>
 
typedef struct {
int vendor;
int family;
60,8 → 51,9
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
} cpu_arch_t;
 
#endif
 
#define CR4_OSFXSR_MASK (1<<9)
 
#endif
 
/** @}
/branches/sparc/kernel/arch/ia32/Makefile.inc
160,5 → 160,4
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/boot/memmap.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/debugger.c \
arch/$(ARCH)/src/syscall.c
arch/$(ARCH)/src/debugger.c
/branches/sparc/kernel/arch/ia32/src/syscall.c
File deleted
/branches/sparc/kernel/arch/ia32/src/asm.S
147,45 → 147,6
popfl
.endm
 
/*
* The SYSENTER syscall mechanism can be used for syscalls with
* four or fewer arguments. To pass these four arguments, we
* use four registers: EDX, ECX, EBX, ESI. The syscall number
* is passed in EAX. We use EDI to remember the return address
* and EBP to remember the stack. The INT-based syscall mechanism
* can actually handle six arguments plus the syscall number
* entirely in registers.
*/
.global sysenter_handler
sysenter_handler:
pushl %ebp # remember user stack
pushl %edi # remember return user address
 
pushl %gs # remember TLS
 
pushl %eax # syscall number
subl $8, %esp # unused sixth and fifth argument
pushl %esi # fourth argument
pushl %ebx # third argument
pushl %ecx # second argument
pushl %edx # first argument
 
movw $16, %ax
movw %ax, %ds
movw %ax, %es
 
cld
call syscall_handler
addl $28, %esp # remove arguments from stack
 
pop %gs # restore TLS
 
pop %edx # prepare return EIP for SYSEXIT
pop %ecx # prepare userspace ESP for SYSEXIT
 
sysexit # return to userspace
 
 
## Declare interrupt handlers
#
# Declare interrupt handlers for n interrupt
/branches/sparc/kernel/arch/ia32/src/proc/scheduler.c
58,14 → 58,8
*/
void before_thread_runs_arch(void)
{
uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE -
CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE -
SP_DELTA];
 
/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */
write_msr(IA32_MSR_SYSENTER_ESP, kstk);
 
/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */
CPU->arch.tss->esp0 = kstk;
CPU->arch.tss->ss0 = selector(KDATA_DES);
 
/* Set up TLS in GS register */
/branches/sparc/kernel/arch/ia32/src/cpu/cpu.c
42,7 → 42,6
#include <fpu_context.h>
 
#include <arch/smp/apic.h>
#include <arch/syscall.h>
 
/*
* Identification of CPUs.
124,9 → 123,6
: "i" (CR4_OSFXSR_MASK|(1<<10))
);
}
/* Setup fast SYSENTER/SYSEXIT syscalls */
syscall_setup_cpu();
}
 
void cpu_identify(void)
/branches/sparc/kernel/generic/src/udebug/udebug.c
File deleted
/branches/sparc/kernel/generic/src/udebug/udebug_ops.c
File deleted
/branches/sparc/kernel/generic/src/udebug/udebug_ipc.c
File deleted
/branches/sparc/kernel/generic/src/main/uinit.c
46,9 → 46,7
#include <userspace.h>
#include <mm/slab.h>
#include <arch.h>
#include <udebug/udebug.h>
 
 
/** Thread used to bring up userspace thread.
*
* @param arg Pointer to structure containing userspace entry and stack
67,10 → 65,6
* deployed for the event of forceful task termination.
*/
thread_detach(THREAD);
 
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
uarg.uspace_entry = ((uspace_arg_t *) arg)->uspace_entry;
uarg.uspace_stack = ((uspace_arg_t *) arg)->uspace_stack;
/branches/sparc/kernel/generic/src/proc/task.c
155,18 → 155,7
 
ta->capabilities = 0;
ta->cycles = 0;
 
#ifdef CONFIG_UDEBUG
/* Init debugging stuff */
udebug_task_init(&ta->udebug);
 
/* Init kbox stuff */
ipc_answerbox_init(&ta->kernel_box, ta);
ta->kb_thread = NULL;
mutex_initialize(&ta->kb_cleanup_lock, MUTEX_PASSIVE);
ta->kb_finished = false;
#endif
 
ipc_answerbox_init(&ta->answerbox, ta);
for (i = 0; i < IPC_MAX_PHONES; i++)
ipc_phone_init(&ta->phones[i]);
/branches/sparc/kernel/generic/src/proc/thread.c
180,10 → 180,6
return -1;
}
 
#ifdef CONFIG_UDEBUG
mutex_initialize(&t->udebug.lock, MUTEX_PASSIVE);
#endif
 
return 0;
}
 
351,11 → 347,6
avltree_node_initialize(&t->threads_tree_node);
t->threads_tree_node.key = (uintptr_t) t;
 
#ifdef CONFIG_UDEBUG
/* Init debugging stuff */
udebug_thread_initialize(&t->udebug);
#endif
 
/* might depend on previous initialization */
thread_create_arch(t);
 
418,17 → 409,12
ipl_t ipl;
 
/*
* Attach to the specified task.
* Attach to the current task.
*/
ipl = interrupts_disable();
spinlock_lock(&task->lock);
 
atomic_inc(&task->refcount);
 
/* Must not count kbox thread into lifecount */
if (t->flags & THREAD_FLAG_USPACE)
atomic_inc(&task->lifecount);
 
atomic_inc(&task->lifecount);
list_append(&t->th_link, &task->th_head);
spinlock_unlock(&task->lock);
 
451,19 → 437,14
{
ipl_t ipl;
 
if (THREAD->flags & THREAD_FLAG_USPACE) {
#ifdef CONFIG_UDEBUG
/* Generate udebug THREAD_E event */
udebug_thread_e_event();
#endif
if (atomic_predec(&TASK->lifecount) == 0) {
/*
* We are the last userspace thread in the task that
* still has not exited. With the exception of the
* moment the task was created, new userspace threads
* can only be created by threads of the same task.
* We are safe to perform cleanup.
*/
if (atomic_predec(&TASK->lifecount) == 0) {
/*
* We are the last thread in the task that still has not exited.
* With the exception of the moment the task was created, new
* threads can only be created by threads of the same task.
* We are safe to perform cleanup.
*/
if (THREAD->flags & THREAD_FLAG_USPACE) {
ipc_cleanup();
futex_cleanup();
LOG("Cleanup of task %" PRIu64" completed.", TASK->taskid);
760,11 → 741,6
thread_attach(t, TASK);
thread_ready(t);
 
#ifdef CONFIG_UDEBUG
/* Generate udebug THREAD_B event */
udebug_thread_b_event(t);
#endif
 
return 0;
} else
free(kernel_uarg);
/branches/sparc/kernel/generic/src/mm/as.c
385,7 → 385,7
if (pages < area->pages) {
bool cond;
uintptr_t start_free = area->base + pages * PAGE_SIZE;
uintptr_t start_free = area->base + pages*PAGE_SIZE;
 
/*
* Shrinking the area.
395,7 → 395,7
/*
* Start TLB shootdown sequence.
*/
tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base +
tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base +
pages * PAGE_SIZE, area->pages - pages);
 
/*
/branches/sparc/kernel/generic/src/ipc/kbox.c
File deleted
/branches/sparc/kernel/generic/src/ipc/sysipc.c
42,9 → 42,8
#include <ipc/sysipc.h>
#include <ipc/irq.h>
#include <ipc/ipcrsc.h>
#include <ipc/kbox.h>
#include <udebug/udebug_ipc.h>
#include <arch/interrupt.h>
#include <print.h>
#include <syscall/copy.h>
#include <security/cap.h>
#include <mm/as.h>
296,11 → 295,10
/** Called before the request is sent.
*
* @param call Call structure with the request.
* @param phone Phone that the call will be sent through.
*
* @return Return 0 on success, ELIMIT or EPERM on error.
*/
static int request_preprocess(call_t *call, phone_t *phone)
static int request_preprocess(call_t *call)
{
int newphid;
size_t size;
342,10 → 340,6
return rc;
}
break;
#ifdef CONFIG_UDEBUG
case IPC_M_DEBUG_ALL:
return udebug_request_preprocess(call, phone);
#endif
default:
break;
}
375,7 → 369,6
 
if (call->buffer) {
/* This must be an affirmative answer to IPC_M_DATA_READ. */
/* or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ... */
uintptr_t dst = IPC_GET_ARG1(call->data);
size_t size = IPC_GET_ARG2(call->data);
int rc = copy_to_uspace((void *) dst, call->buffer, size);
406,13 → 399,7
return -1;
}
IPC_SET_ARG5(call->data, phoneid);
}
switch (IPC_GET_METHOD(call->data)) {
case IPC_M_DEBUG_ALL:
return -1;
default:
break;
}
}
return 0;
}
 
454,7 → 441,7
IPC_SET_ARG4(call.data, 0);
IPC_SET_ARG5(call.data, 0);
 
if (!(res = request_preprocess(&call, phone))) {
if (!(res = request_preprocess(&call))) {
rc = ipc_call_sync(phone, &call);
if (rc != EOK)
return rc;
494,7 → 481,7
 
GET_CHECK_PHONE(phone, phoneid, return ENOENT);
 
if (!(res = request_preprocess(&call, phone))) {
if (!(res = request_preprocess(&call))) {
rc = ipc_call_sync(phone, &call);
if (rc != EOK)
return rc;
563,7 → 550,7
*/
IPC_SET_ARG5(call->data, 0);
 
if (!(res = request_preprocess(call, phone)))
if (!(res = request_preprocess(call)))
ipc_call(phone, call);
else
ipc_backsend_err(phone, call, res);
597,7 → 584,7
ipc_call_free(call);
return (unative_t) rc;
}
if (!(res = request_preprocess(call, phone)))
if (!(res = request_preprocess(call)))
ipc_call(phone, call);
else
ipc_backsend_err(phone, call, res);
822,16 → 809,11
 
ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
 
atomic_dec(&TASK->active_calls);
 
if (call->flags & IPC_CALL_DISCARD_ANSWER) {
ipc_call_free(call);
goto restart;
} else {
/*
* Decrement the counter of active calls only if the
* call is not an answer to IPC_M_PHONE_HUNGUP,
* which doesn't contribute to the counter.
*/
atomic_dec(&TASK->active_calls);
}
 
STRUCT_TO_USPACE(&calldata->args, &call->data.args);
886,30 → 868,5
return 0;
}
 
#include <console/console.h>
 
/**
* Syscall connect to a task by id.
*
* @return Phone id on success, or negative error code.
*/
unative_t sys_ipc_connect_kbox(sysarg64_t *uspace_taskid_arg)
{
#ifdef CONFIG_UDEBUG
sysarg64_t taskid_arg;
int rc;
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
 
LOG("sys_ipc_connect_kbox(%" PRIu64 ")\n", taskid_arg.value);
 
return ipc_connect_kbox(taskid_arg.value);
#else
return (unative_t) ENOTSUP;
#endif
}
 
/** @}
*/
/branches/sparc/kernel/generic/src/ipc/ipc.c
43,7 → 43,6
#include <synch/waitq.h>
#include <synch/synch.h>
#include <ipc/ipc.h>
#include <ipc/kbox.h>
#include <errno.h>
#include <mm/slab.h>
#include <arch.h>
52,7 → 51,6
#include <debug.h>
 
#include <print.h>
#include <console/console.h>
#include <proc/thread.h>
#include <arch/interrupt.h>
#include <ipc/irq.h>
429,7 → 427,7
*
* @param lst Head of the list to be cleaned up.
*/
void ipc_cleanup_call_list(link_t *lst)
static void ipc_cleanup_call_list(link_t *lst)
{
call_t *call;
 
444,31 → 442,33
}
}
 
/** Disconnects all phones connected to an answerbox.
/** Cleans up all IPC communication of the current task.
*
* @param box Answerbox to disconnect phones from.
* @param notify_box If true, the answerbox will get a hangup message for
* each disconnected phone.
* Note: ipc_hangup sets returning answerbox to TASK->answerbox, you
* have to change it as well if you want to cleanup other tasks than TASK.
*/
void ipc_answerbox_slam_phones(answerbox_t *box, bool notify_box)
void ipc_cleanup(void)
{
int i;
call_t *call;
phone_t *phone;
DEADLOCK_PROBE_INIT(p_phonelck);
ipl_t ipl;
call_t *call;
 
call = notify_box ? ipc_call_alloc(0) : NULL;
/* Disconnect all our phones ('ipc_phone_hangup') */
for (i = 0; i < IPC_MAX_PHONES; i++)
ipc_phone_hangup(&TASK->phones[i]);
 
/* Disconnect all connected irqs */
ipc_irq_cleanup(&TASK->answerbox);
 
/* Disconnect all phones connected to our answerbox */
restart_phones:
ipl = interrupts_disable();
spinlock_lock(&box->lock);
while (!list_empty(&box->connected_phones)) {
phone = list_get_instance(box->connected_phones.next,
spinlock_lock(&TASK->answerbox.lock);
while (!list_empty(&TASK->answerbox.connected_phones)) {
phone = list_get_instance(TASK->answerbox.connected_phones.next,
phone_t, link);
if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
spinlock_unlock(&box->lock);
interrupts_restore(ipl);
spinlock_unlock(&TASK->answerbox.lock);
DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);
goto restart_phones;
}
475,70 → 475,13
/* Disconnect phone */
ASSERT(phone->state == IPC_PHONE_CONNECTED);
 
phone->state = IPC_PHONE_SLAMMED;
list_remove(&phone->link);
phone->state = IPC_PHONE_SLAMMED;
 
if (notify_box) {
mutex_unlock(&phone->lock);
spinlock_unlock(&box->lock);
interrupts_restore(ipl);
 
/*
* Send one message to the answerbox for each
* phone. Used to make sure the kbox thread
* wakes up after the last phone has been
* disconnected.
*/
IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP);
call->flags |= IPC_CALL_DISCARD_ANSWER;
_ipc_call(phone, box, call);
 
/* Allocate another call in advance */
call = ipc_call_alloc(0);
 
/* Must start again */
goto restart_phones;
}
 
mutex_unlock(&phone->lock);
}
 
spinlock_unlock(&box->lock);
interrupts_restore(ipl);
 
/* Free unused call */
if (call)
ipc_call_free(call);
}
 
/** Cleans up all IPC communication of the current task.
*
* Note: ipc_hangup sets returning answerbox to TASK->answerbox, you
* have to change it as well if you want to cleanup other tasks than TASK.
*/
void ipc_cleanup(void)
{
int i;
call_t *call;
 
/* Disconnect all our phones ('ipc_phone_hangup') */
for (i = 0; i < IPC_MAX_PHONES; i++)
ipc_phone_hangup(&TASK->phones[i]);
 
/* Disconnect all connected irqs */
ipc_irq_cleanup(&TASK->answerbox);
 
/* Disconnect all phones connected to our regular answerbox */
ipc_answerbox_slam_phones(&TASK->answerbox, false);
 
#ifdef CONFIG_UDEBUG
/* Clean up kbox thread and communications */
ipc_kbox_cleanup();
#endif
 
/* Answer all messages in 'calls' and 'dispatched_calls' queues */
spinlock_lock(&TASK->answerbox.lock);
ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
ipc_cleanup_call_list(&TASK->answerbox.calls);
spinlock_unlock(&TASK->answerbox.lock);
574,13 → 517,7
(call->flags & IPC_CALL_NOTIF));
ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
/*
* Record the receipt of this call in the current task's counter
* of active calls. IPC_M_PHONE_HUNGUP calls do not contribute
* to this counter so do not record answers to them either.
*/
if (!(call->flags & IPC_CALL_DISCARD_ANSWER))
atomic_dec(&TASK->active_calls);
atomic_dec(&TASK->active_calls);
ipc_call_free(call);
}
}
/branches/sparc/kernel/generic/src/lib/memstr.c
34,10 → 34,12
* @file
* @brief Memory string operations.
*
* This file provides architecture independent functions to manipulate blocks of
* memory. These functions are optimized as much as generic functions of this
* type can be. However, architectures are free to provide even more optimized
* versions of these functions.
* This file provides architecture independent functions
* to manipulate blocks of memory. These functions
* are optimized as much as generic functions of
* this type can be. However, architectures are
* free to provide even more optimized versions of these
* functions.
*/
 
#include <memstr.h>
44,33 → 46,32
#include <arch/types.h>
#include <align.h>
 
/** Copy block of memory.
/** Copy block of memory
*
* Copy cnt bytes from src address to dst address. The copying is done
* word-by-word and then byte-by-byte. The source and destination memory areas
* cannot overlap.
* Copy cnt bytes from src address to dst address.
* The copying is done word-by-word and then byte-by-byte.
* The source and destination memory areas cannot overlap.
*
* @param src Source address to copy from.
* @param dst Destination address to copy to.
* @param cnt Number of bytes to copy.
* @param src Origin address to copy from.
* @param dst Origin address to copy to.
* @param cnt Number of bytes to copy.
*
* @return Destination address.
*/
void *_memcpy(void *dst, const void *src, size_t cnt)
void *_memcpy(void * dst, const void *src, size_t cnt)
{
unsigned int i, j;
if (ALIGN_UP((uintptr_t) src, sizeof(unative_t)) != (uintptr_t) src ||
ALIGN_UP((uintptr_t) dst, sizeof(unative_t)) != (uintptr_t) dst) {
ALIGN_UP((uintptr_t) dst, sizeof(unative_t)) != (uintptr_t) dst) {
for (i = 0; i < cnt; i++)
((uint8_t *) dst)[i] = ((uint8_t *) src)[i];
} else {
for (i = 0; i < cnt / sizeof(unative_t); i++)
((unative_t *) dst)[i] = ((unative_t *) src)[i];
for (j = 0; j < cnt % sizeof(unative_t); j++)
((uint8_t *)(((unative_t *) dst) + i))[j] =
((uint8_t *)(((unative_t *) src) + i))[j];
((uint8_t *)(((unative_t *) dst) + i))[j] = ((uint8_t *)(((unative_t *) src) + i))[j];
}
return (char *) dst;
78,12 → 79,12
 
/** Fill block of memory
*
* Fill cnt bytes at dst address with the value x. The filling is done
* byte-by-byte.
* Fill cnt bytes at dst address with the value x.
* The filling is done byte-by-byte.
*
* @param dst Destination address to fill.
* @param cnt Number of bytes to fill.
* @param x Value to fill.
* @param dst Origin address to fill.
* @param cnt Number of bytes to fill.
* @param x Value to fill.
*
*/
void _memsetb(void *dst, size_t cnt, uint8_t x)
95,14 → 96,14
p[i] = x;
}
 
/** Fill block of memory.
/** Fill block of memory
*
* Fill cnt words at dst address with the value x. The filling is done
* word-by-word.
* Fill cnt words at dst address with the value x.
* The filling is done word-by-word.
*
* @param dst Destination address to fill.
* @param cnt Number of words to fill.
* @param x Value to fill.
* @param dst Origin address to fill.
* @param cnt Number of words to fill.
* @param x Value to fill.
*
*/
void _memsetw(void *dst, size_t cnt, uint16_t x)
114,16 → 115,16
p[i] = x;
}
 
/** Copy string.
/** Copy string
*
* Copy string from src address to dst address. The copying is done
* char-by-char until the null character. The source and destination memory
* areas cannot overlap.
* Copy string from src address to dst address.
* The copying is done char-by-char until the null
* character. The source and destination memory areas
* cannot overlap.
*
* @param src Source string to copy from.
* @param dst Destination string to copy to.
* @param src Origin string to copy from.
* @param dst Origin string to copy to.
*
* @return Address of the destination string.
*/
char *strcpy(char *dest, const char *src)
{
/branches/sparc/kernel/generic/src/syscall/syscall.c
53,7 → 53,6
#include <syscall/copy.h>
#include <sysinfo/sysinfo.h>
#include <console/console.h>
#include <udebug/udebug.h>
 
/** Print using kernel facility
*
102,16 → 101,9
{
unative_t rc;
 
#ifdef CONFIG_UDEBUG
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
#endif
 
if (id < SYSCALL_END) {
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
if (id < SYSCALL_END)
rc = syscall_table[id](a1, a2, a3, a4, a5, a6);
} else {
else {
printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id);
task_kill(TASK->taskid);
thread_exit();
119,11 → 111,6
if (THREAD->interrupted)
thread_exit();
 
#ifdef CONFIG_UDEBUG
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
udebug_stoppable_end();
#endif
return rc;
}
178,9 → 165,7
(syshandler_t) sys_sysinfo_value,
/* Debug calls */
(syshandler_t) sys_debug_enable_console,
 
(syshandler_t) sys_ipc_connect_kbox
(syshandler_t) sys_debug_enable_console
};
 
/** @}
/branches/sparc/kernel/generic/src/console/cmd.c
398,17 → 398,17
.argc = 0
};
 
/* Data and methods for 'ipc' command */
static int cmd_ipc(cmd_arg_t *argv);
static cmd_arg_t ipc_argv = {
/* Data and methods for 'ipc_task' command */
static int cmd_ipc_task(cmd_arg_t *argv);
static cmd_arg_t ipc_task_argv = {
.type = ARG_TYPE_INT,
};
static cmd_info_t ipc_info = {
.name = "ipc",
.description = "ipc <taskid> Show IPC information of given task.",
.func = cmd_ipc,
static cmd_info_t ipc_task_info = {
.name = "ipc_task",
.description = "ipc_task <taskid> Show IPC information of given task.",
.func = cmd_ipc_task,
.argc = 1,
.argv = &ipc_argv
.argv = &ipc_task_argv
};
 
/* Data and methods for 'zone' command */
461,7 → 461,7
&uptime_info,
&halt_info,
&help_info,
&ipc_info,
&ipc_task_info,
&set4_info,
&slabs_info,
&symaddr_info,
937,7 → 937,7
*
* return Always 1
*/
int cmd_ipc(cmd_arg_t * argv) {
int cmd_ipc_task(cmd_arg_t * argv) {
ipc_print_task(argv[0].intval);
return 1;
}
/branches/sparc/kernel/generic/include/udebug/udebug_ipc.h
File deleted
/branches/sparc/kernel/generic/include/udebug/udebug.h
File deleted
/branches/sparc/kernel/generic/include/udebug/udebug_ops.h
File deleted
/branches/sparc/kernel/generic/include/ipc/kbox.h
File deleted
/branches/sparc/kernel/generic/include/ipc/ipc.h
195,12 → 195,6
*/
#define IPC_M_DATA_READ 7
 
/** Debug the recipient.
* - ARG1 - specifies the debug method (from udebug_method_t)
* - other arguments are specific to the debug method
*/
#define IPC_M_DEBUG_ALL 8
 
/* Well-known methods */
#define IPC_M_LAST_SYSTEM 511
#define IPC_M_PING 512
313,8 → 307,6
extern int ipc_phone_hangup(phone_t *);
extern void ipc_backsend_err(phone_t *, call_t *, unative_t);
extern void ipc_print_task(task_id_t);
extern void ipc_answerbox_slam_phones(answerbox_t *, bool);
extern void ipc_cleanup_call_list(link_t *);
 
extern answerbox_t *ipc_phone_0;
 
/branches/sparc/kernel/generic/include/ipc/sysipc.h
57,7 → 57,6
unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
irq_code_t *ucode);
unative_t sys_ipc_unregister_irq(inr_t inr, devno_t devno);
unative_t sys_ipc_connect_kbox(sysarg64_t *task_id);
 
#endif
 
/branches/sparc/kernel/generic/include/proc/task.h
52,7 → 52,6
#include <arch/cpu.h>
#include <mm/tlb.h>
#include <proc/scheduler.h>
#include <udebug/udebug.h>
 
struct thread;
 
94,20 → 93,6
* certain extent.
*/
atomic_t active_calls;
 
#ifdef CONFIG_UDEBUG
/** Debugging stuff */
udebug_task_t udebug;
 
/** Kernel answerbox */
answerbox_t kernel_box;
/** Thread used to service kernel answerbox */
struct thread *kb_thread;
/** Kbox thread creation vs. begin of cleanup mutual exclusion */
mutex_t kb_cleanup_lock;
/** True if cleanup of kbox has already started */
bool kb_finished;
#endif
/** Architecture specific task data. */
task_arch_t arch;
/branches/sparc/kernel/generic/include/proc/thread.h
46,7 → 46,6
#include <arch/cpu.h>
#include <mm/tlb.h>
#include <proc/uarg.h>
#include <udebug/udebug.h>
 
#define THREAD_STACK_SIZE STACK_SIZE
#define THREAD_NAME_BUFLEN 20
204,12 → 203,6
 
/** Thread's kernel stack. */
uint8_t *kstack;
 
#ifdef CONFIG_UDEBUG
/** Debugging stuff */
udebug_thread_t udebug;
#endif
 
} thread_t;
 
/** Thread list lock.
/branches/sparc/kernel/generic/include/syscall/syscall.h
78,7 → 78,6
SYS_SYSINFO_VALUE,
SYS_DEBUG_ENABLE_CONSOLE,
SYS_IPC_CONNECT_KBOX,
SYSCALL_END
} syscall_t;
 
/branches/sparc/kernel/kernel.config
149,8 → 149,6
# Virtually indexed D-cache support
! [ARCH=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n)
 
# Support for userspace debuggers
! CONFIG_UDEBUG (n/y)
 
## Debugging configuration directives
 
/branches/sparc/kernel/Makefile
44,7 → 44,7
 
GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) \
-fno-builtin -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Werror \
-nostdlib -nostdinc -pipe
-nostdlib -nostdinc
 
ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) \
-fno-builtin -Wall -Wmissing-prototypes -Werror \
150,10 → 150,6
endif
endif
 
ifeq ($(CONFIG_UDEBUG),y)
DEFS += -DCONFIG_UDEBUG
endif
 
## Simple detection for the type of the host system
#
HOST = $(shell uname)
287,17 → 283,6
generic/src/security/cap.c \
generic/src/sysinfo/sysinfo.c
 
## Udebug interface sources
#
 
ifeq ($(CONFIG_UDEBUG),y)
GENERIC_SOURCES += \
generic/src/ipc/kbox.c \
generic/src/udebug/udebug.c \
generic/src/udebug/udebug_ops.c \
generic/src/udebug/udebug_ipc.c
endif
 
## Test sources
#
 
365,7 → 350,7
ln -sfn ../../genarch/include/ generic/include/genarch
 
depend: archlinks
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
-makedepend $(DEFS) $(CFLAGS) -f - $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
 
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in
$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -D__LINKER__ -E -x c $< | grep -v "^\#" > $@