[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: some more 110h4 clues...



itschere@TechFak.Uni-Bielefeld.DE writes:

> > If my memory serves me right, this is the upwards pointer to the
> > parent process' basepage.
> 
>  It *is*.

 here's the fix :)  and something else for you all to test...

1. exec and base->p_parent...

Index: mem.c
@@ -1137,8 +1137,8 @@
 	long len = 0, minalt = 0, coresize, altsize;
 	MMAP map;
 	MEMREGION *m, *savemem = 0;
-	BASEPAGE *b;
-	PROC *parent = 0;	/* keep compiler happy... */
+	BASEPAGE *b, *bparent = 0;
+	PROC *parent = 0;
 	short protmode;
 	int i;
 
@@ -1252,8 +1252,15 @@
 		execproc->ctxt[SYSCALL].sr |= 0x2000;
 		execproc->ctxt[SYSCALL].ssp = (long)(execproc->stack + ISTKSIZE);
 
-		if (savemem)
-			fork_restore(parent, savemem);
+/* save basepage p_parent */
+		bparent = execproc->base->p_parent;
+		if (parent) {
+			if (savemem)
+				fork_restore(parent, savemem);
+/* blocking forks keep the same basepage for parent and child,
+   so this p_parent actually was our grandparents...  */
+			bparent = parent->base;
+		}
 		for (i = 0; i < execproc->num_reg; i++) {
 			m = execproc->mem[i];
 			if (m && m->links == 0xfffe) {
@@ -1323,6 +1330,11 @@
 	b->p_env = (char *)env->loc;
 	b->p_flags = flags;
 
+	if (execproc) {
+		execproc->base = b;
+		b->p_parent = bparent;
+	}
+
 	if (cmd)
 		strncpy(b->p_cmdlin, cmd, 126);
 	return m;

2. serial lines...  use the xcon* pointers etc. available thru
Bconmap(-2), set DTR on SCC ports and hack around a bunch of BIOS bugs
while we're at it, including TIOCSBRK for SCC ports.  you still need to
load debugged drivers (before MiNT!) to get reliable flow control and
stop losing chars on all TOS versions _i_ know, your mileage may vary...
at least the remaining bugs should not affect the rest of the system
anymore. (except for the mega STe SCC/DMA hardware bug of course...)

please test this, hard. :)  the MAPTAB stuff is official (its mentioned
in `Profibuch') but i don't know yet if it works as advertised everywhere
including falcons...  if it does i think we can finally implement local
mode, fast RAW IO without hacks in user processes, real cooked mode, etc.

Index: types.h
@@ -19,4 +19,13 @@
 	short buflen, head, tail, low_water, hi_water;
 } IOREC_T;
 
+/* Bconmap struct, * returned by Bconmap(-2) */
+typedef struct {
+	struct {
+		long bconstat, bconin, bcostat, bconout, rsconf;
+		IOREC_T	*iorec;
+	} *maptab;
+	short	maptabsize;
+} BCONMAP2_T;
+
 #endif
Index: bios.c
@@ -11,6 +11,12 @@
 #include "mint.h"
 #include "xbra.h"
 
+#ifdef __GNUC__
+#define INLINE inline
+#else
+#define INLINE
+#endif
+
 #define UNDEF 0		/* should match definition in tty.c */
 
 /* some key definitions */
@@ -66,6 +72,34 @@
 #define xcostat ((long *)0x55eL)
 #define xconout	((long *)0x57eL)
 
+#if 1
+/* if the system has Bconmap the ones >= 6 are in a table available
+ * thru Bconmap(-2)...
+ */
+#define MAPTAB (bconmap2->maptab)
+
+/* and then do BCOSTAT ourselves, the BIOS SCC ones are often broken */
+#define BCOSTAT(dev) \
+	(((unsigned)dev <= 4 && tosvers > 0x0102) ? \
+	   (int)callout1(xcostat[dev], dev) : \
+	   ((has_bconmap && (unsigned)((dev-SERDEV) <= btty_max)) ? \
+		bcxstat(MAPTAB[dev-SERDEV].iorec+1) : Bcostat(dev)))
+#define BCONOUT(dev, c) \
+	(((unsigned)dev <= 4 && tosvers > 0x0102) ? \
+	   callout2(xconout[dev], dev, c) : \
+	   ((has_bconmap && (unsigned)((dev-SERDEV) <= btty_max)) ? \
+		callout2(MAPTAB[dev-SERDEV].bconout, dev, c) : Bconout(dev, c)))
+#define BCONSTAT(dev) \
+	(((unsigned)dev <= 4 && tosvers > 0x0102) ? \
+	   (int)callout1(xconstat[dev], dev) : \
+	   ((has_bconmap && (unsigned)((dev-SERDEV) <= btty_max)) ? \
+		(int)callout1(MAPTAB[dev-SERDEV].bconstat, dev) : Bconstat(dev)))
+#define BCONIN(dev) \
+	(((unsigned)dev <= 4 && tosvers > 0x0102) ? \
+	   callout1(xconin[dev], dev) : \
+	   ((has_bconmap && (unsigned)((dev-SERDEV) <= btty_max)) ? \
+		callout1(MAPTAB[dev-SERDEV].bconin, dev) : Bconin(dev)))
+#else
 #define BCOSTAT(dev) \
 	((tosvers > 0x0102 && (unsigned)dev <= 4) ? \
 	   (int)callout1(xcostat[dev], dev) : Bcostat(dev))
@@ -78,6 +112,7 @@
 #define BCONIN(dev) \
 	((tosvers > 0x0102 && (unsigned)dev <= 4) ? \
 	   callout1(xconin[dev], dev) : Bconin(dev))
+#endif
 #else
 #define BCOSTAT(dev) Bcostat(dev)
 #define BCONOUT(dev,c) Bconout(dev,c)
@@ -87,8 +122,19 @@
 
 /* variables for monitoring the keyboard */
 IOREC_T	*keyrec;		/* keyboard i/o record pointer */
+BCONMAP2_T *bconmap2;		/* bconmap struct */
 short	kintr = 0;		/* keyboard interrupt pending (see intr.s) */
 
+/* replacement *costat for BCOSTAT above */
+INLINE static int bcxstat (wrec)
+IOREC_T *wrec;
+{
+	unsigned s = wrec->head - wrec->tail;
+	if ((int)s <= 0)
+		s += wrec->buflen;
+	return s < 3 ? 0 : -1;
+}
+
 /* Getmpb is not allowed under MiNT */
 
 long ARGS_ON_STACK
@@ -746,6 +792,8 @@
 init_bios()
 {
 	keyrec = (IOREC_T *)Iorec(1);
+	if (has_bconmap)
+		bconmap2 = (BCONMAP2_T *)Bconmap(-2);
 }
 
 /*
Index: xbios.c
@@ -23,6 +23,9 @@
 			 * of TOS which supports Bconmap
 			 */
 
+extern BCONMAP2_T *bconmap2;		/* bconmap struct */
+#define MAPTAB (bconmap2->maptab)
+
 /*
  * Supexec() presents a lot of problems for us: for example, the user
  * may be calling the kernel, or may be changing interrupt vectors
@@ -143,8 +146,12 @@
 	int dev;
 {
 	TRACE(("Iorec(%d)", dev));
-	if (dev == 0 && has_bconmap)
+	if (dev == 0 && has_bconmap) {
+/* get around another BIOS Bug:  in (at least) TOS 2.05 Iorec(0) is broken */
+		if (curproc->bconmap >= 6)
+			return (long)MAPTAB[curproc->bconmap-6].iorec;
 		mapin(curproc->bconmap);
+	}
 	return (long)Iorec(dev);
 }
 
@@ -155,12 +162,21 @@
 	long rsval;
 	static int oldbaud = -1;
 	int ret_oldbaud = 0;
+	extern struct tty ttmfp_tty;
+	extern struct bios_tty bttys[];
+	extern short btty_max;
 
 	TRACE(("Rsconf(%d,%d,%d,%d,%d,%d)", baud, flow,
 		uc, rs, ts, sc));
 
-	if (has_bconmap)
+	if (has_bconmap) {
 		mapin(curproc->bconmap);
+/* more bugs...  serial1 is three-wire, requesting hardware flowcontrol
+ * on it can confuse BIOS
+ */
+		if ((flow & 2) && (unsigned)curproc->bconmap-6 <= btty_max &&
+		    bttys[curproc->bconmap-6].rsel == &(ttmfp_tty.rsel))
+			flow &= ~2;
 
 #ifndef DONT_ONLY030_THIS
 /* Note: the code below must be included, even on a 68030, thanks to a bug
@@ -177,7 +193,7 @@
 	3. Rsconf() discards any buffered output
 		-> use Iorec() to ensure all buffered data was sent before call
 */
-	else if (tosvers < 0x0104) {
+	} else if (tosvers < 0x0104) {
 		if (baud == -2) {
 			ret_oldbaud = 1;
 			baud = -1;
Index: biosfs.c
@@ -6,6 +6,12 @@
 
 /* simple biosfs.c */
 
+#ifdef __GNUC__
+#define INLINE inline
+#else
+#define INLINE
+#endif
+
 #include "mint.h"
 
 extern struct kerinfo kernelinfo;	/* see main.c */
@@ -146,6 +152,38 @@
 	{"", 0, 0, 0, 0, 0}
 };
 
+extern BCONMAP2_T *bconmap2;		/* bconmap struct */
+#define MAPTAB (bconmap2->maptab)
+
+/* set/reset bits in SCC w5 */
+INLINE static void scc_set5 (control, setp, bits, iorec)
+volatile char *control;
+int setp;
+unsigned char bits;
+IOREC_T *iorec;
+{
+	volatile char dummy;
+
+	short sr = spl7();
+
+#if 1
+/* sanity check: if the w5 copy at offset 1d has bit 3 off something is wrong */
+	if (!(((char *) iorec)[0x1d] & 8)) {
+		spl(sr);
+		ALERT ("scc_set5: iorec %lx w5 copy has sender enable bit off, w5 not changed", iorec);
+		return;
+	}
+#endif
+	dummy = *((volatile char *) 0xfffffa01);
+	*control = 5;
+	dummy = *((volatile char *) 0xfffffa01);
+	if (setp)
+		*control = (((char *) iorec)[0x1d] |= bits);
+	else
+		*control = (((char *) iorec)[0x1d] &= ~bits);
+	spl(sr);
+}
+
 #define	MAX_BTTY	4	/* 4 bios_tty structs */
 
 struct bios_tty bttys[MAX_BTTY];
@@ -231,12 +269,16 @@
 			b->next = 0;
 			break;
 		}
-	/* SERIAL2 is not present on the Mega STe or Falcon */
+	/* SERIAL1(!) is not present on the Mega STe or Falcon,
+	 * device 8 is SCC channel A
+	 */
 		if (mch != TT && b->private == 8) {
+			b->name[6] = '2';	/* "serial2" */
+			b->tty = &scca_tty;
 			b->next = 0;
 			break;
 		}
-			
+
 	}
 	bdevlast = b;
 	if (b->name[0] == 0) {
@@ -1347,7 +1389,6 @@
 		break;
 	case TIOCFLUSH:
 	    {
-		int oldmap;
 		IOREC_T *ior;
 		int flushtype;
 		short sr;
@@ -1360,13 +1401,10 @@
 			flushtype = (int) *r;
 		}
 		if (dev == 1 || dev >= 6) {
-/* trick uiorec into setting the correct port (it uses curproc->bconmap) */
-			oldmap = curproc->bconmap;
-			if (has_bconmap)
-				curproc->bconmap = (dev == 1)
-						? curproc->bconmap
-						: dev;
-			ior = (IOREC_T *) uiorec(0);
+			if (has_bconmap && dev >= 6)
+				ior = MAPTAB[dev-6].iorec;
+			else
+				ior = (IOREC_T *) uiorec(0);
 			if (flushtype & 1) {
 				sr = spl7();
 				ior->head = ior->tail = 0;
@@ -1378,7 +1416,6 @@
 				ior->head = ior->tail = 0;
 				spl(sr);
 			}
-			curproc->bconmap = oldmap;
 		} else if (dev == 3 || dev == 2 || dev == 5) {
 			if (dev == 3) {
 				/* midi */
@@ -1397,23 +1434,18 @@
 	    }
 	case TIOCOUTQ:
 	    {
-		int oldmap;
 		IOREC_T *ior;
 
 		dev = f->fc.aux;
 
 		if (dev == 1 || dev >= 6) {
-/* trick uiorec into setting the correct port (it uses curproc->bconmap) */
-			oldmap = curproc->bconmap;
-			if (has_bconmap)
-				curproc->bconmap = (dev == 1)
-						? curproc->bconmap
-						: dev;
-			ior = (IOREC_T *) uiorec(0) + 1;
+			if (has_bconmap && dev >= 6)
+				ior = MAPTAB[dev-6].iorec + 1;
+			else
+				ior = (IOREC_T *) uiorec(0) + 1;
 			*r = ior->tail - ior->head;
 			if (*r < 0)
 				*r += ior->buflen;
-			curproc->bconmap = oldmap;
 		}
  		else
 			*r = 0;
@@ -1450,9 +1482,14 @@
 				oldbaud = baudmap[i];
 			*r = oldbaud;
 			if (newbaud > 0) {
-	/* BUG: assert DTR works only on modem1 */
+	/* assert DTR works only on modem1 and SCC lines */
 				if (dev == 1 || dev == 6) {
 					Offgibit(0xef);
+				} else if (dev == 7 ||
+					   ((struct tty *)f->devinfo) == &scca_tty) {
+					scc_set5 ((volatile char *) (dev == 7 ?
+						    0xffff8c85L : 0xffff8c81L),
+						  1, (1 << 7), MAPTAB[dev-6].iorec);
 				}
 				if (newbaud == oldbaud) {
 					curproc->bconmap = oldmap;
@@ -1472,9 +1509,14 @@
 				curproc->bconmap = oldmap;
 				return ERANGE;
 			} else if (newbaud == 0L) {
-	/* BUG: drop DTR: works only on modem1 */
+	/* drop DTR: works only on modem1 and SCC lines */
 				if (dev == 1 || dev == 6) {
 					Ongibit(0x10);
+				} else if (dev == 7 ||
+					   ((struct tty *)f->devinfo) == &scca_tty) {
+					scc_set5 ((volatile char *) (dev == 7 ?
+						    0xffff8c85L : 0xffff8c81L),
+						  0, (1 << 7), MAPTAB[dev-6].iorec);
 				}
 			}
 			curproc->bconmap = oldmap;
@@ -1500,8 +1542,25 @@
 
 		dev = f->fc.aux;
 		if (dev == 1 || dev >= 6) {
-			if (has_bconmap)
-				mapin((dev == 1) ? curproc->bconmap : dev);
+			if (has_bconmap) {
+				if (dev == 1)
+					dev = curproc->bconmap;
+/* YABB (Yet Another BIOS Bug):
+   SCC Rsconf looks for the break bit in the wrong place...  if this
+   dev's Rsconf is in ROM do it ourselves, otherwise assume the user
+   has installed a fix.
+*/
+				if ((dev == 7 ||
+				     ((struct tty *)f->devinfo) == &scca_tty) &&
+				    MAPTAB[dev-6].rsconf > 0xe00000L &&
+				    MAPTAB[dev-6].rsconf < 0xefffffL) {
+					scc_set5 ((volatile char *) (dev == 7 ?
+						    0xffff8c85L : 0xffff8c81L),
+						  (mode == TIOCSBRK), (1 << 4), MAPTAB[dev-6].iorec);
+					break;
+				}
+				mapin(dev);
+			}
 		} else {
 			return EINVFN;
 		}
-- 
J"urgen Lock / nox@jelal.north.de / UUCP: ..!uunet!unido!uniol!jelal!nox
								...ohne Gewehr
PGP public key fingerprint =  8A 18 58 54 03 7B FC 12  1F 8B 63 C7 19 27 CF DA