Changeset f47fd19 in mainline for kernel/arch/sparc64/src


Ignore:
Timestamp:
2006-08-21T13:36:34Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a7961271
Parents:
ee289cf0
Message:

sparc64 work.
Define the istate structure.
Move the identity-mapping handler to assembly.
Make the preemptible handler more general so that TL=1 MMU exceptions can make use of it.

Little bit of formatting and indentation.

Location:
kernel/arch/sparc64/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc64/src/mm/tlb.c

    ree289cf0 rf47fd19  
    3535#include <arch/mm/tlb.h>
    3636#include <mm/tlb.h>
     37#include <mm/as.h>
     38#include <mm/asid.h>
    3739#include <arch/mm/frame.h>
    3840#include <arch/mm/page.h>
    3941#include <arch/mm/mmu.h>
    40 #include <mm/asid.h>
     42#include <arch/interrupt.h>
     43#include <arch.h>
    4144#include <print.h>
    4245#include <arch/types.h>
     
    4750#include <arch/asm.h>
    4851#include <symtab.h>
     52
     53static void dtlb_pte_copy(pte_t *t);
     54static void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str);
    4955
    5056char *context_encoding[] = {
     
    100106}
    101107
     108void dtlb_pte_copy(pte_t *t)
     109{
     110}
     111
    102112/** ITLB miss handler. */
    103 void fast_instruction_access_mmu_miss(void)
     113void fast_instruction_access_mmu_miss(int n, istate_t *istate)
    104114{
    105115        panic("%s\n", __FUNCTION__);
    106116}
    107117
    108 /** DTLB miss handler. */
    109 void fast_data_access_mmu_miss(void)
     118/** DTLB miss handler.
     119 *
     120 * Note that some faults (e.g. kernel faults) were already resolved
     121 * by the low-level, assembly language part of the fast_data_access_mmu_miss
     122 * handler.
     123 */
     124void fast_data_access_mmu_miss(int n, istate_t *istate)
    110125{
    111126        tlb_tag_access_reg_t tag;
    112         uintptr_t tpc;
    113         char *tpc_str;
     127        uintptr_t va;
     128        pte_t *t;
    114129
    115130        tag.value = dtlb_tag_access_read();
    116         if (tag.context != ASID_KERNEL || tag.vpn == 0) {
    117                 tpc = tpc_read();
    118                 tpc_str = get_symtab_entry(tpc);
    119 
    120                 printf("Faulting page: %p, ASID=%d\n", tag.vpn * PAGE_SIZE, tag.context);
    121                 printf("TPC=%p, (%s)\n", tpc, tpc_str ? tpc_str : "?");
    122                 panic("%s\n", __FUNCTION__);
    123         }
    124 
    125         /*
    126          * Identity map piece of faulting kernel address space.
    127          */
    128         dtlb_insert_mapping(tag.vpn * PAGE_SIZE, tag.vpn * FRAME_SIZE, PAGESIZE_8K, false, true);
     131        va = tag.vpn * PAGE_SIZE;
     132        if (tag.context == ASID_KERNEL) {
     133                if (!tag.vpn) {
     134                        /* NULL access in kernel */
     135                        do_fast_data_access_mmu_miss_fault(istate, __FUNCTION__);
     136                }
     137                do_fast_data_access_mmu_miss_fault(istate, "Unexpected kernel page fault.");
     138        }
     139
     140        page_table_lock(AS, true);
     141        t = page_mapping_find(AS, va);
     142        if (t) {
     143                /*
     144                 * The mapping was found in the software page hash table.
     145                 * Insert it into DTLB.
     146                 */
     147                dtlb_pte_copy(t);
     148                page_table_unlock(AS, true);
     149        } else {
     150                /*
     151                 * Forward the page fault to the address space page fault handler.
     152                 */             
     153                page_table_unlock(AS, true);
     154                if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
     155                        do_fast_data_access_mmu_miss_fault(istate, __FUNCTION__);
     156                }
     157        }
    129158}
    130159
    131160/** DTLB protection fault handler. */
    132 void fast_data_access_protection(void)
     161void fast_data_access_protection(int n, istate_t *istate)
    133162{
    134163        panic("%s\n", __FUNCTION__);
     
    162191}
    163192
     193void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str)
     194{
     195        tlb_tag_access_reg_t tag;
     196        uintptr_t va;
     197        char *tpc_str = get_symtab_entry(istate->tpc);
     198
     199        tag.value = dtlb_tag_access_read();
     200        va = tag.vpn * PAGE_SIZE;
     201
     202        printf("Faulting page: %p, ASID=%d\n", va, tag.context);
     203        printf("TPC=%p, (%s)\n", istate->tpc, tpc_str);
     204        panic("%s\n", str);
     205}
     206
    164207/** Invalidate all unlocked ITLB and DTLB entries. */
    165208void tlb_invalidate_all(void)
  • kernel/arch/sparc64/src/trap/trap_table.S

    ree289cf0 rf47fd19  
    4444#include <arch/trap/mmu.h>
    4545#include <arch/stack.h>
     46#include <arch/regdef.h>
    4647
    4748#define TABLE_SIZE      TRAP_TABLE_SIZE
     
    276277
    277278
    278 /* Preemptible trap handler.
    279  *
    280  * This trap handler makes arrangements to
    281  * make calling scheduler() possible.
    282  *
    283  * The caller is responsible for doing save
    284  * and allocating PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE
    285  * bytes on stack.
     279/* Preemptible trap handler for TL=1.
     280 *
     281 * This trap handler makes arrangements to make calling of scheduler() from
     282 * within a trap context possible. It is guaranteed to function only when traps
     283 * are not nested (i.e. for TL=1).
     284 *
     285 * Every trap handler on TL=1 that makes a call to the scheduler needs to
     286 * be based on this function. The reason behind it is that the nested
     287 * trap levels and the automatic saving of the interrupted context by hardware
     288 * does not work well together with scheduling (i.e. a thread cannot be rescheduled
     289 * with TL>0). Therefore it is necessary to eliminate the effect of trap levels
     290 * by software and save the necessary state on the kernel stack.
     291 *
     292 * Note that for traps with TL>1, more state needs to be saved. This function
     293 * is therefore not going to work when TL>1.
     294 *
     295 * The caller is responsible for doing SAVE and allocating
     296 * PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE bytes on the stack.
    286297 *
    287298 * Input registers:
     
    300311        rdpr %pstate, %g4
    301312
     313        /*
     314         * The following memory accesses will not fault
     315         * because special provisions are made to have
     316         * the kernel stack of THREAD locked in DTLB.
     317         */
    302318        stx %g1, [%fp + STACK_BIAS + SAVED_TSTATE]
    303319        stx %g2, [%fp + STACK_BIAS + SAVED_TPC]
     
    314330         * - switch to normal globals.
    315331         */
    316         and %g4, ~1, %g4                ! mask alternate globals
     332        and %g4, ~(PSTATE_AG_BIT|PSTATE_IG_BIT|PSTATE_MG_BIT), %g4
    317333        wrpr %g4, 0, %pstate
    318334         
     
    325341         * Call the higher-level handler.
    326342         */
     343        mov %fp, %o1                            ! calculate istate address
    327344        call %l0
    328         nop
    329        
    330         /*
    331          * Restore the normal global register set.
     345        add %o1, STACK_BIAS + SAVED_PSTATE, %o1 ! calculate istate address
     346       
     347        /*
     348         * Restore      the normal global register set.
    332349         */
    333350        RESTORE_GLOBALS
     
    335352        /*
    336353         * Restore PSTATE from saved copy.
    337          * Alternate globals become active.
     354         * Alternate/Interrupt/MM globals become active.
    338355         */
    339356        ldx [%fp + STACK_BIAS + SAVED_PSTATE], %l4
     
    358375
    359376        /*
    360          * On execution of retry instruction, CWP will be restored from TSTATE register.
    361          * However, because of scheduling, it is possible that CWP in saved TSTATE
    362          * is different from current CWP. The following chunk of code fixes CWP
    363          * in the saved copy of TSTATE.
     377         * On execution of the RETRY instruction, CWP will be restored from the TSTATE
     378         * register. However, because of scheduling, it is possible that CWP in the saved
     379         * TSTATE is different from the current CWP. The following chunk of code fixes
     380         * CWP in the saved copy of TSTATE.
    364381         */
    365382        rdpr %cwp, %g4          ! read current CWP
Note: See TracChangeset for help on using the changeset viewer.