Ignore:
Timestamp:
2006-08-29T15:35:44Z (19 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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.