shithub: riscv

Download patch

ref: a8ad9632ff7447b8ca448cc23dfbc60f0e36d8ec
parent: 87b61fddf25d5a3278509e636ab7328ac582d9a0
parent: c33588da6fc879d6c355cd1df29b4c1a8f75f854
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon May 22 16:15:37 EDT 2023

merge...

--- a/sys/man/1/kbmap
+++ b/sys/man/1/kbmap
@@ -1,11 +1,22 @@
 .TH KBMAP 1
 .SH NAME
-kbmap \- show a list of available keyboard maps and switch between them.
+kbmap, kbremap \- show a list of available keyboard maps and switch between them.
 .SH SYNOPSIS
 .B kbmap
 [
 .IR file ...
 ]
+.PP
+.B kbremap
+[
+.B -m
+.I mod
+]
+[
+.B -k
+.I scancode
+]
+map1 map2 ...
 .SH DESCRIPTION
 .I Kbmap
 shows a single column consisting of the names of keyboard maps for different
@@ -18,16 +29,49 @@
 keyboard mapping defined in the corresponding file to become current
 for the system; typing 'q' quits.
 .PP
+.I Kbremap
+reads keyboard events from standard input, filters out a shortcut
+to change the keyboard map, and writes the result to standard
+output. The shortcut cycles through the keyboard maps provided
+as arguments. By default this shortcut is mapped to
+.LR Ctrl
++
+.LR Space .
+The
+.B -m
+and
+.B -k
+flags change the default mod and key used respectfully.
+.I Mod
+is given as a numeric shift layer as understood by
+.IR kbdfs (8).
+.PP
 .I Kbmap
-requires that the file
+and
+.I kbremap
+require that the file
 .B /dev/kbmap
 served by 
 .IR kbdfs (8)
 exists and is writable.
-..SH FILES
-.TF /lib/kbmap/*
+.SH EXAMPLES
+Use
+.I kbremap
+with
+.B /dev/kbdtap
+provided by
+.IR rio (4):
+.IP
+.EX
+kbremap us de uk </dev/kbdtap >/dev/kbdtap
+.EE
+.PP
+.SH FILES
+.B /sys/lib/kbmap/*
 .SH SOURCE
 .B /sys/src/cmd/kbmap.c
+.br
+.B /sys/src/cmd/kbremap.c
 .SH "SEE ALSO"
 .IR kbdfs (8)
 .SH BUGS
--- a/sys/src/cmd/aux/acpi.c
+++ b/sys/src/cmd/aux/acpi.c
@@ -9,6 +9,7 @@
 typedef struct Bat Bat;
 typedef struct Tbl Tbl;
 typedef struct Therm Therm;
+typedef struct FACP FACP;
 
 struct Batstat {
 	int rate;
@@ -45,6 +46,31 @@
 	void *tmp;
 };
 
+struct FACP {
+	int ok;
+
+	uvlong pm1a;
+	int pm1aspace;
+	int pm1awid;
+
+	uvlong pm1b;
+	int pm1bspace;
+	int pm1bwid;
+
+	uvlong gpe0;
+	ulong gpe0len;
+	int gpe0space;
+	int gpe0wid;
+
+	uvlong gpe1;
+	ulong gpe1len;
+	int gpe1space;
+	int gpe1wid;
+
+	ulong slpa;
+	ulong slpb;
+};
+
 enum {
 	Tblsz = 4+4+1+1+6+8+4+4+4,
 
@@ -56,12 +82,11 @@
 	SLP_TM = 0x1c00,
 };
 
-static ulong PM1a_CNT_BLK, PM1b_CNT_BLK, SLP_TYPa, SLP_TYPb;
-static ulong GPE0_BLK, GPE1_BLK, GPE0_BLK_LEN, GPE1_BLK_LEN;
-static int ec, mem, iofd[5], nbats, ntherms, facp;
+static int ec, mem, iofd[5], nbats, ntherms;
 static char *uid = "pm", *units[] = {"mW", "mA"};
 static Therm therms[16];
 static Bat bats[4];
+static FACP facp;
 
 static int
 enumec(void *dot, void *)
@@ -240,16 +265,32 @@
 	close(ctl);
 }
 
+static ulong
+get32(uchar *p)
+{
+	return p[3]<<24 | p[2]<<16 | p[1]<<8 | p[0];
+}
+
+static uvlong
+get64(uchar *p)
+{
+	return ((uvlong)p[7]<<56) | ((uvlong)p[6]<<48)
+			| ((uvlong)p[5]<<40) | ((uvlong)p[4]<<32)
+			| ((uvlong)p[3]<<24) | ((uvlong)p[2]<<16)
+			| ((uvlong)p[1]<<8) | ((uvlong)p[0]);
+}
+
 static void
-outw(long addr, ushort val)
+amlwrite(Amlio *io, int addr, int wid, uvlong v)
 {
-	uchar buf[2];
+	uchar b[8];
 
-	if(addr == 0)
-		return;
-	buf[0] = val;
-	buf[1] = val >> 8;
-	pwrite(iofd[2], buf, 2, addr);
+	b[0] = v; b[1] = v >> 8;
+	b[2] = v >> 16; b[3] = v >> 24;
+	b[4] = v >> 32; b[5] = v >> 40;
+	b[6] = v >> 48; b[7] = v >> 56;
+
+	(*io->write)(io, b, 1<<(wid-1), addr);
 }
 
 static void
@@ -256,8 +297,10 @@
 poweroff(void)
 {
 	int n;
+	void *tts, *pts;
+	Amlio ioa, iob;
 
-	if(facp == 0){
+	if(facp.ok == 0){
 		werrstr("no FACP");
 		return;
 	}
@@ -264,18 +307,43 @@
 
 	wirecpu0();
 
+	/* The ACPI spec requires we call _TTS and _PTS to prepare
+	 * the system to go to _S5 state. If they fail, too bad,
+	 * try to go to _S5 state anyway. */
+	pts = amlval(amlwalk(amlroot, "_PTS"));
+	tts = amlval(amlwalk(amlroot, "_TTS"));
+	if(pts)
+		amleval(pts, "i", 5, nil);
+	if(tts)
+		amleval(tts, "i", 5, nil);
+
 	/* disable GPEs */
