source: trunk/target/linux/lantiq/patches-3.3/0053-MIPS-lantiq-VPE-extensions.patch @ 31307

Last change on this file since 31307 was 31307, checked in by blogic, 4 years ago

[lantiq] adds 3.3 patches and files

File size: 33.3 KB
  • arch/mips/Kconfig

    From 948bb4dd94209332253d2b69c28f44e2bb11f518 Mon Sep 17 00:00:00 2001
    From: John Crispin <blogic@openwrt.org>
    Date: Thu, 29 Sep 2011 20:30:40 +0200
    Subject: [PATCH 53/70] MIPS: lantiq: VPE extensions
    
    ---
     arch/mips/Kconfig                  |   22 +++
     arch/mips/include/asm/mipsmtregs.h |   54 +++++++
     arch/mips/kernel/Makefile          |    3 +-
     arch/mips/kernel/mips-mt.c         |   97 +++++++++++--
     arch/mips/kernel/mtsched_proc.c    |  279 ++++++++++++++++++++++++++++++++++++
     arch/mips/kernel/perf_proc.c       |  191 ++++++++++++++++++++++++
     arch/mips/kernel/proc.c            |   17 +++
     arch/mips/kernel/smtc.c            |    7 +
     arch/mips/kernel/vpe.c             |  250 ++++++++++++++++++++++++++++++++-
     9 files changed, 905 insertions(+), 15 deletions(-)
     create mode 100644 arch/mips/kernel/mtsched_proc.c
     create mode 100644 arch/mips/kernel/perf_proc.c
    
    diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
    index 0dd8ae3..4a36923 100644
    a b config MIPS_VPE_LOADER 
    19351935          Includes a loader for loading an elf relocatable object 
    19361936          onto another VPE and running it. 
    19371937 
     1938config IFX_VPE_EXT 
     1939        bool "IFX APRP Extensions" 
     1940        depends on MIPS_VPE_LOADER 
     1941        default y 
     1942        help 
     1943          IFX included extensions in APRP 
     1944 
     1945config PERFCTRS 
     1946        bool "34K Performance counters" 
     1947        depends on MIPS_MT && PROC_FS 
     1948        default n 
     1949        help 
     1950          34K Performance counter through /proc 
     1951 
     1952config MTSCHED 
     1953        bool "Support mtsched priority configuration for TCs" 
     1954        depends on MIPS_MT && PROC_FS 
     1955        default y 
     1956        help 
     1957          Support for mtsched priority configuration for TCs through 
     1958          /proc/mips/mtsched 
     1959 
    19381960config MIPS_MT_SMTC_IM_BACKSTOP 
    19391961        bool "Use per-TC register bits as backstop for inhibited IM bits" 
    19401962        depends on MIPS_MT_SMTC 
  • arch/mips/include/asm/mipsmtregs.h

    diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h
    index c9420aa..04bfb4b 100644
    a b  
    2828#define read_c0_vpeconf0()              __read_32bit_c0_register($1, 2) 
    2929#define write_c0_vpeconf0(val)          __write_32bit_c0_register($1, 2, val) 
    3030 
     31#define read_c0_vpeconf1()              __read_32bit_c0_register($1, 3) 
     32#define write_c0_vpeconf1(val)          __write_32bit_c0_register($1, 3, val) 
     33 
     34#define read_c0_vpeschedule()           __read_32bit_c0_register($1, 5) 
     35#define write_c0_vpeschedule(val)       __write_32bit_c0_register($1, 5, val) 
     36 
     37#define read_c0_vpeschefback()          __read_32bit_c0_register($1, 6) 
     38#define write_c0_vpeschefback(val)      __write_32bit_c0_register($1, 6, val) 
     39 
     40#define read_c0_vpeopt()              __read_32bit_c0_register($1, 7) 
     41#define write_c0_vpeopt(val)          __write_32bit_c0_register($1, 7, val) 
     42 
    3143#define read_c0_tcstatus()              __read_32bit_c0_register($2, 1) 
    3244#define write_c0_tcstatus(val)          __write_32bit_c0_register($2, 1, val) 
    3345 
    3446#define read_c0_tcbind()                __read_32bit_c0_register($2, 2) 
     47#define write_c0_tcbind(val)            __write_32bit_c0_register($2, 2, val) 
    3548 
    3649#define read_c0_tccontext()             __read_32bit_c0_register($2, 5) 
    3750#define write_c0_tccontext(val)         __write_32bit_c0_register($2, 5, val) 
    3851 
     52#define read_c0_tcschedule()            __read_32bit_c0_register($2, 6) 
     53#define write_c0_tcschedule(val)        __write_32bit_c0_register($2, 6, val) 
     54 
     55#define read_c0_tcschefback()           __read_32bit_c0_register($2, 7) 
     56#define write_c0_tcschefback(val)       __write_32bit_c0_register($2, 7, val) 
     57 
     58 
    3959#else /* Assembly */ 
    4060/* 
    4161 * Macros for use in assembly language code 
     
    7494#define MVPCONTROL_STLB_SHIFT   2 
    7595#define MVPCONTROL_STLB         (_ULCAST_(1) << MVPCONTROL_STLB_SHIFT) 
    7696 
     97#define MVPCONTROL_CPA_SHIFT    3 
     98#define MVPCONTROL_CPA          (_ULCAST_(1) << MVPCONTROL_CPA_SHIFT) 
    7799 
    78100/* MVPConf0 fields */ 
    79101#define MVPCONF0_PTC_SHIFT      0 
     
    84106#define MVPCONF0_TCA            ( _ULCAST_(1) << MVPCONF0_TCA_SHIFT) 
    85107#define MVPCONF0_PTLBE_SHIFT    16 
    86108#define MVPCONF0_PTLBE          (_ULCAST_(0x3ff) << MVPCONF0_PTLBE_SHIFT) 
     109#define MVPCONF0_PCP_SHIFT      27 
     110#define MVPCONF0_PCP            (_ULCAST_(1) << MVPCONF0_PCP_SHIFT) 
    87111#define MVPCONF0_TLBS_SHIFT     29 
    88112#define MVPCONF0_TLBS           (_ULCAST_(1) << MVPCONF0_TLBS_SHIFT) 
    89113#define MVPCONF0_M_SHIFT        31 
     
    121145#define VPECONF0_VPA            (_ULCAST_(1) << VPECONF0_VPA_SHIFT) 
    122146#define VPECONF0_MVP_SHIFT      1 
    123147#define VPECONF0_MVP            (_ULCAST_(1) << VPECONF0_MVP_SHIFT) 
     148#define VPECONF0_ICS_SHIFT      16 
     149#define VPECONF0_ICS            (_ULCAST_(1) << VPECONF0_ICS_SHIFT) 
     150#define VPECONF0_DCS_SHIFT      17 
     151#define VPECONF0_DCS            (_ULCAST_(1) << VPECONF0_DCS_SHIFT) 
    124152#define VPECONF0_XTC_SHIFT      21 
    125153#define VPECONF0_XTC            (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT) 
    126154 
     155/* VPEOpt fields */ 
     156#define VPEOPT_DWX_SHIFT        0 
     157#define VPEOPT_IWX_SHIFT        8 
     158#define VPEOPT_IWX0             ( _ULCAST_(0x1) << VPEOPT_IWX_SHIFT) 
     159#define VPEOPT_IWX1             ( _ULCAST_(0x2) << VPEOPT_IWX_SHIFT) 
     160#define VPEOPT_IWX2             ( _ULCAST_(0x4) << VPEOPT_IWX_SHIFT) 
     161#define VPEOPT_IWX3             ( _ULCAST_(0x8) << VPEOPT_IWX_SHIFT) 
     162#define VPEOPT_DWX0             ( _ULCAST_(0x1) << VPEOPT_DWX_SHIFT) 
     163#define VPEOPT_DWX1             ( _ULCAST_(0x2) << VPEOPT_DWX_SHIFT) 
     164#define VPEOPT_DWX2             ( _ULCAST_(0x4) << VPEOPT_DWX_SHIFT) 
     165#define VPEOPT_DWX3             ( _ULCAST_(0x8) << VPEOPT_DWX_SHIFT) 
     166 
    127167/* TCStatus fields (per TC) */ 
    128168#define TCSTATUS_TASID          (_ULCAST_(0xff)) 
    129169#define TCSTATUS_IXMT_SHIFT     10 
    do { \ 
    350390#define write_vpe_c0_vpecontrol(val)    mttc0(1, 1, val) 
    351391#define read_vpe_c0_vpeconf0()          mftc0(1, 2) 
    352392#define write_vpe_c0_vpeconf0(val)      mttc0(1, 2, val) 
     393#define read_vpe_c0_vpeschedule()       mftc0(1, 5) 
     394#define write_vpe_c0_vpeschedule(val)   mttc0(1, 5, val) 
     395#define read_vpe_c0_vpeschefback()      mftc0(1, 6) 
     396#define write_vpe_c0_vpeschefback(val)  mttc0(1, 6, val) 
     397#define read_vpe_c0_vpeopt()            mftc0(1, 7) 
     398#define write_vpe_c0_vpeopt(val)        mttc0(1, 7, val) 
     399#define read_vpe_c0_wired()             mftc0(6, 0) 
     400#define write_vpe_c0_wired(val)         mttc0(6, 0, val) 
    353401#define read_vpe_c0_count()             mftc0(9, 0) 
    354402#define write_vpe_c0_count(val)         mttc0(9, 0, val) 
    355403#define read_vpe_c0_status()            mftc0(12, 0) 
    do { \ 
    381429#define write_tc_c0_tchalt(val)         mttc0(2, 4, val) 
    382430#define read_tc_c0_tccontext()          mftc0(2, 5) 
    383431#define write_tc_c0_tccontext(val)      mttc0(2, 5, val) 
     432#define read_tc_c0_tcschedule()         mftc0(2, 6) 
     433#define write_tc_c0_tcschedule(val)     mttc0(2, 6, val) 
     434#define read_tc_c0_tcschefback()        mftc0(2, 7) 
     435#define write_tc_c0_tcschefback(val)    mttc0(2, 7, val) 
     436#define read_tc_c0_entryhi()            mftc0(10, 0) 
     437#define write_tc_c0_entryhi(val)        mttc0(10, 0, val) 
    384438 
    385439/* GPR */ 
    386440#define read_tc_gpr_sp()                mftgpr(29) 
  • arch/mips/kernel/Makefile

    diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
    index 0c6877e..4d75dd7 100644
    a b obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o 
    9090 
    9191obj-$(CONFIG_KGDB)              += kgdb.o 
    9292obj-$(CONFIG_PROC_FS)           += proc.o 
    93  
     93obj-$(CONFIG_MTSCHED)           += mtsched_proc.o 
     94obj-$(CONFIG_PERFCTRS)          += perf_proc.o 
    9495obj-$(CONFIG_64BIT)             += cpu-bugs64.o 
    9596 
    9697obj-$(CONFIG_I8253)             += i8253.o 
  • arch/mips/kernel/mips-mt.c

    diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c
    index c23d11f..11d6489 100644
    a b  
    2121#include <asm/cacheflush.h> 
    2222 
    2323int vpelimit; 
    24  
    2524static int __init maxvpes(char *str) 
    2625{ 
    2726        get_option(&str, &vpelimit); 
    28  
    2927        return 1; 
    3028} 
    31  
    3229__setup("maxvpes=", maxvpes); 
    3330 
    3431int tclimit; 
    35  
    3632static int __init maxtcs(char *str) 
    3733{ 
    3834        get_option(&str, &tclimit); 
     35        return 1; 
     36} 
     37__setup("maxtcs=", maxtcs); 
    3938 
     39#ifdef CONFIG_IFX_VPE_EXT 
     40int stlb; 
     41static int __init istlbshared(char *str) 
     42{ 
     43        get_option(&str, &stlb); 
    4044        return 1; 
    4145} 
     46__setup("vpe_tlb_shared=", istlbshared); 
    4247 
    43 __setup("maxtcs=", maxtcs); 
     48int vpe0_wired; 
     49static int __init vpe0wired(char *str) 
     50{ 
     51        get_option(&str, &vpe0_wired); 
     52        return 1; 
     53} 
     54__setup("vpe0_wired_tlb_entries=", vpe0wired); 
     55 
     56int vpe1_wired; 
     57static int __init vpe1wired(char *str) 
     58{ 
     59        get_option(&str, &vpe1_wired); 
     60        return 1; 
     61} 
     62__setup("vpe1_wired_tlb_entries=", vpe1wired); 
     63 
     64#ifdef CONFIG_MIPS_MT_SMTC 
     65extern int nostlb; 
     66#endif 
     67void configure_tlb(void) 
     68{ 
     69        int vpeflags, tcflags, tlbsiz; 
     70        unsigned int config1val; 
     71        vpeflags = dvpe(); 
     72        tcflags = dmt(); 
     73        write_c0_vpeconf0((read_c0_vpeconf0() | VPECONF0_MVP)); 
     74        write_c0_mvpcontrol((read_c0_mvpcontrol() | MVPCONTROL_VPC)); 
     75        mips_ihb(); 
     76        //printk("stlb = %d, vpe0_wired = %d vpe1_wired=%d\n", stlb,vpe0_wired, vpe1_wired); 
     77        if (stlb) { 
     78                if (!(read_c0_mvpconf0() & MVPCONF0_TLBS)) { 
     79                        emt(tcflags); 
     80                        evpe(vpeflags); 
     81                        return; 
     82                } 
     83 
     84                write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_STLB); 
     85                write_c0_wired(vpe0_wired + vpe1_wired); 
     86                if (((read_vpe_c0_config() & MIPS_CONF_MT) >> 7) == 1) { 
     87                        config1val = read_vpe_c0_config1(); 
     88                        tlbsiz = (((config1val >> 25) & 0x3f) + 1); 
     89                        if (tlbsiz > 64) 
     90                                tlbsiz = 64; 
     91                        cpu_data[0].tlbsize = tlbsiz; 
     92                        current_cpu_data.tlbsize = tlbsiz; 
     93                } 
     94 
     95        } 
     96        else { 
     97                write_c0_mvpcontrol(read_c0_mvpcontrol() & ~MVPCONTROL_STLB); 
     98                write_c0_wired(vpe0_wired); 
     99        } 
     100 
     101        ehb(); 
     102        write_c0_mvpcontrol((read_c0_mvpcontrol() & ~MVPCONTROL_VPC)); 
     103        ehb(); 
     104        local_flush_tlb_all(); 
     105 
     106        printk("Wired TLB entries for Linux read_c0_wired() = %d\n", read_c0_wired()); 
     107#ifdef CONFIG_MIPS_MT_SMTC 
     108        nostlb = !stlb; 
     109#endif 
     110        emt(tcflags); 
     111        evpe(vpeflags); 
     112} 
     113#endif 
    44114 
    45115/* 
    46116 * Dump new MIPS MT state for the core. Does not leave TCs halted. 
    void mips_mt_regdump(unsigned long mvpctl) 
    78148                        if ((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) { 
    79149                                printk("  VPE %d\n", i); 
    80150                                printk("   VPEControl : %08lx\n", 
    81                                        read_vpe_c0_vpecontrol()); 
     151                                        read_vpe_c0_vpecontrol()); 
    82152                                printk("   VPEConf0 : %08lx\n", 
    83                                        read_vpe_c0_vpeconf0()); 
     153                                        read_vpe_c0_vpeconf0()); 
    84154                                printk("   VPE%d.Status : %08lx\n", 
    85                                        i, read_vpe_c0_status()); 
     155                                        i, read_vpe_c0_status()); 
    86156                                printk("   VPE%d.EPC : %08lx %pS\n", 
    87                                        i, read_vpe_c0_epc(), 
    88                                        (void *) read_vpe_c0_epc()); 
     157                                        i, read_vpe_c0_epc(), 
     158                                        (void *) read_vpe_c0_epc()); 
    89159                                printk("   VPE%d.Cause : %08lx\n", 
    90                                        i, read_vpe_c0_cause()); 
     160                                        i, read_vpe_c0_cause()); 
    91161                                printk("   VPE%d.Config7 : %08lx\n", 
    92                                        i, read_vpe_c0_config7()); 
     162                                        i, read_vpe_c0_config7()); 
    93163                                break; /* Next VPE */ 
    94164                        } 
    95165                } 
    void mips_mt_set_cpuoptions(void) 
    287357                printk("Mapped %ld ITC cells starting at 0x%08x\n", 
    288358                        ((itcblkgrn & 0x7fe00000) >> 20), itc_base); 
    289359        } 
     360#ifdef CONFIG_IFX_VPE_EXT 
     361        configure_tlb(); 
     362#endif 
    290363} 
    291364 
    292365/* 
  • new file arch/mips/kernel/mtsched_proc.c

    diff --git a/arch/mips/kernel/mtsched_proc.c b/arch/mips/kernel/mtsched_proc.c
    new file mode 100644
    index 0000000..4dafded
    - +  
     1/* 
     2 * /proc hooks for MIPS MT scheduling policy management for 34K cores 
     3 * 
     4 *  This program is free software; you can distribute it and/or modify it 
     5 *  under the terms of the GNU General Public License (Version 2) as 
     6 *  published by the Free Software Foundation. 
     7 * 
     8 *  This program is distributed in the hope it will be useful, but WITHOUT 
     9 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
     10 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
     11 *  for more details. 
     12 * 
     13 *  You should have received a copy of the GNU General Public License along 
     14 *  with this program; if not, write to the Free Software Foundation, Inc., 
     15 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 
     16 * 
     17 * Copyright (C) 2006 Mips Technologies, Inc 
     18 */ 
     19 
     20#include <linux/kernel.h> 
     21 
     22#include <asm/cpu.h> 
     23#include <asm/processor.h> 
     24#include <asm/system.h> 
     25#include <asm/mipsregs.h> 
     26#include <asm/mipsmtregs.h> 
     27#include <asm/uaccess.h> 
     28#include <linux/proc_fs.h> 
     29 
     30static struct proc_dir_entry *mtsched_proc; 
     31 
     32#ifndef CONFIG_MIPS_MT_SMTC 
     33#define NTCS 2 
     34#else 
     35#define NTCS NR_CPUS 
     36#endif 
     37#define NVPES 2 
     38 
     39int lastvpe = 1; 
     40int lasttc = 8; 
     41 
     42static int proc_read_mtsched(char *page, char **start, off_t off, 
     43                        int count, int *eof, void *data) 
     44{ 
     45        int totalen = 0; 
     46        int len; 
     47 
     48        int i; 
     49        int vpe; 
     50        int mytc; 
     51        unsigned long flags; 
     52        unsigned int mtflags; 
     53        unsigned int haltstate; 
     54        unsigned int vpes_checked[NVPES]; 
     55        unsigned int vpeschedule[NVPES]; 
     56        unsigned int vpeschefback[NVPES]; 
     57        unsigned int tcschedule[NTCS]; 
     58        unsigned int tcschefback[NTCS]; 
     59 
     60        /* Dump the state of the MIPS MT scheduling policy manager */ 
     61        /* Inititalize control state */ 
     62        for(i = 0; i < NVPES; i++) { 
     63                vpes_checked[i] = 0; 
     64                vpeschedule[i] = 0; 
     65                vpeschefback[i] = 0; 
     66        } 
     67        for(i = 0; i < NTCS; i++) { 
     68                tcschedule[i] = 0; 
     69                tcschefback[i] = 0; 
     70        } 
     71 
     72        /* Disable interrupts and multithreaded issue */ 
     73        local_irq_save(flags); 
     74        mtflags = dvpe(); 
     75 
     76        /* Then go through the TCs, halt 'em, and extract the values */ 
     77        mytc = (read_c0_tcbind() & TCBIND_CURTC) >> TCBIND_CURTC_SHIFT; 
     78        for(i = 0; i < NTCS; i++) { 
     79                if(i == mytc) { 
     80                        /* No need to halt ourselves! */ 
     81                        tcschedule[i] = read_c0_tcschedule(); 
     82                        tcschefback[i] = read_c0_tcschefback(); 
     83                        /* If VPE bound to TC hasn't been checked, do it */ 
     84                        vpe = read_c0_tcbind() & TCBIND_CURVPE; 
     85                        if(!vpes_checked[vpe]) { 
     86                                vpeschedule[vpe] = read_c0_vpeschedule(); 
     87                                vpeschefback[vpe] = read_c0_vpeschefback(); 
     88                                vpes_checked[vpe] = 1; 
     89                        } 
     90                } else { 
     91                        settc(i); 
     92                        haltstate = read_tc_c0_tchalt(); 
     93                        write_tc_c0_tchalt(TCHALT_H); 
     94                        mips_ihb(); 
     95                        tcschedule[i] = read_tc_c0_tcschedule(); 
     96                        tcschefback[i] = read_tc_c0_tcschefback(); 
     97                        /* If VPE bound to TC hasn't been checked, do it */ 
     98                        vpe = read_tc_c0_tcbind() & TCBIND_CURVPE; 
     99                        if(!vpes_checked[vpe]) { 
     100                            vpeschedule[vpe] = read_vpe_c0_vpeschedule(); 
     101                            vpeschefback[vpe] = read_vpe_c0_vpeschefback(); 
     102                            vpes_checked[vpe] = 1; 
     103                        } 
     104                        if(!haltstate) write_tc_c0_tchalt(0); 
     105                } 
     106        } 
     107        /* Re-enable MT and interrupts */ 
     108        evpe(mtflags); 
     109        local_irq_restore(flags); 
     110 
     111        for(vpe=0; vpe < NVPES; vpe++) { 
     112                len = sprintf(page, "VPE[%d].VPEschedule  = 0x%08x\n", 
     113                        vpe, vpeschedule[vpe]); 
     114                totalen += len; 
     115                page += len; 
     116                len = sprintf(page, "VPE[%d].VPEschefback = 0x%08x\n", 
     117                        vpe, vpeschefback[vpe]); 
     118                totalen += len; 
     119                page += len; 
     120        } 
     121        for(i=0; i < NTCS; i++) { 
     122                len = sprintf(page, "TC[%d].TCschedule    = 0x%08x\n", 
     123                        i, tcschedule[i]); 
     124                totalen += len; 
     125                page += len; 
     126                len = sprintf(page, "TC[%d].TCschefback   = 0x%08x\n", 
     127                        i, tcschefback[i]); 
     128                totalen += len; 
     129                page += len; 
     130        } 
     131        return totalen; 
     132} 
     133 
     134/* 
     135 * Write to perf counter registers based on text input 
     136 */ 
     137 
     138#define TXTBUFSZ 100 
     139 
     140static int proc_write_mtsched(struct file *file, const char *buffer, 
     141                                unsigned long count, void *data) 
     142{ 
     143        int len = 0; 
     144        char mybuf[TXTBUFSZ]; 
     145        /* At most, we will set up 9 TCs and 2 VPEs, 11 entries in all */ 
     146        char entity[1];   //, entity1[1]; 
     147        int number[1]; 
     148        unsigned long value[1]; 
     149        int nparsed = 0 , index = 0; 
     150        unsigned long flags; 
     151        unsigned int mtflags; 
     152        unsigned int haltstate; 
     153        unsigned int tcbindval; 
     154 
     155        if(count >= TXTBUFSZ) len = TXTBUFSZ-1; 
     156        else len = count; 
     157        memset(mybuf,0,TXTBUFSZ); 
     158        if(copy_from_user(mybuf, buffer, len)) return -EFAULT; 
     159 
     160        nparsed = sscanf(mybuf, "%c%d %lx", 
     161                 &entity[0] ,&number[0], &value[0]); 
     162 
     163        /* 
     164         * Having acquired the inputs, which might have 
     165         * generated exceptions and preemptions, 
     166         * program the registers. 
     167         */ 
     168        /* Disable interrupts and multithreaded issue */ 
     169        local_irq_save(flags); 
     170        mtflags = dvpe(); 
     171 
     172        if(entity[index] == 't' ) { 
     173                /* Set TCSchedule or TCScheFBack of specified TC */ 
     174                if(number[index] > NTCS) goto skip; 
     175                /* If it's our own TC, do it direct */ 
     176                if(number[index] == 
     177                                ((read_c0_tcbind() & TCBIND_CURTC) 
     178                                >> TCBIND_CURTC_SHIFT)) { 
     179                        if(entity[index] == 't') 
     180                                 write_c0_tcschedule(value[index]); 
     181                        else 
     182                                write_c0_tcschefback(value[index]); 
     183                } else { 
     184                /* Otherwise, we do it via MTTR */ 
     185                        settc(number[index]); 
     186                        haltstate = read_tc_c0_tchalt(); 
     187                        write_tc_c0_tchalt(TCHALT_H); 
     188                        mips_ihb(); 
     189                        if(entity[index] == 't') 
     190                                 write_tc_c0_tcschedule(value[index]); 
     191                        else 
     192                                write_tc_c0_tcschefback(value[index]); 
     193                        mips_ihb(); 
     194                        if(!haltstate) write_tc_c0_tchalt(0); 
     195                } 
     196        } else if(entity[index] == 'v') { 
     197                /* Set VPESchedule of specified VPE */ 
     198                if(number[index] > NVPES) goto skip; 
     199                tcbindval = read_c0_tcbind(); 
     200                /* Are we doing this to our current VPE? */ 
     201                if((tcbindval & TCBIND_CURVPE) == number[index]) { 
     202                        /* Then life is simple */ 
     203                        write_c0_vpeschedule(value[index]); 
     204                } else { 
     205                        /* 
     206                         * Bind ourselves to the other VPE long enough 
     207                         * to program the bind value. 
     208                         */ 
     209                        write_c0_tcbind((tcbindval & ~TCBIND_CURVPE) 
     210                                           | number[index]); 
     211                        mips_ihb(); 
     212                        write_c0_vpeschedule(value[index]); 
     213                        mips_ihb(); 
     214                        /* Restore previous binding */ 
     215                        write_c0_tcbind(tcbindval); 
     216                        mips_ihb(); 
     217                } 
     218        } 
     219 
     220        else if(entity[index] == 'r') { 
     221                unsigned int vpes_checked[2], vpe ,i , mytc; 
     222                vpes_checked[0] = vpes_checked[1] = 0; 
     223 
     224                /* Then go through the TCs, halt 'em, and extract the values */ 
     225                mytc = (read_c0_tcbind() & TCBIND_CURTC) >> TCBIND_CURTC_SHIFT; 
     226 
     227                for(i = 0; i < NTCS; i++) { 
     228                        if(i == mytc) { 
     229                                /* No need to halt ourselves! */ 
     230                                write_c0_vpeschefback(0); 
     231                                write_c0_tcschefback(0); 
     232                        } else { 
     233                                settc(i); 
     234                                haltstate = read_tc_c0_tchalt(); 
     235                                write_tc_c0_tchalt(TCHALT_H); 
     236                                mips_ihb(); 
     237                                write_tc_c0_tcschefback(0); 
     238                                /* If VPE bound to TC hasn't been checked, do it */ 
     239                                vpe = read_tc_c0_tcbind() & TCBIND_CURVPE; 
     240                                if(!vpes_checked[vpe]) { 
     241                                    write_vpe_c0_vpeschefback(0); 
     242                                    vpes_checked[vpe] = 1; 
     243                                } 
     244                                if(!haltstate) write_tc_c0_tchalt(0); 
     245                        } 
     246                } 
     247        } 
     248        else { 
     249                printk ("\n Usage : <t/v><0/1> <Hex Value>\n Example : t0 0x01\n"); 
     250        } 
     251 
     252skip: 
     253        /* Re-enable MT and interrupts */ 
     254        evpe(mtflags); 
     255        local_irq_restore(flags); 
     256        return (len); 
     257} 
     258 
     259static int __init init_mtsched_proc(void) 
     260{ 
     261        extern struct proc_dir_entry *get_mips_proc_dir(void); 
     262        struct proc_dir_entry *mips_proc_dir; 
     263 
     264        if (!cpu_has_mipsmt) { 
     265                printk("mtsched: not a MIPS MT capable processor\n"); 
     266                return -ENODEV; 
     267        } 
     268 
     269        mips_proc_dir = get_mips_proc_dir(); 
     270 
     271        mtsched_proc = create_proc_entry("mtsched", 0644, mips_proc_dir); 
     272        mtsched_proc->read_proc = proc_read_mtsched; 
     273        mtsched_proc->write_proc = proc_write_mtsched; 
     274 
     275        return 0; 
     276} 
     277 
     278/* Automagically create the entry */ 
     279module_init(init_mtsched_proc); 
  • new file arch/mips/kernel/perf_proc.c

    diff --git a/arch/mips/kernel/perf_proc.c b/arch/mips/kernel/perf_proc.c
    new file mode 100644
    index 0000000..7eec015
    - +  
     1/* 
     2 * /proc hooks for CPU performance counter support for SMTC kernel 
     3 * (and ultimately others) 
     4 * Copyright (C) 2006 Mips Technologies, Inc 
     5 */ 
     6 
     7#include <linux/kernel.h> 
     8 
     9#include <asm/cpu.h> 
     10#include <asm/processor.h> 
     11#include <asm/system.h> 
     12#include <asm/mipsregs.h> 
     13#include <asm/uaccess.h> 
     14#include <linux/proc_fs.h> 
     15 
     16/* 
     17 * /proc diagnostic and statistics hooks 
     18 */ 
     19 
     20 
     21/* Internal software-extended event counters */ 
     22 
     23static unsigned long long extencount[4] = {0,0,0,0}; 
     24 
     25static struct proc_dir_entry *perf_proc; 
     26 
     27static int proc_read_perf(char *page, char **start, off_t off, 
     28                                int count, int *eof, void *data) 
     29{ 
     30        int totalen = 0; 
     31        int len; 
     32 
     33        len = sprintf(page, "PerfCnt[0].Ctl : 0x%08x\n", read_c0_perfctrl0()); 
     34        totalen += len; 
     35        page += len; 
     36        len = sprintf(page, "PerfCnt[0].Cnt : %Lu\n", 
     37                extencount[0] + (unsigned long long)((unsigned)read_c0_perfcntr0())); 
     38        totalen += len; 
     39        page += len; 
     40        len = sprintf(page, "PerfCnt[1].Ctl : 0x%08x\n", read_c0_perfctrl1()); 
     41        totalen += len; 
     42        page += len; 
     43        len = sprintf(page, "PerfCnt[1].Cnt : %Lu\n", 
     44                extencount[1] + (unsigned long long)((unsigned)read_c0_perfcntr1())); 
     45        totalen += len; 
     46        page += len; 
     47        len = sprintf(page, "PerfCnt[2].Ctl : 0x%08x\n", read_c0_perfctrl2()); 
     48        totalen += len; 
     49        page += len; 
     50        len = sprintf(page, "PerfCnt[2].Cnt : %Lu\n", 
     51                extencount[2] + (unsigned long long)((unsigned)read_c0_perfcntr2())); 
     52        totalen += len; 
     53        page += len; 
     54        len = sprintf(page, "PerfCnt[3].Ctl : 0x%08x\n", read_c0_perfctrl3()); 
     55        totalen += len; 
     56        page += len; 
     57        len = sprintf(page, "PerfCnt[3].Cnt : %Lu\n", 
     58                extencount[3] + (unsigned long long)((unsigned)read_c0_perfcntr3())); 
     59        totalen += len; 
     60        page += len; 
     61 
     62        return totalen; 
     63} 
     64 
     65/* 
     66 * Write to perf counter registers based on text input 
     67 */ 
     68 
     69#define TXTBUFSZ 100 
     70 
     71static int proc_write_perf(struct file *file, const char *buffer, 
     72                                unsigned long count, void *data) 
     73{ 
     74        int len; 
     75        int nparsed; 
     76        int index; 
     77        char mybuf[TXTBUFSZ]; 
     78 
     79        int which[4]; 
     80        unsigned long control[4]; 
     81        long long ctrdata[4]; 
     82 
     83        if(count >= TXTBUFSZ) len = TXTBUFSZ-1; 
     84        else len = count; 
     85        memset(mybuf,0,TXTBUFSZ); 
     86        if(copy_from_user(mybuf, buffer, len)) return -EFAULT; 
     87 
     88        nparsed = sscanf(mybuf, 
     89                        "%d %lx %Ld %d %lx %Ld %d %lx %Ld %d %lx %Ld", 
     90                                &which[0], &control[0], &ctrdata[0], 
     91                                &which[1], &control[1], &ctrdata[1], 
     92                                &which[2], &control[2], &ctrdata[2], 
     93                                &which[3], &control[3], &ctrdata[3]); 
     94 
     95        for(index = 0; nparsed >= 3; index++) { 
     96                switch (which[index]) { 
     97                case 0: 
     98                        write_c0_perfctrl0(control[index]); 
     99                        if(ctrdata[index] != -1) { 
     100                            extencount[0] = (unsigned long long)ctrdata[index]; 
     101                            write_c0_perfcntr0((unsigned long)0); 
     102                        } 
     103                        break; 
     104                case 1: 
     105                        write_c0_perfctrl1(control[index]); 
     106                        if(ctrdata[index] != -1) { 
     107                            extencount[1] = (unsigned long long)ctrdata[index]; 
     108                            write_c0_perfcntr1((unsigned long)0); 
     109                        } 
     110                        break; 
     111                case 2: 
     112                        write_c0_perfctrl2(control[index]); 
     113                        if(ctrdata[index] != -1) { 
     114                            extencount[2] = (unsigned long long)ctrdata[index]; 
     115                            write_c0_perfcntr2((unsigned long)0); 
     116                        } 
     117                        break; 
     118                case 3: 
     119                        write_c0_perfctrl3(control[index]); 
     120                        if(ctrdata[index] != -1) { 
     121                            extencount[3] = (unsigned long long)ctrdata[index]; 
     122                            write_c0_perfcntr3((unsigned long)0); 
     123                        } 
     124                        break; 
     125                } 
     126                nparsed -= 3; 
     127        } 
     128        return (len); 
     129} 
     130 
     131extern int (*perf_irq)(void); 
     132 
     133/* 
     134 * Invoked when timer interrupt vector picks up a perf counter overflow 
     135 */ 
     136 
     137static int perf_proc_irq(void) 
     138{ 
     139        unsigned long snapshot; 
     140 
     141        /* 
     142         * It would be nice to do this as a loop, but we don't have 
     143         * indirect access to CP0 registers. 
     144         */ 
     145        snapshot = read_c0_perfcntr0(); 
     146        if ((long)snapshot < 0) { 
     147                extencount[0] += 
     148                        (unsigned long long)((unsigned)read_c0_perfcntr0()); 
     149                write_c0_perfcntr0(0); 
     150        } 
     151        snapshot = read_c0_perfcntr1(); 
     152        if ((long)snapshot < 0) { 
     153                extencount[1] += 
     154                        (unsigned long long)((unsigned)read_c0_perfcntr1()); 
     155                write_c0_perfcntr1(0); 
     156        } 
     157        snapshot = read_c0_perfcntr2(); 
     158        if ((long)snapshot < 0) { 
     159                extencount[2] += 
     160                        (unsigned long long)((unsigned)read_c0_perfcntr2()); 
     161                write_c0_perfcntr2(0); 
     162        } 
     163        snapshot = read_c0_perfcntr3(); 
     164        if ((long)snapshot < 0) { 
     165                extencount[3] += 
     166                        (unsigned long long)((unsigned)read_c0_perfcntr3()); 
     167                write_c0_perfcntr3(0); 
     168        } 
     169        return 0; 
     170} 
     171 
     172static int __init init_perf_proc(void) 
     173{ 
     174        extern struct proc_dir_entry *get_mips_proc_dir(void); 
     175 
     176        struct proc_dir_entry *mips_proc_dir = get_mips_proc_dir(); 
     177 
     178        write_c0_perfcntr0(0); 
     179        write_c0_perfcntr1(0); 
     180        write_c0_perfcntr2(0); 
     181        write_c0_perfcntr3(0); 
     182        perf_proc = create_proc_entry("perf", 0644, mips_proc_dir); 
     183        perf_proc->read_proc = proc_read_perf; 
     184        perf_proc->write_proc = proc_write_perf; 
     185        perf_irq = perf_proc_irq; 
     186 
     187        return 0; 
     188} 
     189 
     190/* Automagically create the entry */ 
     191module_init(init_perf_proc); 
  • arch/mips/kernel/proc.c

    diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
    index e309665..2de204f 100644
    a b  
    77#include <linux/kernel.h> 
    88#include <linux/sched.h> 
    99#include <linux/seq_file.h> 
     10#include <linux/proc_fs.h> 
    1011#include <asm/bootinfo.h> 
    1112#include <asm/cpu.h> 
    1213#include <asm/cpu-features.h> 
    const struct seq_operations cpuinfo_op = { 
    110111        .stop   = c_stop, 
    111112        .show   = show_cpuinfo, 
    112113}; 
     114 
     115/* 
     116 * Support for MIPS/local /proc hooks in /proc/mips/ 
     117 */ 
     118 
     119static struct proc_dir_entry *mips_proc = NULL; 
     120 
     121struct proc_dir_entry *get_mips_proc_dir(void) 
     122{ 
     123       /* 
     124        * This ought not to be preemptable. 
     125        */ 
     126       if(mips_proc == NULL) 
     127               mips_proc = proc_mkdir("mips", NULL); 
     128       return(mips_proc); 
     129} 
  • arch/mips/kernel/smtc.c

    diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
    index 0a42ff3..41f5258 100644
    a b void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) 
    13341334        asid = asid_cache(cpu); 
    13351335 
    13361336        do { 
     1337#ifdef CONFIG_IFX_VPE_EXT 
     1338                /* If TLB is shared between AP and RP (AP is running SMTC), 
     1339                   leave out max ASID i.e., ASID_MASK for RP 
     1340                 */ 
     1341                if (!nostlb && ((asid & ASID_MASK) == (ASID_MASK - 1))) 
     1342                        asid++; 
     1343#endif 
    13371344                if (!((asid += ASID_INC) & ASID_MASK) ) { 
    13381345                        if (cpu_has_vtag_icache) 
    13391346                                flush_icache_all(); 
  • arch/mips/kernel/vpe.c

    diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
    index bfa12a4..e338ba5 100644
    a b static struct kspd_notifications kspd_events; 
    7575static int kspd_events_reqd; 
    7676#endif 
    7777 
     78#ifdef CONFIG_IFX_VPE_EXT 
     79static int is_sdepgm; 
     80extern int stlb; 
     81extern int vpe0_wired; 
     82extern int vpe1_wired; 
     83unsigned int vpe1_load_addr; 
     84 
     85static int __init load_address(char *str) 
     86{ 
     87        get_option(&str, &vpe1_load_addr); 
     88        return 1; 
     89} 
     90__setup("vpe1_load_addr=", load_address); 
     91 
     92#include <asm/mipsmtregs.h> 
     93#define write_vpe_c0_wired(val)         mttc0(6, 0, val) 
     94 
     95#ifndef COMMAND_LINE_SIZE 
     96#       define COMMAND_LINE_SIZE        512 
     97#endif 
     98 
     99char command_line[COMMAND_LINE_SIZE * 2]; 
     100 
     101static unsigned int vpe1_mem; 
     102static int __init vpe1mem(char *str) 
     103{ 
     104        vpe1_mem = memparse(str, &str); 
     105        return 1; 
     106} 
     107__setup("vpe1_mem=", vpe1mem); 
     108 
     109uint32_t vpe1_wdog_ctr; 
     110static int __init wdog_ctr(char *str) 
     111{ 
     112        get_option(&str, &vpe1_wdog_ctr); 
     113        return 1; 
     114} 
     115 
     116__setup("vpe1_wdog_ctr_addr=", wdog_ctr); 
     117EXPORT_SYMBOL(vpe1_wdog_ctr); 
     118 
     119uint32_t vpe1_wdog_timeout; 
     120static int __init wdog_timeout(char *str) 
     121{ 
     122        get_option(&str, &vpe1_wdog_timeout); 
     123        return 1; 
     124} 
     125 
     126__setup("vpe1_wdog_timeout=", wdog_timeout); 
     127EXPORT_SYMBOL(vpe1_wdog_timeout); 
     128 
     129#endif 
    78130/* grab the likely amount of memory we will need. */ 
    79131#ifdef CONFIG_MIPS_VPE_LOADER_TOM 
    80132#define P_SIZE (2 * 1024 * 1024) 
    static void *alloc_progmem(unsigned long len) 
    267319        void *addr; 
    268320 
    269321#ifdef CONFIG_MIPS_VPE_LOADER_TOM 
     322#ifdef CONFIG_IFX_VPE_EXT 
     323        if (vpe1_load_addr) { 
     324                memset((void *)vpe1_load_addr, 0, len); 
     325                return (void *)vpe1_load_addr; 
     326        } 
     327#endif 
     328 
    270329        /* 
    271330         * This means you must tell Linux to use less memory than you 
    272331         * physically have, for example by passing a mem= boot argument. 
    static int vpe_run(struct vpe * v) 
    745804        } 
    746805 
    747806        /* Write the address we want it to start running from in the TCPC register. */ 
     807#if defined(CONFIG_IFX_VPE_EXT) && 0 
     808        if (stlb) 
     809                write_vpe_c0_wired(vpe0_wired + vpe1_wired); 
     810        else 
     811                write_vpe_c0_wired(vpe1_wired); 
     812#endif 
    748813        write_tc_c0_tcrestart((unsigned long)v->__start); 
    749814        write_tc_c0_tccontext((unsigned long)0); 
    750815 
    static int vpe_run(struct vpe * v) 
    758823 
    759824        write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H); 
    760825 
     826#if defined(CONFIG_IFX_VPE_EXT) && 0 
     827        /* 
     828         * $a2 & $a3 are used to pass command line parameters to VPE1. $a2 
     829         * points to the start of the command line string and $a3 points to 
     830         * the end of the string. This convention is identical to the Linux 
     831         * kernel boot parameter passing mechanism. Please note that $a3 is 
     832         * used to pass physical memory size or 0 in SDE tool kit. So, if you 
     833         * are passing comand line parameters through $a2 & $a3 SDE programs 
     834         * don't work as desired. 
     835         */ 
     836        mttgpr(6, command_line); 
     837        mttgpr(7, (command_line + strlen(command_line))); 
     838        if (is_sdepgm) 
     839#endif 
    761840        /* 
    762841         * The sde-kit passes 'memsize' to __start in $a3, so set something 
    763842         * here...  Or set $a3 to zero and define DFLT_STACK_SIZE and 
    static int find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs, 
    832911        if ( (v->__start == 0) || (v->shared_ptr == NULL)) 
    833912                return -1; 
    834913 
     914#ifdef CONFIG_IFX_VPE_EXT 
     915        is_sdepgm = 1; 
     916#endif 
    835917        return 0; 
    836918} 
    837919 
    static int vpe_elfload(struct vpe * v) 
    9931075                           (unsigned long)v->load_addr + v->len); 
    9941076 
    9951077        if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) { 
     1078#ifdef CONFIG_IFX_VPE_EXT 
     1079                if (vpe1_load_addr) { 
     1080                        /* Conversion to KSEG1 is required ??? */ 
     1081                        v->__start = KSEG1ADDR(vpe1_load_addr); 
     1082                        is_sdepgm = 0; 
     1083                        return 0; 
     1084                } 
     1085#endif 
     1086 
    9961087                if (v->__start == 0) { 
    9971088                        printk(KERN_WARNING "VPE loader: program does not contain " 
    9981089                               "a __start symbol\n"); 
    static int vpe_open(struct inode *inode, struct file *filp) 
    10631154        struct vpe_notifications *not; 
    10641155        struct vpe *v; 
    10651156        int ret; 
     1157#ifdef CONFIG_IFX_VPE_EXT 
     1158   int progsize; 
     1159#endif 
    10661160 
    10671161        if (minor != iminor(inode)) { 
    10681162                /* assume only 1 device at the moment. */ 
    static int vpe_open(struct inode *inode, struct file *filp) 
    10881182                release_progmem(v->load_addr); 
    10891183                cleanup_tc(get_tc(tclimit)); 
    10901184        } 
    1091  
     1185#ifdef CONFIG_IFX_VPE_EXT 
     1186        progsize = (vpe1_mem  != 0) ? vpe1_mem : P_SIZE; 
     1187        //printk("progsize = %x\n", progsize); 
     1188        v->pbuffer = vmalloc(progsize); 
     1189        v->plen = progsize; 
     1190#else 
    10921191        /* this of-course trashes what was there before... */ 
    10931192        v->pbuffer = vmalloc(P_SIZE); 
    10941193        if (!v->pbuffer) { 
    static int vpe_open(struct inode *inode, struct file *filp) 
    10961195                return -ENOMEM; 
    10971196        } 
    10981197        v->plen = P_SIZE; 
     1198#endif 
    10991199        v->load_addr = NULL; 
    11001200        v->len = 0; 
    11011201 
     1202#if 0 
    11021203        v->uid = filp->f_cred->fsuid; 
    11031204        v->gid = filp->f_cred->fsgid; 
     1205#endif 
    11041206 
    11051207#ifdef CONFIG_MIPS_APSP_KSPD 
    11061208        /* get kspd to tell us when a syscall_exit happens */ 
    static void kspd_sp_exit( int sp_id) 
    13481450        cleanup_tc(get_tc(sp_id)); 
    13491451} 
    13501452#endif 
     1453#ifdef CONFIG_IFX_VPE_EXT 
     1454int32_t vpe1_sw_start(void* sw_start_addr, uint32_t tcmask, uint32_t flags) 
     1455{ 
     1456        enum vpe_state state; 
     1457        struct vpe *v = get_vpe(tclimit); 
     1458        struct vpe_notifications *not; 
     1459 
     1460        if (tcmask || flags) { 
     1461                printk(KERN_WARNING "Currently tcmask and flags should be 0.\ 
     1462                                other values not supported\n"); 
     1463                return -1; 
     1464        } 
     1465 
     1466        state = xchg(&v->state, VPE_STATE_INUSE); 
     1467        if (state != VPE_STATE_UNUSED) { 
     1468                vpe_stop(v); 
     1469 
     1470                list_for_each_entry(not, &v->notify, list) { 
     1471                        not->stop(tclimit); 
     1472                } 
     1473        } 
     1474 
     1475        v->__start = (unsigned long)sw_start_addr; 
     1476        is_sdepgm = 0; 
     1477 
     1478        if (!vpe_run(v)) { 
     1479                printk(KERN_DEBUG "VPE loader: VPE1 running successfully\n"); 
     1480                return 0; 
     1481        } 
     1482        return -1; 
     1483} 
     1484 
     1485EXPORT_SYMBOL(vpe1_sw_start); 
     1486 
     1487int32_t vpe1_sw_stop(uint32_t flags) 
     1488{ 
     1489        struct vpe *v = get_vpe(tclimit); 
     1490 
     1491        if (!vpe_free(v)) { 
     1492                printk(KERN_DEBUG "RP Stopped\n"); 
     1493                return 0; 
     1494        } 
     1495        else 
     1496                return -1; 
     1497} 
     1498 
     1499EXPORT_SYMBOL(vpe1_sw_stop); 
     1500 
     1501uint32_t vpe1_get_load_addr (uint32_t flags) 
     1502{ 
     1503        return vpe1_load_addr; 
     1504} 
     1505 
     1506EXPORT_SYMBOL(vpe1_get_load_addr); 
     1507 
     1508uint32_t vpe1_get_max_mem (uint32_t flags) 
     1509{ 
     1510        if (!vpe1_mem) 
     1511                return P_SIZE; 
     1512        else 
     1513                return vpe1_mem; 
     1514} 
     1515 
     1516EXPORT_SYMBOL(vpe1_get_max_mem); 
     1517 
     1518void* vpe1_get_cmdline_argument(void) 
     1519{ 
     1520        return saved_command_line; 
     1521} 
     1522 
     1523EXPORT_SYMBOL(vpe1_get_cmdline_argument); 
     1524 
     1525int32_t vpe1_set_boot_param(char *field, char *value, char flags) 
     1526{ 
     1527        char *ptr, string[64]; 
     1528        int start_off, end_off; 
     1529        if (!field) 
     1530                return -1; 
     1531        strcpy(string, field); 
     1532        if (value) { 
     1533                strcat(string, "="); 
     1534                strcat(string, value); 
     1535                strcat(command_line, " "); 
     1536                strcat(command_line, string); 
     1537        } 
     1538        else { 
     1539                ptr = strstr(command_line, string); 
     1540                if (ptr) { 
     1541                        start_off = ptr - command_line; 
     1542                        ptr += strlen(string); 
     1543                        while ((*ptr != ' ') && (*ptr != '\0')) 
     1544                                ptr++; 
     1545                        end_off = ptr - command_line; 
     1546                        command_line[start_off] = '\0'; 
     1547                        strcat (command_line, command_line+end_off); 
     1548                } 
     1549        } 
     1550        return 0; 
     1551} 
     1552 
     1553EXPORT_SYMBOL(vpe1_set_boot_param); 
     1554 
     1555int32_t vpe1_get_boot_param(char *field, char **value, char flags) 
     1556{ 
     1557        char *ptr, string[64]; 
     1558        int i = 0; 
     1559        if (!field) 
     1560                return -1; 
     1561        if ((ptr = strstr(command_line, field))) { 
     1562                ptr += strlen(field) + 1; /* including = */ 
     1563                while ((*ptr != ' ') && (*ptr != '\0')) 
     1564                        string[i++] = *ptr++; 
     1565                string[i] = '\0'; 
     1566                *value = kmalloc((strlen(string) + 1), GFP_KERNEL); 
     1567                if (*value != NULL) 
     1568                        strcpy(*value, string); 
     1569        } 
     1570        else 
     1571                *value = NULL; 
     1572 
     1573        return 0; 
     1574} 
     1575 
     1576EXPORT_SYMBOL(vpe1_get_boot_param); 
     1577 
     1578extern void configure_tlb(void); 
     1579#endif 
    13511580 
    13521581static ssize_t store_kill(struct device *dev, struct device_attribute *attr, 
    13531582                          const char *buf, size_t len) 
    static int __init vpe_module_init(void) 
    14291658                printk("VPE loader: not a MIPS MT capable processor\n"); 
    14301659                return -ENODEV; 
    14311660        } 
     1661#ifdef CONFIG_IFX_VPE_EXT 
     1662#ifndef CONFIG_MIPS_MT_SMTC 
     1663        configure_tlb(); 
     1664#endif 
     1665#endif 
     1666 
     1667#ifndef CONFIG_MIPS_MT_SMTC 
     1668        if (!vpelimit) 
     1669                vpelimit = 1; 
     1670        if (!tclimit) 
     1671                tclimit = 1; 
     1672#endif 
    14321673 
    14331674        if (vpelimit == 0) { 
    14341675                printk(KERN_WARNING "No VPEs reserved for AP/SP, not " 
    static int __init vpe_module_init(void) 
    14731714        mtflags = dmt(); 
    14741715        vpflags = dvpe(); 
    14751716 
     1717        back_to_back_c0_hazard(); 
     1718 
    14761719        /* Put MVPE's into 'configuration state' */ 
    14771720        set_c0_mvpcontrol(MVPCONTROL_VPC); 
    14781721 
    1479         /* dump_mtregs(); */ 
     1722        dump_mtregs(); 
    14801723 
    14811724        val = read_c0_mvpconf0(); 
    14821725        hw_tcs = (val & MVPCONF0_PTC) + 1; 
    static int __init vpe_module_init(void) 
    14881731                 * reschedule send IPIs or similar we might hang. 
    14891732                 */ 
    14901733                clear_c0_mvpcontrol(MVPCONTROL_VPC); 
     1734                back_to_back_c0_hazard(); 
    14911735                evpe(vpflags); 
    14921736                emt(mtflags); 
    14931737                local_irq_restore(flags); 
    static int __init vpe_module_init(void) 
    15131757                        } 
    15141758 
    15151759                        v->ntcs = hw_tcs - tclimit; 
     1760                        write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | 1); 
    15161761 
    15171762                        /* add the tc to the list of this vpe's tc's. */ 
    15181763                        list_add(&t->tc, &v->tc); 
    static int __init vpe_module_init(void) 
    15811826out_reenable: 
    15821827        /* release config state */ 
    15831828        clear_c0_mvpcontrol(MVPCONTROL_VPC); 
     1829        back_to_back_c0_hazard(); 
    15841830 
    15851831        evpe(vpflags); 
    15861832        emt(mtflags); 
Note: See TracBrowser for help on using the repository browser.