shithub: misc

ref: f54501c2592bd7cee283a243391d07f2dd131373
dir: /9legacy/9_bcm.diff/

View raw version
diff -urP sys/src/9/bcm/archbcm.c /sys/src/9/bcm/archbcm.c
--- sys/src/9/bcm/archbcm.c	Thu Jun 24 18:58:12 2021
+++ /sys/src/9/bcm/archbcm.c	Tue Aug 20 11:18:46 2019
@@ -138,7 +138,28 @@
  */
 
 long
-ainc(long *p)
+_xdec(long *p)
+{
+	int s, v;
+
+	s = splhi();
+	v = --*p;
+	splx(s);
+	return v;
+}
+
+void
+_xinc(long *p)
+{
+	int s;
+
+	s = splhi();
+	++*p;
+	splx(s);
+}
+
+int
+ainc(int *p)
 {
 	int s, v;
 
@@ -148,8 +169,8 @@
 	return v;
 }
 
-long
-adec(long *p)
+int
+adec(int *p)
 {
 	int s, v;
 
diff -urP sys/src/9/bcm/main.c /sys/src/9/bcm/main.c
--- sys/src/9/bcm/main.c	Thu Jun 24 18:58:13 2021
+++ /sys/src/9/bcm/main.c	Sat Jul  4 10:38:16 2020
@@ -510,6 +510,7 @@
 	ulong kpages;
 	uintptr pa;
 	char *p;
+	extern ulong xmembase, xmempages;
 
 	if(0 && (p = getconf("service")) != nil){
 		if(strcmp(p, "cpu") == 0)
@@ -531,20 +532,24 @@
 	/*
 	 * pi4 extra memory (beyond video ram) indicated by board id
 	 */
-	switch(getboardrev()&0xF00000){
-	case 0xA00000:
+	switch(getboardrev()&0xFFFFFF){
+	case 0xA03111:
 		break;
-	case 0xB00000:
+	case 0xB03111:
+	case 0xB03112:
 		conf.mem[1].base = 1*GiB;
 		conf.mem[1].limit = 2*GiB;
 		break;
-	case 0xC00000:
+	case 0xC03111:
+	case 0xC03112:
 		conf.mem[1].base = 1*GiB;
 		conf.mem[1].limit = 0xFFF00000;
 		break;
-	case 0xD00000:
+	case 0xD03114:
 		conf.mem[1].base = 1*GiB;
 		conf.mem[1].limit = 0xFFF00000;
+		//xmembase = 1<<20;	/* 4*GiB / BY2PG */
+		//xmempages = 1<<20;	/* as above */
 		break;
 	}
 	if(conf.mem[1].limit > soc.dramsize)
@@ -608,7 +613,7 @@
 		+ conf.nproc*sizeof(Proc)
 		+ conf.nimage*sizeof(Image)
 		+ conf.nswap
-		+ conf.nswppo*sizeof(Page*);
+		+ conf.nswppo*sizeof(Page);
 	mainmem->maxsize = kpages;
 	if(!cpuserver)
 		/*
diff -urP sys/src/9/bcm/screen.c /sys/src/9/bcm/screen.c
--- sys/src/9/bcm/screen.c	Thu Jun 24 18:58:13 2021
+++ /sys/src/9/bcm/screen.c	Mon May 30 11:38:43 2016
@@ -326,11 +326,6 @@
 	set = screensize() == 0;
 	fb = fbinit(set, &xgscreen.r.max.x, &xgscreen.r.max.y, &xgscreen.depth);
 	if(fb == nil){
-		xgscreen.r.max = Pt(640, 480);
-		xgscreen.depth = 16;
-		fb = fbinit(set, &xgscreen.r.max.x, &xgscreen.r.max.y, &xgscreen.depth);
-	}
-	if(fb == nil){
 		print("can't initialise %dx%dx%d framebuffer \n",
 			xgscreen.r.max.x, xgscreen.r.max.y, xgscreen.depth);
 		return;
@@ -349,7 +344,7 @@
 		chan = rgbswap? RGB24 : BGR24;
 		break;
 	case 32:
-		chan = rgbswap? XRGB32 : XBGR32;
+		chan = ARGB32;
 		break;
 	}
 	memsetchan(&xgscreen, chan);
diff -urP sys/src/9/bcm/taslock.c /sys/src/9/bcm/taslock.c
--- sys/src/9/bcm/taslock.c	Thu Jan  1 01:00:00 1970
+++ /sys/src/9/bcm/taslock.c	Fri Mar  4 10:49:37 2016
@@ -0,0 +1,257 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+#include "../port/edf.h"
+
+long maxlockcycles;
+long maxilockcycles;
+long cumlockcycles;
+long cumilockcycles;
+ulong maxlockpc;
+ulong maxilockpc;
+
+struct
+{
+	ulong	locks;
+	ulong	glare;
+	ulong	inglare;
+} lockstats;
+
+static void
+inccnt(Ref *r)
+{
+	_xinc(&r->ref);
+}
+
+static int
+deccnt(Ref *r)
+{
+	int x;
+
+	x = _xdec(&r->ref);
+	if(x < 0)
+		panic("deccnt pc=%#p", getcallerpc(&r));
+	return x;
+}
+
+static void
+dumplockmem(char *tag, Lock *l)
+{
+	uchar *cp;
+	int i;
+
+	iprint("%s: ", tag);
+	cp = (uchar*)l;
+	for(i = 0; i < 64; i++)
+		iprint("%2.2ux ", cp[i]);
+	iprint("\n");
+}
+
+void
+lockloop(Lock *l, ulong pc)
+{
+	Proc *p;
+
+	p = l->p;
+	print("lock %#p loop key %#lux pc %#lux held by pc %#lux proc %lud\n",
+		l, l->key, pc, l->pc, p ? p->pid : 0);
+	dumpaproc(up);
+	if(p != nil)
+		dumpaproc(p);
+}
+
+int
+lock(Lock *l)
+{
+	int i;
+	ulong pc;
+
+	pc = getcallerpc(&l);
+
+	lockstats.locks++;
+	if(up)
+		inccnt(&up->nlocks);	/* prevent being scheded */
+	if(tas(&l->key) == 0){
+		if(up)
+			up->lastlock = l;
+		l->pc = pc;
+		l->p = up;
+		l->isilock = 0;
+#ifdef LOCKCYCLES
+		l->lockcycles = -lcycles();
+#endif
+		return 0;
+	}
+	if(up)
+		deccnt(&up->nlocks);
+
+	lockstats.glare++;
+	for(;;){
+		lockstats.inglare++;
+		i = 0;
+		while(l->key){
+			if(conf.nmach < 2 && up && up->edf && (up->edf->flags & Admitted)){
+				/*
+				 * Priority inversion, yield on a uniprocessor; on a
+				 * multiprocessor, the other processor will unlock
+				 */
+				print("inversion %#p pc %#lux proc %lud held by pc %#lux proc %lud\n",
+					l, pc, up ? up->pid : 0, l->pc, l->p ? l->p->pid : 0);
+				up->edf->d = todget(nil);	/* yield to process with lock */
+			}
+			if(i++ > 100000000){
+				i = 0;
+				lockloop(l, pc);
+			}
+		}
+		if(up)
+			inccnt(&up->nlocks);
+		if(tas(&l->key) == 0){
+			if(up)
+				up->lastlock = l;
+			l->pc = pc;
+			l->p = up;
+			l->isilock = 0;
+#ifdef LOCKCYCLES
+			l->lockcycles = -lcycles();
+#endif
+			return 1;
+		}
+		if(up)
+			deccnt(&up->nlocks);
+	}
+}
+
+void
+ilock(Lock *l)
+{
+	ulong x;
+	ulong pc;
+
+	pc = getcallerpc(&l);
+	lockstats.locks++;
+
+	x = splhi();
+	if(tas(&l->key) != 0){
+		lockstats.glare++;
+		/*
+		 * Cannot also check l->pc, l->m, or l->isilock here
+		 * because they might just not be set yet, or
+		 * (for pc and m) the lock might have just been unlocked.
+		 */
+		for(;;){
+			lockstats.inglare++;
+			splx(x);
+			while(l->key)
+				;
+			x = splhi();
+			if(tas(&l->key) == 0)
+				goto acquire;
+		}
+	}
+acquire:
+	m->ilockdepth++;
+	if(up)
+		up->lastilock = l;
+	l->sr = x;
+	l->pc = pc;
+	l->p = up;
+	l->isilock = 1;
+	l->m = MACHP(m->machno);
+#ifdef LOCKCYCLES
+	l->lockcycles = -lcycles();
+#endif
+}
+
+int
+canlock(Lock *l)
+{
+	if(up)
+		inccnt(&up->nlocks);
+	if(tas(&l->key)){
+		if(up)
+			deccnt(&up->nlocks);
+		return 0;
+	}
+
+	if(up)
+		up->lastlock = l;
+	l->pc = getcallerpc(&l);
+	l->p = up;
+	l->m = MACHP(m->machno);
+	l->isilock = 0;
+#ifdef LOCKCYCLES
+	l->lockcycles = -lcycles();
+#endif
+	return 1;
+}
+
+void
+unlock(Lock *l)
+{
+#ifdef LOCKCYCLES
+	l->lockcycles += lcycles();
+	cumlockcycles += l->lockcycles;
+	if(l->lockcycles > maxlockcycles){
+		maxlockcycles = l->lockcycles;
+		maxlockpc = l->pc;
+	}
+#endif
+	if(l->key == 0)
+		print("unlock: not locked: pc %#p\n", getcallerpc(&l));
+	if(l->isilock)
+		print("unlock of ilock: pc %lux, held by %lux\n", getcallerpc(&l), l->pc);
+	if(l->p != up)
+		print("unlock: up changed: pc %#p, acquired at pc %lux, lock p %#p, unlock up %#p\n", getcallerpc(&l), l->pc, l->p, up);
+	l->m = nil;
+	coherence();
+	l->key = 0;
+	coherence();
+
+	if(up && deccnt(&up->nlocks) == 0 && up->delaysched && islo()){
+		/*
+		 * Call sched if the need arose while locks were held
+		 * But, don't do it from interrupt routines, hence the islo() test
+		 */
+		sched();
+	}
+}
+
+ulong ilockpcs[0x100] = { [0xff] = 1 };
+static int n;
+
+void
+iunlock(Lock *l)
+{
+	ulong sr;
+
+#ifdef LOCKCYCLES
+	l->lockcycles += lcycles();
+	cumilockcycles += l->lockcycles;
+	if(l->lockcycles > maxilockcycles){
+		maxilockcycles = l->lockcycles;
+		maxilockpc = l->pc;
+	}
+	if(l->lockcycles > 2400)
+		ilockpcs[n++ & 0xff]  = l->pc;
+#endif
+	if(l->key == 0)
+		print("iunlock: not locked: pc %#p\n", getcallerpc(&l));
+	if(!l->isilock)
+		print("iunlock of lock: pc %#p, held by %#lux\n", getcallerpc(&l), l->pc);
+	if(islo())
+		print("iunlock while lo: pc %#p, held by %#lux\n", getcallerpc(&l), l->pc);
+
+	sr = l->sr;
+	l->m = nil;
+	coherence();
+	l->key = 0;
+	coherence();
+	m->ilockdepth--;
+	if(up)
+		up->lastilock = nil;
+	splx(sr);
+}
diff -urP sys/src/9/port/portfns.h /sys/src/9/port/portfns.h
--- sys/src/9/port/portfns.h	Sat Jun 26 21:21:40 2021
+++ /sys/src/9/port/portfns.h	Sun Jun 27 13:29:35 2021
@@ -405,6 +405,8 @@
 ulong		µs(void);
 long		ainc(long*);
 long		adec(long*);
+void		_xinc(long*);
+long		_xdec(long*);
 long		lcycles(void);
 
 #pragma varargck argpos iprint	1