Changeset e08162b in mainline


Ignore:
Timestamp:
2016-01-07T13:41:38Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f4582c6
Parents:
7254df6
Message:

sparc64: TSB needs to be naturally aligned

The ITSB and DTSB on sun4u and the TSB on sun4v are mapped by a single
64K page, so they need to be aligned to 64K. Moreover, the TSB pointer
contruction demands the natural alignment: 32K for ITSB/DTSB on sun4u
and 64K for the unified TSB on sun4v.

The code was also streamlined and made more beautiful.

Location:
kernel/arch/sparc64
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc64/include/arch/mm/sun4u/tsb.h

    r7254df6 re08162b  
    4343 * in TLBs - only one TLB entry will do.
    4444 */
    45 #define TSB_SIZE                        2       /* when changing this, change
    46                                                  * as.c as well */
    47 #define ITSB_ENTRY_COUNT                (512 * (1 << TSB_SIZE))
    48 #define DTSB_ENTRY_COUNT                (512 * (1 << TSB_SIZE))
     45#define TSB_BASE_REG_SIZE       2       /* keep in sync with as.c */
     46#define ITSB_ENTRY_COUNT        (512 * (1 << TSB_BASE_REG_SIZE))
     47#define DTSB_ENTRY_COUNT        (512 * (1 << TSB_BASE_REG_SIZE))
     48
     49#define ITSB_ENTRY_MASK         (ITSB_ENTRY_COUNT - 1)
     50#define DTSB_ENTRY_MASK         (DTSB_ENTRY_COUNT - 1)
     51
     52#define TSB_ENTRY_COUNT         (ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT)
     53#define TSB_SIZE                (TSB_ENTRY_COUNT * sizeof(tsb_entry_t))
     54#define TSB_FRAMES              SIZE2FRAMES(TSB_SIZE)
    4955
    5056#define TSB_TAG_TARGET_CONTEXT_SHIFT    48
  • kernel/arch/sparc64/include/arch/mm/sun4v/tsb.h

    r7254df6 re08162b  
    4444 * in TLBs - only one TLB entry will do.
    4545 */
    46 #define TSB_SIZE                        3       /* when changing this, change
    47                                                  * as.c as well */
    48 #define TSB_ENTRY_COUNT                 (512 * (1 << TSB_SIZE))
     46#define TSB_ENTRY_COUNT                 4096
     47#define TSB_ENTRY_MASK                  (TSB_ENTRY_COUNT - 1)
     48#define TSB_SIZE                        (TSB_ENTRY_COUNT * sizeof(tsb_entry_t))
     49#define TSB_FRAMES                      SIZE2FRAMES(TSB_SIZE)
    4950
    5051#ifndef __ASM__
  • kernel/arch/sparc64/src/mm/sun4u/as.c

    r7254df6 re08162b  
    6363{
    6464#ifdef CONFIG_TSB
    65         uintptr_t tsb_phys =
    66             frame_alloc(SIZE2FRAMES((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
    67             sizeof(tsb_entry_t)), flags, 0);
    68         if (!tsb_phys)
     65        uintptr_t tsb_base = frame_alloc(TSB_FRAMES, flags, TSB_SIZE - 1);
     66        if (!tsb_base)
    6967                return -1;
    70        
    71         tsb_entry_t *tsb = (tsb_entry_t *) PA2KA(tsb_phys);
     68
     69        tsb_entry_t *tsb = (tsb_entry_t *) PA2KA(tsb_base);
     70        memsetb(tsb, TSB_SIZE, 0);
    7271       
    7372        as->arch.itsb = tsb;
    7473        as->arch.dtsb = tsb + ITSB_ENTRY_COUNT;
    75        
    76         memsetb(as->arch.itsb, (ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
    77             sizeof(tsb_entry_t), 0);
    7874#endif
    7975       
     
    8480{
    8581#ifdef CONFIG_TSB
    86         size_t frames = SIZE2FRAMES((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
    87             sizeof(tsb_entry_t));
    88         frame_free(KA2PA((uintptr_t) as->arch.itsb), frames);
    89        
    90         return frames;
     82        frame_free(KA2PA((uintptr_t) as->arch.itsb), TSB_FRAMES);
     83       
     84        return TSB_FRAMES;
    9185#else
    9286        return 0;
     
    136130        uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
    137131       
    138         ASSERT(as->arch.itsb && as->arch.dtsb);
     132        ASSERT(as->arch.itsb);
     133        ASSERT(as->arch.dtsb);
    139134       
    140135        uintptr_t tsb = (uintptr_t) as->arch.itsb;
    141136       
    142         if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
     137        if (!overlaps(tsb, TSB_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
    143138                /*
    144139                 * TSBs were allocated from memory not covered
     
    155150         *
    156151         */
    157         tsb_base_reg_t tsb_base;
    158        
    159         tsb_base.value = 0;
    160         tsb_base.size = TSB_SIZE;
    161         tsb_base.split = 0;
    162        
    163         tsb_base.base = ((uintptr_t) as->arch.itsb) >> MMU_PAGE_WIDTH;
    164         itsb_base_write(tsb_base.value);
    165         tsb_base.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH;
    166         dtsb_base_write(tsb_base.value);
     152        tsb_base_reg_t tsb_base_reg;
     153       
     154        tsb_base_reg.value = 0;
     155        tsb_base_reg.size = TSB_BASE_REG_SIZE;
     156        tsb_base_reg.split = 0;
     157       
     158        tsb_base_reg.base = ((uintptr_t) as->arch.itsb) >> MMU_PAGE_WIDTH;
     159        itsb_base_write(tsb_base_reg.value);
     160        tsb_base_reg.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH;
     161        dtsb_base_write(tsb_base_reg.value);
    167162       
    168163#if defined (US3)
     
    207202        uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
    208203       
    209         ASSERT(as->arch.itsb && as->arch.dtsb);
     204        ASSERT(as->arch.itsb);
     205        ASSERT(as->arch.dtsb);
    210206       
    211207        uintptr_t tsb = (uintptr_t) as->arch.itsb;
    212208       
    213         if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
     209        if (!overlaps(tsb, TSB_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
    214210                /*
    215211                 * TSBs were allocated from memory not covered
  • kernel/arch/sparc64/src/mm/sun4u/tsb.c

    r7254df6 re08162b  
    4242#include <debug.h>
    4343
    44 #define TSB_INDEX_MASK  ((1 << (21 + 1 + TSB_SIZE - MMU_PAGE_WIDTH)) - 1)
    45 
    4644/** Invalidate portion of TSB.
    4745 *
     
    6058        size_t cnt;
    6159       
    62         ASSERT(as->arch.itsb && as->arch.dtsb);
     60        ASSERT(as->arch.itsb);
     61        ASSERT(as->arch.dtsb);
    6362       
    64         i0 = (page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
    65         ASSERT(i0 < ITSB_ENTRY_COUNT && i0 < DTSB_ENTRY_COUNT);
     63        i0 = (page >> MMU_PAGE_WIDTH) & ITSB_ENTRY_MASK;
    6664
    6765        if (pages == (size_t) -1 || (pages * 2) > ITSB_ENTRY_COUNT)
     
    7169       
    7270        for (i = 0; i < cnt; i++) {
    73                 as->arch.itsb[(i0 + i) & (ITSB_ENTRY_COUNT - 1)].tag.invalid =
    74                     true;
    75                 as->arch.dtsb[(i0 + i) & (DTSB_ENTRY_COUNT - 1)].tag.invalid =
    76                     true;
     71                as->arch.itsb[(i0 + i) & ITSB_ENTRY_MASK].tag.invalid = true;
     72                as->arch.dtsb[(i0 + i) & DTSB_ENTRY_MASK].tag.invalid = true;
    7773        }
    7874}
     
    8682{
    8783        as_t *as;
    88         tsb_entry_t *tsb;
     84        tsb_entry_t *tte;
    8985        size_t entry;
    9086
     
    9288       
    9389        as = t->as;
    94         entry = ((t->page >> MMU_PAGE_WIDTH) + index) & TSB_INDEX_MASK;
    95         ASSERT(entry < ITSB_ENTRY_COUNT);
    96         tsb = &as->arch.itsb[entry];
     90        entry = ((t->page >> MMU_PAGE_WIDTH) + index) & ITSB_ENTRY_MASK;
     91        tte = &as->arch.itsb[entry];
    9792
    9893        /*
     
    10297         */
    10398
    104         tsb->tag.invalid = true;        /* invalidate the entry
     99        tte->tag.invalid = true;        /* invalidate the entry
    105100                                         * (tag target has this
    106101                                         * set to 0) */
     
    108103        write_barrier();
    109104
    110         tsb->tag.context = as->asid;
     105        tte->tag.context = as->asid;
    111106        /* the shift is bigger than PAGE_WIDTH, do not bother with index  */
    112         tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
    113         tsb->data.value = 0;
    114         tsb->data.size = PAGESIZE_8K;
    115         tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
    116         tsb->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
    117         tsb->data.p = t->k;     /* p as privileged, k as kernel */
    118         tsb->data.v = t->p;     /* v as valid, p as present */
     107        tte->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
     108        tte->data.value = 0;
     109        tte->data.size = PAGESIZE_8K;
     110        tte->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
     111        tte->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
     112        tte->data.p = t->k;     /* p as privileged, k as kernel */
     113        tte->data.v = t->p;     /* v as valid, p as present */
    119114       
    120115        write_barrier();
    121116       
    122         tsb->tag.invalid = false;       /* mark the entry as valid */
     117        tte->tag.invalid = false;       /* mark the entry as valid */
    123118}
    124119
     
    132127{
    133128        as_t *as;
    134         tsb_entry_t *tsb;
     129        tsb_entry_t *tte;
    135130        size_t entry;
    136131       
     
    138133
    139134        as = t->as;
    140         entry = ((t->page >> MMU_PAGE_WIDTH) + index) & TSB_INDEX_MASK;
    141         ASSERT(entry < DTSB_ENTRY_COUNT);
    142         tsb = &as->arch.dtsb[entry];
     135        entry = ((t->page >> MMU_PAGE_WIDTH) + index) & DTSB_ENTRY_MASK;
     136        tte = &as->arch.dtsb[entry];
    143137
    144138        /*
     
    148142         */
    149143
    150         tsb->tag.invalid = true;        /* invalidate the entry
     144        tte->tag.invalid = true;        /* invalidate the entry
    151145                                         * (tag target has this
    152146                                         * set to 0) */
     
    154148        write_barrier();
    155149
    156         tsb->tag.context = as->asid;
     150        tte->tag.context = as->asid;
    157151        /* the shift is bigger than PAGE_WIDTH, do not bother with index */
    158         tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
    159         tsb->data.value = 0;
    160         tsb->data.size = PAGESIZE_8K;
    161         tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
    162         tsb->data.cp = t->c;
     152        tte->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
     153        tte->data.value = 0;
     154        tte->data.size = PAGESIZE_8K;
     155        tte->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
     156        tte->data.cp = t->c;
    163157#ifdef CONFIG_VIRT_IDX_DCACHE
    164         tsb->data.cv = t->c;
     158        tte->data.cv = t->c;
    165159#endif /* CONFIG_VIRT_IDX_DCACHE */
    166         tsb->data.p = t->k;             /* p as privileged */
    167         tsb->data.w = ro ? false : t->w;
    168         tsb->data.v = t->p;
     160        tte->data.p = t->k;             /* p as privileged */
     161        tte->data.w = ro ? false : t->w;
     162        tte->data.v = t->p;
    169163       
    170164        write_barrier();
    171165       
    172         tsb->tag.invalid = false;       /* mark the entry as valid */
     166        tte->tag.invalid = false;       /* mark the entry as valid */
    173167}
    174168
  • kernel/arch/sparc64/src/mm/sun4v/as.c

    r7254df6 re08162b  
    6666{
    6767#ifdef CONFIG_TSB
    68         uintptr_t tsb =
    69             frame_alloc(SIZE2FRAMES(TSB_ENTRY_COUNT * sizeof(tsb_entry_t)),
    70             flags, 0);
    71         if (!tsb)
     68        uintptr_t tsb_base = frame_alloc(TSB_FRAMES, flags, TSB_SIZE - 1);
     69        if (!tsb_base)
    7270                return -1;
    73        
     71
     72        tsb_entry_t *tsb = (tsb_entry_t *) PA2KA(tsb_base);
     73
    7474        as->arch.tsb_description.page_size = PAGESIZE_8K;
    7575        as->arch.tsb_description.associativity = 1;
    7676        as->arch.tsb_description.num_ttes = TSB_ENTRY_COUNT;
    7777        as->arch.tsb_description.pgsize_mask = 1 << PAGESIZE_8K;
    78         as->arch.tsb_description.tsb_base = tsb;
     78        as->arch.tsb_description.tsb_base = tsb_base;
    7979        as->arch.tsb_description.reserved = 0;
    8080        as->arch.tsb_description.context = 0;
    8181       
    82         memsetb((void *) PA2KA(as->arch.tsb_description.tsb_base),
    83                 TSB_ENTRY_COUNT * sizeof(tsb_entry_t), 0);
     82        memsetb(tsb, TSB_SIZE, 0);
    8483#endif
    8584       
     
    9089{
    9190#ifdef CONFIG_TSB
    92         size_t frames = SIZE2FRAMES(TSB_ENTRY_COUNT * sizeof(tsb_entry_t));
    93         frame_free(as->arch.tsb_description.tsb_base, frames);
     91        frame_free(as->arch.tsb_description.tsb_base, TSB_FRAMES);
    9492       
    95         return frames;
     93        return TSB_FRAMES;
    9694#else
    9795        return 0;
     
    126124        uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base);
    127125       
    128         if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
     126        if (!overlaps(tsb, TSB_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
    129127                /*
    130128                 * TSBs were allocated from memory not covered
     
    137135        }
    138136       
    139         __hypercall_fast2(MMU_TSB_CTXNON0, 1, KA2PA(&(as->arch.tsb_description)));
     137        __hypercall_fast2(MMU_TSB_CTXNON0, 1, KA2PA(&as->arch.tsb_description));
    140138#endif
    141139}
     
    166164        uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base);
    167165       
    168         if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
     166        if (!overlaps(tsb, TSB_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
    169167                /*
    170168                 * TSBs were allocated from memory not covered
  • kernel/arch/sparc64/src/mm/sun4v/tsb.c

    r7254df6 re08162b  
    4444#include <debug.h>
    4545
    46 #define TSB_INDEX_MASK  ((1 << (21 + 1 + TSB_SIZE - MMU_PAGE_WIDTH)) - 1)
    47 
    4846/** Invalidate portion of TSB.
    4947 *
     
    5856void tsb_invalidate(as_t *as, uintptr_t page, size_t pages)
    5957{
     58        tsb_entry_t *tsb;
    6059        size_t i0, i;
    6160        size_t cnt;
     
    6362        ASSERT(as->arch.tsb_description.tsb_base);
    6463       
    65         i0 = (page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
    66         ASSERT(i0 < TSB_ENTRY_COUNT);
     64        i0 = (page >> MMU_PAGE_WIDTH) & TSB_ENTRY_MASK;
    6765
    68         if (pages == (size_t) - 1 || (pages) > TSB_ENTRY_COUNT)
     66        if (pages == (size_t) -1 || pages > TSB_ENTRY_COUNT)
    6967                cnt = TSB_ENTRY_COUNT;
    7068        else
    7169                cnt = pages;
    7270       
    73         for (i = 0; i < cnt; i++) {
    74                 ((tsb_entry_t *) PA2KA(as->arch.tsb_description.tsb_base))[
    75                         (i0 + i) & (TSB_ENTRY_COUNT - 1)].data.v = false;
    76         }
     71        tsb = (tsb_entry_t *) PA2KA(as->arch.tsb_description.tsb_base);
     72        for (i = 0; i < cnt; i++)
     73                tsb[(i0 + i) & TSB_ENTRY_MASK].data.v = false;
    7774}
    7875
     
    8582        as_t *as;
    8683        tsb_entry_t *tsb;
    87         size_t entry;
     84        tsb_entry_t *tte;
     85        size_t index;
    8886
    8987        as = t->as;
    90         entry = (t->page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
    91         ASSERT(entry < TSB_ENTRY_COUNT);
    92         tsb = &((tsb_entry_t *) PA2KA(as->arch.tsb_description.tsb_base))[entry];
     88        index = (t->page >> MMU_PAGE_WIDTH) & TSB_ENTRY_MASK;
     89       
     90        tsb = (tsb_entry_t *) PA2KA(as->arch.tsb_description.tsb_base);
     91        tte = &tsb[index];
    9392
    9493        /*
     
    9897         */
    9998
    100         tsb->data.v = false;
     99        tte->data.v = false;
    101100
    102101        write_barrier();
    103102
    104         tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
     103        tte->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
    105104
    106         tsb->data.value = 0;
    107         tsb->data.nfo = false;
    108         tsb->data.ra = t->frame >> MMU_FRAME_WIDTH;
    109         tsb->data.ie = false;
    110         tsb->data.e = false;
    111         tsb->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
    112         tsb->data.cv = false;
    113         tsb->data.p = t->k;     /* p as privileged, k as kernel */
    114         tsb->data.x = true;
    115         tsb->data.w = false;
    116         tsb->data.size = PAGESIZE_8K;
     105        tte->data.value = 0;
     106        tte->data.nfo = false;
     107        tte->data.ra = t->frame >> MMU_FRAME_WIDTH;
     108        tte->data.ie = false;
     109        tte->data.e = false;
     110        tte->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
     111        tte->data.cv = false;
     112        tte->data.p = t->k;     /* p as privileged, k as kernel */
     113        tte->data.x = true;
     114        tte->data.w = false;
     115        tte->data.size = PAGESIZE_8K;
    117116       
    118117        write_barrier();
    119118       
    120         tsb->data.v = t->p;     /* v as valid, p as present */
     119        tte->data.v = t->p;     /* v as valid, p as present */
    121120}
    122121
     
    130129        as_t *as;
    131130        tsb_entry_t *tsb;
    132         size_t entry;
     131        tsb_entry_t *tte;
     132        size_t index;
    133133
    134134        as = t->as;
    135         entry = (t->page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
    136         ASSERT(entry < TSB_ENTRY_COUNT);
    137         tsb = &((tsb_entry_t *) PA2KA(as->arch.tsb_description.tsb_base))[entry];
     135        index = (t->page >> MMU_PAGE_WIDTH) & TSB_ENTRY_MASK;
     136        tsb = (tsb_entry_t *) PA2KA(as->arch.tsb_description.tsb_base);
     137        tte = &tsb[index];
    138138
    139139        /*
     
    143143         */
    144144
    145         tsb->data.v = false;
     145        tte->data.v = false;
    146146
    147147        write_barrier();
    148148
    149         tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
     149        tte->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
    150150
    151         tsb->data.value = 0;
    152         tsb->data.nfo = false;
    153         tsb->data.ra = t->frame >> MMU_FRAME_WIDTH;
    154         tsb->data.ie = false;
    155         tsb->data.e = false;
    156         tsb->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
     151        tte->data.value = 0;
     152        tte->data.nfo = false;
     153        tte->data.ra = t->frame >> MMU_FRAME_WIDTH;
     154        tte->data.ie = false;
     155        tte->data.e = false;
     156        tte->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
    157157#ifdef CONFIG_VIRT_IDX_DCACHE
    158         tsb->data.cv = t->c;
     158        tte->data.cv = t->c;
    159159#endif /* CONFIG_VIRT_IDX_DCACHE */
    160         tsb->data.p = t->k;     /* p as privileged, k as kernel */
    161         tsb->data.x = true;
    162         tsb->data.w = ro ? false : t->w;
    163         tsb->data.size = PAGESIZE_8K;
     160        tte->data.p = t->k;     /* p as privileged, k as kernel */
     161        tte->data.x = true;
     162        tte->data.w = ro ? false : t->w;
     163        tte->data.size = PAGESIZE_8K;
    164164       
    165165        write_barrier();
    166166       
    167         tsb->data.v = t->p;     /* v as valid, p as present */
     167        tte->data.v = t->p;     /* v as valid, p as present */
    168168}
    169169
Note: See TracChangeset for help on using the changeset viewer.