From chris@linux-mips.org Thu Sep  1 11:50:48 2005
Received: with ECARTIS (v1.0.0; list maltalinux-cvs-patches); Thu, 01 Sep 2005 12:50:48 +0100 (BST)
From: chris@linux-mips.org
To:  maltalinux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: malta
Date: Thu, 01 Sep 2005 12:50:48 +0100
X-archive-position: 50
X-ecartis-version: Ecartis v1.0.0
Sender: maltalinux-cvs-patches-bounce@linux-mips.org
Errors-to: maltalinux-cvs-patches-bounce@linux-mips.org
X-original-sender: chris@linux-mips.org
Precedence: bulk
Reply-to: linux-mips@linux-mips.org
X-list: maltalinux-cvs-patches


CVSROOT:	/home/cvs
Module name:	malta
Changes by:	chris@ftp.linux-mips.org	05/09/01 12:50:47

Added files:
	linux/arch/mips/kernel: Tag: MaltaRef_2_6 smp_mt.c 

Log message:
	Reinstated on MaltaRef_2_6 branch

diff -urN malta/linux/arch/mips/kernel/smp_mt.c malta/linux/arch/mips/kernel/smp_mt.c
--- malta/linux/arch/mips/kernel/smp_mt.c	1970/01/01 00:00:00
+++ malta/linux/arch/mips/kernel/smp_mt.c	2005-09-01 12:50:47.556579000 +0100	1.3.1000.1
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  Elizabeth Clarke (beth@mips.com)
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/compiler.h>
+
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/smp.h>
+#include <asm/time.h>
+#include <asm/mipsregs.h>
+#include <asm/cacheflush.h>
+#include <asm/mips-boards/maltaint.h>
+
+static int cpu_ipi_resched_irq, cpu_ipi_call_irq;
+#define MIPS_CPU_IPI_RESCHED_IRQ 0
+#define MIPS_CPU_IPI_CALL_IRQ 1
+
+static struct irqaction irq_call, irq_resched;
+
+static void ipi_resched_dispatch (struct pt_regs *regs);
+static void ipi_call_dispatch (struct pt_regs *regs);
+static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ipi_call_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+static void dump_mtregisters(int vpe, int tc)
+{
+	printk("vpe %d tc %d\n", vpe, tc);
+	
+	settc(tc);
+	
+	printk("  c0 status  0x%lx\n", read_vpe_c0_status());
+	printk("  vpecontrol 0x%lx\n", read_vpe_c0_vpecontrol());
+	printk("  vpeconf0    0x%lx\n", read_vpe_c0_vpeconf0());
+	printk("  tcstatus 0x%lx\n", read_tc_c0_tcstatus());
+	printk("  tcrestart 0x%lx\n", read_tc_c0_tcrestart());
+	printk("  tcbind 0x%lx\n", read_tc_c0_tcbind());
+	printk("  tchalt 0x%lx\n", read_tc_c0_tchalt());
+}
+
+void __init sanitize_tlb_entries(void)
+{
+	int i, tlbsiz;
+	unsigned long mvpconf0, ncpu;
+	
+	if (!cpu_has_mipsmt)
+		return;
+
+ 	write_c0_mvpcontrol( read_c0_mvpcontrol() | MVPCONTROL_VPC );
+
+	/* Disable TLB sharing */
+ 	write_c0_mvpcontrol( read_c0_mvpcontrol() & ~MVPCONTROL_STLB );
+
+	mvpconf0 = read_c0_mvpconf0();
+
+	printk("MVPConf0 0x%lx TLBS %lx PTLBE %ld\n", mvpconf0,
+		   (mvpconf0 & MVPCONF0_TLBS) >> MVPCONF0_TLBS_SHIFT,
+			   (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT);
+
+	tlbsiz = (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT;
+	ncpu = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
+	
+	printk(" tlbsiz %d ncpu %ld\n", tlbsiz, ncpu);
+
+	if (tlbsiz > 0) {
+		/* share them out across the vpe's */
+		tlbsiz /= ncpu;
+
+		printk("setting Config1.MMU_size to %d\n", tlbsiz);
+
+		for (i = 0; i < ncpu; i++) {
+			settc(i);
+		
+			if( i == 0 )
+				write_c0_config1( (read_c0_config1() & ~(0x3f << 25)) | (tlbsiz << 25) );
+			else
+				write_vpe_c0_config1((read_vpe_c0_config1() & ~(0x3f << 25)) |
+						   (tlbsiz << 25) );
+		}
+	}
+
+	write_c0_mvpcontrol( read_c0_mvpcontrol() & ~MVPCONTROL_VPC );	
+}
+
+#if 0
+/*
+ * Use c0_MVPConf0 to find out how many CPUs are available, setting up
+ * phys_cpu_present_map and the logical/physical mappings.
+ */
+void __init prom_build_cpu_map(void)
+{
+	int i, num, ncpus;
+
+	cpus_clear(phys_cpu_present_map);
+
+	/* assume we boot on cpu 0.... */
+	cpu_set(0, phys_cpu_present_map);
+	__cpu_number_map[0] = 0;
+	__cpu_logical_map[0] = 0;
+
+	if (cpu_has_mipsmt) {
+		ncpus = ((read_c0_mvpconf0() & (MVPCONF0_PVPE)) >> MVPCONF0_PVPE_SHIFT) + 1;
+		for (i=1, num=0; i< NR_CPUS && i<ncpus; i++) {
+			cpu_set(i, phys_cpu_present_map);
+			__cpu_number_map[i] = ++num;
+			__cpu_logical_map[num] = i;
+		}
+		
+		printk("%i available secondary CPU(s)\n", num);
+	}
+}
+#endif
+
+
+/*
+ * Common setup before any secondaries are started
+ * Make sure all CPU's are in a sensible state before we boot any of the
+ * secondarys
+ */
+void prom_prepare_cpus(unsigned int max_cpus)
+{
+	int i, num;
+	unsigned long val;
+
+	if (!cpu_has_mipsmt)
+		return;
+
+	/* disable MT so we can configure */
+	dvpe();
+	dmt();
+	
+	/* Put MVPE's into 'configuration state' */
+	write_c0_mvpcontrol( read_c0_mvpcontrol() | MVPCONTROL_VPC );
+
+	val = read_c0_mvpconf0();
+
+	/* we'll always have more TC's than VPE's, so loop setting everything
+	   to a sensible state */
+	for (i = 0, num = 0; i <= ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT); i++) {
+		settc(i);
+
+		/* VPE's */
+		if (i <= ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) {
+
+			/* deactivate all but vpe0 */
+			if (i != 0) {
+				unsigned long tmp = read_vpe_c0_vpeconf0();
+				
+				tmp &= ~VPECONF0_VPA;
+			
+				/* master VPE */
+				tmp |= VPECONF0_MVP;
+				write_vpe_c0_vpeconf0(tmp);
+
+				/* Record this as available CPU */
+				if (i < max_cpus) {
+					cpu_set(i, phys_cpu_present_map);
+					__cpu_number_map[i]	= ++num;
+					__cpu_logical_map[num]	= i;
+				}
+			}
+			
+			/* disable multi-threading with TC's */
+			write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
+
+			if (i != 0) {
+				write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
+				write_vpe_c0_cause(read_vpe_c0_cause() & ~CAUSEF_IP);
+
+				/* set config to be the same as vpe0, particularly kseg0 coherency alg */
+				write_vpe_c0_config( read_c0_config());
+			}
+
+		}
+
+		/* TC's */
+
+		if (i != 0) {
+			unsigned long tmp;
+
+			/* bind a TC to each VPE, May as well put all excess TC's
+			   on the last VPE */
+			if ( i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1) )
+				write_tc_c0_tcbind(read_tc_c0_tcbind() | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) );
+			else {
+				write_tc_c0_tcbind( read_tc_c0_tcbind() | i);
+
+				/* and set XTC */
+				write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | (i << VPECONF0_XTC_SHIFT));
+			}
+			
+			tmp = read_tc_c0_tcstatus();
+
+			/* mark not allocated and not dynamically allocatable */
+			tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+			tmp |= TCSTATUS_IXMT;		/* interrupt exempt */
+			write_tc_c0_tcstatus(tmp);
+			
+			write_tc_c0_tchalt(TCHALT_H);
+		}
+	}
+	
+	/* release config state */
+	write_c0_mvpcontrol( read_c0_mvpcontrol() & ~ MVPCONTROL_VPC );
+
+	/* we'll wait until starting the secondary cpu(s) before starting MVPE */
+
+	printk("Detected %i available secondary CPU(s)\n", num);
+
+	/* set up ipi interrupts */
+	memset( &irq_call, 0, sizeof(struct irqaction));
+	memset( &irq_resched, 0, sizeof(struct irqaction));
+
+	if (cpu_has_vint) {
+		set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
+		set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
+	}
+
+	cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
+	cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ;
+
+	irq_resched.handler = ipi_resched_interrupt;
+	irq_resched.flags = SA_INTERRUPT;
+	irq_resched.name = "IPI_resched";
+
+	irq_call.handler = ipi_call_interrupt;
+	irq_call.flags = SA_INTERRUPT;
+	irq_call.name = "IPI_call";
+
+	setup_irq(cpu_ipi_resched_irq, &irq_resched);
+	setup_irq(cpu_ipi_call_irq, &irq_call);
+
+	/* need to mark IPI's as IRQ_PER_CPU */
+	irq_desc[cpu_ipi_resched_irq].status |= IRQ_PER_CPU;
+	irq_desc[cpu_ipi_call_irq].status |= IRQ_PER_CPU;
+}
+
+
+/*
+ * Setup the PC, SP, and GP of a secondary processor and start it
+ * running!
+ * smp_bootstrap is the place to resume from
+ * __KSTK_TOS(idle) is apparently the stack pointer
+ * (unsigned long)idle->thread_info the gp
+ * assumes a 1:1 mapping of TC => VPE
+ *
+ */
+void prom_boot_secondary(int cpu, struct task_struct *idle)
+{
+
+	dvpe();
+	write_c0_mvpcontrol( read_c0_mvpcontrol() | MVPCONTROL_VPC );
+
+	settc(cpu);
+	
+	/* restart */
+	write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);
+
+	/* enable the tc this vpe/cpu will be running */
+	write_tc_c0_tcstatus((read_tc_c0_tcstatus() & ~TCSTATUS_IXMT) | TCSTATUS_A);
+	
+	write_tc_c0_tchalt(0);
+
+	/* enable the VPE */
+	write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | VPECONF0_VPA);
+
+	/* stack pointer */
+	write_tc_gpr_sp(  __KSTK_TOS(idle) );
+
+	/* global pointer */
+	write_tc_gpr_gp( (unsigned long)idle->thread_info );
+
+	flush_icache_range((unsigned long)idle->thread_info,
+					   (unsigned long)idle->thread_info +
+					   sizeof(struct thread_info));
+	
+	/* finally out of configuration and into chaos */
+	write_c0_mvpcontrol( read_c0_mvpcontrol() & ~MVPCONTROL_VPC );
+
+	evpe(EVPE_ENABLE);
+}
+
+void prom_init_secondary(void)
+{
+	write_c0_status((read_c0_status() & ~ST0_IM )
+			| (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP7));
+}
+
+void prom_smp_finish(void)
+{
+	write_c0_compare (read_c0_count() + (8* mips_hpt_frequency/HZ));
+	
+	local_irq_enable();
+}
+
+void prom_cpus_done(void)
+{}
+
+void core_send_ipi(int cpu, unsigned int action)
+{
+	int i;
+	unsigned long flags;
+	int vpflags;
+
+	local_irq_save (flags);
+
+	vpflags = dvpe();	/* cant access the other CPU's registers whilst MVPE enabled */
+
+	switch( action ) {
+		
+		case SMP_CALL_FUNCTION:
+			i = C_SW1;
+			break;
+
+		default:
+		case SMP_RESCHEDULE_YOURSELF:
+			i = C_SW0;
+			break;
+	}
+
+	/* 1:1 mapping of vpe and tc... */
+	settc(cpu);
+	write_vpe_c0_cause(read_vpe_c0_cause() | i);
+	evpe(vpflags);
+
+	local_irq_restore (flags);
+}
+
+static void ipi_resched_dispatch (struct pt_regs *regs)
+{
+	do_IRQ (MIPS_CPU_IPI_RESCHED_IRQ, regs);
+}
+
+static void ipi_call_dispatch (struct pt_regs *regs)
+{
+	do_IRQ (MIPS_CPU_IPI_CALL_IRQ, regs);
+}
+
+irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	irqreturn_t r = IRQ_HANDLED;
+	return r;
+}
+
+irqreturn_t ipi_call_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	irqreturn_t r = IRQ_HANDLED;
+	smp_call_function_interrupt();
+	return r;
+}

