maltalinux-cvs-patches
[Top] [All Lists]

CVS Update@linux-mips.org: malta

To: maltalinux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: malta
From: chris@linux-mips.org
Date: Thu, 28 Jul 2005 18:26:21 +0100
Reply-to: linux-mips@linux-mips.org
Sender: maltalinux-cvs-patches-bounce@linux-mips.org
CVSROOT:        /home/cvs
Module name:    malta
Changes by:     chris@ftp.linux-mips.org        05/07/28 18:26:20

Modified files:
        linux/arch/mips: Tag: MaltaRef_2_6 Kconfig Makefile 
        linux/arch/mips/kernel: Tag: MaltaRef_2_6 Makefile genex.S 
                                irq_cpu.c traps.c 
        linux/arch/mips/mips-boards/generic: Tag: MaltaRef_2_6 time.c 

Log message:
        * arch/mips/mips-boards/generic/time.c (mips_timer_interrupt): SMP
        timer support.
        
        * arch/mips/kernel/traps.c (do_mt): MT exception handler.
        (mips_srs_alloc): Corrected spinlock usage.
        (mips_srs_free): Corrected spinlock usage.
        (per_cpu_trap_init): Disable VPE operation before changing cause
        register (not strictly necessary because 2nd VPE shouldn't be
        running...)
        (trap_init): Install MT exception handler.
        
        * arch/mips/kernel/irq_cpu.c: Check cpu_has_mipsmt before using 
dvpe/evpe.
        
        * arch/mips/kernel/genex.S: Added MT exception.
        
        * arch/mips/kernel/Makefile: Added smp_mt.c.
        
        * arch/mips/Makefile: Added CONFIG_MIPS_MIPSSIM support.
        
        * arch/mips/Kconfig: Added MIPS_MIPSSIM and MIPS_MT_SMP. Make SMP
        dependent on MIPS_MT_SMP.

diff -urN malta/linux/arch/mips/Kconfig malta/linux/arch/mips/Kconfig
--- malta/linux/arch/mips/Kconfig       2005/07/27 14:17:17     1.73.1000.8
+++ malta/linux/arch/mips/Kconfig       2005/07/28 17:26:18     1.73.1000.9
@@ -289,6 +289,12 @@
          This enables support for the MIPS Technologies SEAD evaluation
          board.
 
+config MIPS_MIPSSIM
+       bool 'Support for MIPS simulator (MIPSsim)'
+       select IRQ_CPU
+       help
+         This enables support for the MIPS Technologies MIPSsim simulator.
+
 config MOMENCO_JAGUAR_ATX
        bool "Support for Momentum Jaguar board"
        select BOOT_ELF32
@@ -1150,6 +1156,14 @@
 config MIPS_MT
        bool "Enable MIPS MT"
 
+choice
+       prompt "MIPS MT options"
+       depends on MIPS_MT
+
+config MIPS_MT_SMP
+       bool "Use 1 TC on each available VPE for SMP"
+       select SMP
+
 config MIPS_VPE_LOADER
        bool "VPE loader support."
        depends on MIPS_MT
@@ -1158,6 +1172,8 @@
          Includes a loader for loading an elf relocatable object
          onto another VPE and running it.
 
+endchoice
+
 config MIPS_VPE_LOADER_TOM
        bool "Load VPE program into memory hidden from linux"
        depends on MIPS_VPE_LOADER
@@ -1291,7 +1307,7 @@
 
 config SMP
        bool "Multi-Processing support"
-       depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || 
SGI_IP27 
+       depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || 
SGI_IP27 || MIPS_MT_SMP
        ---help---
          This enables support for systems with more than one CPU. If you have
          a system with only one CPU, like most personal computers, say N. If
diff -urN malta/linux/arch/mips/Makefile malta/linux/arch/mips/Makefile
--- malta/linux/arch/mips/Makefile      2005/06/21 13:23:40     1.167.1000.5
+++ malta/linux/arch/mips/Makefile      2005/07/28 17:26:18     1.167.1000.6
@@ -423,6 +423,13 @@
 load-$(CONFIG_MIPS_SEAD)       += 0xffffffff80100000
 
 #
