/trunk/kernel/arch/sparc64/include/asm.h |
---|
321,10 → 321,15 |
__asm__ volatile ("flushw\n"); |
} |
void cpu_halt(void); |
void cpu_sleep(void); |
void asm_delay_loop(uint32_t t); |
extern void cpu_halt(void); |
extern void cpu_sleep(void); |
extern void asm_delay_loop(uint32_t t); |
extern uint64_t read_from_ag_g7(void); |
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); |
#endif |
/** @} |
/trunk/kernel/arch/sparc64/include/trap/regwin.h |
---|
41,8 → 41,12 |
#include <arch/arch.h> |
#define TT_CLEAN_WINDOW 0x24 |
#define TT_SPILL_0_NORMAL 0x80 |
#define TT_FILL_0_NORMAL 0xc0 |
#define TT_SPILL_0_NORMAL 0x80 /* kernel spills */ |
#define TT_SPILL_1_NORMAL 0x84 /* userspace spills */ |
#define TT_SPILL_2_NORMAL 0x88 /* spills to userspace window buffer */ |
#define TT_SPILL_0_OTHER 0xa0 /* spills to userspace window buffer */ |
#define TT_FILL_0_NORMAL 0xc0 /* kernel fills */ |
#define TT_FILL_1_NORMAL 0xc4 /* userspace fills */ |
#define REGWIN_HANDLER_SIZE 128 |
98,7 → 102,7 |
* Macro used by the userspace during normal spills. |
*/ |
.macro SPILL_NORMAL_HANDLER_USERSPACE |
wr ASI_AIUP, %asi |
wr %g0, ASI_AIUP, %asi |
stxa %l0, [%sp + STACK_BIAS + L0_OFFSET] %asi |
stxa %l1, [%sp + STACK_BIAS + L1_OFFSET] %asi |
stxa %l2, [%sp + STACK_BIAS + L2_OFFSET] %asi |
120,26 → 124,29 |
.endm |
/* |
* Macro used by the userspace during other spills. |
* Macro used to spill userspace window to userspace window buffer. |
* It can be either triggered from preemptible_handler doing SAVE |
* at (TL=1) or from normal kernel code doing SAVE when OTHERWIN>0 |
* at (TL=0). |
*/ |
.macro SPILL_OTHER_HANDLER_USERSPACE |
wr ASI_AIUS, %asi |
stxa %l0, [%sp + STACK_BIAS + L0_OFFSET] %asi |
stxa %l1, [%sp + STACK_BIAS + L1_OFFSET] %asi |
stxa %l2, [%sp + STACK_BIAS + L2_OFFSET] %asi |
stxa %l3, [%sp + STACK_BIAS + L3_OFFSET] %asi |
stxa %l4, [%sp + STACK_BIAS + L4_OFFSET] %asi |
stxa %l5, [%sp + STACK_BIAS + L5_OFFSET] %asi |
stxa %l6, [%sp + STACK_BIAS + L6_OFFSET] %asi |
stxa %l7, [%sp + STACK_BIAS + L7_OFFSET] %asi |
stxa %i0, [%sp + STACK_BIAS + I0_OFFSET] %asi |
stxa %i1, [%sp + STACK_BIAS + I1_OFFSET] %asi |
stxa %i2, [%sp + STACK_BIAS + I2_OFFSET] %asi |
stxa %i3, [%sp + STACK_BIAS + I3_OFFSET] %asi |
stxa %i4, [%sp + STACK_BIAS + I4_OFFSET] %asi |
stxa %i5, [%sp + STACK_BIAS + I5_OFFSET] %asi |
stxa %i6, [%sp + STACK_BIAS + I6_OFFSET] %asi |
stxa %i7, [%sp + STACK_BIAS + I7_OFFSET] %asi |
.macro SPILL_TO_USPACE_WINDOW_BUFFER |
stx %l0, [%g7 + L0_OFFSET] |
stx %l1, [%g7 + L1_OFFSET] |
stx %l2, [%g7 + L2_OFFSET] |
stx %l3, [%g7 + L3_OFFSET] |
stx %l4, [%g7 + L4_OFFSET] |
stx %l5, [%g7 + L5_OFFSET] |
stx %l6, [%g7 + L6_OFFSET] |
stx %l7, [%g7 + L7_OFFSET] |
stx %i0, [%g7 + I0_OFFSET] |
stx %i1, [%g7 + I1_OFFSET] |
stx %i2, [%g7 + I2_OFFSET] |
stx %i3, [%g7 + I3_OFFSET] |
stx %i4, [%g7 + I4_OFFSET] |
stx %i5, [%g7 + I5_OFFSET] |
stx %i6, [%g7 + I6_OFFSET] |
stx %i7, [%g7 + I7_OFFSET] |
add %g7, STACK_WINDOW_SAVE_AREA_SIZE, %g7 |
saved |
retry |
.endm |
173,7 → 180,7 |
* Macro used by the userspace during normal fills. |
*/ |
.macro FILL_NORMAL_HANDLER_USERSPACE |
wr ASI_AIUP, %asi |
wr %g0, ASI_AIUP, %asi |
ldxa [%sp + STACK_BIAS + L0_OFFSET] %asi, %l0 |
ldxa [%sp + STACK_BIAS + L1_OFFSET] %asi, %l1 |
ldxa [%sp + STACK_BIAS + L2_OFFSET] %asi, %l2 |
194,31 → 201,6 |
retry |
.endm |
/* |
* Macro used by the userspace during other fills. |
*/ |
.macro FILL_OTHER_HANDLER_USERSPACE |
wr ASI_AIUS, %asi |
ldxa [%sp + STACK_BIAS + L0_OFFSET] %asi, %l0 |
ldxa [%sp + STACK_BIAS + L1_OFFSET] %asi, %l1 |
ldxa [%sp + STACK_BIAS + L2_OFFSET] %asi, %l2 |
ldxa [%sp + STACK_BIAS + L3_OFFSET] %asi, %l3 |
ldxa [%sp + STACK_BIAS + L4_OFFSET] %asi, %l4 |
ldxa [%sp + STACK_BIAS + L5_OFFSET] %asi, %l5 |
ldxa [%sp + STACK_BIAS + L6_OFFSET] %asi, %l6 |
ldxa [%sp + STACK_BIAS + L7_OFFSET] %asi, %l7 |
ldxa [%sp + STACK_BIAS + I0_OFFSET] %asi, %i0 |
ldxa [%sp + STACK_BIAS + I1_OFFSET] %asi, %i1 |
ldxa [%sp + STACK_BIAS + I2_OFFSET] %asi, %i2 |
ldxa [%sp + STACK_BIAS + I3_OFFSET] %asi, %i3 |
ldxa [%sp + STACK_BIAS + I4_OFFSET] %asi, %i4 |
ldxa [%sp + STACK_BIAS + I5_OFFSET] %asi, %i5 |
ldxa [%sp + STACK_BIAS + I6_OFFSET] %asi, %i6 |
ldxa [%sp + STACK_BIAS + I7_OFFSET] %asi, %i7 |
restored |
retry |
.endm |
.macro CLEAN_WINDOW_HANDLER |
rdpr %cleanwin, %l0 |
add %l0, 1, %l0 |
/trunk/kernel/arch/sparc64/include/context.h |
---|
54,8 → 54,8 |
#endif |
#define context_set(c, _pc, stack, size) \ |
(c)->pc = ((uintptr_t) _pc) - 8; \ |
(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA); \ |
(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)->cleanwin = 0 |
/trunk/kernel/arch/sparc64/src/asm.S |
---|
106,3 → 106,40 |
memsetb: |
b _memsetb |
nop |
.macro WRITE_ALTERNATE_REGISTER reg, bit |
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp |
rdpr %pstate, %l0 |
wrpr %l0, \bit, %pstate |
mov %i0, \reg |
wrpr %l0, 0, %pstate |
ret |
restore |
.endm |
.macro READ_ALTERNATE_REGISTER reg, bit |
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp |
rdpr %pstate, %l0 |
wrpr %l0, \bit, %pstate |
mov \reg, %i0 |
wrpr %l0, 0, %pstate |
ret |
restore |
.endm |
.global write_to_ag_g6 |
write_to_ag_g6: |
WRITE_ALTERNATE_REGISTER %g6, PSTATE_AG_BIT |
.global write_to_ag_g7 |
write_to_ag_g7: |
WRITE_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT |
.global write_to_ig_g6 |
write_to_ig_g6: |
WRITE_ALTERNATE_REGISTER %g6, PSTATE_IG_BIT |
.global read_from_ag_g7 |
read_from_ag_g7: |
READ_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT |
/trunk/kernel/arch/sparc64/src/proc/scheduler.c |
---|
36,6 → 36,8 |
#include <proc/thread.h> |
#include <arch.h> |
#include <arch/asm.h> |
#include <arch/regdef.h> |
#include <arch/stack.h> |
#include <arch/mm/tlb.h> |
#include <arch/mm/page.h> |
#include <config.h> |
51,6 → 53,8 |
* |
* Ensure that thread's kernel stack, as well as userspace window |
* buffer for userspace threads, are locked in DTLB. |
* For userspace threads, initialize reserved global registers |
* in the alternate and interrupt sets. |
*/ |
void before_thread_runs_arch(void) |
{ |
82,6 → 86,14 |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, (uintptr_t) uw_buf); |
dtlb_insert_mapping(uw_buf, KA2PA(uw_buf), PAGESIZE_8K, true, true); |
} |
/* |
* Write kernel stack address to %g6 and a pointer to the last item |
* in the userspace window buffer to %g7 in the alternate and interrupt sets. |
*/ |
write_to_ig_g6((uintptr_t) THREAD->kstack + STACK_SIZE - STACK_BIAS); |
write_to_ag_g6((uintptr_t) THREAD->kstack + STACK_SIZE - STACK_BIAS); |
write_to_ag_g7((uintptr_t) THREAD->arch.uspace_window_buffer); |
} |
} |
123,6 → 135,9 |
*/ |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, (uintptr_t) uw_buf); |
} |
/* sample the state of the userspace window buffer */ |
THREAD->arch.uspace_window_buffer = (uint8_t *) read_from_ag_g7(); |
} |
} |
/trunk/kernel/arch/sparc64/src/trap/trap_table.S |
---|
203,6 → 203,18 |
spill_0_normal: |
SPILL_NORMAL_HANDLER_KERNEL |
/* TT = 0x84, TL = 0, spill_1_normal handler */ |
.org trap_table + TT_SPILL_1_NORMAL*ENTRY_SIZE |
.global spill_1_normal |
spill_1_normal: |
SPILL_NORMAL_HANDLER_USERSPACE |
/* TT = 0x88, TL = 0, spill_2_normal handler */ |
.org trap_table + TT_SPILL_2_NORMAL*ENTRY_SIZE |
.global spill_2_normal |
spill_2_normal: |
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 |
209,6 → 221,12 |
fill_0_normal: |
FILL_NORMAL_HANDLER_KERNEL |
/* TT = 0xc4, TL = 0, fill_1_normal handler */ |
.org trap_table + TT_FILL_1_NORMAL*ENTRY_SIZE |
.global fill_1_normal |
fill_1_normal: |
FILL_NORMAL_HANDLER_USERSPACE |
/* |
* Handlers for TL>0. |
*/ |
267,6 → 285,18 |
spill_0_normal_high: |
SPILL_NORMAL_HANDLER_KERNEL |
/* TT = 0x88, TL > 0, spill_2_normal handler */ |
.org trap_table + (TT_SPILL_2_NORMAL+512)*ENTRY_SIZE |
.global spill_2_normal_high |
spill_2_normal_high: |
SPILL_TO_USPACE_WINDOW_BUFFER |
/* TT = 0xa0, TL > 0, spill_0_other handler */ |
.org trap_table + (TT_SPILL_0_OTHER+512)*ENTRY_SIZE |
.global spill_0_other_high |
spill_0_other_high: |
SPILL_TO_USPACE_WINDOW_BUFFER |
/* TT = 0xc0, TL > 0, fill_0_normal handler */ |
.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE |
.global fill_0_normal_high |
289,7 → 319,7 |
* %g1 Address of function to call. |
* %g2 Argument for the function. |
* %g6 Pre-set as kernel stack base if trap from userspace. |
* %g7 Reserved. |
* %g7 Pre-set as address of the userspace window buffer. |
*/ |
.global preemptible_handler |
preemptible_handler: |