From beth@linux-mips.org Fri Sep  2 10:49:48 2005
Received: with ECARTIS (v1.0.0; list maltalinux-cvs-patches); Fri, 02 Sep 2005 11:49:48 +0100 (BST)
From: beth@linux-mips.org
To:  maltalinux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: malta
Date: Fri, 02 Sep 2005 11:49:48 +0100
X-archive-position: 51
X-ecartis-version: Ecartis v1.0.0
Sender: maltalinux-cvs-patches-bounce@linux-mips.org
Errors-to: maltalinux-cvs-patches-bounce@linux-mips.org
X-original-sender: beth@linux-mips.org
Precedence: bulk
Reply-to: linux-mips@linux-mips.org
X-list: maltalinux-cvs-patches


CVSROOT:	/home/cvs
Module name:	malta
Changes by:	beth@ftp.linux-mips.org	05/09/02 11:49:46

Modified files:
	linux/arch/mips/mm: Tag: MaltaRef_2_6 cache.c 
	linux/include/asm-mips/mach-sibyte: Tag: MaltaRef_2_6 
	                                    cpu-feature-overrides.h 

Log message:
	* arch/mips/mm/cache.c: Fix SB1 cache.
	
	* include/asm-mips/mach-sibyte/cpu-feature-overrides.h: Set cpu_has_mipsmt
	to zero for completeness.