+# MIPS simulator (MIPSsim)
+#
+core-$(CONFIG_MIPS_MIPSSIM)    += arch/mips/mips-boards/sim/
+cflags-$(CONFIG_MIPS_MIPSSIM)  += -Iinclude/asm-mips/mach-sim
+load-$(CONFIG_MIPS_MIPSSIM)    += 0xffffffff80100000
+
+#
 # Momentum Ocelot board
 #
 # The Ocelot setup.o must be linked early - it does the ioremap() for the
diff -urN malta/linux/arch/mips/kernel/Makefile 
malta/linux/arch/mips/kernel/Makefile
--- malta/linux/arch/mips/kernel/Makefile       2005/07/27 13:37:54     
1.80.1000.5
+++ malta/linux/arch/mips/kernel/Makefile       2005/07/28 17:26:19     
1.80.1000.6
@@ -34,6 +34,8 @@
 
 obj-$(CONFIG_SMP)              += smp.o
 
+obj-$(CONFIG_MIPS_MT_SMP)      += smp_mt.o
+
 obj-$(CONFIG_MIPS_VPE_LOADER)  += vpe.o
 obj-$(CONFIG_MIPS_VPE_APSP_API)        += rtlx.o
 obj-$(CONFIG_MIPS_APSP_KSPD)   += kspd.o
diff -urN malta/linux/arch/mips/kernel/genex.S 
malta/linux/arch/mips/kernel/genex.S
--- malta/linux/arch/mips/kernel/genex.S        2005/06/21 13:24:02     
1.7.1000.2
+++ malta/linux/arch/mips/kernel/genex.S        2005/07/28 17:26:19     
1.7.1000.3
@@ -323,6 +323,7 @@
        BUILD_HANDLER mdmx mdmx sti silent              /* #22 */
        BUILD_HANDLER watch watch sti verbose           /* #23 */
        BUILD_HANDLER mcheck mcheck cli verbose         /* #24 */
+       BUILD_HANDLER mt mt sti verbose                 /* #25 */
        BUILD_HANDLER dsp dsp sti silent                /* #26 */
        BUILD_HANDLER reserved reserved sti verbose     /* others */
 
diff -urN malta/linux/arch/mips/kernel/irq_cpu.c 
malta/linux/arch/mips/kernel/irq_cpu.c
--- malta/linux/arch/mips/kernel/irq_cpu.c      2005/07/22 13:21:43     
1.8.1000.3
+++ malta/linux/arch/mips/kernel/irq_cpu.c      2005/07/28 17:26:19     
1.8.1000.4
@@ -47,11 +47,12 @@
         * to stop other VPEs whenever the local VPE does
         * anything similar.
         */
-       unsigned int vpflags = dvpe();
+       unsigned int vpflags = cpu_has_mipsmt ? dvpe() : 0;
 #endif /* CONFIG_MIPS_MT */
        clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
 #ifdef CONFIG_MIPS_MT
-       evpe(vpflags);
+       if (cpu_has_mipsmt)
+               evpe(vpflags);
 #endif /* CONFIG_MIPS_MT */
        set_c0_status(0x100 << (irq - mips_cpu_irq_base));
        irq_enable_hazard();
@@ -97,14 +98,15 @@
 static void mips_cpu_irq_ack(unsigned int irq)
 {
 #ifdef CONFIG_MIPS_MT
-       unsigned int vpflags = dvpe();
+       unsigned int vpflags = cpu_has_mipsmt ? dvpe() : 0;
 #endif /* CONFIG_MIPS_MT */
 
        /* Only necessary for soft interrupts */
        clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
 
 #ifdef CONFIG_MIPS_MT
-       evpe(vpflags);
+       if (cpu_has_mipsmt)
+               evpe(vpflags);
 #endif /* CONFIG_MIPS_MT */
        mask_mips_irq(irq);
 }
