Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 70a1c59 in mainline


Ignore:
Timestamp:
2009-11-15T19:12:47Z (12 years ago)
Author:
Pavel Rimsky <pavel@…>
Branches:
lfn, master
Children:
5f678b1c
Parents:
69b68d1f
Message:

Kernel MM implemented.

Location:
kernel/arch/sparc64
Files:
1 deleted
4 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc64/Makefile.inc

    r69b68d1f r70a1c59  
    8080        arch/$(KARCH)/src/proc/scheduler.c \
    8181        arch/$(KARCH)/src/proc/thread.c \
    82         arch/$(KARCH)/src/trap/mmu.S \
     82        arch/$(KARCH)/src/trap/$(USARCH)/mmu.S \
    8383        arch/$(KARCH)/src/trap/$(USARCH)/trap_table.S \
    8484        arch/$(KARCH)/src/trap/trap.c \
  • kernel/arch/sparc64/include/trap/sun4v/mmu.h

    r69b68d1f r70a1c59  
    11/*
    22 * Copyright (c) 2006 Jakub Jermar
     3 * Copyright (c) 2008 Pavel Rimsky
    34 * All rights reserved.
    45 *
     
    4041#include <arch/stack.h>
    4142#include <arch/regdef.h>
     43#include <arch/arch.h>
     44#include <arch/sun4v/arch.h>
     45#include <arch/sun4v/hypercall.h>
     46#include <arch/mm/sun4v/mmu.h>
    4247#include <arch/mm/tlb.h>
    4348#include <arch/mm/mmu.h>
     
    5257#define TT_FAST_DATA_ACCESS_MMU_MISS            0x68
    5358#define TT_FAST_DATA_ACCESS_PROTECTION          0x6c
     59#define TT_CPU_MONDO                            0x7c
    5460
    5561#define FAST_MMU_HANDLER_SIZE                   128
     
    5763#ifdef __ASM__
    5864
     65/* MMU fault status area data fault offset */
     66#define FSA_DFA_OFFSET                          0x48
     67
     68/* MMU fault status area data context */
     69#define FSA_DFC_OFFSET                          0x50
     70
     71/* offset of the target address within the TTE Data entry */
     72#define TTE_DATA_TADDR_OFFSET                   13
     73
    5974.macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
    60         /*
    61          * First, try to refill TLB from TSB.
    62          */
    63 #ifdef CONFIG_TSB
    64         ldxa [%g0] ASI_IMMU, %g1                        ! read TSB Tag Target Register
    65         ldxa [%g0] ASI_IMMU_TSB_8KB_PTR_REG, %g2        ! read TSB 8K Pointer
    66         ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4            ! 16-byte atomic load into %g4 and %g5
    67         cmp %g1, %g4                                    ! is this the entry we are looking for?
    68         bne,pn %xcc, 0f
    69         nop
    70         stxa %g5, [%g0] ASI_ITLB_DATA_IN_REG            ! copy mapping from ITSB to ITLB
    71         retry
    72 #endif
    73 
    74 0:
    75         wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
    7675        PREEMPTIBLE_HANDLER fast_instruction_access_mmu_miss
    7776.endm
    7877
     78/*
     79 * Handler of the Fast Data Access MMU Miss trap. If the trap occurred in the kernel
     80 * (context 0), an identity mapping (with displacement) is installed. Otherwise
     81 * a higher level service routine is called.
     82 */
    7983.macro FAST_DATA_ACCESS_MMU_MISS_HANDLER tl
    80 //MH
    81         save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
    82         set 0x8000, %o0
    83         set 0x0, %o1
    84         setx 0x80000000804087c3, %g1, %o2
    85         set 0x3, %o3
    86         ta 0x83
    87         restore %g0, 0, %g0
    88         retry
    89 #if 0
    90         /*
    91          * First, try to refill TLB from TSB.
    92          */
     84        mov SCRATCHPAD_MMU_FSA, %g1
     85        ldxa [%g1] ASI_SCRATCHPAD, %g1                  ! g1 <= RA of MMU fault status area
    9386
    94 #ifdef CONFIG_TSB
    95         ldxa [%g0] ASI_DMMU, %g1                        ! read TSB Tag Target Register
    96         srlx %g1, TSB_TAG_TARGET_CONTEXT_SHIFT, %g2     ! is this a kernel miss?
    97         brz,pn %g2, 0f
    98         ldxa [%g0] ASI_DMMU_TSB_8KB_PTR_REG, %g3        ! read TSB 8K Pointer
    99         ldda [%g3] ASI_NUCLEUS_QUAD_LDD, %g4            ! 16-byte atomic load into %g4 and %g5
    100         cmp %g1, %g4                                    ! is this the entry we are looking for?
    101         bne,pn %xcc, 0f
     87        /* read faulting context */
     88        add %g1, FSA_DFC_OFFSET, %g2                    ! g2 <= RA of data fault context
     89        ldxa [%g2] ASI_REAL, %g3                        ! read the fault context
     90
     91        /* read the faulting address */
     92        add %g1, FSA_DFA_OFFSET, %g2                    ! g2 <= RA of data fault address
     93        ldxa [%g2] ASI_REAL, %g1                        ! read the fault address
     94        srlx %g1, TTE_DATA_TADDR_OFFSET, %g1            ! truncate it to page boundary
     95        sllx %g1, TTE_DATA_TADDR_OFFSET, %g1
     96
     97        /* service by higher-level routine when context != 0 */
     98        brnz %g3, 0f
    10299        nop
    103         stxa %g5, [%g0] ASI_DTLB_DATA_IN_REG            ! copy mapping from DTSB to DTLB
    104         retry
    105 #endif
     100        /* exclude page number 0 from installing the identity mapping */
     101        brz %g1, 0f
     102        nop
    106103
    107104        /*
    108          * Second, test if it is the portion of the kernel address space
    109          * which is faulting. If that is the case, immediately create
    110          * identity mapping for that page in DTLB. VPN 0 is excluded from
    111          * this treatment.
    112          *
    113          * Note that branch-delay slots are used in order to save space.
     105         * Installing the identity does not fit into 32 instructions, call
     106         * a separate routine. The routine performs RETRY, hence the call never
     107         * returns.
    114108         */
    115 0:
    116 //MH
    117 //      sethi %hi(fast_data_access_mmu_miss_data_hi), %g7
    118         wr %g0, ASI_DMMU, %asi
    119         ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1             ! read the faulting Context and VPN
    120         set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
    121         andcc %g1, %g2, %g3                             ! get Context
    122         bnz %xcc, 0f                                    ! Context is non-zero
    123         andncc %g1, %g2, %g3                            ! get page address into %g3
    124         bz  %xcc, 0f                                    ! page address is zero
    125 //MH
    126 //      ldx [%g7 + %lo(end_of_identity)], %g4
    127         cmp %g3, %g4
    128         bgeu %xcc, 0f
     109        ba install_identity_mapping
     110        nop     
    129111
    130         ldx [%g7 + %lo(kernel_8k_tlb_data_template)], %g2
    131         add %g3, %g2, %g2
    132         stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG            ! identity map the kernel page
    133         retry
     112        0:
    134113
    135114        /*
    136          * Third, catch and handle special cases when the trap is caused by
    137          * the userspace register window spill or fill handler. In case
    138          * one of these two traps caused this trap, we just lower the trap
    139          * level and service the DTLB miss. In the end, we restart
    140          * the offending SAVE or RESTORE.
     115         * One of the scenarios in which this trap can occur is when the
     116         * register window spill/fill handler accesses a memory which is not
     117         * mapped. In such a case, this handler will be called from TL = 1.
     118         * We handle the situation by pretending that the MMU miss occurred
     119         * on TL = 0. Once the MMU miss trap is services, the instruction which
     120         * caused the spill/fill trap is restarted, the spill/fill trap occurs,
     121         * but this time its handler accesse memory which IS mapped.
    141122         */
    1421230:
     
    146127
    147128        /*
    148          * Switch from the MM globals.
     129         * Save the faulting virtual page and faulting context to the %g2
     130         * register. The most significant 51 bits of the %g2 register will
     131         * contain the virtual address which caused the fault truncated to the
     132         * page boundary. The least significant 13 bits of the %g2 register
     133         * will contain the number of the context in which the fault occurred.
     134         * The value of the %g2 register will be passed as a parameter to the
     135         * higher level service routine.
    149136         */
    150         wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
     137        or %g1, %g3, %g2
    151138
    152         /*
    153          * Read the Tag Access register for the higher-level handler.
    154          * This is necessary to survive nested DTLB misses.
    155          */     
    156         ldxa [VA_DMMU_TAG_ACCESS] %asi, %g2
    157 
    158         /*
    159          * g2 will be passed as an argument to fast_data_access_mmu_miss().
    160          */
    161139        PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
    162 #endif
    163140.endm
    164141
     142/*
     143 * Handler of the Fast Data MMU Protection trap. Finds the trapping address
     144 * and context and calls higher level service routine.
     145 */
    165146.macro FAST_DATA_ACCESS_PROTECTION_HANDLER tl
    166147        /*
    167148         * The same special case as in FAST_DATA_ACCESS_MMU_MISS_HANDLER.
    168149         */
     150        .if (\tl > 0)
     151                wrpr %g0, 1, %tl
     152        .endif
    169153
    170 .if (\tl > 0)
    171         wrpr %g0, 1, %tl
    172 .endif
     154        mov SCRATCHPAD_MMU_FSA, %g1
     155        ldxa [%g1] ASI_SCRATCHPAD, %g1                  ! g1 <= RA of MMU fault status area
    173156
    174         /*
    175          * Switch from the MM globals.
    176          */
    177         wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
     157        /* read faulting context */
     158        add %g1, FSA_DFC_OFFSET, %g2                    ! g2 <= RA of data fault context
     159        ldxa [%g2] ASI_REAL, %g3                        ! read the fault context
    178160
    179         /*
    180          * Read the Tag Access register for the higher-level handler.
    181          * This is necessary to survive nested DTLB misses.
    182          */     
    183         mov VA_DMMU_TAG_ACCESS, %g2
    184         ldxa [%g2] ASI_DMMU, %g2
     161        /* read the faulting address */
     162        add %g1, FSA_DFA_OFFSET, %g2                    ! g2 <= RA of data fault address
     163        ldxa [%g2] ASI_REAL, %g1                        ! read the fault address
     164        srlx %g1, TTE_DATA_TADDR_OFFSET, %g1            ! truncate it to page boundary
     165        sllx %g1, TTE_DATA_TADDR_OFFSET, %g1
    185166
    186         /*
    187          * g2 will be passed as an argument to fast_data_access_mmu_miss().
    188          */
     167        /* the same as for FAST_DATA_ACCESS_MMU_MISS_HANDLER */
     168        or %g1, %g3, %g2
     169
    189170        PREEMPTIBLE_HANDLER fast_data_access_protection
    190171.endm
    191 
    192172#endif /* __ASM__ */
    193173
  • kernel/arch/sparc64/src/drivers/niagara.c

    r69b68d1f r70a1c59  
    6666static niagara_instance_t *instance = NULL;
    6767
    68 /* functions referenced from definitions of I/O operations structures */
    6968static void niagara_putchar(outdev_t *, const wchar_t, bool);
    70 //static void niagara_noop(chardev_t *);
    71 //static char niagara_read(chardev_t *);
    7269
    7370/** character device operations */
     
    104101chardev_t niagara_io;
    105102
    106 /**
    107  * Niagara IRQ structure. So far used only for notifying the userspace of the
    108  * key being pressed, not for kernel being informed about keyboard interrupts.
    109  */
    110 static irq_t niagara_irq;
    111 
    112103/** defined in drivers/kbd.c */
    113104extern kbd_type_t kbd_type;
     
    119110static char read_char;
    120111
    121 /**
    122  * The driver works in polled mode, so no interrupt should be handled by it.
    123  */
    124 static irq_ownership_t niagara_claim(void)
    125 {
    126         return IRQ_DECLINE;
    127 }
    128 
    129 /**
    130  * The driver works in polled mode, so no interrupt should be handled by it.
    131  */
    132 static void niagara_irq_handler(irq_t *irq, void *arg, ...)
    133 {
    134         panic("Not yet implemented, SGCN works in polled mode.\n");
    135 }
    136112
    137113#endif
     
    146122/** Writes a single character to the standard output. */
    147123static void niagara_putchar(outdev_t *dev, const wchar_t ch, bool silent)
    148 //static void niagara_putchar(struct chardev * cd, const char c)
    149124{
    150125        do_putchar(ch);
     
    230205        if (__hypercall_fast_ret1(0, 0, 0, 0, 0, CONS_GETCHAR, &c) == EOK) {
    231206                indev_push_character(instance->srlnin, c);
    232                 #if 0
    233                 ipl_t ipl = interrupts_disable();
    234                 spinlock_lock(&niagara_irq.lock);
    235 
    236                 if (niagara_irq.notif_cfg.notify &&
    237                                 niagara_irq.notif_cfg.answerbox) {
    238                         /*
    239                          * remember the character, uspace will pick it
    240                          * up using pseudocode
    241                          */
    242                         read_char = (char) c;
    243                         ipc_irq_send_notif(&niagara_irq);
    244                         spinlock_unlock(&niagara_irq.lock);
    245                         interrupts_restore(ipl);
    246                         return;
    247                 } else {
    248                         spinlock_unlock(&niagara_irq.lock);
    249                         interrupts_restore(ipl);       
    250 
    251                         chardev_push_character(&niagara_io, c);
    252                         if (c == '\r')
    253                                 chardev_push_character(&niagara_io, '\n');
    254                 }
    255                 #endif
    256207        }
    257208
     
    334285        ddi_parea_register(&outbuf_parea);
    335286
    336         chardev_initialize("niagara_io", &niagara_io, &niagara_ops);
    337         stdin = &niagara_io;
    338         stdout = &niagara_io;
    339287        #endif
    340288
     
    351299        niagara_init();
    352300
    353         // TODO - move to console init
    354301        if (instance) {
    355302                srln_instance_t *srln_instance = srln_init();
  • kernel/arch/sparc64/src/sun4v/sparc64.c

    r69b68d1f r70a1c59  
    102102void arch_post_smp_init(void)
    103103{
    104         //MH
    105         //standalone_sparc64_console_init();
    106104        niagarain_init();
    107105}
Note: See TracChangeset for help on using the changeset viewer.