diff -urN malta/linux/arch/mips/mm/cache.c malta/linux/arch/mips/mm/cache.c
--- malta/linux/arch/mips/mm/cache.c	2005/06/21 13:24:14	1.13.1000.2
+++ malta/linux/arch/mips/mm/cache.c	2005/09/02 10:49:46	1.13.1000.3
@@ -123,6 +123,9 @@
     defined(CONFIG_CPU_RM7000) || defined(CONFIG_CPU_RM9000)
 		ld_mmu_r4xx0();
 #endif
+#ifdef CONFIG_CPU_SB1
+		ld_mmu_sb1();
+#endif
 	} else switch (current_cpu_data.cputype) {
 #ifdef CONFIG_CPU_R3000
 	case CPU_R2000:
@@ -145,11 +148,6 @@
 		ld_mmu_r4xx0();
 		break;
 #endif
-#ifdef CONFIG_CPU_SB1
-	case CPU_SB1:
-		ld_mmu_sb1();
-		break;
-#endif
 
 	case CPU_R8000:
 		panic("R8000 is unsupported");
diff -urN malta/linux/include/asm-mips/mach-sibyte/cpu-feature-overrides.h malta/linux/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
--- malta/linux/include/asm-mips/mach-sibyte/cpu-feature-overrides.h	2005/06/21 13:36:41	1.3.1000.1
+++ malta/linux/include/asm-mips/mach-sibyte/cpu-feature-overrides.h	2005/09/02 10:49:46	1.3.1000.2
@@ -27,6 +27,7 @@
 #define cpu_has_ic_fills_f_dc	0
 #define cpu_has_dsp		0
 #define cpu_icache_snoops_remote_store	0
+#define cpu_has_mipsmt		0
 
 #define cpu_has_nofpuex		0
 #define cpu_has_64bits		1

From beth@linux-mips.org Fri Sep  2 17:02:56 2005
Received: with ECARTIS (v1.0.0; list maltalinux-cvs-patches); Fri, 02 Sep 2005 18:02:56 +0100 (BST)
From: beth@linux-mips.org
To:  maltalinux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: malta
Date: Fri, 02 Sep 2005 18:02:56 +0100
X-archive-position: 52
X-ecartis-version: Ecartis v1.0.0
Sender: maltalinux-cvs-patches-bounce@linux-mips.org
Errors-to: maltalinux-cvs-patches-bounce@linux-mips.org
X-original-sender: beth@linux-mips.org
Precedence: bulk
Reply-to: linux-mips@linux-mips.org
X-list: maltalinux-cvs-patches


CVSROOT:	/home/cvs
Module name:	malta
Changes by:	beth@ftp.linux-mips.org	05/09/02 18:02:54

Modified files:
	linux/arch/mips/kernel: Tag: MaltaRef_2_6 kspd.c rtlx.c vpe.c 

Log message:
	* arch/mips/kernel/kspd.c: Stop KSPD from trying to read from the
	syscall channel if we are stopping.
	
	* arch/mips/kernel/rtlx.c: Fix bug where multiple process could
	open /dev/rt? and sit on the wait queue for SP to set up the
	shared structure.
	
	* arch/mips/kernel/vpe.c: Fix loading of fully linked SP images.
	__start symbol wasn't found so the TC's restart address was incorrect.

diff -urN malta/linux/arch/mips/kernel/kspd.c malta/linux/arch/mips/kernel/kspd.c
--- malta/linux/arch/mips/kernel/Attic/kspd.c	2005/08/19 13:47:36	1.1.1000.4
+++ malta/linux/arch/mips/kernel/Attic/kspd.c	2005/09/02 17:02:54	1.1.1000.5
@@ -113,7 +113,6 @@
 	register long int _arg1  __asm__ ("$5") = arg1;
 	register long int _arg2  __asm__ ("$6") = arg2;
 	register long int _arg3  __asm__ ("$7") = arg3;
-//	register long int eflag  __asm__ ("$7") = 1;
 
 	mm_segment_t old_fs;
 
@@ -286,8 +285,10 @@
 	} else {
 		/* wait for some data, allow it to sleep */
 		rtlx_read_poll(RTLX_CHANNEL_SYSIO, 1);
-
-		sp_work_handle_request();
+		
+		/* Check we haven't been woken because we are stopping */
+		if (!sp_stopping)
+			sp_work_handle_request();
 	}
 
 	if (!sp_stopping)
