Changeset e386cbf in mainline


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

sparc64 work.
Dump take_over_tlb_and_tt() and add its assembly language replacement.

Location:
kernel/arch/sparc64
Files:
8 edited

Legend:

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

    rb3e8c90 re386cbf  
    3636#define __sparc64_ARCH_H__
    3737
    38 #include <arch/types.h>
    39 
    40 extern void take_over_tlb_and_tt(uintptr_t base);
    41 
    4238#endif
    4339
  • kernel/arch/sparc64/include/boot/boot.h

    rb3e8c90 re386cbf  
    4040#define LMA                     VMA
    4141
     42#ifndef __ASM__
    4243#ifndef __LINKER__
    4344
     
    9293
    9394#endif
     95#endif
    9496
    9597#endif
  • kernel/arch/sparc64/include/mm/mmu.h

    rb3e8c90 re386cbf  
    104104typedef union lsu_cr_reg lsu_cr_reg_t;
    105105
    106 #endif /* !__ASM__ */
     106#endif /* !def __ASM__ */
    107107
    108108#endif
  • kernel/arch/sparc64/include/mm/tlb.h

    rb3e8c90 re386cbf  
    3636#define __sparc64_TLB_H__
    3737
     38
     39#define ITLB_ENTRY_COUNT                64
     40#define DTLB_ENTRY_COUNT                64
     41
     42#define MEM_CONTEXT_KERNEL              0
     43#define MEM_CONTEXT_TEMP                1
     44
     45/** Page sizes. */
     46#define PAGESIZE_8K     0
     47#define PAGESIZE_64K    1
     48#define PAGESIZE_512K   2
     49#define PAGESIZE_4M     3
     50
     51/** Bit width of the TLB-locked portion of kernel address space. */
     52#define KERNEL_PAGE_WIDTH       22      /* 4M */
     53
     54/* TLB Demap Operation types. */
     55#define TLB_DEMAP_PAGE          0
     56#define TLB_DEMAP_CONTEXT       1
     57
     58#define TLB_DEMAP_TYPE_SHIFT    6
     59
     60/* TLB Demap Operation Context register encodings. */
     61#define TLB_DEMAP_PRIMARY       0
     62#define TLB_DEMAP_SECONDARY     1
     63#define TLB_DEMAP_NUCLEUS       2
     64
     65#define TLB_DEMAP_CONTEXT_SHIFT 4
     66
     67/* TLB Tag Access shifts */
     68#define TLB_TAG_ACCESS_CONTEXT_SHIFT    0
     69#define TLB_TAG_ACCESS_VPN_SHIFT        13
     70
     71#ifndef __ASM__
     72
    3873#include <arch/mm/tte.h>
    3974#include <arch/mm/mmu.h>
     
    4378#include <arch/types.h>
    4479#include <typedefs.h>
    45 
    46 #define ITLB_ENTRY_COUNT                64
    47 #define DTLB_ENTRY_COUNT                64
    48 
    49 /** Page sizes. */
    50 #define PAGESIZE_8K     0
    51 #define PAGESIZE_64K    1
    52 #define PAGESIZE_512K   2
    53 #define PAGESIZE_4M     3
    54 
    55 /** Bit width of the TLB-locked portion of kernel address space. */
    56 #define KERNEL_PAGE_WIDTH       22      /* 4M */
    5780
    5881union tlb_context_reg {
     
    91114typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
    92115
    93 /** TLB Demap Operation types. */
    94 #define TLB_DEMAP_PAGE          0
    95 #define TLB_DEMAP_CONTEXT       1
    96 
    97 /** TLB Demap Operation Context register encodings. */
    98 #define TLB_DEMAP_PRIMARY       0
    99 #define TLB_DEMAP_SECONDARY     1
    100 #define TLB_DEMAP_NUCLEUS       2
    101116
    102117/** TLB Demap Operation Address. */
     
    385400        da.vpn = pg.vpn;
    386401       
    387         asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
     402        asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);     /* da.value is the address within the ASI */
    388403        flush();
    389404}
     
    407422        da.vpn = pg.vpn;
    408423       
    409         asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
     424        asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the address within the ASI */
    410425        membar();
    411426}
     
    417432extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
    418433
     434#endif /* !def __ASM__ */
     435
    419436#endif
    420437
  • kernel/arch/sparc64/include/mm/tte.h

    rb3e8c90 re386cbf  
    3535#ifndef __sparc64_TTE_H__
    3636#define __sparc64_TTE_H__
     37
     38#define TTE_G           (1<<0)
     39#define TTE_W           (1<<1)
     40#define TTE_P           (1<<2)
     41#define TTE_E           (1<<3)
     42#define TTE_CV          (1<<4)
     43#define TTE_CP          (1<<5)
     44#define TTE_L           (1<<6)
     45
     46#define TTE_V_SHIFT     63
     47#define TTE_SIZE_SHIFT  61
     48
     49#ifndef __ASM__
    3750
    3851#include <arch/types.h>
     
    7689typedef union tte_data tte_data_t;
    7790
     91#endif /* !def __ASM__ */
     92
    7893#endif
    7994
  • kernel/arch/sparc64/include/trap/trap.h

    rb3e8c90 re386cbf  
    3636#define __sparc64_TRAP_H__
    3737
    38 #include <arch/trap/trap_table.h>
    39 #include <arch/asm.h>
    40 
    41 /** Switch to in-kernel trap table. */
    42 static inline void trap_switch_trap_table(void)
    43 {
    44         /* Point TBA to kernel trap table. */
    45         tba_write((uint64_t) trap_table);
    46 }
    47 
    4838extern void trap_init(void);
    4939
  • kernel/arch/sparc64/src/sparc64.c

    rb3e8c90 re386cbf  
    9292}
    9393
    94 /** Take over TLB and trap table.
    95  *
    96  * Initialize ITLB and DTLB and switch to kernel
    97  * trap table.
    98  *
    99  * First, demap context 0 and install the
    100  * global 4M locked kernel mapping.
    101  *
    102  * Second, prepare a temporary IMMU mapping in
    103  * context 1, switch to it, demap context 0,
    104  * install the global 4M locked kernel mapping
    105  * in context 0 and switch back to context 0.
    106  *
    107  * @param base Base address that will be hardwired in both TLBs.
    108  */
    109 void take_over_tlb_and_tt(uintptr_t base)
    110 {
    111         tlb_tag_access_reg_t tag;
    112         tlb_data_t data;
    113         frame_address_t fr;
    114         page_address_t pg;
    115 
    116         /*
    117          * Switch to the kernel trap table.
    118          */
    119         trap_switch_trap_table();
    120 
    121         fr.address = base;
    122         pg.address = base;
    123 
    124         /*
    125          * We do identity mapping of 4M-page at 4M.
    126          */
    127         tag.value = 0;
    128         tag.context = 0;
    129         tag.vpn = pg.vpn;
    130 
    131         data.value = 0;
    132         data.v = true;
    133         data.size = PAGESIZE_4M;
    134         data.pfn = fr.pfn;
    135         data.l = true;
    136         data.cp = 1;
    137         data.cv = 0;
    138         data.p = true;
    139         data.w = true;
    140         data.g = true;
    141 
    142         /*
    143          * Straightforwardly demap DMUU context 0,
    144          * and replace it with the locked kernel mapping.
    145          */
    146         dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);
    147         dtlb_tag_access_write(tag.value);
    148         dtlb_data_in_write(data.value);
    149 
    150         /*
    151          * Install kernel code mapping in context 1
    152          * and switch to it.
    153          */
    154         tag.context = 1;
    155         data.g = false;
    156         itlb_tag_access_write(tag.value);
    157         itlb_data_in_write(data.value);
    158         mmu_primary_context_write(1);
    159        
    160         /*
    161          * Demap old context 0.
    162          */
    163         itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);
    164        
    165         /*
    166          * Install the locked kernel mapping in context 0
    167          * and switch to it.
    168          */
    169         tag.context = 0;
    170         data.g = true;
    171         itlb_tag_access_write(tag.value);
    172         itlb_data_in_write(data.value);
    173         mmu_primary_context_write(0);
    174 }
    175 
    17694/** @}
    17795 */
  • kernel/arch/sparc64/src/start.S

    rb3e8c90 re386cbf  
    2828
    2929#include <arch/regdef.h>
     30#include <arch/boot/boot.h>
     31
     32#include <arch/mm/mmu.h>
     33#include <arch/mm/tlb.h>
     34#include <arch/mm/tte.h>
    3035
    3136.register %g2, #scratch
     
    5358.global kernel_image_start
    5459kernel_image_start:
     60
     61        /*
     62         * Setup basic runtime environment.
     63         */
     64
    5565        flushw                          ! flush all but the active register window
    56 
    57         /*
    58          * Disable interrupts and disable 32-bit address masking.
    59          */
    60         rdpr %pstate, %l0
    61         and %l0, ~(PSTATE_AM_BIT|PSTATE_IE_BIT), %l0
    62         wrpr %l0, 0, %pstate
     66        wrpr %g0, 0, %tl                ! TL = 0, primary context register is used
     67
     68        ! Disable interrupts and disable 32-bit address masking.
     69        rdpr %pstate, %g1
     70        and %g1, ~(PSTATE_AM_BIT|PSTATE_IE_BIT), %g1
     71        wrpr %g1, 0, %pstate
     72
     73        wrpr %r0, 0, %pil               ! intialize %pil
    6374
    6475        /*
     
    7283        nop
    7384
    74         set kernel_image_start, %o0
    75         /*
    76          * Take over control of MMU.
    77          *
    78          * First, take over DMMU for which we don't need to issue
    79          * any FLUSH instructions. Because of that, we can
    80          * demap the old DTLB pretty straightforwardly.
    81          */
    82         call take_over_tlb_and_tt
    83         nop
    84 
    85         wrpr %r0, 0, %pil
    86 
     85        /*
     86         * Switch to kernel trap table.
     87         */
     88        set trap_table, %g1
     89        wrpr %g1, 0, %tba
     90
     91        /*
     92         * Take over the DMMU by installing global locked
     93         * TTE entry identically mapping the first 4M
     94         * of memory.
     95         *
     96         * In case of DMMU, no FLUSH instructions need to be
     97         * issued. Because of that, the old DTLB contents can
     98         * be demapped pretty straightforwardly and without
     99         * causing any traps.
     100         */
     101
     102        wr %g0, ASI_DMMU, %asi
     103
     104#define SET_TLB_DEMAP_CMD(r1, context_id) \
     105        set (TLB_DEMAP_CONTEXT<<TLB_DEMAP_TYPE_SHIFT) | (context_id<<TLB_DEMAP_CONTEXT_SHIFT), %r1
     106       
     107        ! demap context 0
     108        SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS)
     109        stxa %g0, [%g1] ASI_DMMU_DEMAP                 
     110        membar #Sync
     111
     112#define SET_TLB_TAG(r1, context) \
     113        set VMA | (context<<TLB_TAG_ACCESS_CONTEXT_SHIFT), %r1
     114
     115        ! write DTLB tag
     116        SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL)
     117        stxa %g1, [VA_DMMU_TAG_ACCESS] %asi                     
     118        membar #Sync
     119
     120#define SET_TLB_DATA(r1, r2, imm) \
     121        set TTE_L | TTE_CP | TTE_P | TTE_W | LMA | imm, %r1; \
     122        set PAGESIZE_4M, %r2; \
     123        sllx %r2, TTE_SIZE_SHIFT, %r2; \
     124        or %r1, %r2, %r1; \
     125        set 1, %r2; \
     126        sllx %r2, TTE_V_SHIFT, %r2; \
     127        or %r1, %r2, %r1;
     128       
     129        ! write DTLB data and install the kernel mapping
     130        SET_TLB_DATA(g1, g2, TTE_G)
     131        stxa %g1, [%g0] ASI_DTLB_DATA_IN_REG           
     132        membar #Sync
     133       
     134        /*
     135         * Now is time to take over the IMMU.
     136         * Unfortunatelly, it cannot be done as easily as the DMMU,
     137         * because the IMMU is mapping the code it executes.
     138         *
     139         * [ Note that brave experiments with disabling the IMMU
     140         * and using the DMMU approach failed after a dozen
     141         * of desparate days with only little success. ]
     142         *
     143         * The approach used here is inspired from OpenBSD.
     144         * First, the kernel creates IMMU mapping for itself
     145         * in context 1 (MEM_CONTEXT_TEMP) and switches to
     146         * it. Context 0 (MEM_CONTEXT_KERNEL) can be demapped
     147         * afterwards and replaced with the kernel permanent
     148         * mapping. Finally, the kernel switches back to
     149         * context 0 and demaps context 1.
     150         *
     151         * Moreover, the IMMU requires use of the FLUSH instructions.
     152         * But that is OK because we always use operands with
     153         * addresses already mapped by the taken over DTLB.
     154         */
     155       
     156        set kernel_image_start, %g7
     157       
     158        ! write ITLB tag of context 1
     159        SET_TLB_TAG(g1, MEM_CONTEXT_TEMP)
     160        set VA_DMMU_TAG_ACCESS, %g2
     161        stxa %g1, [%g2] ASI_IMMU
     162        flush %g7
     163
     164        ! write ITLB data and install the temporary mapping in context 1
     165        SET_TLB_DATA(g1, g2, 0)                 ! use non-global mapping
     166        stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG           
     167        flush %g7
     168       
     169        ! switch to context 1
     170        set MEM_CONTEXT_TEMP, %g1
     171        stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!!
     172        flush %g7
     173       
     174        ! demap context 0
     175        SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS)
     176        stxa %g0, [%g1] ASI_IMMU_DEMAP                 
     177        flush %g7
     178       
     179        ! write ITLB tag of context 0
     180        SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL)
     181        set VA_DMMU_TAG_ACCESS, %g2
     182        stxa %g1, [%g2] ASI_IMMU
     183        flush %g7
     184
     185        ! write ITLB data and install the permanent kernel mapping in context 0
     186        SET_TLB_DATA(g1, g2, 0)                 ! use non-global mapping
     187        stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG           
     188        flush %g7
     189
     190        ! switch to context 0
     191        stxa %g0, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!!
     192        flush %g7
     193
     194        ! ensure nucleus mapping
     195        wrpr %g0, 1, %tl
     196
     197        ! set context 1 in the primary context register
     198        set MEM_CONTEXT_TEMP, %g1
     199        stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!!
     200        flush %g7
     201
     202        ! demap context 1
     203        SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_PRIMARY)
     204        stxa %g0, [%g1] ASI_IMMU_DEMAP                 
     205        flush %g7
     206       
     207        ! set context 0 in the primary context register
     208        stxa %g0, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!!
     209        flush %g7
     210       
     211        ! set TL back to 0
     212        wrpr %g0, 0, %tl
     213       
    87214        call main_bsp
    88215        nop
Note: See TracChangeset for help on using the changeset viewer.