diff -urN malta/linux/arch/mips/kernel/traps.c 
malta/linux/arch/mips/kernel/traps.c
--- malta/linux/arch/mips/kernel/traps.c        2005/07/12 16:23:40     
1.193.1000.6
+++ malta/linux/arch/mips/kernel/traps.c        2005/07/28 17:26:19     
1.193.1000.7
@@ -56,6 +56,7 @@
 extern asmlinkage void handle_fpe(void);
 extern asmlinkage void handle_mdmx(void);
 extern asmlinkage void handle_watch(void);
+extern asmlinkage void handle_mt(void);
 extern asmlinkage void handle_dsp(void);
 extern asmlinkage void handle_mcheck(void);
 extern asmlinkage void handle_reserved(void);
@@ -801,6 +802,44 @@
              (regs->cp0_status & ST0_TS) ? "" : "not ");
 }
 
+asmlinkage void do_mt(struct pt_regs *regs)
+{
+       int subcode;
+
+       die_if_kernel("MIPS MT Thread exception in kernel", regs);
+
+       if (cpu_has_mipsmt) {
+               subcode = (read_vpe_c0_vpecontrol() & VPECONTROL_EXCPT) 
+                       >> VPECONTROL_EXCPT_SHIFT;
+               switch(subcode) {
+               case 0:
+                       printk("Thread Underflow\n");
+                       break;
+               case 1:
+                       printk("Thread Overflow\n");
+                       break;
+               case 2:
+                       printk("Invalid YIELD Qualifier\n");
+                       break;
+               case 3:
+                       printk("Gating Storage Exception\n");
+                       break;
+               case 4:
+                       printk("YIELD Scheduler Exception\n");
+                       break;
+               case 5:
+                       printk("Gating Storage Schedulier Exception\n");
+                       break;
+               default:
+                       printk("*** UNKNOWN THREAD EXCEPTION %d ***\n",
+                              subcode);
+                       break;
+               }
+       }
+       force_sig(SIGILL, current);
+}
+
+
 asmlinkage void do_dsp(struct pt_regs *regs)
 {
        if (cpu_has_dsp)
@@ -996,18 +1035,18 @@
        int set;
        long flags;
 
-       spin_lock_irqsave(sr->sr_lock, flags);
+       spin_lock_irqsave(&sr->sr_lock, flags);
        
        for (set = 0; set < sr->sr_supported; set++) {
                if ((sr->sr_allocated & (1 << set)) == 0) {
                        sr->sr_allocated |= 1 << set;
-                       spin_unlock_irqrestore(sr->sr_lock, flags);
+                       spin_unlock_irqrestore(&sr->sr_lock, flags);
                        return set;
                }
        }
 
        /* None available */
-       spin_unlock_irqrestore(sr->sr_lock, flags);
+       spin_unlock_irqrestore(&sr->sr_lock, flags);
        return -1;
 }
 
@@ -1016,9 +1055,9 @@
        struct shadow_registers *sr = &shadow_registers;
        long flags;
 
-       spin_lock_irqsave(sr->sr_lock, flags);
+       spin_lock_irqsave(&sr->sr_lock, flags);
        sr->sr_allocated &= ~(1 << set);
-       spin_unlock_irqrestore(sr->sr_lock, flags);
+       spin_unlock_irqrestore(&sr->sr_lock, flags);
 }
 
 void *set_vi_srs_handler (int n, void *addr, int srs)
@@ -1189,8 +1228,17 @@
                /* Setting vector spacing enables EI/VI mode  */
                change_c0_intctl (0x3e0, VECTORSPACING);
        }
-       if (cpu_has_divec)
+       if (cpu_has_divec) {
+#ifdef CONFIG_MIPS_MT
+               unsigned int vpflags;
+               vpflags = cpu_has_mipsmt ? dvpe() : 0;
+#endif
                set_c0_cause(CAUSEF_IV);
+#ifdef CONFIG_MIPS_MT
+               if (cpu_has_mipsmt)
+                       evpe(vpflags);
+#endif
+       }
 
        cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
        TLBMISS_HANDLER_SETUP();