-	for(n = 0; GPE0_BLK > 0 && n < GPE0_BLK_LEN/2; n += 2){
-		outw(GPE0_BLK + GPE0_BLK_LEN/2 + n, 0); /* EN */
-		outw(GPE0_BLK + n, 0xffff); /* STS */
+	ioa.space = facp.gpe0space;
+	iob.space = facp.gpe1space;
+	ioa.off = facp.gpe0;
+	iob.off = facp.gpe1;
+	amlmapio(&ioa);
+	amlmapio(&iob);
+
+	for(n = 0; facp.gpe0 > 0 && n < facp.gpe0len/2; n += facp.gpe0wid){
+		amlwrite(&ioa, facp.gpe0len/2 + n, facp.gpe0wid, 0);
+		amlwrite(&ioa, n, facp.gpe0wid, ~0);
 	}
-	for(n = 0; GPE1_BLK > 0 && n < GPE1_BLK_LEN/2; n += 2){
-		outw(GPE1_BLK + GPE1_BLK_LEN/2 + n, 0); /* EN */
-		outw(GPE1_BLK + n, 0xffff); /* STS */
+
+	for(n = 0; facp.gpe1 > 0 && n < facp.gpe1len/2; n += facp.gpe1wid){
+		amlwrite(&iob, facp.gpe1len/2 + n, facp.gpe1wid, 0);
+		amlwrite(&iob, n, facp.gpe1wid, ~0);
 	}
 
-	outw(PM1a_CNT_BLK, ((SLP_TYPa << 10) & SLP_TM) | SLP_EN);
-	outw(PM1b_CNT_BLK, ((SLP_TYPb << 10) & SLP_TM) | SLP_EN);
+	ioa.space = facp.pm1aspace;
+	iob.space = facp.pm1bspace;
+	ioa.off = facp.pm1a;
+	iob.off = facp.pm1b;
+	amlmapio(&ioa);
+	amlmapio(&iob);
+
+	amlwrite(&ioa, 0, facp.pm1awid, ((facp.slpa << 10) & SLP_TM) | SLP_EN);
+	amlwrite(&iob, 0, facp.pm1bwid, ((facp.slpb << 10) & SLP_TM) | SLP_EN);
 	sleep(100);
 
 	/*
@@ -287,9 +355,10 @@
 	 * PM1a_CNT_BLK seems to have no effect but 0x7 seems
 	 * to work fine. So trying the following as a last effort.
 	 */
-	SLP_TYPa |= SLP_TYPb;
-	outw(PM1a_CNT_BLK, ((SLP_TYPa << 10) & SLP_TM) | SLP_EN);
-	outw(PM1b_CNT_BLK, ((SLP_TYPa << 10) & SLP_TM) | SLP_EN);
+
+	facp.slpa |= facp.slpb;
+	amlwrite(&ioa, 0, facp.pm1awid, ((facp.slpa << 10) & SLP_TM) | SLP_EN);
+	amlwrite(&iob, 0, facp.pm1bwid, ((facp.slpa << 10) & SLP_TM) | SLP_EN);
 	sleep(100);
 
 	werrstr("acpi failed");
@@ -360,12 +429,8 @@
 	.write = fswrite,
 };
 
-static ulong
-get32(uchar *p)
-{
-	return p[3]<<24 | p[2]<<16 | p[1]<<8 | p[0];
-}
 
+
 void
 threadmain(int argc, char **argv)
 {
@@ -431,19 +496,58 @@
 		}else if(memcmp("SSDT", t->sig, 4) == 0){
 			amlload(t->data, l);
 		}else if(memcmp("FACP", t->sig, 4) == 0){
-			facp = 1;
-			PM1a_CNT_BLK = get32(((uchar*)t) + 64);
-			PM1b_CNT_BLK = get32(((uchar*)t) + 68);
-			GPE0_BLK = get32(((uchar*)t) + 80);
-			GPE1_BLK = get32(((uchar*)t) + 84);
-			GPE0_BLK_LEN = *(((uchar*)t) + 92);
-			GPE1_BLK_LEN = *(((uchar*)t) + 93);
+			facp.ok = 1;
+			if(t->rev >= 2) {
+				/* try the ACPI 2.0 method */
+				facp.pm1aspace = *(((uchar*)t) + 172);
+				facp.pm1awid = *(((uchar*)t) + 175);
+				facp.pm1a = get64(((uchar*)t) + 176);
+
+				facp.pm1bspace = *(((uchar*)t) + 184);
+				facp.pm1bwid = *(((uchar*)t) + 187);
+				facp.pm1b = get64(((uchar*)t) + 188);
+
+				facp.gpe0space = *(((uchar*)t) + 220);
+				facp.gpe0wid = *(((uchar*)t) + 223);
+				facp.gpe0 = get64(((uchar*)t) + 224);
+
+				facp.gpe1space = *(((uchar*)t) + 232);
+				facp.gpe1wid = *(((uchar*)t) + 235);
+				facp.gpe1 = get64(((uchar*)t) + 236);
+			}
+
+			/* fall back to the ACPI 1.0 io port method */
+			if(!facp.pm1a) {
+				facp.pm1aspace = IoSpace;
+				facp.pm1awid = 2;
+				facp.pm1a = get32(((uchar*)t) + 64);
+			}
+
+			if(!facp.pm1b) {
+				facp.pm1bspace = IoSpace;
+				facp.pm1bwid = 2;
+				facp.pm1b = get32(((uchar*)t) + 68);
+			}
+
+			if(!facp.gpe0) {
+				facp.gpe0space = IoSpace;
+				facp.gpe0wid = 2;
+				facp.gpe0 = get32(((uchar*)t) + 80);
+				facp.gpe0len = *(((uchar*)t) + 92);
+			}
+
+			if(!facp.gpe1) {
+				facp.gpe1space = IoSpace;
+				facp.gpe1wid = 2;
+				facp.gpe1 = get32(((uchar*)t) + 84);
+				facp.gpe1len = *(((uchar*)t) + 93);
+			}
 		}
 	}
 	if(amleval(amlwalk(amlroot, "_S5"), "", &r) >= 0 && amltag(r) == 'p' && amllen(r) >= 2){
 		rr = amlval(r);
-		SLP_TYPa = amlint(rr[0]);
-		SLP_TYPb = amlint(rr[1]);
+		facp.slpa = amlint(rr[0]);
+		facp.slpb = amlint(rr[1]);
 	}
 	close(fd);
 