diff -urN malta/linux/arch/mips/kernel/rtlx.c malta/linux/arch/mips/kernel/rtlx.c
--- malta/linux/arch/mips/kernel/rtlx.c	2005/08/19 13:47:36	1.1.1000.5
+++ malta/linux/arch/mips/kernel/rtlx.c	2005/09/02 17:02:54	1.1.1000.6
@@ -52,6 +52,7 @@
 static struct chan_waitqueues {
 	wait_queue_head_t rt_queue;
 	wait_queue_head_t lx_queue;
+	int in_open;
 } channel_wqs[RTLX_CHANNELS];
 
 static struct irqaction irq;
@@ -61,7 +62,6 @@
 
 extern void *vpe_get_shared(int index);
 static int rtlx_init(struct rtlx_info *rtlxi);
-DECLARE_MUTEX(wq_mutex);
 
 static void rtlx_dispatch(struct pt_regs *regs)
 {
@@ -111,7 +111,7 @@
 static int rtlx_init(struct rtlx_info *rtlxi)
 {
 	if (rtlxi->id != RTLX_ID) {
-		printk(KERN_ERR "no valid RTLX id at 0x%p found 0x%x should be 0x%x\n", 
+		printk(KERN_ERR "no valid RTLX id at 0x%p found 0x%lx should be 0x%x\n", 
 		       rtlxi, rtlxi->id, RTLX_ID);
 		return -ENOEXEC;
 	}
@@ -149,6 +149,18 @@
 	int ret;
 	struct rtlx_channel *chan;
 	volatile struct rtlx_info **p;
+	
+	if (index >= RTLX_CHANNELS) {
+		printk(KERN_DEBUG "rtlx_open index out of range\n");
+		return -ENOSYS;
+	}
+
+	if (channel_wqs[index].in_open) {
+		printk(KERN_DEBUG "rtlx_open channel %d already opened\n", index);
+		return -EBUSY;
+	}
+
+	channel_wqs[index].in_open++;
 
 	if (rtlx == NULL) {
 		if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
@@ -171,6 +183,7 @@
 			} else {
 				printk( KERN_DEBUG "No SP program loaded, and device "
 					"opened with O_NONBLOCK\n");
+				channel_wqs[index].in_open = 0;
 				return -ENOSYS;
 			}
 		}
@@ -186,12 +199,7 @@
 				while (*p == NULL) {
 					schedule();
 
-					/* reset task state to interruptable otherwise
-					   we'll whizz round here like a very fast loopy 
-					   thing. schedule() appears to return with state
-					   set to TASK_RUNNING. 
-
-					   If the loaded SP program, for whatever reason, 
+					/* If the loaded SP program, for whatever reason, 
 					   doesn't set up the shared structure *p will never
 					   become true. So whoever connected to either /dev/rt?
 					   or if it was kspd, will then take up rather a lot of 
@@ -209,6 +217,7 @@
 			else {
 				printk(" *vpe_get_shared is NULL. "
 				       "Has an SP program been loaded?\n");
+				channel_wqs[index].in_open = 0;
 				return -ENOSYS;
 			}
 		}
@@ -216,20 +225,26 @@
 		if ((unsigned int)*p < KSEG0) {
 			printk(KERN_WARNING "vpe_get_shared returned an invalid pointer "
 			       "maybe an error code %d\n", (int)*p);
+			channel_wqs[index].in_open = 0;
 			return -ENOSYS;
 		}
 		
-		if ((ret = rtlx_init(*p)) < 0)
+		if ((ret = rtlx_init(*p)) < 0) {
+			channel_wqs[index].in_open = 0;
 			return ret;
+		}
 	}
-	
+
 	chan = &rtlx->channel[index];
 	
 	/* already open? */
-	if (chan->lx_state == RTLX_STATE_OPENED)
+	if (chan->lx_state == RTLX_STATE_OPENED) {
+		channel_wqs[index].in_open = 0;
 		return -EBUSY;
+	}
 
 	chan->lx_state = RTLX_STATE_OPENED;
+	channel_wqs[index].in_open = 0;
 	return 0;
 }	
 
@@ -478,6 +493,7 @@
 	for (i = 0; i < RTLX_CHANNELS; i++) {
 		init_waitqueue_head(&channel_wqs[i].rt_queue);
 		init_waitqueue_head(&channel_wqs[i].lx_queue);
+		channel_wqs[i].in_open = 0;
 	}
 
 	/* set up notifiers */
diff -urN malta/linux/arch/mips/kernel/vpe.c malta/linux/arch/mips/kernel/vpe.c
--- malta/linux/arch/mips/kernel/vpe.c	2005/08/19 13:47:36	1.1.1000.4
+++ malta/linux/arch/mips/kernel/vpe.c	2005/09/02 17:02:54	1.1.1000.5
@@ -164,8 +164,10 @@
 } vpecontrol;
 
 static void release_progmem(void *ptr);
-static void dump_vpe(vpe_t * v);
 extern void save_gp_address(unsigned int secbase, unsigned int rel);
+#ifdef VPE_DEBUG
+static void dump_vpe(vpe_t * v);
+#endif
 
 /* get the vpe associated with this minor */
 struct vpe *get_vpe(int minor)
@@ -741,9 +743,6 @@
 	/* disable MT (using dvpe) */
 	dvpe();
 
-	/* Put MVPE's into 'configuration state' */
-	write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_VPC);
-
 	if (!list_empty(&v->tc)) {
 		if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
 			printk(KERN_WARNING "VPE: TC %d is already in use.\n",
@@ -756,6 +755,9 @@
 		return -ENOEXEC;
 	}
 
+	/* Put MVPE's into 'configuration state' */
+	write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_VPC);
+
 	settc(t->index);
 
 	/* should check it is halted, and not activated */