@@ -1331,6 +1379,9 @@
        if (cpu_has_mcheck)
                set_except_vector(24, handle_mcheck);
 
+       if (cpu_has_mipsmt)
+               set_except_vector(25, handle_mt);
+
        if (cpu_has_dsp)
                set_except_vector(26, handle_dsp);
 
diff -urN malta/linux/arch/mips/mips-boards/generic/time.c 
malta/linux/arch/mips/mips-boards/generic/time.c
--- malta/linux/arch/mips/mips-boards/generic/time.c    2005/06/21 13:24:12     
1.23.1000.3
+++ malta/linux/arch/mips/mips-boards/generic/time.c    2005/07/28 17:26:20     
1.23.1000.4
@@ -61,6 +61,15 @@
 static unsigned int timer_tick_count=0;
 static int mips_cpu_timer_irq;
 
+static inline void scroll_display_message(void)
+{
+       if ((timer_tick_count++ % HZ) == 0) {
+               mips_display_message(&display_string[display_count++]);
+               if (display_count == MAX_DISPLAY_COUNT)
+                       display_count = 0;
+       }
+}
+
 static void mips_timer_dispatch (struct pt_regs *regs)
 {
        do_IRQ (mips_cpu_timer_irq, regs);
@@ -68,17 +77,42 @@
 
 irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+#ifdef CONFIG_SMP 
+       int cpu = smp_processor_id();
+
+       if (cpu == 0) {
+               /*
+                * CPU 0 handles the global timer interrupt job and process 
accounting
+                * resets count/compare registers to trigger next timer int.
+                */
+               (void) timer_interrupt(irq, dev_id, regs);
+               scroll_display_message();
+       }
+       else {
+               /* Everyone else needs to reset the timer int here as 
+                  ll_local_timer_interrupt doesn't */
+               /*
+                * FIXME: need to cope with counter underflow.
+                * More support needs to be added to kernel/time for
+                * counter/timer interrupts on multiple CPU's
+                */
+               write_c0_compare (read_c0_count() + (mips_hpt_frequency/HZ));
+               /*
+                * other CPUs should do profiling and process accounting
+                */
+               local_timer_interrupt (irq, dev_id, regs);
+       }
+
+       return IRQ_HANDLED;
+#else
        irqreturn_t r;
 
        r = timer_interrupt(irq, dev_id, regs);
 
-       if ((timer_tick_count++ % HZ) == 0) {
-               mips_display_message(&display_string[display_count++]);
-               if (display_count == MAX_DISPLAY_COUNT)
-                       display_count = 0;
-       }
+       scroll_display_message();
 
        return r;
+#endif
 }
 
 /*
@@ -89,7 +123,7 @@
        unsigned int prid = read_c0_prid() & 0xffff00;
        unsigned int count;
 
-#ifdef CONFIG_MIPS_SEAD
+#if defined(CONFIG_MIPS_SEAD) || defined(CONFIG_MIPS_MIPSSIM)
        /*
         * The SEAD board doesn't have a real time clock, so we can't
         * really calculate the timer frequency
@@ -176,6 +210,13 @@
        irq->handler = mips_timer_interrupt;    /* we use our own handler */
        setup_irq(mips_cpu_timer_irq, irq);
 
+#ifdef CONFIG_SMP
+       /* irq_desc(riptor) is a global resource, when the interrupt overlaps
+          on seperate cpu's the first one tries to handle the second interrupt.
+          The effect is that the int remains disabled on the second cpu.
+          Mark the interrupt with IRQ_PER_CPU to avoid any confusion */
+       irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU;
+#endif
 
         /* to generate the first timer interrupt */
        write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ);

<Prev in Thread] Current Thread [Next in Thread>