From cfa70adda5479cb3ac144ad8b0e43184319bd909 Mon Sep 17 00:00:00 2001 From: Jakub Jermar Date: Sun, 3 Sep 2006 23:37:14 +0000 Subject: [PATCH] sparc64 update. - Prototype userspace layer implementation that at least relates to sparc64 and compiles cleanly. - Fixes for kernel's preemptible_handler and code related to running userspace. - Enable userspace. Several dozen instructions are now run in userspace! We are pretty near the userspace milestone for sparc64. --- boot/arch/sparc64/loader/Makefile | 10 +++- kernel/arch/sparc64/include/asm.h | 2 +- kernel/arch/sparc64/include/mm/as.h | 2 +- kernel/arch/sparc64/include/mm/tlb.h | 2 +- kernel/arch/sparc64/include/trap/mmu.h | 19 ++++--- kernel/arch/sparc64/src/asm.S | 8 +++ kernel/arch/sparc64/src/context.S | 1 - kernel/arch/sparc64/src/mm/tlb.c | 4 +- kernel/arch/sparc64/src/proc/scheduler.c | 2 - kernel/arch/sparc64/src/sparc64.c | 16 +++++- kernel/arch/sparc64/src/start.S | 3 ++ kernel/arch/sparc64/src/trap/trap_table.S | 30 +++++++---- kernel/generic/src/proc/task.c | 2 +- uspace/libc/arch/sparc64/_link.ld.in | 12 +++-- uspace/libc/arch/sparc64/include/atomic.h | 61 ++++++++++++++++------ uspace/libc/arch/sparc64/include/config.h | 4 +- uspace/libc/arch/sparc64/include/context_offset.h | 22 +++++++- uspace/libc/arch/sparc64/include/endian.h | 9 ++-- uspace/libc/arch/sparc64/include/limits.h | 4 +- uspace/libc/arch/sparc64/include/psthread.h | 59 ++++++++++++++------- .../libc/arch/sparc64/include/stack.h | 25 +++++---- uspace/libc/arch/sparc64/include/stackarg.h | 5 +- uspace/libc/arch/sparc64/include/syscall.h | 2 +- uspace/libc/arch/sparc64/include/thread.h | 31 +++++++---- uspace/libc/arch/sparc64/include/types.h | 8 +-- uspace/libc/arch/sparc64/src/entry.s | 16 ++++++ .../libc/arch/sparc64/src/psthread.S | 19 +++---- uspace/libc/arch/sparc64/src/thread.c | 19 ++++--- uspace/libc/arch/sparc64/src/thread_entry.s | 9 +++- 29 files changed, 274 insertions(+), 132 deletions(-) copy kernel/arch/sparc64/include/mm/as.h => uspace/libc/arch/sparc64/include/stack.h (74%) copy kernel/arch/sparc64/src/context.S => uspace/libc/arch/sparc64/src/psthread.S (92%) diff --git a/boot/arch/sparc64/loader/Makefile b/boot/arch/sparc64/loader/Makefile index b356d8cce..00aa0ea9a 100644 --- a/boot/arch/sparc64/loader/Makefile +++ b/boot/arch/sparc64/loader/Makefile @@ -57,7 +57,15 @@ SOURCES = \ boot.S COMPONENTS = \ - $(KERNELDIR)/kernel.bin + $(KERNELDIR)/kernel.bin \ + $(USPACEDIR)/ns/ns \ + $(USPACEDIR)/init/init \ + $(USPACEDIR)/fb/fb \ + $(USPACEDIR)/kbd/kbd \ + $(USPACEDIR)/console/console \ + $(USPACEDIR)/tetris/tetris \ + $(USPACEDIR)/ipcc/ipcc \ + $(USPACEDIR)/klog/klog OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS)))) diff --git a/kernel/arch/sparc64/include/asm.h b/kernel/arch/sparc64/include/asm.h index 83a7d7c1f..e084c105f 100644 --- a/kernel/arch/sparc64/include/asm.h +++ b/kernel/arch/sparc64/include/asm.h @@ -330,7 +330,7 @@ extern void write_to_ag_g6(uint64_t val); extern void write_to_ag_g7(uint64_t val); extern void write_to_ig_g6(uint64_t val); -extern void switch_to_userspace(uint64_t pc, uint64_t sp); +extern void switch_to_userspace(uint64_t pc, uint64_t sp, uint64_t uarg); #endif diff --git a/kernel/arch/sparc64/include/mm/as.h b/kernel/arch/sparc64/include/mm/as.h index ed1208427..645f49843 100644 --- a/kernel/arch/sparc64/include/mm/as.h +++ b/kernel/arch/sparc64/include/mm/as.h @@ -42,7 +42,7 @@ #define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000 #define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffff -#define USTACK_ADDRESS_ARCH (0x7fffffffffffffff-(PAGE_SIZE-1)) +#define USTACK_ADDRESS_ARCH (0xffffffffffffffffULL-(PAGE_SIZE-1)) extern void as_arch_init(void); diff --git a/kernel/arch/sparc64/include/mm/tlb.h b/kernel/arch/sparc64/include/mm/tlb.h index 0f3e28de4..e159cc717 100644 --- a/kernel/arch/sparc64/include/mm/tlb.h +++ b/kernel/arch/sparc64/include/mm/tlb.h @@ -179,7 +179,7 @@ static inline uint64_t mmu_secondary_context_read(void) */ static inline void mmu_secondary_context_write(uint64_t v) { - asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v); + asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v); flush(); } diff --git a/kernel/arch/sparc64/include/trap/mmu.h b/kernel/arch/sparc64/include/trap/mmu.h index df33853b8..449b6137f 100644 --- a/kernel/arch/sparc64/include/trap/mmu.h +++ b/kernel/arch/sparc64/include/trap/mmu.h @@ -127,17 +127,16 @@ */ .macro HANDLE_MMU_TRAPS_FROM_SPILL_OR_FILL rdpr %tl, %g1 - dec %g1 - brz %g1, 0f ! if TL was 1, skip + sub %g1, 1, %g2 + brz %g2, 0f ! if TL was 1, skip nop - wrpr %g1, 0, %tl ! TL-- - rdpr %tt, %g2 - cmp %g2, TT_SPILL_1_NORMAL - be 0f ! trap from spill_1_normal - cmp %g2, TT_FILL_1_NORMAL - be 0f ! trap from fill_1_normal - inc %g1 - wrpr %g1, 0, %tl ! another trap, TL++ + wrpr %g2, 0, %tl ! TL-- + rdpr %tt, %g3 + cmp %g3, TT_SPILL_1_NORMAL + be 0f ! trap from spill_1_normal? + cmp %g3, TT_FILL_1_NORMAL + bne,a 0f ! trap from fill_1_normal? (negated condition) + wrpr %g1, 0, %tl ! TL++ 0: .endm diff --git a/kernel/arch/sparc64/src/asm.S b/kernel/arch/sparc64/src/asm.S index db42cb526..b22d42936 100644 --- a/kernel/arch/sparc64/src/asm.S +++ b/kernel/arch/sparc64/src/asm.S @@ -150,6 +150,7 @@ read_from_ag_g7: * * %o0 Userspace entry address. * %o1 Userspace stack pointer address. + * %o2 Userspace address of uarg structure. */ .global switch_to_userspace switch_to_userspace: @@ -157,6 +158,8 @@ switch_to_userspace: wrpr %g0, 0, %cleanwin ! avoid information leak save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp + mov %i3, %o0 ! uarg + clr %i2 clr %i3 clr %i4 @@ -178,5 +181,10 @@ switch_to_userspace: ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1 stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi flush %i7 + + /* + * Spills and fills will be handled by the userspace handlers. + */ + wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate done ! jump to userspace diff --git a/kernel/arch/sparc64/src/context.S b/kernel/arch/sparc64/src/context.S index 8adac849b..9dfbdcbd8 100644 --- a/kernel/arch/sparc64/src/context.S +++ b/kernel/arch/sparc64/src/context.S @@ -27,7 +27,6 @@ # #include -#include /** * Both context_save_arch() and context_restore_arch() are diff --git a/kernel/arch/sparc64/src/mm/tlb.c b/kernel/arch/sparc64/src/mm/tlb.c index f19b72493..f277b3691 100644 --- a/kernel/arch/sparc64/src/mm/tlb.c +++ b/kernel/arch/sparc64/src/mm/tlb.c @@ -136,7 +136,7 @@ void dtlb_pte_copy(pte_t *t, bool ro) data.l = false; data.cp = t->c; data.cv = t->c; - data.p = t->p; + data.p = t->k; /* p like privileged */ data.w = ro ? false : t->w; data.g = t->g; @@ -166,7 +166,7 @@ void itlb_pte_copy(pte_t *t) data.l = false; data.cp = t->c; data.cv = t->c; - data.p = t->p; + data.p = t->k; /* p like privileged */ data.w = false; data.g = t->g; diff --git a/kernel/arch/sparc64/src/proc/scheduler.c b/kernel/arch/sparc64/src/proc/scheduler.c index 9919abe2c..2cf02f728 100644 --- a/kernel/arch/sparc64/src/proc/scheduler.c +++ b/kernel/arch/sparc64/src/proc/scheduler.c @@ -126,8 +126,6 @@ void after_thread_ran_arch(void) */ ASSERT(THREAD->arch.uspace_window_buffer); - flushw(); /* force all userspace windows into memory */ - uintptr_t uw_buf = ALIGN_DOWN((uintptr_t) THREAD->arch.uspace_window_buffer, PAGE_SIZE); if (!overlaps(uw_buf, PAGE_SIZE, base, 1<uspace_entry, ((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE - - (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS)); + - (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS), + (uintptr_t) kernel_uarg->uspace_uarg); for (;;) ; diff --git a/kernel/arch/sparc64/src/start.S b/kernel/arch/sparc64/src/start.S index eb9121868..30df39580 100644 --- a/kernel/arch/sparc64/src/start.S +++ b/kernel/arch/sparc64/src/start.S @@ -208,6 +208,9 @@ kernel_image_start: ! set TL back to 0 wrpr %g0, 0, %tl + + call arch_pre_main + nop call main_bsp nop diff --git a/kernel/arch/sparc64/src/trap/trap_table.S b/kernel/arch/sparc64/src/trap/trap_table.S index 2719d2fad..3c624b73e 100644 --- a/kernel/arch/sparc64/src/trap/trap_table.S +++ b/kernel/arch/sparc64/src/trap/trap_table.S @@ -218,6 +218,12 @@ spill_1_normal: spill_2_normal: SPILL_TO_USPACE_WINDOW_BUFFER +/* TT = 0xa0, TL = 0, spill_0_other handler */ +.org trap_table + TT_SPILL_0_OTHER*ENTRY_SIZE +.global spill_0_other +spill_0_other: + SPILL_TO_USPACE_WINDOW_BUFFER + /* TT = 0xc0, TL = 0, fill_0_normal handler */ .org trap_table + TT_FILL_0_NORMAL*ENTRY_SIZE .global fill_0_normal @@ -547,12 +553,12 @@ fill_0_normal_high: .endif /* - * Mark the CANSAVE windows as OTHER windows. + * Mark the CANRESTORE windows as OTHER windows. * Set CLEANWIN to NWINDOW-1 so that clean_window traps do not occur. */ - rdpr %cansave, %l0 + rdpr %canrestore, %l0 wrpr %l0, %otherwin - wrpr %g0, %cansave + wrpr %g0, %canrestore wrpr %g0, NWINDOW - 1, %cleanwin /* @@ -641,8 +647,10 @@ fill_0_normal_high: /* * If OTHERWIN is zero, then all the userspace windows have been - * spilled to kernel memory (i.e. register window buffer). If - * OTHERWIN is non-zero, then some userspace windows are still + * spilled to kernel memory (i.e. register window buffer). Moreover, + * if the scheduler was called in the meantime, all valid windows + * belonging to other threads were spilled by context_restore(). + * If OTHERWIN is non-zero, then some userspace windows are still * valid. Others might have been spilled. However, the CWP pointer * needs no fixing because the scheduler had not been called. */ @@ -659,7 +667,7 @@ fill_0_normal_high: */ and %g1, TSTATE_CWP_MASK, %l0 inc %l0 - and %l0, TSTATE_CWP_MASK, %l0 ! %l0 mod NWINDOW + and %l0, NWINDOW - 1, %l0 ! %l0 mod NWINDOW rdpr %cwp, %l1 cmp %l0, %l1 bz 0f ! CWP is ok @@ -667,13 +675,12 @@ fill_0_normal_high: /* * Fix CWP. - * Just for reminder, the input registers in the current window - * are the output registers of the window to which we want to - * restore. Because the fill trap fills only input and local + * In order to recapitulate, the input registers in the current + * window are the output registers of the window to which we want + * to restore. Because the fill trap fills only input and local * registers of a window, we need to preserve those output * registers manually. */ - flushw mov %sp, %g2 stx %i0, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0] stx %i1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1] @@ -738,7 +745,8 @@ fill_0_normal_high: * Fill all windows stored in the buffer. */ clr %g4 -0: andcc %g7, PAGE_WIDTH - 1, %g0 ! PAGE_SIZE alignment check + 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 diff --git a/kernel/generic/src/proc/task.c b/kernel/generic/src/proc/task.c index 4f3d62c15..c344d4fab 100644 --- a/kernel/generic/src/proc/task.c +++ b/kernel/generic/src/proc/task.c @@ -220,7 +220,7 @@ task_t * task_run_program(void *program_addr, char *name) /* * Create the main thread. */ - t1 = thread_create(uinit, kernel_uarg, task, 0, "uinit"); + t1 = thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE, "uinit"); ASSERT(t1); /* diff --git a/uspace/libc/arch/sparc64/_link.ld.in b/uspace/libc/arch/sparc64/_link.ld.in index dde3ee275..e0eac0ecc 100644 --- a/uspace/libc/arch/sparc64/_link.ld.in +++ b/uspace/libc/arch/sparc64/_link.ld.in @@ -7,9 +7,9 @@ PHDRS { } SECTIONS { - . = 0x1000; + . = 0x2000; - .init ALIGN(0x1000) : SUBALIGN(0x1000) { + .init ALIGN(0x2000) : SUBALIGN(0x2000) { *(.init); } :text .text : { @@ -17,7 +17,11 @@ SECTIONS { *(.rodata*); } :text - .data ALIGN(0x1000) : SUBALIGN(0x1000) { + .got ALIGN(0x2000) : SUBALIGN(0x2000) { + _gp = .; + *(.got*); + } :data + .data ALIGN(0x2000) : SUBALIGN(0x2000) { *(.data); *(.sdata); } :data @@ -37,7 +41,7 @@ SECTIONS { *(.bss); } :data - . = ALIGN(0x1000); + . = ALIGN(0x2000); _heap = .; /DISCARD/ : { diff --git a/uspace/libc/arch/sparc64/include/atomic.h b/uspace/libc/arch/sparc64/include/atomic.h index be132c703..b214d5724 100644 --- a/uspace/libc/arch/sparc64/include/atomic.h +++ b/uspace/libc/arch/sparc64/include/atomic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 Martin Decky + * Copyright (C) 2005 Jakub Jermar * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,45 +26,74 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** @addtogroup libcsparc64 +/** @addtogroup libcsparc64 * @{ */ /** @file */ -#ifndef __sparc64_ATOMIC_H__ -#define __sparc64_ATOMIC_H__ +#ifndef LIBC_sparc64_ATOMIC_H_ +#define LIBC_sparc64_ATOMIC_H_ -static inline void atomic_inc(atomic_t *val) +#include + +/** Atomic add operation. + * + * Use atomic compare and swap operation to atomically add signed value. + * + * @param val Atomic variable. + * @param i Signed value to be added. + * + * @return Value of the atomic variable as it existed before addition. + */ +static inline long atomic_add(atomic_t *val, int i) { + uint64_t a, b; + volatile uint64_t x = (uint64_t) &val->count; + + __asm__ volatile ( + "0:\n" + "ldx %0, %1\n" + "add %1, %3, %2\n" + "casx %0, %1, %2\n" + "cmp %1, %2\n" + "bne 0b\n" /* The operation failed and must be attempted again if a != b. */ + "nop\n" + : "=m" (*((uint64_t *)x)), "=r" (a), "=r" (b) + : "r" (i) + ); + + return a; } -static inline void atomic_dec(atomic_t *val) +static inline long atomic_preinc(atomic_t *val) { + return atomic_add(val, 1) + 1; } static inline long atomic_postinc(atomic_t *val) { - atomic_inc(val); - return val->count - 1; + return atomic_add(val, 1); +} + +static inline long atomic_predec(atomic_t *val) +{ + return atomic_add(val, -1) - 1; } static inline long atomic_postdec(atomic_t *val) { - atomic_dec(val); - return val->count + 1; + return atomic_add(val, -1); } -static inline long atomic_preinc(atomic_t *val) +static inline void atomic_inc(atomic_t *val) { - atomic_inc(val); - return val->count; + (void) atomic_add(val, 1); } -static inline long atomic_predec(atomic_t *val) +static inline void atomic_dec(atomic_t *val) { - atomic_dec(val); - return val->count; + (void) atomic_add(val, -1); } #endif diff --git a/uspace/libc/arch/sparc64/include/config.h b/uspace/libc/arch/sparc64/include/config.h index 2a72fa9f6..9975309b1 100644 --- a/uspace/libc/arch/sparc64/include/config.h +++ b/uspace/libc/arch/sparc64/include/config.h @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** @addtogroup libsparc64 +/** @addtogroup libcsparc64 * @{ */ /** @file @@ -35,7 +35,7 @@ #ifndef LIBC_sparc64_CONFIG_H_ #define LIBC_sparc64_CONFIG_H_ -#define PAGE_WIDTH 12 +#define PAGE_WIDTH 13 #define PAGE_SIZE (1< directly - use instead." @@ -43,6 +43,5 @@ #endif - /** @} +/** @} */ - diff --git a/uspace/libc/arch/sparc64/include/limits.h b/uspace/libc/arch/sparc64/include/limits.h index 262b82299..971b29eb8 100644 --- a/uspace/libc/arch/sparc64/include/limits.h +++ b/uspace/libc/arch/sparc64/include/limits.h @@ -32,8 +32,8 @@ /** @file */ -#ifndef __sparc64__LIMITS_H__ -#define __sparc64__LIMITS_H__ +#ifndef LIBC_sparc64__LIMITS_H_ +#define LIBC_sparc64__LIMITS_H_ #define LONG_MIN MIN_INT64 #define LONG_MAX MAX_INT64 diff --git a/uspace/libc/arch/sparc64/include/psthread.h b/uspace/libc/arch/sparc64/include/psthread.h index 76292b4bd..01f30d128 100644 --- a/uspace/libc/arch/sparc64/include/psthread.h +++ b/uspace/libc/arch/sparc64/include/psthread.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Martin Decky + * Copyright (C) 2005 Jakub Jermar * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,35 +26,56 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** @addtogroup libcsparc64 +/** @addtogroup libcsparc64 * @{ */ /** @file */ -#ifndef __LIBC__sparc64__PSTHREAD_H__ -#define __LIBC__sparc64__PSTHREAD_H__ +#ifndef LIBC_sparc64_PSTHREAD_H_ +#define LIBC_sparc64_PSTHREAD_H_ +#include #include +#include -/* We define our own context_set, because we need to set - * the TLS pointer to the tcb+0x7000 - * - * See tls_set in thread.h - */ -#define context_set(c, _pc, stack, size, ptls) \ - (c)->pc = (sysarg_t) (_pc); \ - (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \ - (c)->tls = ((sysarg_t) (ptls)) + 0x7000 + sizeof(tcb_t); +#define SP_DELTA STACK_WINDOW_SAVE_AREA_SIZE -#define SP_DELTA 16 +#ifdef context_set +#undef context_set +#endif -typedef struct { - uint64_t sp; - uint64_t pc; +#define context_set(c, _pc, stack, size, ptls) \ + (c)->pc = ((uintptr_t) _pc) - 8; \ + (c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA); \ + (c)->fp = -STACK_BIAS; \ + (c)->tp = ptls - uint64_t tls; -} __attribute__ ((packed)) context_t; +/* + * Only save registers that must be preserved across + * function calls. + */ +typedef struct { + uintptr_t sp; /* %o6 */ + uintptr_t pc; /* %o7 */ + uint64_t i0; + uint64_t i1; + uint64_t i2; + uint64_t i3; + uint64_t i4; + uint64_t i5; + uintptr_t fp; /* %i6 */ + uintptr_t i7; + uint64_t l0; + uint64_t l1; + uint64_t l2; + uint64_t l3; + uint64_t l4; + uint64_t l5; + uint64_t l6; + uint64_t l7; + uint64_t tp; /* %g7 */ +} context_t; #endif diff --git a/kernel/arch/sparc64/include/mm/as.h b/uspace/libc/arch/sparc64/include/stack.h similarity index 74% copy from kernel/arch/sparc64/include/mm/as.h copy to uspace/libc/arch/sparc64/include/stack.h index ed1208427..fe161f68f 100644 --- a/kernel/arch/sparc64/include/mm/as.h +++ b/uspace/libc/arch/sparc64/include/stack.h @@ -26,28 +26,31 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** @addtogroup sparc64mm +/** @addtogroup libcsparc64 * @{ */ /** @file */ -#ifndef KERN_sparc64_AS_H_ -#define KERN_sparc64_AS_H_ +#ifndef LIBC_sparc64_STACK_H_ +#define LIBC_sparc64_STACK_H_ -#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 1 +#define STACK_ITEM_SIZE 8 -#define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000 -#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffff -#define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000 -#define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffff +/** According to SPARC Compliance Definition, every stack frame is 16-byte aligned. */ +#define STACK_ALIGNMENT 16 -#define USTACK_ADDRESS_ARCH (0x7fffffffffffffff-(PAGE_SIZE-1)) +/** + * 16-extended-word save area for %i[0-7] and %l[0-7] registers. + */ +#define STACK_WINDOW_SAVE_AREA_SIZE (16*STACK_ITEM_SIZE) -extern void as_arch_init(void); +/** + * By convention, the actual top of the stack is %sp + STACK_BIAS. + */ +#define STACK_BIAS 2047 #endif /** @} */ - diff --git a/uspace/libc/arch/sparc64/include/stackarg.h b/uspace/libc/arch/sparc64/include/stackarg.h index d208b1750..23707b102 100644 --- a/uspace/libc/arch/sparc64/include/stackarg.h +++ b/uspace/libc/arch/sparc64/include/stackarg.h @@ -32,11 +32,10 @@ /** @file */ -#ifndef __LIBC__STACKARG_H__ -#define __LIBC__STACKARG_H__ +#ifndef LIBC_sparc64_STACKARG_H_ +#define LIBC_sparc64_STACKARG_H_ #endif - /** @} */ diff --git a/uspace/libc/arch/sparc64/include/syscall.h b/uspace/libc/arch/sparc64/include/syscall.h index 2c9644e5f..7a442eb4b 100644 --- a/uspace/libc/arch/sparc64/include/syscall.h +++ b/uspace/libc/arch/sparc64/include/syscall.h @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** @addtogroup libc +/** @addtogroup libcsparc64 * @{ */ /** @file diff --git a/uspace/libc/arch/sparc64/include/thread.h b/uspace/libc/arch/sparc64/include/thread.h index 8dd11b37b..3e2a3c3fe 100644 --- a/uspace/libc/arch/sparc64/include/thread.h +++ b/uspace/libc/arch/sparc64/include/thread.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2006 Martin Decky + * Copyright (C) 2006 Ondrej Palkovsky + * Copyright (C) 2006 Jakub Jermar * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,30 +27,38 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** @addtogroup libcsparc64 +/** @addtogroup libcsparc64 * @{ */ -/** @file +/** + * @file + * @brief sparc64 TLS functions. + * + * The implementation is based on the IA-32 implementation which was also + * designed by Sun and is virtually the same, except the TCB is stored in + * %g7 (of the normal set). */ -#ifndef __LIBC__sparc64__THREAD_H__ -#define __LIBC__sparc64__THREAD_H__ - -#define PPC_TP_OFFSET 0x7000 +#ifndef LIBC_sparc64_THREAD_H_ +#define LIBC_sparc64_THREAD_H_ typedef struct { + void *self; void *pst_data; } tcb_t; static inline void __tcb_set(tcb_t *tcb) { - void *tp = tcb; - tp += PPC_TP_OFFSET + sizeof(tcb_t); + __asm__ volatile ("mov %0, %%g7\n" : : "r" (tcb) : "g7"); } -static inline tcb_t *__tcb_get(void) +static inline tcb_t * __tcb_get(void) { - return (tcb_t *)(PPC_TP_OFFSET - sizeof(tcb_t)); + void *retval; + + __asm__ volatile ("mov %%g7, %0\n" : "=r" (retval)); + + return retval; } #endif diff --git a/uspace/libc/arch/sparc64/include/types.h b/uspace/libc/arch/sparc64/include/types.h index c059f8ccd..efafa94c1 100644 --- a/uspace/libc/arch/sparc64/include/types.h +++ b/uspace/libc/arch/sparc64/include/types.h @@ -35,12 +35,12 @@ #ifndef LIBC_sparc64_TYPES_H_ #define LIBC_sparc64_TYPES_H_ -typedef unsigned int sysarg_t; -typedef unsigned int size_t; -typedef signed int ssize_t; +typedef unsigned long sysarg_t; +typedef unsigned long size_t; +typedef signed long ssize_t; typedef ssize_t off_t; -typedef char int8_t; +typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; typedef long int int64_t; diff --git a/uspace/libc/arch/sparc64/src/entry.s b/uspace/libc/arch/sparc64/src/entry.s index b38e29519..07e5cf585 100644 --- a/uspace/libc/arch/sparc64/src/entry.s +++ b/uspace/libc/arch/sparc64/src/entry.s @@ -37,5 +37,21 @@ # # __entry: + sethi %hi(_gp), %l7 + call __main + or %l7, %lo(_gp), %l7 + call __io_init + nop + call main + nop + call __exit + nop __entry_driver: + sethi %hi(_gp), %l7 + call __main + or %l7, %lo(_gp), %l7 + call main + nop + call __exit + nop diff --git a/kernel/arch/sparc64/src/context.S b/uspace/libc/arch/sparc64/src/psthread.S similarity index 92% copy from kernel/arch/sparc64/src/context.S copy to uspace/libc/arch/sparc64/src/psthread.S index 8adac849b..5cdcb411b 100644 --- a/kernel/arch/sparc64/src/context.S +++ b/uspace/libc/arch/sparc64/src/psthread.S @@ -26,8 +26,7 @@ # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -#include -#include +#include /** * Both context_save_arch() and context_restore_arch() are @@ -39,8 +38,8 @@ .text -.global context_save_arch -.global context_restore_arch +.global context_save +.global context_restore .macro CONTEXT_STORE r stx %sp, [\r + OFFSET_SP] @@ -61,8 +60,7 @@ stx %l5, [\r + OFFSET_L5] stx %l6, [\r + OFFSET_L6] stx %l7, [\r + OFFSET_L7] - rdpr %cleanwin, %g1 - stx %g1, [\r + OFFSET_CLEANWIN] + stx %g7, [\r + OFFSET_TP] .endm .macro CONTEXT_LOAD r @@ -84,23 +82,22 @@ ldx [\r + OFFSET_L5], %l5 ldx [\r + OFFSET_L6], %l6 ldx [\r + OFFSET_L7], %l7 - ldx [\r + OFFSET_CLEANWIN], %g1 - wrpr %g1, %g0, %cleanwin + ldx [\r + OFFSET_TP], %g7 .endm -context_save_arch: +context_save: CONTEXT_STORE %o0 retl mov 1, %o0 ! context_save_arch returns 1 -context_restore_arch: +context_restore: # # Flush all active windows. # This is essential, because CONTEXT_LOAD overwrites # %sp of CWP - 1 with the value written to %fp of CWP. # Flushing all active windows mitigates this problem # as CWP - 1 becomes the overlap window. - # + # flushw CONTEXT_LOAD %o0 diff --git a/uspace/libc/arch/sparc64/src/thread.c b/uspace/libc/arch/sparc64/src/thread.c index bdea304c0..e189625a7 100644 --- a/uspace/libc/arch/sparc64/src/thread.c +++ b/uspace/libc/arch/sparc64/src/thread.c @@ -26,10 +26,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** @addtogroup libcsparc64 +/** @addtogroup libcsparc64 sparc64 + * @ingroup lc * @{ */ /** @file + * */ #include @@ -39,20 +41,23 @@ * * @param data Start of data section * @return pointer to tcb_t structure - * */ tcb_t * __alloc_tls(void **data, size_t size) { - tcb_t *result; + tcb_t *tcb; + + *data = malloc(sizeof(tcb_t) + size); + + tcb = (tcb_t *) (*data + size); + tcb->self = tcb; - result = malloc(sizeof(tcb_t) + size); - *data = ((void *)result) + sizeof(tcb_t); - return result; + return tcb; } void __free_tls_arch(tcb_t *tcb, size_t size) { - free(tcb); + void *start = ((void *)tcb) - size; + free(start); } /** @} diff --git a/uspace/libc/arch/sparc64/src/thread_entry.s b/uspace/libc/arch/sparc64/src/thread_entry.s index 29fbdfdc5..448771bc5 100644 --- a/uspace/libc/arch/sparc64/src/thread_entry.s +++ b/uspace/libc/arch/sparc64/src/thread_entry.s @@ -1,5 +1,5 @@ # -# Copyright (C) 2006 Martin Decky +# Copyright (C) 2006 Jakub Jermar # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -34,5 +34,10 @@ # # __thread_entry: - + sethi %hi(_gp), %l7 + call __thread_main ! %o0 contains address of uarg + or %l7, %lo(_gp), %l7 + + ! not reached + .end __thread_entry -- 2.11.4.GIT