/trunk/kernel/arch/sparc64/include/asm.h |
---|
330,7 → 330,7 |
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 |
/trunk/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 |
/trunk/kernel/arch/sparc64/include/mm/tlb.h |
---|
179,7 → 179,7 |
*/ |
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(); |
} |
/trunk/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); |
/trunk/kernel/arch/sparc64/src/asm.S |
---|
150,6 → 150,7 |
* |
* %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 |
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 |
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 |
/trunk/kernel/arch/sparc64/src/proc/scheduler.c |
---|
126,8 → 126,6 |
*/ |
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<<KERNEL_PAGE_WIDTH)) { |
/* |
/trunk/kernel/arch/sparc64/src/sparc64.c |
---|
48,6 → 48,19 |
bootinfo_t bootinfo; |
void arch_pre_main(void) |
{ |
/* Setup usermode */ |
init.cnt = bootinfo.taskmap.count; |
uint32_t i; |
for (i = 0; i < bootinfo.taskmap.count; i++) { |
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr); |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
} |
} |
void arch_pre_mm_init(void) |
{ |
trap_init(); |
98,7 → 111,8 |
{ |
switch_to_userspace((uintptr_t) kernel_uarg->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 (;;) |
; |
/trunk/kernel/arch/sparc64/src/context.S |
---|
27,7 → 27,6 |
# |
#include <arch/context_offset.h> |
#include <arch/stack.h> |
/** |
* Both context_save_arch() and context_restore_arch() are |
/trunk/kernel/arch/sparc64/src/trap/trap_table.S |
---|
218,6 → 218,12 |
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 |
.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 |
/* |
* 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 |
*/ |
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 |
/* |
* 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 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 |
/trunk/kernel/arch/sparc64/src/mm/tlb.c |
---|
136,7 → 136,7 |
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 |
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; |
/trunk/kernel/arch/sparc64/src/start.S |
---|
208,6 → 208,9 |
! set TL back to 0 |
wrpr %g0, 0, %tl |
call arch_pre_main |
nop |
call main_bsp |
nop |