source: branches/contrib/debian/package-build/linux-patch-bcm47xx/patches-3.16/159-cpu_fixes.patch @ 716

Last change on this file since 716 was 716, checked in by ehem, 4 years ago

Adjust BCM47xx patches

Get rid of fuzz during application, this should make application more
reliable and potentially provide better warnings in future.

File size: 13.8 KB
  • arch/mips/include/asm/r4kcache.h

    a b  
    1919#include <asm/mipsmtregs.h>
    2020#include <asm/uaccess.h> /* for segment_eq() */
    2121
     22#ifdef CONFIG_BCM47XX
     23#include <asm/paccess.h>
     24#include <linux/ssb/ssb.h>
     25#define BCM4710_DUMMY_RREG() ((void) *((u8 *) KSEG1ADDR(SSB_ENUM_BASE)))
     26
     27#define BCM4710_FILL_TLB(addr) (*(volatile unsigned long *)(addr))
     28#define BCM4710_PROTECTED_FILL_TLB(addr) ({ unsigned long x; get_dbe(x, (volatile unsigned long *)(addr)); })
     29#else
     30#define BCM4710_DUMMY_RREG()
     31
     32#define BCM4710_FILL_TLB(addr)
     33#define BCM4710_PROTECTED_FILL_TLB(addr)
     34#endif
     35
    2236/*
    2337 * This macro return a properly sign-extended address suitable as base address
    2438 * for indexed cache operations.  Two issues here:
    static inline void flush_icache_line_ind 
    151165static inline void flush_dcache_line_indexed(unsigned long addr)
    152166{
    153167        __dflush_prologue
     168        BCM4710_DUMMY_RREG();
    154169        cache_op(Index_Writeback_Inv_D, addr);
    155170        __dflush_epilogue
    156171}
    static inline void flush_icache_line(uns 
    178193static inline void flush_dcache_line(unsigned long addr)
    179194{
    180195        __dflush_prologue
     196        BCM4710_DUMMY_RREG();
    181197        cache_op(Hit_Writeback_Inv_D, addr);
    182198        __dflush_epilogue
    183199}
    static inline void flush_dcache_line(uns 
    185201static inline void invalidate_dcache_line(unsigned long addr)
    186202{
    187203        __dflush_prologue
     204        BCM4710_DUMMY_RREG();
    188205        cache_op(Hit_Invalidate_D, addr);
    189206        __dflush_epilogue
    190207}
    static inline void protected_flush_icach 
    240257#ifdef CONFIG_EVA
    241258                protected_cachee_op(Hit_Invalidate_I, addr);
    242259#else
     260                BCM4710_DUMMY_RREG();
    243261                protected_cache_op(Hit_Invalidate_I, addr);
    244262#endif
    245263                break;
    static inline void protected_flush_icach 
    254272 */
    255273static inline void protected_writeback_dcache_line(unsigned long addr)
    256274{
     275        BCM4710_DUMMY_RREG();
    257276#ifdef CONFIG_EVA
    258277        protected_cachee_op(Hit_Writeback_Inv_D, addr);
    259278#else
    static inline void invalidate_tcache_pag 
    463482                : "r" (base),                                           \
    464483                  "i" (op));
    465484
     485static inline void blast_dcache(void)
     486{
     487        unsigned long start = KSEG0;
     488        unsigned long dcache_size = current_cpu_data.dcache.waysize * current_cpu_data.dcache.ways;
     489        unsigned long end = (start + dcache_size);
     490
     491        do {
     492                BCM4710_DUMMY_RREG();
     493                cache_op(Index_Writeback_Inv_D, start);
     494                start += current_cpu_data.dcache.linesz;
     495        } while(start < end);
     496}
     497
     498static inline void blast_dcache_page(unsigned long page)
     499{
     500        unsigned long start = page;
     501        unsigned long end = start + PAGE_SIZE;
     502
     503        BCM4710_FILL_TLB(start);
     504        do {
     505                BCM4710_DUMMY_RREG();
     506                cache_op(Hit_Writeback_Inv_D, start);
     507                start += current_cpu_data.dcache.linesz;
     508        } while(start < end);
     509}
     510
     511static inline void blast_dcache_page_indexed(unsigned long page)
     512{
     513        unsigned long start = page;
     514        unsigned long end = start + PAGE_SIZE;
     515        unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
     516        unsigned long ws_end = current_cpu_data.dcache.ways <<
     517                               current_cpu_data.dcache.waybit;
     518        unsigned long ws, addr;
     519        for (ws = 0; ws < ws_end; ws += ws_inc) {
     520                start = page + ws;
     521                for (addr = start; addr < end; addr += current_cpu_data.dcache.linesz) {
     522                        BCM4710_DUMMY_RREG();
     523                        cache_op(Index_Writeback_Inv_D, addr);
     524                }
     525        }
     526}
     527
    466528/* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */
    467 #define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, extra)    \
     529#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, extra, war) \
    468530static inline void extra##blast_##pfx##cache##lsize(void)               \
    469531{                                                                       \
    470532        unsigned long start = INDEX_BASE;                               \
    static inline void extra##blast_##pfx##c 
    476538                                                                        \
    477539        __##pfx##flush_prologue                                         \
    478540                                                                        \
     541        war                                                             \
    479542        for (ws = 0; ws < ws_end; ws += ws_inc)                         \
    480543                for (addr = start; addr < end; addr += lsize * 32)      \
    481544                        cache##lsize##_unroll32(addr|ws, indexop);      \
    static inline void extra##blast_##pfx##c 
    490553                                                                        \
    491554        __##pfx##flush_prologue                                         \
    492555                                                                        \
     556        war                                                             \
    493557        do {                                                            \
    494558                cache##lsize##_unroll32(start, hitop);                  \
    495559                start += lsize * 32;                                    \
    static inline void extra##blast_##pfx##c 
    508572                               current_cpu_data.desc.waybit;            \
    509573        unsigned long ws, addr;                                         \
    510574                                                                        \
     575        war                                                             \
     576                                                                        \
    511577        __##pfx##flush_prologue                                         \
    512578                                                                        \
    513579        for (ws = 0; ws < ws_end; ws += ws_inc)                         \
    static inline void extra##blast_##pfx##c 
    517583        __##pfx##flush_epilogue                                         \
    518584}
    519585
    520 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, )
    521 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, )
    522 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, )
    523 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, )
    524 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, )
    525 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I_Loongson2, 32, loongson2_)
    526 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, )
    527 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, )
    528 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, )
    529 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, )
    530 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 128, )
    531 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 128, )
    532 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, )
    533 
    534 __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, )
    535 __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32, )
    536 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16, )
    537 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32, )
    538 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64, )
    539 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128, )
     586__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, , )
     587__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, , BCM4710_FILL_TLB(start);)
     588__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, , )
     589__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, , )
     590__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, , BCM4710_FILL_TLB(start);)
     591__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I_Loongson2, 32, loongson2_, BCM4710_FILL_TLB(start);)
     592__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, , )
     593__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, , )
     594__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, , BCM4710_FILL_TLB(start);)
     595__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, , )
     596__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 128, , )
     597__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 128, , )
     598__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, , )
     599
     600__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, , )
     601__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32, , )
     602__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16, , )
     603__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32, , )
     604__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64, , )
     605__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128, , )
    540606
    541607#define __BUILD_BLAST_USER_CACHE(pfx, desc, indexop, hitop, lsize) \
    542608static inline void blast_##pfx##cache##lsize##_user_page(unsigned long page) \
    __BUILD_BLAST_USER_CACHE(d, dcache, Inde 
    565631__BUILD_BLAST_USER_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
    566632
    567633/* build blast_xxx_range, protected_blast_xxx_range */
    568 #define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, extra)        \
     634#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, extra, war, war2)     \
    569635static inline void prot##extra##blast_##pfx##cache##_range(unsigned long start, \
    570636                                                    unsigned long end)  \
    571637{                                                                       \
    572638        unsigned long lsize = cpu_##desc##_line_size();                 \
    573639        unsigned long addr = start & ~(lsize - 1);                      \
    574640        unsigned long aend = (end - 1) & ~(lsize - 1);                  \
     641        war                                                             \
    575642                                                                        \
    576643        __##pfx##flush_prologue                                         \
    577644                                                                        \
    578645        while (1) {                                                     \
     646                war2                                                    \
    579647                prot##cache_op(hitop, addr);                            \
    580648                if (addr == aend)                                       \
    581649                        break;                                          \
    static inline void prot##extra##blast_## 
    587655
    588656#ifndef CONFIG_EVA
    589657
    590 __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, )
    591 __BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_, )
     658__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, , BCM4710_PROTECTED_FILL_TLB(addr); BCM4710_PROTECTED_FILL_TLB(aend);, BCM4710_DUMMY_RREG();)
     659__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_, , , )
    592660
    593661#else
    594662
    __BUILD_PROT_BLAST_CACHE_RANGE(d, dcache 
    625693__BUILD_PROT_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I)
    626694
    627695#endif
    628 __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_, )
     696__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_, , , )
    629697__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I_Loongson2, \
    630         protected_, loongson2_)
    631 __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, , )
    632 __BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, , )
    633 __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , )
     698        protected_, loongson2_, , )
     699__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, , , BCM4710_FILL_TLB(addr); BCM4710_FILL_TLB(aend);, BCM4710_DUMMY_RREG();)
     700__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, , , , )
     701__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , , , )
    634702/* blast_inv_dcache_range */
    635 __BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , )
    636 __BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, , )
     703__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , , , BCM4710_DUMMY_RREG();)
     704__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, , , , )
    637705
    638706#endif /* _ASM_R4KCACHE_H */
  • arch/mips/include/asm/stackframe.h

    a b  
    333333                .macro  RESTORE_SP_AND_RET
    334334                LONG_L  sp, PT_R29(sp)
    335335                .set    arch=r4000
     336#ifdef CONFIG_BCM47XX
     337                nop
     338                nop
     339#endif
    336340                eret
    337341                .set    mips0
    338342                .endm
  • arch/mips/kernel/genex.S

    a b  
    3232NESTED(except_vec3_generic, 0, sp)
    3333        .set    push
    3434        .set    noat
     35#ifdef CONFIG_BCM47XX
     36        nop
     37        nop
     38#endif
    3539#if R5432_CP0_INTERRUPT_WAR
    3640        mfc0    k0, CP0_INDEX
    3741#endif
  • arch/mips/mm/c-r4k.c

    a b  
    3838#include <asm/traps.h>
    3939#include <asm/dma-coherence.h>
    4040
     41/* For enabling BCM4710 cache workarounds */
     42int bcm4710 = 0;
     43
    4144/*
    4245 * Special Variant of smp_call_function for use by cache functions:
    4346 *
    static void r4k_blast_dcache_user_page_s 
    149152{
    150153        unsigned long  dc_lsize = cpu_dcache_line_size();
    151154
     155        if (bcm4710)
     156                r4k_blast_dcache_page = blast_dcache_page;
     157        else
    152158        if (dc_lsize == 0)
    153159                r4k_blast_dcache_user_page = (void *)cache_noop;
    154160        else if (dc_lsize == 16)
    static void r4k_blast_dcache_page_indexe 
    167173{
    168174        unsigned long dc_lsize = cpu_dcache_line_size();
    169175
     176        if (bcm4710)
     177                r4k_blast_dcache_page_indexed = blast_dcache_page_indexed;
     178        else
    170179        if (dc_lsize == 0)
    171180                r4k_blast_dcache_page_indexed = (void *)cache_noop;
    172181        else if (dc_lsize == 16)
    static void r4k_blast_dcache_setup(void) 
    186195{
    187196        unsigned long dc_lsize = cpu_dcache_line_size();
    188197
     198        if (bcm4710)
     199                r4k_blast_dcache = blast_dcache;
     200        else
    189201        if (dc_lsize == 0)
    190202                r4k_blast_dcache = (void *)cache_noop;
    191203        else if (dc_lsize == 16)
    static void local_r4k_flush_cache_sigtra 
    784796        unsigned long addr = (unsigned long) arg;
    785797
    786798        R4600_HIT_CACHEOP_WAR_IMPL;
     799        BCM4710_PROTECTED_FILL_TLB(addr);
     800        BCM4710_PROTECTED_FILL_TLB(addr + 4);
    787801        if (dc_lsize)
    788802                protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
    789803        if (!cpu_icache_snoops_remote_store && scache_size)
    static void coherency_setup(void) 
    15661580         * silly idea of putting something else there ...
    15671581         */
    15681582        switch (current_cpu_type()) {
     1583        case CPU_BMIPS3300:
     1584                {
     1585                        u32 cm;
     1586                        cm = read_c0_diag();
     1587                        /* Enable icache */
     1588                        cm |= (1 << 31);
     1589                        /* Enable dcache */
     1590                        cm |= (1 << 30);
     1591                        write_c0_diag(cm);
     1592                }
     1593                break;
    15691594        case CPU_R4000PC:
    15701595        case CPU_R4000SC:
    15711596        case CPU_R4000MC:
    void r4k_cache_init(void) 
    16121637        extern void build_copy_page(void);
    16131638        struct cpuinfo_mips *c = &current_cpu_data;
    16141639
     1640        /* Check if special workarounds are required */
     1641#ifdef CONFIG_BCM47XX
     1642        if (current_cpu_data.cputype == CPU_BMIPS32 && (current_cpu_data.processor_id & 0xff) == 0) {
     1643                printk("Enabling BCM4710A0 cache workarounds.\n");
     1644                bcm4710 = 1;
     1645        } else
     1646#endif
     1647                bcm4710 = 0;
     1648
    16151649        probe_pcache();
    16161650        setup_scache();
    16171651
    void r4k_cache_init(void) 
    16811715         */
    16821716        local_r4k___flush_cache_all(NULL);
    16831717
     1718#ifdef CONFIG_BCM47XX
     1719        {
     1720                static void (*_coherency_setup)(void);
     1721                _coherency_setup = (void (*)(void)) KSEG1ADDR(coherency_setup);
     1722                _coherency_setup();
     1723        }
     1724#else
    16841725        coherency_setup();
     1726#endif
    16851727        board_cache_error_setup = r4k_cache_error_setup;
    16861728}
    16871729
  • arch/mips/mm/tlbex.c

    a b static void build_r4000_tlb_refill_handl 
    12841284                        /* No need for uasm_i_nop */
    12851285                }
    12861286
     1287#ifdef CONFIG_BCM47XX
     1288                uasm_i_nop(&p);
     1289#endif
    12871290#ifdef CONFIG_64BIT
    12881291                build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
    12891292#else
    build_r4000_tlbchange_handler_head(u32 * 
    18451848{
    18461849        struct work_registers wr = build_get_work_registers(p);
    18471850
     1851#ifdef CONFIG_BCM47XX
     1852        uasm_i_nop(p);
     1853#endif
    18481854#ifdef CONFIG_64BIT
    18491855        build_get_pmde64(p, l, r, wr.r1, wr.r2); /* get pmd in ptr */
    18501856#else
Note: See TracBrowser for help on using the repository browser.