--- a/sys/src/cmd/ip/ppp/ipaux.c
+++ b/sys/src/cmd/ip/ppp/ipaux.c
@@ -8,10 +8,18 @@
 ptclcsum(Block *bp, int offset, int len)
 {
 	uchar *addr;
-	int blen;
+	ulong losum, hisum;
+	ushort csum;
+	int odd, blen, x;
 
-	if(bp == nil || bp->rptr + offset >= bp->wptr)
+	/* Correct to front of data area */
+	while(bp != nil && offset && offset >= BLEN(bp)) {
+		offset -= BLEN(bp);
+		bp = bp->next;
+	}
+	if(bp == nil)
 		return 0;
+
 	addr = bp->rptr + offset;
 	blen = BLEN(bp) - offset;
 	if(blen < len)
--- a/sys/src/cmd/ip/tftpd.c
+++ b/sys/src/cmd/ip/tftpd.c
@@ -204,7 +204,7 @@
  				exits(0);
 			remoteaddr(ldir, raddr, sizeof(raddr));
 			pid = getpid();
-			syslog(0, flog, "tftp %d connection from %s dir %s",
+			syslog(0, flog, "tftpd %d connection from %s dir %s",
 				pid, raddr, ldir);
 			doserve(dfd);
 			exits("done");
@@ -227,7 +227,7 @@
 			n = strtol(val, nil, 10);
 			if (n < op->min || n > op->max) {
 				nak(fd, Errbadopt, "option value out of range");
-				syslog(dbg, flog, "tftp bad option value from "
+				syslog(dbg, flog, "tftpd bad option value from "
 					"client: %s %s", name, val);
 				sysfatal("bad option value from client: %s %s",
 					name, val);
--- /dev/null
+++ b/sys/src/cmd/kbremap.c
@@ -1,0 +1,80 @@
+#include <u.h>
+#include <libc.h>
+
+char *mod = "4";
+char *key = "57";
+enum{ Kswitch = 0xF000|0x0701 };
+
+static void
+writemap(char *file)
+{
+	int i, fd, ofd;
+	char buf[8192];
+
+	if((fd = open(file, OREAD)) < 0)
+		sysfatal("cannot open %s: %r", file);
+
+	if((ofd = open("/dev/kbmap", OWRITE)) < 0)
+		sysfatal("cannot open /dev/kbmap: %r");
+
+	while((i = read(fd, buf, sizeof buf)) > 0)
+		if(write(ofd, buf, i) != i)
+			sysfatal("writing /dev/kbmap: %r");
+
+	fprint(ofd, "%s\t%s\t0x%X\n", mod, key, Kswitch);
+	close(fd);
+	close(ofd);
+}
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s [ -m mod ] [ -k scancode ] map1 map2 ...\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	char *p, buf[8192];
+	Rune r;
+	long n;
+	int index;
+
+	index = 0;
+	ARGBEGIN{
+	case 'm':
+		mod = EARGF(usage());
+		break;
+	case 'k':
+		key = EARGF(usage());
+		break;
+	default:
+		usage();
+	}ARGEND;
+	if(argc < 2)
+		usage();
+
+	chdir("/sys/lib/kbmap");
+	writemap("ascii");
+	writemap(argv[0]);
+	for(;;){
+		n = read(0, buf, sizeof buf - 1);
+		if(n <= 0)
+			break;
+		buf[n] = '\0';
+		for(p = buf; p < buf+n; p += strlen(p) + 1){
+			chartorune(&r, p+1);
+			if(*p != 'c' || r != Kswitch){
+				write(1, p, strlen(p));
+				continue;
+			}
+			index++;
+			if(argv[index] == nil)
+				index = 0;
+			writemap("ascii");
+			writemap(argv[index]);
+		}
+	}
+	exits(nil);
+}
--- a/sys/src/cmd/nusb/ether/ether.c
+++ b/sys/src/cmd/nusb/ether/ether.c
@@ -642,15 +642,18 @@
 		ctlif = datif = nil;
 		for(j = 0; j < nelem(c->iface); j++){
 			for(iface = c->iface[j]; iface != nil; iface = iface->next){
-				if(iface->id == ctlid)
+				if(ctlif == nil && iface->id == ctlid)
 					ctlif = iface;
-				if(iface->id == datid)
+				if(datif == nil && iface->id == datid)
 					datif = iface;
 			}
 			if(datif != nil && ctlif != nil){
-				if(Subclass(ctlif->csp) == Scether)
+				if(Subclass(ctlif->csp) == Scether) {
+					if(setconf(d, c) < 0)
+						break;
 					if(ifaceinit(d, datif, ein, eout) != -1)
 						return 0;
+				}
 				break;
 			}
 		}		
@@ -659,6 +662,8 @@
 	/* try any other one that seems to be ok */
 	for(i = 0; i < nelem(ud->conf); i++){
 		if((c = ud->conf[i]) != nil){
+			if(setconf(d, c) < 0)
+				break;
 			for(j = 0; j < nelem(c->iface); j++){
 				for(datif = c->iface[j]; datif != nil; datif = datif->next){
 					if(ifaceinit(d, datif, ein, eout) != -1)
--- a/sys/src/cmd/nusb/lib/dev.c
+++ b/sys/src/cmd/nusb/lib/dev.c
@@ -483,6 +483,16 @@
 }
 
 int
+setconf(Dev *d, Conf *c)
+{
+	if(usbcmd(d, Rh2d|Rstd|Rdev, Rsetconf, c->cval, 0, nil, 0) > 0) {
+		werrstr("setconf: %s: %r", d->dir);
+		return -1;
+	}
+	return 0;
+}
+
+int
 setalt(Dev *d, Iface *ifc)
 {
 	if(usbcmd(d, Rh2d|Rstd|Riface, Rsetiface, ifc->alt, ifc->id, nil, 0) < 0){
--- a/sys/src/cmd/nusb/lib/usb.h
+++ b/sys/src/cmd/nusb/lib/usb.h
@@ -353,6 +353,7 @@
 int	unstall(Dev *dev, Dev *ep, int dir);
 int	usbcmd(Dev *d, int type, int req, int value, int index, uchar *data, int count);
 Dev*	getdev(char *devid);
+int	setconf(Dev *d, Conf *c);
 int	setalt(Dev *d, Iface *ifc);
 
 extern int usbdebug;	/* more messages for bigger values */
--- a/sys/src/cmd/riow.c
+++ b/sys/src/cmd/riow.c
@@ -444,7 +444,7 @@
 main(int argc, char **argv)
 {
 	char b[128];
-	int i, j, n;
+	int i, j, n, r;
 
 	for(n = 0; sticky[n] != nil; n++)
 		;
@@ -468,18 +468,19 @@
 		ws[i].vd = vd;
 	fprint(3, "%d\n", vd);
 
-	for(i = 0;;){
-		if((n = read(0, b+i, sizeof(b)-i)) <= 0)
+	for(n = 0;;){
+		if((r = read(0, b+n, sizeof(b)-n-1)) <= 0)
 			break;
-		n += i;
-		for(j = 0; j < n; j++){
+		n += r;
+		b[n] = 0;
+		for(i = j = 0; j <= n; j++){
 			if(b[j] == 0){
 				process(b+i);
 				i = j+1;
 			}
 		}
-		memmove(b, b+i, j-i);
-		i -= j;
+		n = j-i;
+		memmove(b, b+i, n);
 	}
 
 	exits(nil);
--- a/sys/src/libaml/aml.c
+++ b/sys/src/libaml/aml.c
@@ -150,7 +150,7 @@
 	Oindex, Omatch, Omutex, Oevent,
 	Ocfld, Ocfld0, Ocfld1, Ocfld2, Ocfld4, Ocfld8,
 	Oif, Oelse, Owhile, Obreak, Oret, Ocall, 
-	Ostore, Oderef, Ootype, Osize, Oref, Ocref, Ocat,
+	Ostore, Oderef, Ootype, Osize, Oref, Ocref, Ocat, Ocatr, Omid,
 	Oacq, Osignal, Orel, Ostall, Osleep, Oload, Ounload,
 	Otodec, Otohex, Otoint, Otostr,
 };
@@ -1711,6 +1711,66 @@
 }
 
 static void*
+evalcatres(void)
+{
+	void *r, *a, *b;
+	int n, m;
+	uchar c[2];
+
+	a = FP->arg[0];
+	b = FP->arg[1];
+	if(a == nil)
+		a = copy('b', a);
+	if(b == nil)
+		b = copy('b', b);
+	if(TAG(a) != 'b' || TAG(b) != 'b')
+		return nil;
+
+	n = SIZE(a);
+	m = SIZE(b);
+	r = mk('b', n + m + 2);
+	memmove(r, a, n);
+	memmove((uchar*)r + n, b, m);
+
+	c[0] = 0x78;
+	c[1] = 0;
+	memmove((uchar*)r + n + m, c, 2);
+
+	store(r, FP->arg[2]);
+	return r;
+}
+
+static void*
+evalmid(void)
+{
+	void *r, *a;
+	int n, m;
+
+	a = FP->arg[1];
+	n = ival(FP->arg[1]);
+	m = ival(FP->arg[2]);
+	if(a == nil)
+		a = copy('b', a);
+
+	switch(TAG(a)) {
+	default:
+		return nil; /* botch */
+	case 's':
+	case 'b':
+		if(n > SIZE(a))
+			n = SIZE(a);
+		if((n + m) > SIZE(a))
+			m = SIZE(a) - n;
+
+		r = mk(TAG(a), m); memmove(r, (uchar*)a + n, m);
+		break;
+	}
+
+	store(r, FP->arg[3]);
+	return r;
+}
+
+static void*
 evalindex(void)
 {
 	Field *f;
@@ -2150,6 +2210,8 @@
 	[Ocref]		"CondRefOf",		"@@",		evalcondref,
 	[Oderef]	"DerefOf",		"@",		evalderef,
 	[Ocat]		"Concatenate",		"**@",		evalcat,
+	[Ocatr]		"ConcatenateRes",	"***",		evalcatres,
+	[Omid]		"Mid",				"*ii@",		evalmid,
 
 	[Oacq]		"Acquire",		"@2",		evalnop,
 	[Osignal]	"Signal",		"@",		evalnop,
@@ -2182,10 +2244,10 @@
 /* 68 */	Oenv,	Oenv,	Oenv,	Oenv,	Oenv,	Oenv,	Oenv,	Obad,
 /* 70 */	Ostore,	Oref,	Oadd,	Ocat,	Osub,	Oinc,	Odec,	Omul,
 /* 78 */	Odiv,	Oshl,	Oshr,	Oand,	Onand,	Oor,	Onor,	Oxor,
-/* 80 */	Onot,	Olbit,	Orbit,	Oderef,	Obad,	Omod,	Obad,	Osize,
+/* 80 */	Onot,	Olbit,	Orbit,	Oderef,	Ocatr,	Omod,	Obad,	Osize,
 /* 88 */	Oindex,	Omatch,	Ocfld4,	Ocfld2,	Ocfld1,	Ocfld0,	Ootype,	Ocfld8,
 /* 90 */	Oland,	Olor,	Olnot,	Oleq,	Olgt,	Ollt,	Obad,	Otodec,
-/* 98 */	Otohex,	Otoint,	Obad,	Obad,	Otostr,	Obad,	Obad,	Obad,
+/* 98 */	Otohex,	Otoint,	Obad,	Obad,	Otostr,	Obad,	Omid,	Obad,
 /* A0 */	Oif,	Oelse,	Owhile,	Onop,	Oret,	Obreak,	Obad,	Obad,
 /* A8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
 /* B0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,