@@ -773,10 +775,8 @@
 
 	/* Write the address we want it to start running from in the TCPC register. */
 	write_tc_c0_tcrestart((unsigned long)v->__start);
-
 	write_tc_c0_tccontext((unsigned long)0);
 
-
 	/* mark the TC as activated, not interrupt exempt and not dynamically 
 	   allocatable */
 	val = read_tc_c0_tcstatus();
@@ -823,7 +823,7 @@
 	return 0;
 }
 
-static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs,
+static int find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs,
 				      unsigned int symindex, const char *strtab,
 				      struct module *mod)
 {
@@ -840,6 +840,9 @@
 		}
 	}
 
+	if ( (v->__start == 0) || (v->shared_ptr == NULL))
+		return -1;
+
 	return 0;
 }
 
@@ -974,6 +977,19 @@
 		}
 	} else {
 		for (i = 0; i < hdr->e_shnum; i++) {
+
+			/* Internal symbols and strings. */
+			if (sechdrs[i].sh_type == SHT_SYMTAB) {
+				symindex = i;
+				strindex = sechdrs[i].sh_link;
+				strtab = (char *)hdr + sechdrs[strindex].sh_offset;
+
+				/* mark the symtab's address for when we try to find the 
+				   magic symbols */
+				sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
+			}
+
+			/* filter sections we dont want in the final image */
 			if (!(sechdrs[i].sh_flags & SHF_ALLOC) || 
 			    (sechdrs[i].sh_type == SHT_MIPS_REGINFO)) {
 				printk( KERN_DEBUG " ignoring section, "
@@ -992,12 +1008,13 @@
 				return -ENOEXEC;
 			}
 
-			printk(KERN_DEBUG " copying section sh_name %s, sh_addr 0x%x size 0x%x\n", 
+			printk(KERN_DEBUG " copying section sh_name %s, sh_addr 0x%x "
+			       "size 0x%x0 from x%p\n", 
 			       secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr,
-			       sechdrs[i].sh_size);
+			       sechdrs[i].sh_size, hdr + sechdrs[i].sh_offset);
 
 			if (sechdrs[i].sh_type != SHT_NOBITS)
-				memcpy((void *)sechdrs[i].sh_addr, v->pbuffer + sechdrs[i].sh_offset,
+				memcpy((void *)sechdrs[i].sh_addr, (char *)hdr + sechdrs[i].sh_offset,
 					sechdrs[i].sh_size);
 			else
 				memset((void *)sechdrs[i].sh_addr, 0, sechdrs[i].sh_size);
@@ -1022,6 +1039,7 @@
 	return err;
 }
 
+#ifdef VPE_DEBUG
 static void dump_vpe(vpe_t * v)
 {
 	struct tc *t;
@@ -1035,6 +1053,7 @@
 		dump_tc(t);
 	}
 }
+#endif
 
 static void cleanup_tc(struct tc *tc)
 {
@@ -1129,6 +1148,8 @@
 		printk("VPE: open, getcwd returned %d\n", ret);
 	}
 
+	v->shared_ptr = NULL;
+	v->__start = 0;
 	return 0;
 }
 
@@ -1157,14 +1178,6 @@
 		ret = -ENOEXEC;
 	}
 
