Changeset 0fa6044 in mainline


Ignore:
Timestamp:
2006-08-29T15:35:44Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e11ae91
Parents:
32fffef0
Message:

sparc64 work.

Fix bug introduced in revision 1852. When fixing CWP,
the input registers of the current window (i.e. output
registers of the window belonging to the interrupted
context) must be preserved. Preserve those registers
in memory. Sure there exist more efficient ways how to
copy the inputs.

Simplify before_thread_runs_arch(), resp. after_thread_ran_arch(),
and make them install, resp. uninstall, DTLB locked mapping for
eventual userspace window buffer.

Location:
kernel
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc64/include/asm.h

    r32fffef0 r0fa6044  
    316316}
    317317
     318/** Flush all valid register windows to memory. */
     319static inline void flushw(void)
     320{
     321        __asm__ volatile ("flushw\n");
     322}
     323
    318324void cpu_halt(void);
    319325void cpu_sleep(void);
  • kernel/arch/sparc64/include/trap/trap_table.h

    r32fffef0 r0fa6044  
    8282 * definition of the istate structure.
    8383 */
    84 #define PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE    (STACK_WINDOW_SAVE_AREA_SIZE+(4*8))
     84#define PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE    (STACK_WINDOW_SAVE_AREA_SIZE+(12*8))
    8585#define SAVED_TSTATE    -(1*8)
    8686#define SAVED_TPC       -(2*8)
    87 #define SAVED_TNPC      -(3*8)
     87#define SAVED_TNPC      -(3*8)          /* <-- istate_t begins here */
     88/* alignment gap */
     89#define SAVED_I0        -(5*8)
     90#define SAVED_I1        -(6*8)
     91#define SAVED_I2        -(7*8)
     92#define SAVED_I3        -(8*8)
     93#define SAVED_I4        -(9*8)
     94#define SAVED_I5        -(10*8)
     95#define SAVED_I6        -(11*8)
     96#define SAVED_I7        -(12*8)
    8897
    8998.macro PREEMPTIBLE_HANDLER f
  • kernel/arch/sparc64/src/proc/scheduler.c

    r32fffef0 r0fa6044  
    3636#include <proc/thread.h>
    3737#include <arch.h>
     38#include <arch/asm.h>
    3839#include <arch/mm/tlb.h>
    3940#include <arch/mm/page.h>
    4041#include <config.h>
    4142#include <align.h>
     43#include <macros.h>
    4244
    4345/** Perform sparc64 specific tasks needed before the new task is run. */
     
    4648}
    4749
    48 /** Ensure that thread's kernel stack is locked in TLB. */
     50/** Perform sparc64 specific steps before scheduling a thread.
     51 *
     52 * Ensure that thread's kernel stack, as well as userspace window
     53 * buffer for userspace threads, are locked in DTLB.
     54 */
    4955void before_thread_runs_arch(void)
    5056{
     
    5359        base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH);
    5460
    55         if ((uintptr_t) THREAD->kstack < base || (uintptr_t) THREAD->kstack > base + (1<<KERNEL_PAGE_WIDTH)) {
     61        if (!overlaps((uintptr_t) THREAD->kstack, PAGE_SIZE, base, (1<<KERNEL_PAGE_WIDTH))) {
    5662                /*
    5763                 * Kernel stack of this thread is not locked in DTLB.
     
    5965                 * If not, create a locked mapping for it.
    6066                 */
    61                  dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, (uintptr_t) THREAD->kstack);
    62                  dtlb_insert_mapping((uintptr_t) THREAD->kstack, KA2PA(THREAD->kstack), PAGESIZE_8K, true, true);
    63         }       
     67                dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, (uintptr_t) THREAD->kstack);
     68                dtlb_insert_mapping((uintptr_t) THREAD->kstack, KA2PA(THREAD->kstack), PAGESIZE_8K, true, true);
     69        }
     70       
     71        if ((THREAD->flags & THREAD_FLAG_USPACE)) {
     72                /*
     73                 * If this thread executes also in userspace, we have to lock
     74                 * its userspace window buffer into DTLB.
     75                 */
     76                ASSERT(THREAD->arch.uspace_window_buffer);
     77                uintptr_t uw_buf = (uintptr_t) THREAD->arch.uspace_window_buffer;
     78                if (!overlaps(uw_buf, PAGE_SIZE, base, 1<<KERNEL_PAGE_WIDTH)) {
     79                        /*
     80                         * The buffer is not covered by the 4M locked kernel DTLB entry.
     81                         */
     82                        dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, (uintptr_t) uw_buf);
     83                        dtlb_insert_mapping(uw_buf, KA2PA(uw_buf), PAGESIZE_8K, true, true);
     84                }
     85        }
    6486}
    6587
    66 /** Unlock thread's stack from TLB, if necessary. */
     88/** Perform sparc64 specific steps before a thread stops running.
     89 *
     90 * Demap any locked DTLB entries isntalled by the thread (i.e. kernel stack
     91 * and userspace window buffer).
     92 */
    6793void after_thread_ran_arch(void)
    6894{
     
    7197        base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH);
    7298
    73         if ((uintptr_t) THREAD->kstack < base || (uintptr_t) THREAD->kstack > base + (1<<KERNEL_PAGE_WIDTH)) {
     99        if (!overlaps((uintptr_t) THREAD->kstack, PAGE_SIZE, base, (1<<KERNEL_PAGE_WIDTH))) {
    74100                /*
    75101                 * Kernel stack of this thread is locked in DTLB.
     
    78104                dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, (uintptr_t) THREAD->kstack);
    79105        }
     106       
     107        if ((THREAD->flags & THREAD_FLAG_USPACE)) {
     108                /*
     109                 * If this thread executes also in userspace, we have to force all
     110                 * its still-active userspace windows into the userspace window buffer
     111                 * and demap the buffer from DTLB.
     112                 */
     113                ASSERT(THREAD->arch.uspace_window_buffer);
     114               
     115                flushw();       /* force all userspace windows into memory */
     116               
     117                uintptr_t uw_buf = (uintptr_t) THREAD->arch.uspace_window_buffer;
     118                if (!overlaps(uw_buf, PAGE_SIZE, base, 1<<KERNEL_PAGE_WIDTH)) {
     119                        /*
     120                         * The buffer is not covered by the 4M locked kernel DTLB entry
     121                         * and therefore it was given a dedicated locked DTLB entry.
     122                         * Demap it.
     123                         */
     124                        dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, (uintptr_t) uw_buf);
     125                }
     126        }
    80127}
    81128
  • kernel/arch/sparc64/src/trap/trap_table.S

    r32fffef0 r0fa6044  
    413413        /*
    414414         * Fix CWP.
    415          */
    416         mov %fp, %g1
     415         * Just for reminder, the input registers in the current window
     416         * are the output registers of the window to which we want to
     417         * restore. Because the fill trap fills only input and local
     418         * registers of a window, we need to preserve those output
     419         * registers manually.
     420         */
    417421        flushw
     422        mov %sp, %g1
     423        stx %i0, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0]
     424        stx %i1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1]
     425        stx %i2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2]
     426        stx %i3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3]
     427        stx %i4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4]
     428        stx %i5, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5]
     429        stx %i6, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6]
     430        stx %i7, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7]
    418431        wrpr %l0, 0, %cwp
    419         mov %g1, %fp
    420        
     432        mov %g1, %sp
     433        ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0], %i0
     434        ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1], %i1
     435        ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2], %i2
     436        ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3
     437        ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4
     438        ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5
     439        ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6
     440        ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7
     441
    421442        /*
    422443         * OTHERWIN != 0 or fall-through from the OTHERWIN == 0 case.
  • kernel/generic/include/macros.h

    r32fffef0 r0fa6044  
    3333 */
    3434
    35 #ifndef __MACROS_H__
    36 #define __MACROS_H__
     35#ifndef KERN_MACROS_H_
     36#define KERN_MACROS_H_
    3737
    3838#include <arch/types.h>
     
    4949#define max(a,b)        ((a) > (b) ? (a) : (b))
    5050
    51 /** Return true if the interlvals overlap. */
     51/** Return true if the interlvals overlap.
     52 *
     53 * @param s1 Start address of the first interval.
     54 * @param sz1 Size of the first interval.
     55 * @param s2 Start address of the second interval.
     56 * @param sz2 Size of the second interval.
     57 */
    5258static inline int overlaps(uintptr_t s1, size_t sz1, uintptr_t s2, size_t sz2)
    5359{
  • kernel/generic/src/main/kinit.c

    r32fffef0 r0fa6044  
    155155#ifdef CONFIG_TEST
    156156        test();
    157         printf("\nTest finished, please reboot\n");
     157        printf("\nTest finished, please reboot.\n");
    158158#else  /* CONFIG_TEST */
    159159
Note: See TracChangeset for help on using the changeset viewer.