-	/* It's good to be able to run the SP and if it chokes have a look at
-	   the /dev/rt?. But if we reset the pointer to the shared struct we 
-	   loose what has happened. So perhaps if garbage is sent to the vpe 
-	   device, use it as a trigger for the reset. Hopefully a nice 
-	   executable will be along shortly. */
-	if (ret < 0)
-		v->shared_ptr = NULL;
-
 	// cleanup any temp buffers
 	if (v->pbuffer)
 		vfree(v->pbuffer);

From beth@linux-mips.org Fri Sep 16 10:39:33 2005
Received: with ECARTIS (v1.0.0; list maltalinux-cvs-patches); Fri, 16 Sep 2005 11:39:33 +0100 (BST)
From: beth@linux-mips.org
To:  maltalinux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: malta
Date: Fri, 16 Sep 2005 11:39:33 +0100
X-archive-position: 53
X-ecartis-version: Ecartis v1.0.0
Sender: maltalinux-cvs-patches-bounce@linux-mips.org
Errors-to: maltalinux-cvs-patches-bounce@linux-mips.org
X-original-sender: beth@linux-mips.org
Precedence: bulk
Reply-to: linux-mips@linux-mips.org
X-list: maltalinux-cvs-patches


CVSROOT:	/home/cvs
Module name:	malta
Changes by:	beth@ftp.linux-mips.org	05/09/16 11:39:32

Modified files:
	linux/arch/mips/kernel: Tag: MaltaRef_2_6 kspd.c 

Log message:
	Added further MTSP syscalls.

diff -urN malta/linux/arch/mips/kernel/kspd.c malta/linux/arch/mips/kernel/kspd.c
--- malta/linux/arch/mips/kernel/Attic/kspd.c	2005/09/02 17:02:54	1.1.1000.5
+++ malta/linux/arch/mips/kernel/Attic/kspd.c	2005/09/16 10:39:32	1.1.1000.6
@@ -31,6 +31,8 @@
 static struct workqueue_struct *workqueue = NULL;
 static struct work_struct work;
 
+extern unsigned long cpu_khz;
+
 struct mtsp_syscall {
     int cmd;
     unsigned char abi;
@@ -57,12 +59,17 @@
 
 /* these should match with those in the SDE kit */
 #define MTSP_SYSCALL_BASE	0
-#define MTSP_SYSCALL_EXIT    (MTSP_SYSCALL_BASE + 0)
-#define MTSP_SYSCALL_OPEN    (MTSP_SYSCALL_BASE + 1)
-#define MTSP_SYSCALL_READ    (MTSP_SYSCALL_BASE + 2)
-#define MTSP_SYSCALL_WRITE   (MTSP_SYSCALL_BASE + 3)
-#define MTSP_SYSCALL_CLOSE   (MTSP_SYSCALL_BASE + 4)
-#define MTSP_SYSCALL_LSEEK32 (MTSP_SYSCALL_BASE + 5)
+#define MTSP_SYSCALL_EXIT       (MTSP_SYSCALL_BASE + 0)
+#define MTSP_SYSCALL_OPEN       (MTSP_SYSCALL_BASE + 1)
+#define MTSP_SYSCALL_READ       (MTSP_SYSCALL_BASE + 2)
+#define MTSP_SYSCALL_WRITE      (MTSP_SYSCALL_BASE + 3)
+#define MTSP_SYSCALL_CLOSE      (MTSP_SYSCALL_BASE + 4)
+#define MTSP_SYSCALL_LSEEK32 	(MTSP_SYSCALL_BASE + 5)
+#define MTSP_SYSCALL_ISATTY  	(MTSP_SYSCALL_BASE + 6)
+#define MTSP_SYSCALL_GETTIME 	(MTSP_SYSCALL_BASE + 7)
+#define MTSP_SYSCALL_PIPEFREQ 	(MTSP_SYSCALL_BASE + 8)
+#define MTSP_SYSCALL_GETTOD  	(MTSP_SYSCALL_BASE + 9)
+
 
 #define	MTSP_O_RDONLY	0x0000	
 #define	MTSP_O_WRONLY	0x0001	
@@ -183,6 +190,9 @@
 	struct mtsp_syscall_generic generic;
 	struct mtsp_syscall_ret ret;
 	struct kspd_notifications *n;
+	struct timeval tv;
+	struct timezone tz;
+
 	char *vcwd;
 	mm_segment_t old_fs;
 	int size;
@@ -210,10 +220,21 @@
 		sp_setfsuidgid( vpe_getuid(SP_VPE), vpe_getgid(SP_VPE));
 
 	switch (sc.cmd) {
-		
-		/* needs the flags argument translating from SDE kit to
-		   linux */
 
+		case MTSP_SYSCALL_PIPEFREQ:
+			ret.retval = cpu_khz * 1000;
+			ret.errno = 0;
+			break;
+
+		case MTSP_SYSCALL_GETTOD:
+			memset(&tz, 0, sizeof(tz));
+			if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv, 
+						     (int)&tz, 0,0)) == 0)
+				ret.retval = tv.tv_sec;
+			
+			ret.errno = errno;
+			break;
+		
 		case MTSP_SYSCALL_EXIT:
 			list_for_each_entry(n, &kspd_notifylist, list) {
 				n->kspd_sp_exit(SP_VPE);

From beth@linux-mips.org Fri Sep 16 10:41:13 2005
Received: with ECARTIS (v1.0.0; list maltalinux-cvs-patches); Fri, 16 Sep 2005 11:41:14 +0100 (BST)
From: beth@linux-mips.org
To:  maltalinux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: malta
Date: Fri, 16 Sep 2005 11:41:13 +0100
X-archive-position: 54
X-ecartis-version: Ecartis v1.0.0
Sender: maltalinux-cvs-patches-bounce@linux-mips.org
Errors-to: maltalinux-cvs-patches-bounce@linux-mips.org
X-original-sender: beth@linux-mips.org
Precedence: bulk
Reply-to: linux-mips@linux-mips.org
X-list: maltalinux-cvs-patches


CVSROOT:	/home/cvs
Module name:	malta
Changes by:	beth@ftp.linux-mips.org	05/09/16 11:41:12

Modified files:
	linux/arch/mips/kernel: Tag: MaltaRef_2_6 rtlx.c 

Log message:
	Tweaked the read and write poll handling.

diff -urN malta/linux/arch/mips/kernel/rtlx.c malta/linux/arch/mips/kernel/rtlx.c
--- malta/linux/arch/mips/kernel/rtlx.c	2005/09/02 17:02:54	1.1.1000.6
+++ malta/linux/arch/mips/kernel/rtlx.c	2005/09/16 10:41:12	1.1.1000.7
@@ -78,7 +78,8 @@
 	int i;
 
 	for (i = 0; i < RTLX_CHANNELS; i++) {
-			wake_up_interruptible(&channel_wqs[i].lx_queue);
+			wake_up(&channel_wqs[i].lx_queue);
+			wake_up(&channel_wqs[i].rt_queue);
 	}
 
 	return r;
@@ -256,7 +257,12 @@
 
 unsigned int rtlx_read_poll(int index, int can_sleep)
 {
-	struct rtlx_channel *chan = &rtlx->channel[index];
+	struct rtlx_channel *chan; 
+	
+	if (rtlx == NULL)
+		return 0;
+
+	chan = &rtlx->channel[index];
 	
 	/* data available to read? */
 	if (chan->lx_read == chan->lx_write) {
@@ -289,7 +295,7 @@
 	}
 	
 	return (chan->lx_write + chan->buffer_size - chan->lx_read)
-	       % chan->buffer_size;
+		% chan->buffer_size;
 }
 
 unsigned int rtlx_write_poll(int index)
@@ -398,11 +404,15 @@
 	struct rtlx_channel *chan;
 
 	minor = MINOR(file->f_dentry->d_inode->i_rdev);
-	chan = &rtlx->channel[minor];
 
 	poll_wait(file, &channel_wqs[minor].rt_queue, wait);
 	poll_wait(file, &channel_wqs[minor].lx_queue, wait);
 
+	if (rtlx == NULL)
+		return 0;
+
+	chan = &rtlx->channel[minor];
+
 	/* data available to read? */
 	if (rtlx_read_poll(minor, 0))
 		mask |= POLLIN | POLLRDNORM;

From beth@linux-mips.org Fri Sep 16 10:45:44 2005
Received: with ECARTIS (v1.0.0; list maltalinux-cvs-patches); Fri, 16 Sep 2005 11:45:44 +0100 (BST)
From: beth@linux-mips.org
To:  maltalinux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: malta
Date: Fri, 16 Sep 2005 11:45:44 +0100
X-archive-position: 55
X-ecartis-version: Ecartis v1.0.0
Sender: maltalinux-cvs-patches-bounce@linux-mips.org
Errors-to: maltalinux-cvs-patches-bounce@linux-mips.org
X-original-sender: beth@linux-mips.org
Precedence: bulk
Reply-to: linux-mips@linux-mips.org
X-list: maltalinux-cvs-patches


CVSROOT:	/home/cvs
Module name:	malta
Changes by:	beth@ftp.linux-mips.org	05/09/16 11:45:43

Modified files:
	linux/arch/mips/kernel: Tag: MaltaRef_2_6 vpe.c 
	linux/arch/mips/mips-boards/generic: Tag: MaltaRef_2_6 memory.c 

Log message:
	* arch/mips/kernel/vpe.c: Set $a3 to the physical or assumed memory size
	so SP programs can set their stack pointer to the top of memory.
	
	* arch/mips/mips-boards/generic/memory.c: Rearranged memsize handling to
	keep a note of the physical or determined memory sizes for use by the
	VPE loader.

diff -urN malta/linux/arch/mips/kernel/vpe.c malta/linux/arch/mips/kernel/vpe.c
--- malta/linux/arch/mips/kernel/vpe.c	2005/09/02 17:02:54	1.1.1000.5
+++ malta/linux/arch/mips/kernel/vpe.c	2005/09/16 10:45:43	1.1.1000.6
@@ -58,6 +58,9 @@
 #include <asm/vpe.h>
 #include <asm/kspd.h>
 
+#include <asm/mips-boards/prom.h>
+
+
 typedef void *vpe_handle;
 
 #if 0
@@ -94,6 +97,8 @@
 #define P_SIZE (256 * 1024)
 #endif
 
+extern unsigned long physical_memsize;
+
 #define MAX_VPES 16
 
 #define VPE_PATH_MAX 256
@@ -785,11 +790,10 @@
 	
 	write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
 
-	/* The sde-kit passes 'memsize' to __start in $a3, so set something here...
-	   Or set $a3 to zero and define DFLT_STACK_SIZE and DFLT_HEAP_SIZE when you compile
-	   your program */
-
-	mttgpr($7, 0);
+	/* The sde-kit passes 'memsize' to __start in $a3, so if we have the info
+	   from YAMON, then set it. Otherwise set $a3 to zero and define DFLT_STACK_SIZE
+	   and DFLT_HEAP_SIZE when you compile your program */
+	mttgpr($7, physical_memsize);
 
 	/* set up VPE1 */
 	/* bind the TC to VPE 1 as late as possible so we only have the final VPE 
diff -urN malta/linux/arch/mips/mips-boards/generic/memory.c malta/linux/arch/mips/mips-boards/generic/memory.c
--- malta/linux/arch/mips/mips-boards/generic/memory.c	2005/06/21 13:24:12	1.11.1000.2
+++ malta/linux/arch/mips/mips-boards/generic/memory.c	2005/09/16 10:45:43	1.11.1000.3
@@ -49,6 +49,9 @@
 /* References to section boundaries */
 extern char _end;
 
+/* determined physical memory size, not overridden by command line args  */
+unsigned long physical_memsize = 0L;
+
 #define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
 
 
@@ -58,28 +61,30 @@
 	unsigned int memsize;
 	char cmdline[CL_SIZE], *ptr;
 
-	/* Check the command line first for a memsize directive */
+	/* otherwise look in the environment */
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
+		physical_memsize = 0x02000000;
+	} else {
+#ifdef DEBUG
+		prom_printf("prom_memsize = %s\n", memsize_str);
+#endif
+		physical_memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+
+	/* Check the command line for a memsize directive that overrides 
+	   the physical/default amount */
 	strcpy(cmdline, arcs_cmdline);
 	ptr = strstr(cmdline, "memsize=");
 	if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
 		ptr = strstr(ptr, " memsize=");
 		
-	if (ptr) {
+	if (ptr)
 		memsize = memparse(ptr + 8, &ptr);
-	}
-	else {
-		/* otherwise look in the environment */
-		memsize_str = prom_getenv("memsize");
-		if (!memsize_str) {
-			prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
-			memsize = 0x02000000;
-		} else {
-#ifdef DEBUG
-			prom_printf("prom_memsize = %s\n", memsize_str);
-#endif
-			memsize = simple_strtol(memsize_str, NULL, 0);
-		}
-	}
+	else
+		memsize = physical_memsize;
+
 	memset(mdesc, 0, sizeof(mdesc));
 
 	mdesc[0].type = yamon_dontuse;

From beth@linux-mips.org Fri Sep 16 16:34:05 2005
Received: with ECARTIS (v1.0.0; list maltalinux-cvs-patches); Fri, 16 Sep 2005 17:34:05 +0100 (BST)
From: beth@linux-mips.org
To:  maltalinux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: malta
Date: Fri, 16 Sep 2005 17:34:05 +0100
X-archive-position: 56
X-ecartis-version: Ecartis v1.0.0
Sender: maltalinux-cvs-patches-bounce@linux-mips.org
Errors-to: maltalinux-cvs-patches-bounce@linux-mips.org
X-original-sender: beth@linux-mips.org
Precedence: bulk
Reply-to: linux-mips@linux-mips.org
X-list: maltalinux-cvs-patches


CVSROOT:	/home/cvs
Module name:	malta
Changes by:	beth@ftp.linux-mips.org	05/09/16 17:34:04

Modified files:
	linux/arch/mips/mips-boards/mipssim: Tag: MaltaRef_2_6 sim_mem.c 

Log message:
	* arch/mips/mips-boards/mipssim/sim_mem.c: Add declaration for
	physical_memsize.

diff -urN malta/linux/arch/mips/mips-boards/mipssim/sim_mem.c malta/linux/arch/mips/mips-boards/mipssim/sim_mem.c
--- malta/linux/arch/mips/mips-boards/mipssim/Attic/sim_mem.c	2005/08/15 19:26:46	1.1.1000.1
+++ malta/linux/arch/mips/mips-boards/mipssim/Attic/sim_mem.c	2005/09/16 16:34:04	1.1.1000.2
@@ -44,6 +44,9 @@
 /* References to section boundaries */
 extern char _end;
 
+/* determined physical memory size, not overridden by command line args  */
+unsigned long physical_memsize = 0L;
+
 #define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
 
 

