9front - general discussion about 9front
 help / color / mirror / Atom feed
* Kernel patches (cpufreqctl, Radeon on amd64, trivia)
@ 2020-01-11  3:59 Robert Ransom
  2020-01-11 20:33 ` [9front] " cinap_lenrek
  0 siblings, 1 reply; 3+ messages in thread
From: Robert Ransom @ 2020-01-11  3:59 UTC (permalink / raw)
  To: 9front

[-- Attachment #1: Type: text/plain, Size: 762 bytes --]

Patch 7513: Removes the unused Proc.movetime variable and a comment
describing the algorithm which once used it.  Trivial, tested, and
working.

Patch 7514: Makes the vgaradeon driver compile on amd64.  GRUB sets up
my framebuffer, so I have not yet tested it.

Patches 7515, 7517, 7518: Adds CPU frequency scaling support for AMD
family 10h and later, and sets the lowest-power state during boot.
Tested and working on one of my family 10h systems.  I don't consider
it finished, but it is worth applying upstream.  Note that the
'powersave' command prints out PstateMaxVal; this should probably be
removed someday, but not until it has been tested more broadly.

Patch 7516 (note out of sequence): Fixes a comment typo in bootrc.
Trivial, tested, and working.

[-- Attachment #2: 7513.patch --]
[-- Type: text/x-patch, Size: 1257 bytes --]

# HG changeset patch
# User Robert Ransom <rransom.8774@gmail.com>
# Date 1576991633 18000
# Node ID 85dfb4d0d5ee93073cde636cc5288e72116b46e5
# Parent  8b68d6a763e0312d58c1fc6a1514d8fffb61f9c6
Remove relics of CPU 'load balancing' policy in scheduler

This code was deleted from Plan 9 before the 9front repo began.
Proc.movetime was used by it, but has never been referenced in 9front.

diff --git a/sys/src/9/port/portdat.h b/sys/src/9/port/portdat.h
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -755,7 +755,6 @@
 	ulong	lastupdate;
 	uchar	yield;		/* non-zero if the process just did a sleep(0) */
 	ulong	readytime;	/* time process came ready */
-	ulong	movetime;	/* last time process switched processors */
 	int	preempted;	/* true if this process hasn't finished the interrupt
 				 *  that last preempted it
 				 */
diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -525,8 +525,7 @@
 loop:
 	/*
 	 *  find a process that last ran on this processor (affinity),
-	 *  or one that hasn't moved in a while (load balancing).  Every
-	 *  time around the loop affinity goes down.
+	 *  or one that can be moved to this processor.
 	 */
 	spllo();
 	for(i = 0;; i++){

[-- Attachment #3: 7514.patch --]
[-- Type: text/x-patch, Size: 10456 bytes --]

# HG changeset patch
# User Robert Ransom <rransom.8774@gmail.com>
# Date 1578147512 18000
# Node ID 939ab197463703d4835622103bde410bd0a2acd7
# Parent  85dfb4d0d5ee93073cde636cc5288e72116b46e5
Adapt vgaradeon driver to 64-bit

Not yet tested.

diff --git a/sys/src/9/pc/vgaradeon.c b/sys/src/9/pc/vgaradeon.c
--- a/sys/src/9/pc/vgaradeon.c
+++ b/sys/src/9/pc/vgaradeon.c
@@ -28,45 +28,45 @@
 /* mmio access */
 
 static void
-OUTREG8(ulong mmio, ulong offset, uchar val)
+OUTREG8(ulong *mmio, ulong offset, uchar val)
 {
-	((uchar*)KADDR((mmio + offset)))[0] = val;
+	((uchar*)KADDR((((uintptr)mmio) + offset)))[0] = val;
 }
 
 static void
-OUTREG(ulong mmio, ulong offset, ulong val)
+OUTREG(ulong *mmio, ulong offset, ulong val)
 {
-	((ulong*)KADDR((mmio + offset)))[0] = val;
+	((ulong*)KADDR((((uintptr)mmio) + offset)))[0] = val;
 }
 
 static ulong
-INREG(ulong mmio, ulong offset)
+INREG(ulong *mmio, ulong offset)
 {
-	return ((ulong*)KADDR((mmio + offset)))[0];
+	return ((ulong*)KADDR((((uintptr)mmio) + offset)))[0];
 }
 
 static void
-OUTREGP(ulong mmio, ulong offset, ulong val, ulong mask)
+OUTREGP(ulong *mmio, ulong offset, ulong val, ulong mask)
 {
 	OUTREG(mmio, offset, (INREG(mmio, offset) & mask) | val);
 }
 
 static void
-OUTPLL(ulong mmio, ulong offset, ulong val)
+OUTPLL(ulong *mmio, ulong offset, ulong val)
 {
 	OUTREG8(mmio, CLOCK_CNTL_INDEX, (offset & 0x3f) | PLL_WR_EN);
 	OUTREG(mmio, CLOCK_CNTL_DATA, val);
 }
 
 static ulong
-INPLL(ulong mmio, ulong offset)
+INPLL(ulong *mmio, ulong offset)
 {
 	OUTREG8(mmio, CLOCK_CNTL_INDEX, offset & 0x3f);
 	return INREG(mmio, CLOCK_CNTL_DATA);
 }
 
 static void
-OUTPLLP(ulong mmio, ulong offset, ulong val, ulong mask)
+OUTPLLP(ulong *mmio, ulong offset, ulong val, ulong mask)
 {
 	OUTPLL(mmio, offset, (INPLL(mmio, offset) & mask) | val);
 }
@@ -174,10 +174,10 @@
 		y = 0;
 	}
 
-	OUTREG((ulong)scr->mmio, CUR_OFFSET, storage + oy * 256);
-	OUTREG((ulong)scr->mmio, CUR_HORZ_VERT_OFF,
+	OUTREG(scr->mmio, CUR_OFFSET, storage + oy * 256);
+	OUTREG(scr->mmio, CUR_HORZ_VERT_OFF,
 		(ox & 0x7fff) << 16 | (oy & 0x7fff));
-	OUTREG((ulong)scr->mmio, CUR_HORZ_VERT_POSN,
+	OUTREG(scr->mmio, CUR_HORZ_VERT_POSN,
 		(x & 0x7fff) << 16 | (y & 0x7fff));
 	return 0;
 }
@@ -187,7 +187,7 @@
 {
 	if(scr->mmio == nil)
 		return;
-	OUTREGP((ulong)scr->mmio, CRTC_GEN_CNTL, 0, ~CRTC_CUR_EN);
+	OUTREGP(scr->mmio, CRTC_GEN_CNTL, 0, ~CRTC_CUR_EN);
 }
 
 static void
@@ -200,11 +200,11 @@
 
 	radeoncurdisable(scr);
 	storage = scr->apsize - 1*Meg;
-	scr->storage = (ulong)KADDR(scr->paddr + storage);
+	scr->storage = (uintptr)KADDR(scr->paddr + storage);
 	radeoncurload(scr, &arrow);
 	radeoncurmove(scr, ZP);
 
-	OUTREGP((ulong)scr->mmio, CRTC_GEN_CNTL, CRTC_CUR_EN | 2<<20,
+	OUTREGP(scr->mmio, CRTC_GEN_CNTL, CRTC_CUR_EN | 2<<20,
 		~(CRTC_CUR_EN | 3<<20));
 }
 
@@ -223,24 +223,24 @@
 
 	mask = CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | CRTC_VSYNC_DIS;
 	if (blank == 0) {
-		OUTREGP((ulong)scr->mmio, CRTC_EXT_CNTL, 0, ~mask);
+		OUTREGP(scr->mmio, CRTC_EXT_CNTL, 0, ~mask);
 		return;
 	}
 
 	cp = getconf("*dpms");
 	if (cp) {
 		if (strcmp(cp, "standby") == 0)
-			OUTREGP((ulong)scr->mmio, CRTC_EXT_CNTL,
+			OUTREGP(scr->mmio, CRTC_EXT_CNTL,
 				CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS, ~mask);
 		else if (strcmp(cp, "suspend") == 0)
-			OUTREGP((ulong)scr->mmio, CRTC_EXT_CNTL,
+			OUTREGP(scr->mmio, CRTC_EXT_CNTL,
 				CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS, ~mask);
 		else if (strcmp(cp, "off") == 0)
-			OUTREGP((ulong)scr->mmio, CRTC_EXT_CNTL, mask, ~mask);
+			OUTREGP(scr->mmio, CRTC_EXT_CNTL, mask, ~mask);
 		return;
 	}
 
-	OUTREGP((ulong)scr->mmio, CRTC_EXT_CNTL, mask, ~mask);
+	OUTREGP(scr->mmio, CRTC_EXT_CNTL, mask, ~mask);
 }
 
 /* hw acceleration */
@@ -251,7 +251,7 @@
 	int i;
 
 	for (i = 0; i < 2000000; i++)
-		if (INREG((ulong)scr->mmio, RBBM_STATUS) & RBBM_FIFOCNT_MASK >=
+		if (INREG(scr->mmio, RBBM_STATUS) & RBBM_FIFOCNT_MASK >=
 		    entries)
 			return;
 	iprint("radeon: fifo timeout\n");
@@ -266,12 +266,12 @@
 		int i;
 
 		for (i = 0; i < 2000000; i++)
-			if (!(INREG((ulong)scr->mmio, RBBM_STATUS) & RBBM_ACTIVE))
+			if (!(INREG(scr->mmio, RBBM_STATUS) & RBBM_ACTIVE))
 				return;
 
 		iprint("radeon: idle timed out: %uld entries, stat=0x%.8ulx\n",
-			INREG((ulong)scr->mmio, RBBM_STATUS) & RBBM_FIFOCNT_MASK,
-			INREG((ulong)scr->mmio, RBBM_STATUS));
+			INREG(scr->mmio, RBBM_STATUS) & RBBM_FIFOCNT_MASK,
+			INREG(scr->mmio, RBBM_STATUS));
 	}
 }
 
@@ -284,15 +284,15 @@
 		return 0;
 
 	radeonwaitfifo(scr, 6);
-	OUTREG((ulong)scr->mmio, DP_GUI_MASTER_CNTL,
+	OUTREG(scr->mmio, DP_GUI_MASTER_CNTL,
 		dp_gui_master_cntl | GMC_BRUSH_SOLID_COLOR |
 		GMC_SRC_DATATYPE_COLOR | ROP3_P);
-	OUTREG((ulong)scr->mmio, DP_BRUSH_FRGD_CLR, color);
-	OUTREG((ulong)scr->mmio, DP_WRITE_MASK, ~0ul);
-	OUTREG((ulong)scr->mmio, DP_CNTL,
+	OUTREG(scr->mmio, DP_BRUSH_FRGD_CLR, color);
+	OUTREG(scr->mmio, DP_WRITE_MASK, ~0ul);
+	OUTREG(scr->mmio, DP_CNTL,
 		DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
-	OUTREG((ulong)scr->mmio, DST_Y_X, r.min.y << 16 | r.min.x);
-	OUTREG((ulong)scr->mmio, DST_WIDTH_HEIGHT, Dx(r) << 16 | Dy(r));
+	OUTREG(scr->mmio, DST_Y_X, r.min.y << 16 | r.min.x);
+	OUTREG(scr->mmio, DST_WIDTH_HEIGHT, Dx(r) << 16 | Dy(r));
 
 	radeonwaitidle(scr);
 	return 1;
@@ -329,14 +329,14 @@
 		dp_cntl |= DST_X_LEFT_TO_RIGHT;
 
 	radeonwaitfifo(scr, 6);
-	OUTREG((ulong)scr->mmio, DP_GUI_MASTER_CNTL, dp_gui_master_cntl |
+	OUTREG(scr->mmio, DP_GUI_MASTER_CNTL, dp_gui_master_cntl |
 		GMC_BRUSH_NONE | GMC_SRC_DATATYPE_COLOR | DP_SRC_SOURCE_MEMORY |
 		ROP3_S);
-	OUTREG((ulong)scr->mmio, DP_WRITE_MASK, ~0ul);
-	OUTREG((ulong)scr->mmio, DP_CNTL, dp_cntl);
-	OUTREG((ulong)scr->mmio, SRC_Y_X, ys << 16 | xs);
-	OUTREG((ulong)scr->mmio, DST_Y_X, yd << 16 | xd);
-	OUTREG((ulong)scr->mmio, DST_WIDTH_HEIGHT, w << 16 | h);
+	OUTREG(scr->mmio, DP_WRITE_MASK, ~0ul);
+	OUTREG(scr->mmio, DP_CNTL, dp_cntl);
+	OUTREG(scr->mmio, SRC_Y_X, ys << 16 | xs);
+	OUTREG(scr->mmio, DST_Y_X, yd << 16 | xd);
+	OUTREG(scr->mmio, DST_WIDTH_HEIGHT, w << 16 | h);
 
 	radeonwaitidle(scr);
 
@@ -376,75 +376,75 @@
 	}
 
 	/* disable 3D */
-	OUTREG((ulong)scr->mmio, RB3D_CNTL, 0);
+	OUTREG(scr->mmio, RB3D_CNTL, 0);
 
 	/* flush engine */
-	OUTREGP((ulong)scr->mmio, RB2D_DSTCACHE_CTLSTAT,
+	OUTREGP(scr->mmio, RB2D_DSTCACHE_CTLSTAT,
 		RB2D_DC_FLUSH_ALL, ~RB2D_DC_FLUSH_ALL);
 	for (i = 0; i < 2000000; i++)
-		if (!(INREG((ulong)scr->mmio, RB2D_DSTCACHE_CTLSTAT) &
+		if (!(INREG(scr->mmio, RB2D_DSTCACHE_CTLSTAT) &
 		    RB2D_DC_BUSY))
 			break;
 
 	/* reset 2D engine */
-	clock_cntl_index = INREG((ulong)scr->mmio, CLOCK_CNTL_INDEX);
+	clock_cntl_index = INREG(scr->mmio, CLOCK_CNTL_INDEX);
 
-	mclk_cntl = INPLL((ulong)scr->mmio, MCLK_CNTL);
-	OUTPLL((ulong)scr->mmio, MCLK_CNTL, mclk_cntl | FORCEON_MCLKA |
+	mclk_cntl = INPLL(scr->mmio, MCLK_CNTL);
+	OUTPLL(scr->mmio, MCLK_CNTL, mclk_cntl | FORCEON_MCLKA |
 		FORCEON_MCLKB | FORCEON_YCLKA | FORCEON_YCLKB | FORCEON_MC |
 		FORCEON_AIC);
-	rbbm_soft_reset = INREG((ulong)scr->mmio, RBBM_SOFT_RESET);
+	rbbm_soft_reset = INREG(scr->mmio, RBBM_SOFT_RESET);
 
-	OUTREG((ulong)scr->mmio, RBBM_SOFT_RESET, rbbm_soft_reset |
+	OUTREG(scr->mmio, RBBM_SOFT_RESET, rbbm_soft_reset |
 		SOFT_RESET_CP | SOFT_RESET_HI | SOFT_RESET_SE | SOFT_RESET_RE |
 		SOFT_RESET_PP | SOFT_RESET_E2 | SOFT_RESET_RB);
-	INREG((ulong)scr->mmio, RBBM_SOFT_RESET);
-	OUTREG((ulong)scr->mmio, RBBM_SOFT_RESET, rbbm_soft_reset &
+	INREG(scr->mmio, RBBM_SOFT_RESET);
+	OUTREG(scr->mmio, RBBM_SOFT_RESET, rbbm_soft_reset &
 		~(SOFT_RESET_CP | SOFT_RESET_HI | SOFT_RESET_SE | SOFT_RESET_RE |
 		SOFT_RESET_PP | SOFT_RESET_E2 | SOFT_RESET_RB));
-	INREG((ulong)scr->mmio, RBBM_SOFT_RESET);
+	INREG(scr->mmio, RBBM_SOFT_RESET);
 
-	OUTPLL((ulong)scr->mmio, MCLK_CNTL, mclk_cntl);
-	OUTREG((ulong)scr->mmio, CLOCK_CNTL_INDEX, clock_cntl_index);
+	OUTPLL(scr->mmio, MCLK_CNTL, mclk_cntl);
+	OUTREG(scr->mmio, CLOCK_CNTL_INDEX, clock_cntl_index);
 
 	/* init 2D engine */
 	radeonwaitfifo(scr, 1);
-	OUTREG((ulong)scr->mmio, RB2D_DSTCACHE_MODE, 0);
+	OUTREG(scr->mmio, RB2D_DSTCACHE_MODE, 0);
 
 	pitch = Dx(scr->gscreen->r) * bpp;
 	radeonwaitfifo(scr, 4);
-	OUTREG((ulong)scr->mmio, DEFAULT_PITCH, pitch);
-	OUTREG((ulong)scr->mmio, DST_PITCH, pitch);
-	OUTREG((ulong)scr->mmio, SRC_PITCH, pitch);
-	OUTREG((ulong)scr->mmio, DST_PITCH_OFFSET_C, 0);
+	OUTREG(scr->mmio, DEFAULT_PITCH, pitch);
+	OUTREG(scr->mmio, DST_PITCH, pitch);
+	OUTREG(scr->mmio, SRC_PITCH, pitch);
+	OUTREG(scr->mmio, DST_PITCH_OFFSET_C, 0);
 
 	radeonwaitfifo(scr, 3);
-	OUTREG((ulong)scr->mmio, DEFAULT_OFFSET, 0);
-	OUTREG((ulong)scr->mmio, DST_OFFSET, 0);
-	OUTREG((ulong)scr->mmio, SRC_OFFSET, 0);
+	OUTREG(scr->mmio, DEFAULT_OFFSET, 0);
+	OUTREG(scr->mmio, DST_OFFSET, 0);
+	OUTREG(scr->mmio, SRC_OFFSET, 0);
 
 	radeonwaitfifo(scr, 1);
-	OUTREGP((ulong)scr->mmio, DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
+	OUTREGP(scr->mmio, DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
 
 	radeonwaitfifo(scr, 1);
-	OUTREG((ulong)scr->mmio, DEFAULT_SC_BOTTOM_RIGHT,
+	OUTREG(scr->mmio, DEFAULT_SC_BOTTOM_RIGHT,
 		DEFAULT_SC_RIGHT_MAX | DEFAULT_SC_BOTTOM_MAX);
 
 	dp_gui_master_cntl = dtype << GMC_DST_DATATYPE_SHIFT |
 		GMC_SRC_PITCH_OFFSET_CNTL | GMC_DST_PITCH_OFFSET_CNTL |
 		GMC_CLR_CMP_CNTL_DIS;
 	radeonwaitfifo(scr, 1);
-	OUTREG((ulong)scr->mmio, DP_GUI_MASTER_CNTL,
+	OUTREG(scr->mmio, DP_GUI_MASTER_CNTL,
 	    dp_gui_master_cntl | GMC_BRUSH_SOLID_COLOR | GMC_SRC_DATATYPE_COLOR);
 
 	radeonwaitfifo(scr, 7);
-	OUTREG((ulong)scr->mmio, DST_LINE_START,    0);
-	OUTREG((ulong)scr->mmio, DST_LINE_END,      0);
-	OUTREG((ulong)scr->mmio, DP_BRUSH_FRGD_CLR, ~0ul);
-	OUTREG((ulong)scr->mmio, DP_BRUSH_BKGD_CLR, 0);
-	OUTREG((ulong)scr->mmio, DP_SRC_FRGD_CLR,   ~0ul);
-	OUTREG((ulong)scr->mmio, DP_SRC_BKGD_CLR,   0);
-	OUTREG((ulong)scr->mmio, DP_WRITE_MASK,     ~0ul);
+	OUTREG(scr->mmio, DST_LINE_START,    0);
+	OUTREG(scr->mmio, DST_LINE_END,      0);
+	OUTREG(scr->mmio, DP_BRUSH_FRGD_CLR, ~0ul);
+	OUTREG(scr->mmio, DP_BRUSH_BKGD_CLR, 0);
+	OUTREG(scr->mmio, DP_SRC_FRGD_CLR,   ~0ul);
+	OUTREG(scr->mmio, DP_SRC_BKGD_CLR,   0);
+	OUTREG(scr->mmio, DP_WRITE_MASK,     ~0ul);
 
 	radeonwaitidle(scr);
 
diff --git a/sys/src/9/pc64/pc64 b/sys/src/9/pc64/pc64
--- a/sys/src/9/pc64/pc64
+++ b/sys/src/9/pc64/pc64
@@ -129,7 +129,7 @@
 #	vgamga4xx	+cur
 #	vganeomagic	+cur
 #	vganvidia	+cur
-#	vgaradeon	+cur
+	vgaradeon	+cur
 #	vgargb524	=cur
 #	vgas3		+cur vgasavage
 #	vgat2r4		+cur

[-- Attachment #4: 7515.patch --]
[-- Type: text/x-patch, Size: 2817 bytes --]

# HG changeset patch
# User Robert Ransom <rransom.8774@gmail.com>
# Date 1578147960 18000
# Node ID 48a158c0731b26c142a404cc3fdd04e679a3bca1
# Parent  939ab197463703d4835622103bde410bd0a2acd7
Add minimal CPU frequency support for AMD family 10h and later

This uses the 'hardware P-state control' present through the
current family 17h processors.  Family 10h also has the registers
for the older software COF/VID control mechanism required by family
0fh (and earlier?), so this really ought to be generalized to
support more than one type of CPU frequency control on the same
system.

diff --git a/sys/src/9/pc/cpufreq.c b/sys/src/9/pc/cpufreq.c
new file mode 100644
--- /dev/null
+++ b/sys/src/9/pc/cpufreq.c
@@ -0,0 +1,97 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+
+enum {
+	CMpowersave,
+};
+
+static Cmdtab amdpstatectlmsg[] = {
+	CMpowersave,	"powersave",	1,
+};
+
+static int
+amdpstatecpufreqok(void)
+{
+	ulong regs[4];
+
+	if(strcmp(m->cpuidid, "AuthenticAMD") == 0){
+		cpuid(0x80000007, regs);
+		return (regs[3] & (1 << 7)) != 0;
+	}
+	return 0;
+}
+
+static void
+amdpstateset(ulong pst)
+{
+	vlong cmdmsr;
+	long i;
+	Mach *w;
+
+	w = up->wired;
+	cmdmsr = pst & 15;
+	for(i = 0; i < conf.nmach; ++i){
+		procwired(up, i);
+		sched();
+		if(wrmsr(0xC0010062, cmdmsr) < 0)
+			print("error setting P-state %uld on mach %ld\n", pst, i);
+	}
+	up->wired = w;
+	sched();
+}
+
+static void
+amdpstatectl(Cmdbuf *cb)
+{
+	Cmdtab *ct;
+	vlong limmsr;
+	ulong PstateMaxVal;
+
+	ct = lookupcmd(cb, amdpstatectlmsg, nelem(amdpstatectlmsg));
+	switch(ct->index){
+	case CMpowersave:
+		if(rdmsr(0xC0010061, &limmsr) < 0){
+			cmderror(cb, "MSRC001_0061 unsupported?!");
+			return;
+		}
+		PstateMaxVal = (limmsr >> 4) & 15;
+		print("PStateMaxVal: %uld\n", PstateMaxVal);
+
+		amdpstateset(PstateMaxVal);
+
+		return;
+	}
+
+	cmderror(cb, "bad cpufreq control message");
+}
+
+static long
+amdpstatectlwrite(Chan *c, void *a, long n, vlong off)
+{
+	Cmdbuf *cb;
+
+	if(off || n >= READSTR)
+		error(Ebadarg);
+
+	cb = parsecmd(a, n);
+	if(waserror()){
+		free(cb);
+		nexterror();
+	}
+	amdpstatectl(cb);
+	poperror();
+	free(cb);
+	return n;
+}
+
+void
+cpufreqlink(void)
+{
+	if(amdpstatecpufreqok())
+		addarchfile("cpufreqctl", 0664, nil, amdpstatectlwrite);
+}
diff --git a/sys/src/9/pc/pc b/sys/src/9/pc/pc
--- a/sys/src/9/pc/pc
+++ b/sys/src/9/pc/pc
@@ -48,6 +48,7 @@
 	devpccard
 	devi82365
 	cputemp
+	cpufreq
 	apm		apmjump
 	ether2000	ether8390
 	ether2114x	pci
diff --git a/sys/src/9/pc64/pc64 b/sys/src/9/pc64/pc64
--- a/sys/src/9/pc64/pc64
+++ b/sys/src/9/pc64/pc64
@@ -47,6 +47,7 @@
 #	devpccard
 #	devi82365
 	cputemp
+	cpufreq
 #	ether2000	ether8390
 #	ether2114x	pci
 #	ether589	etherelnk3

[-- Attachment #5: 7516.patch --]
[-- Type: text/x-patch, Size: 572 bytes --]

# HG changeset patch
# User Robert Ransom <rransom.8774@gmail.com>
# Date 1578551282 18000
# Node ID 7d487cd61e9268bd7fd0d88e20f8479d6939e960
# Parent  48a158c0731b26c142a404cc3fdd04e679a3bca1
Fix comment typo

diff -r 48a158c0731b -r 7d487cd61e92 sys/src/9/boot/bootrc
--- a/sys/src/9/boot/bootrc	Sat Jan 04 09:26:00 2020 -0500
+++ b/sys/src/9/boot/bootrc	Thu Jan 09 01:28:02 2020 -0500
@@ -17,7 +17,7 @@
 for(i in I l^(0 1 2 3))
 	bind -qa '#'$i /net
 
-# usualy better than 1970
+# usually better than 1970
 cat '#r/rtc' >/dev/time >[2]/dev/null
 
 # reparse variables

[-- Attachment #6: 7517.patch --]
[-- Type: text/x-patch, Size: 691 bytes --]

# HG changeset patch
# User Robert Ransom <rransom.8774@gmail.com>
# Date 1578551612 18000
# Node ID 64f92cdc003b532a34e90fda087c7a59977058b2
# Parent  7d487cd61e9268bd7fd0d88e20f8479d6939e960
Reduce CPU power and heat early in bootrc if possible

diff -r 7d487cd61e92 -r 64f92cdc003b sys/src/9/boot/bootrc
--- a/sys/src/9/boot/bootrc	Thu Jan 09 01:28:02 2020 -0500
+++ b/sys/src/9/boot/bootrc	Thu Jan 09 01:33:32 2020 -0500
@@ -17,6 +17,10 @@
 for(i in I l^(0 1 2 3))
 	bind -qa '#'$i /net
 
+# cut CPU frequency back from maximum if possible/necessary
+if(test -e /dev/cpufreqctl)
+	echo 'powersave' >>/dev/cpufreqctl
+
 # usually better than 1970
 cat '#r/rtc' >/dev/time >[2]/dev/null
 

[-- Attachment #7: 7518.patch --]
[-- Type: text/x-patch, Size: 5417 bytes --]

# HG changeset patch
# User Robert Ransom <rransom.8774@gmail.com>
# Date 1578731009 18000
# Node ID 6fd1dc88184ef0db3b95278fc9e6fe0a987d22f3
# Parent  64f92cdc003b532a34e90fda087c7a59977058b2
Add support for setting any CPU frequency level to amdpstate driver

Not finished, but now the 'powersave' command can be undone.  Needs
to be extended to print out the frequency and other values of the
available P-states, and to check and print various other values in
the processor's PCI configuration spaces.

Reading the effective CPU frequency will take more work, including
two additional assembly routines.

diff -r 64f92cdc003b -r 6fd1dc88184e sys/src/9/pc/cpufreq.c
--- a/sys/src/9/pc/cpufreq.c	Thu Jan 09 01:33:32 2020 -0500
+++ b/sys/src/9/pc/cpufreq.c	Sat Jan 11 03:23:29 2020 -0500
@@ -6,12 +6,41 @@
 #include "io.h"
 #include "../port/error.h"
 
+/* Relevant hardware documentation for AMD "hardware P-state control":
+
+   AMD document 25481 - CPUID Specification
+     Fn0000_0006 - EffFreq bit (read effective frequency) - TODO   
+     Fn8000_0007 - HwPstate, VID, and FID bits
+
+   AMD document 31116 - AMD Family 10h BKDG
+     section 2.4.2.1.3 Core P-state Control (p. 54)
+     MSR reference MSRC001_0061 to _0063 (p. 427,428)
+     Note that MSRC001_0070 and _0071 (software low-level COF/VID control)
+       used on family 0Fh are still present; however, the processor's
+       "core performance boost" feature will clash with the older
+       mechanism unless CPB is disabled first.
+
+   AMD document 56255 - AMD Family 17h OSRR (cut-down version of BKDG)
+     confirms that this P-state mechanism is still in use;
+     specifies P-state bitfields as 3 bits wide;
+     MSRC001_0070 and _0071 are no longer documented as COF/VID control,
+       but not yet used for P-states.
+
+   AMD document 24593 Rev. 3.32 October 2019 - arch. manual vol 2 System Programming
+     specifies P-state bitfields as 4 bits wide; 
+     MSRC001_0070 and _0071 would fall within the range used by firmware
+       to provide supported P-state values to the processor.
+
+*/
+
 enum {
 	CMpowersave,
+	CMpstate,
 };
 
 static Cmdtab amdpstatectlmsg[] = {
 	CMpowersave,	"powersave",	1,
+	CMpstate,	"pstate",	2,
 };
 
 static int
@@ -26,44 +55,64 @@
 	return 0;
 }
 
-static void
+static int
 amdpstateset(ulong pst)
 {
 	vlong cmdmsr;
 	long i;
 	Mach *w;
+	int failed = 0;
 
 	w = up->wired;
 	cmdmsr = pst & 15;
 	for(i = 0; i < conf.nmach; ++i){
 		procwired(up, i);
 		sched();
-		if(wrmsr(0xC0010062, cmdmsr) < 0)
+		if(wrmsr(0xC0010062, cmdmsr) < 0){
 			print("error setting P-state %uld on mach %ld\n", pst, i);
+			failed = -1;
+		}
 	}
 	up->wired = w;
 	sched();
+
+	return failed;
 }
 
 static void
 amdpstatectl(Cmdbuf *cb)
 {
 	Cmdtab *ct;
+	char *p;
 	vlong limmsr;
-	ulong PstateMaxVal;
+	ulong pst;
 
 	ct = lookupcmd(cb, amdpstatectlmsg, nelem(amdpstatectlmsg));
 	switch(ct->index){
 	case CMpowersave:
 		if(rdmsr(0xC0010061, &limmsr) < 0){
-			cmderror(cb, "MSRC001_0061 unsupported?!");
+			cmderror(cb, "MSRC001_0061 (PState limits) unreadable");
 			return;
 		}
-		PstateMaxVal = (limmsr >> 4) & 15;
-		print("PStateMaxVal: %uld\n", PstateMaxVal);
+		pst = (limmsr >> 4) & 15;
+		print("PStateMaxVal: %uld\n", pst);
 
-		amdpstateset(PstateMaxVal);
+		if(amdpstateset(pst) < 0)
+			cmderror(cb, "error setting min-power P-state");
+		return;
+	case CMpstate:
+		p = cb->f[1];
+		if((*p == 'P') || (*p == 'p'))
+			++p;
 
+		pst = strtoul(p, &p, 10);
+		if(*p){
+			cmderror(cb, "invalid P-state format");
+			return;
+		}
+
+		if(amdpstateset(pst) < 0)
+			cmderror(cb, "error setting specified P-state");
 		return;
 	}
 
@@ -71,7 +120,65 @@
 }
 
 static long
-amdpstatectlwrite(Chan *c, void *a, long n, vlong off)
+amdpstatectlread(Chan *, void *a, long n, vlong off)
+{
+	char *p, *s, *e;
+	ulong offset = off;
+	int hwcrvalid, limmsrvalid;
+	ulong cpuidregs[4];
+	vlong hwcr, limmsr;
+	int cpuidCPB;
+	int CpbDis, PstateMaxVal, CurPstateLimit;
+
+	cpuid(0x80000007, cpuidregs);
+	hwcrvalid   = (rdmsr(0xC0010015, &hwcr)   >= 0);
+	limmsrvalid = (rdmsr(0xC0010061, &limmsr) >= 0);
+
+	cpuidCPB = ((cpuidregs[3] & (1 << 9)) != 0);
+
+	s = smalloc(READSTR);
+	if(waserror()){
+		free(s);
+		nexterror();
+	}
+	p = s; e = s+READSTR;
+	p = seprint(p, e, "type %s\n", "amdpstate");
+	p = seprint(p, e, "boostavail %s\n",
+		(cpuidCPB) ? "yes" : "no");
+	/* FIXME check bits in PCI config space too; requires ECAM */   
+
+	if(hwcrvalid){
+		CpbDis = ((ulong)hwcr & (1 << 25));
+		p = seprint(p, e, "boost %s\n",
+			CpbDis ? "disabled" : "enabled");
+	}else{
+		p = seprint(p, e, "ERROR MSRC001_0015 (HWCR) unreadable\n");
+	}
+
+	if(limmsrvalid){
+		PstateMaxVal = (limmsr >> 4) & 15;
+		CurPstateLimit = limmsr & 15;
+		p = seprint(p, e, "pstaterange %d %d\n", PstateMaxVal, CurPstateLimit);
+	}else{
+		PstateMaxVal = -1;
+		CurPstateLimit = 0;
+		p = seprint(p, e, "ERROR MSRC001_0061 (PState limits) unreadable\n");
+	}
+
+	/* TODO dump more data */   
+	USED(PstateMaxVal);
+	USED(CurPstateLimit);
+
+	USED(p);
+	n = readstr(offset, a, n, s);
+	poperror();
+	free(s);
+
+	return n;
+}
+
+static long
+amdpstatectlwrite(Chan *, void *a, long n, vlong off)
 {
 	Cmdbuf *cb;
 
@@ -93,5 +200,5 @@
 cpufreqlink(void)
 {
 	if(amdpstatecpufreqok())
-		addarchfile("cpufreqctl", 0664, nil, amdpstatectlwrite);
+		addarchfile("cpufreqctl", 0664, amdpstatectlread, amdpstatectlwrite);
 }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [9front] Kernel patches (cpufreqctl, Radeon on amd64, trivia)
  2020-01-11  3:59 Kernel patches (cpufreqctl, Radeon on amd64, trivia) Robert Ransom
@ 2020-01-11 20:33 ` cinap_lenrek
  2020-01-11 21:24   ` Robert Ransom
  0 siblings, 1 reply; 3+ messages in thread
From: cinap_lenrek @ 2020-01-11 20:33 UTC (permalink / raw)
  To: 9front

applied the trivial ones.

Patch 7514, 7515, 7517, 7518 got mangled (by postmaster@ewsd?) in the mail.
can you resubmit please and put me directly in CC?

--
cinap


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [9front] Kernel patches (cpufreqctl, Radeon on amd64, trivia)
  2020-01-11 20:33 ` [9front] " cinap_lenrek
@ 2020-01-11 21:24   ` Robert Ransom
  0 siblings, 0 replies; 3+ messages in thread
From: Robert Ransom @ 2020-01-11 21:24 UTC (permalink / raw)
  To: 9front; +Cc: cinap_lenrek

[-- Attachment #1: Type: text/plain, Size: 247 bytes --]

On 1/11/20, cinap_lenrek@felloff.net <cinap_lenrek@felloff.net> wrote:
> applied the trivial ones.
>
> Patch 7514, 7515, 7517, 7518 got mangled (by postmaster@ewsd?) in the mail.
> can you resubmit please and put me directly in CC?

See attached.

[-- Attachment #2: 7514.patch --]
[-- Type: text/x-patch, Size: 10456 bytes --]

# HG changeset patch
# User Robert Ransom <rransom.8774@gmail.com>
# Date 1578147512 18000
# Node ID 939ab197463703d4835622103bde410bd0a2acd7
# Parent  85dfb4d0d5ee93073cde636cc5288e72116b46e5
Adapt vgaradeon driver to 64-bit

Not yet tested.

diff --git a/sys/src/9/pc/vgaradeon.c b/sys/src/9/pc/vgaradeon.c
--- a/sys/src/9/pc/vgaradeon.c
+++ b/sys/src/9/pc/vgaradeon.c
@@ -28,45 +28,45 @@
 /* mmio access */
 
 static void
-OUTREG8(ulong mmio, ulong offset, uchar val)
+OUTREG8(ulong *mmio, ulong offset, uchar val)
 {
-	((uchar*)KADDR((mmio + offset)))[0] = val;
+	((uchar*)KADDR((((uintptr)mmio) + offset)))[0] = val;
 }
 
 static void
-OUTREG(ulong mmio, ulong offset, ulong val)
+OUTREG(ulong *mmio, ulong offset, ulong val)
 {
-	((ulong*)KADDR((mmio + offset)))[0] = val;
+	((ulong*)KADDR((((uintptr)mmio) + offset)))[0] = val;
 }
 
 static ulong
-INREG(ulong mmio, ulong offset)
+INREG(ulong *mmio, ulong offset)
 {
-	return ((ulong*)KADDR((mmio + offset)))[0];
+	return ((ulong*)KADDR((((uintptr)mmio) + offset)))[0];
 }
 
 static void
-OUTREGP(ulong mmio, ulong offset, ulong val, ulong mask)
+OUTREGP(ulong *mmio, ulong offset, ulong val, ulong mask)
 {
 	OUTREG(mmio, offset, (INREG(mmio, offset) & mask) | val);
 }
 
 static void
-OUTPLL(ulong mmio, ulong offset, ulong val)
+OUTPLL(ulong *mmio, ulong offset, ulong val)
 {
 	OUTREG8(mmio, CLOCK_CNTL_INDEX, (offset & 0x3f) | PLL_WR_EN);
 	OUTREG(mmio, CLOCK_CNTL_DATA, val);
 }
 
 static ulong
-INPLL(ulong mmio, ulong offset)
+INPLL(ulong *mmio, ulong offset)
 {
 	OUTREG8(mmio, CLOCK_CNTL_INDEX, offset & 0x3f);
 	return INREG(mmio, CLOCK_CNTL_DATA);
 }
 
 static void
-OUTPLLP(ulong mmio, ulong offset, ulong val, ulong mask)
+OUTPLLP(ulong *mmio, ulong offset, ulong val, ulong mask)
 {
 	OUTPLL(mmio, offset, (INPLL(mmio, offset) & mask) | val);
 }
@@ -174,10 +174,10 @@
 		y = 0;
 	}
 
-	OUTREG((ulong)scr->mmio, CUR_OFFSET, storage + oy * 256);
-	OUTREG((ulong)scr->mmio, CUR_HORZ_VERT_OFF,
+	OUTREG(scr->mmio, CUR_OFFSET, storage + oy * 256);
+	OUTREG(scr->mmio, CUR_HORZ_VERT_OFF,
 		(ox & 0x7fff) << 16 | (oy & 0x7fff));
-	OUTREG((ulong)scr->mmio, CUR_HORZ_VERT_POSN,
+	OUTREG(scr->mmio, CUR_HORZ_VERT_POSN,
 		(x & 0x7fff) << 16 | (y & 0x7fff));
 	return 0;
 }
@@ -187,7 +187,7 @@
 {
 	if(scr->mmio == nil)
 		return;
-	OUTREGP((ulong)scr->mmio, CRTC_GEN_CNTL, 0, ~CRTC_CUR_EN);
+	OUTREGP(scr->mmio, CRTC_GEN_CNTL, 0, ~CRTC_CUR_EN);
 }
 
 static void
@@ -200,11 +200,11 @@
 
 	radeoncurdisable(scr);
 	storage = scr->apsize - 1*Meg;
-	scr->storage = (ulong)KADDR(scr->paddr + storage);
+	scr->storage = (uintptr)KADDR(scr->paddr + storage);
 	radeoncurload(scr, &arrow);
 	radeoncurmove(scr, ZP);
 
-	OUTREGP((ulong)scr->mmio, CRTC_GEN_CNTL, CRTC_CUR_EN | 2<<20,
+	OUTREGP(scr->mmio, CRTC_GEN_CNTL, CRTC_CUR_EN | 2<<20,
 		~(CRTC_CUR_EN | 3<<20));
 }
 
@@ -223,24 +223,24 @@
 
 	mask = CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | CRTC_VSYNC_DIS;
 	if (blank == 0) {
-		OUTREGP((ulong)scr->mmio, CRTC_EXT_CNTL, 0, ~mask);
+		OUTREGP(scr->mmio, CRTC_EXT_CNTL, 0, ~mask);
 		return;
 	}
 
 	cp = getconf("*dpms");
 	if (cp) {
 		if (strcmp(cp, "standby") == 0)
-			OUTREGP((ulong)scr->mmio, CRTC_EXT_CNTL,
+			OUTREGP(scr->mmio, CRTC_EXT_CNTL,
 				CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS, ~mask);
 		else if (strcmp(cp, "suspend") == 0)
-			OUTREGP((ulong)scr->mmio, CRTC_EXT_CNTL,
+			OUTREGP(scr->mmio, CRTC_EXT_CNTL,
 				CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS, ~mask);
 		else if (strcmp(cp, "off") == 0)
-			OUTREGP((ulong)scr->mmio, CRTC_EXT_CNTL, mask, ~mask);
+			OUTREGP(scr->mmio, CRTC_EXT_CNTL, mask, ~mask);
 		return;
 	}
 
-	OUTREGP((ulong)scr->mmio, CRTC_EXT_CNTL, mask, ~mask);
+	OUTREGP(scr->mmio, CRTC_EXT_CNTL, mask, ~mask);
 }
 
 /* hw acceleration */
@@ -251,7 +251,7 @@
 	int i;
 
 	for (i = 0; i < 2000000; i++)
-		if (INREG((ulong)scr->mmio, RBBM_STATUS) & RBBM_FIFOCNT_MASK >=
+		if (INREG(scr->mmio, RBBM_STATUS) & RBBM_FIFOCNT_MASK >=
 		    entries)
 			return;
 	iprint("radeon: fifo timeout\n");
@@ -266,12 +266,12 @@
 		int i;
 
 		for (i = 0; i < 2000000; i++)
-			if (!(INREG((ulong)scr->mmio, RBBM_STATUS) & RBBM_ACTIVE))
+			if (!(INREG(scr->mmio, RBBM_STATUS) & RBBM_ACTIVE))
 				return;
 
 		iprint("radeon: idle timed out: %uld entries, stat=0x%.8ulx\n",
-			INREG((ulong)scr->mmio, RBBM_STATUS) & RBBM_FIFOCNT_MASK,
-			INREG((ulong)scr->mmio, RBBM_STATUS));
+			INREG(scr->mmio, RBBM_STATUS) & RBBM_FIFOCNT_MASK,
+			INREG(scr->mmio, RBBM_STATUS));
 	}
 }
 
@@ -284,15 +284,15 @@
 		return 0;
 
 	radeonwaitfifo(scr, 6);
-	OUTREG((ulong)scr->mmio, DP_GUI_MASTER_CNTL,
+	OUTREG(scr->mmio, DP_GUI_MASTER_CNTL,
 		dp_gui_master_cntl | GMC_BRUSH_SOLID_COLOR |
 		GMC_SRC_DATATYPE_COLOR | ROP3_P);
-	OUTREG((ulong)scr->mmio, DP_BRUSH_FRGD_CLR, color);
-	OUTREG((ulong)scr->mmio, DP_WRITE_MASK, ~0ul);
-	OUTREG((ulong)scr->mmio, DP_CNTL,
+	OUTREG(scr->mmio, DP_BRUSH_FRGD_CLR, color);
+	OUTREG(scr->mmio, DP_WRITE_MASK, ~0ul);
+	OUTREG(scr->mmio, DP_CNTL,
 		DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
-	OUTREG((ulong)scr->mmio, DST_Y_X, r.min.y << 16 | r.min.x);
-	OUTREG((ulong)scr->mmio, DST_WIDTH_HEIGHT, Dx(r) << 16 | Dy(r));
+	OUTREG(scr->mmio, DST_Y_X, r.min.y << 16 | r.min.x);
+	OUTREG(scr->mmio, DST_WIDTH_HEIGHT, Dx(r) << 16 | Dy(r));
 
 	radeonwaitidle(scr);
 	return 1;
@@ -329,14 +329,14 @@
 		dp_cntl |= DST_X_LEFT_TO_RIGHT;
 
 	radeonwaitfifo(scr, 6);
-	OUTREG((ulong)scr->mmio, DP_GUI_MASTER_CNTL, dp_gui_master_cntl |
+	OUTREG(scr->mmio, DP_GUI_MASTER_CNTL, dp_gui_master_cntl |
 		GMC_BRUSH_NONE | GMC_SRC_DATATYPE_COLOR | DP_SRC_SOURCE_MEMORY |
 		ROP3_S);
-	OUTREG((ulong)scr->mmio, DP_WRITE_MASK, ~0ul);
-	OUTREG((ulong)scr->mmio, DP_CNTL, dp_cntl);
-	OUTREG((ulong)scr->mmio, SRC_Y_X, ys << 16 | xs);
-	OUTREG((ulong)scr->mmio, DST_Y_X, yd << 16 | xd);
-	OUTREG((ulong)scr->mmio, DST_WIDTH_HEIGHT, w << 16 | h);
+	OUTREG(scr->mmio, DP_WRITE_MASK, ~0ul);
+	OUTREG(scr->mmio, DP_CNTL, dp_cntl);
+	OUTREG(scr->mmio, SRC_Y_X, ys << 16 | xs);
+	OUTREG(scr->mmio, DST_Y_X, yd << 16 | xd);
+	OUTREG(scr->mmio, DST_WIDTH_HEIGHT, w << 16 | h);
 
 	radeonwaitidle(scr);
 
@@ -376,75 +376,75 @@
 	}
 
 	/* disable 3D */
-	OUTREG((ulong)scr->mmio, RB3D_CNTL, 0);
+	OUTREG(scr->mmio, RB3D_CNTL, 0);
 
 	/* flush engine */
-	OUTREGP((ulong)scr->mmio, RB2D_DSTCACHE_CTLSTAT,
+	OUTREGP(scr->mmio, RB2D_DSTCACHE_CTLSTAT,
 		RB2D_DC_FLUSH_ALL, ~RB2D_DC_FLUSH_ALL);
 	for (i = 0; i < 2000000; i++)
-		if (!(INREG((ulong)scr->mmio, RB2D_DSTCACHE_CTLSTAT) &
+		if (!(INREG(scr->mmio, RB2D_DSTCACHE_CTLSTAT) &
 		    RB2D_DC_BUSY))
 			break;
 
 	/* reset 2D engine */
-	clock_cntl_index = INREG((ulong)scr->mmio, CLOCK_CNTL_INDEX);
+	clock_cntl_index = INREG(scr->mmio, CLOCK_CNTL_INDEX);
 
-	mclk_cntl = INPLL((ulong)scr->mmio, MCLK_CNTL);
-	OUTPLL((ulong)scr->mmio, MCLK_CNTL, mclk_cntl | FORCEON_MCLKA |
+	mclk_cntl = INPLL(scr->mmio, MCLK_CNTL);
+	OUTPLL(scr->mmio, MCLK_CNTL, mclk_cntl | FORCEON_MCLKA |
 		FORCEON_MCLKB | FORCEON_YCLKA | FORCEON_YCLKB | FORCEON_MC |
 		FORCEON_AIC);
-	rbbm_soft_reset = INREG((ulong)scr->mmio, RBBM_SOFT_RESET);
+	rbbm_soft_reset = INREG(scr->mmio, RBBM_SOFT_RESET);
 
-	OUTREG((ulong)scr->mmio, RBBM_SOFT_RESET, rbbm_soft_reset |
+	OUTREG(scr->mmio, RBBM_SOFT_RESET, rbbm_soft_reset |
 		SOFT_RESET_CP | SOFT_RESET_HI | SOFT_RESET_SE | SOFT_RESET_RE |
 		SOFT_RESET_PP | SOFT_RESET_E2 | SOFT_RESET_RB);
-	INREG((ulong)scr->mmio, RBBM_SOFT_RESET);
-	OUTREG((ulong)scr->mmio, RBBM_SOFT_RESET, rbbm_soft_reset &
+	INREG(scr->mmio, RBBM_SOFT_RESET);
+	OUTREG(scr->mmio, RBBM_SOFT_RESET, rbbm_soft_reset &
 		~(SOFT_RESET_CP | SOFT_RESET_HI | SOFT_RESET_SE | SOFT_RESET_RE |
 		SOFT_RESET_PP | SOFT_RESET_E2 | SOFT_RESET_RB));
-	INREG((ulong)scr->mmio, RBBM_SOFT_RESET);
+	INREG(scr->mmio, RBBM_SOFT_RESET);
 
-	OUTPLL((ulong)scr->mmio, MCLK_CNTL, mclk_cntl);
-	OUTREG((ulong)scr->mmio, CLOCK_CNTL_INDEX, clock_cntl_index);
+	OUTPLL(scr->mmio, MCLK_CNTL, mclk_cntl);
+	OUTREG(scr->mmio, CLOCK_CNTL_INDEX, clock_cntl_index);
 
 	/* init 2D engine */
 	radeonwaitfifo(scr, 1);
-	OUTREG((ulong)scr->mmio, RB2D_DSTCACHE_MODE, 0);
+	OUTREG(scr->mmio, RB2D_DSTCACHE_MODE, 0);
 
 	pitch = Dx(scr->gscreen->r) * bpp;
 	radeonwaitfifo(scr, 4);
-	OUTREG((ulong)scr->mmio, DEFAULT_PITCH, pitch);
-	OUTREG((ulong)scr->mmio, DST_PITCH, pitch);
-	OUTREG((ulong)scr->mmio, SRC_PITCH, pitch);
-	OUTREG((ulong)scr->mmio, DST_PITCH_OFFSET_C, 0);
+	OUTREG(scr->mmio, DEFAULT_PITCH, pitch);
+	OUTREG(scr->mmio, DST_PITCH, pitch);
+	OUTREG(scr->mmio, SRC_PITCH, pitch);
+	OUTREG(scr->mmio, DST_PITCH_OFFSET_C, 0);
 
 	radeonwaitfifo(scr, 3);
-	OUTREG((ulong)scr->mmio, DEFAULT_OFFSET, 0);
-	OUTREG((ulong)scr->mmio, DST_OFFSET, 0);
-	OUTREG((ulong)scr->mmio, SRC_OFFSET, 0);
+	OUTREG(scr->mmio, DEFAULT_OFFSET, 0);
+	OUTREG(scr->mmio, DST_OFFSET, 0);
+	OUTREG(scr->mmio, SRC_OFFSET, 0);
 
 	radeonwaitfifo(scr, 1);
-	OUTREGP((ulong)scr->mmio, DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
+	OUTREGP(scr->mmio, DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
 
 	radeonwaitfifo(scr, 1);
-	OUTREG((ulong)scr->mmio, DEFAULT_SC_BOTTOM_RIGHT,
+	OUTREG(scr->mmio, DEFAULT_SC_BOTTOM_RIGHT,
 		DEFAULT_SC_RIGHT_MAX | DEFAULT_SC_BOTTOM_MAX);
 
 	dp_gui_master_cntl = dtype << GMC_DST_DATATYPE_SHIFT |
 		GMC_SRC_PITCH_OFFSET_CNTL | GMC_DST_PITCH_OFFSET_CNTL |
 		GMC_CLR_CMP_CNTL_DIS;
 	radeonwaitfifo(scr, 1);
-	OUTREG((ulong)scr->mmio, DP_GUI_MASTER_CNTL,
+	OUTREG(scr->mmio, DP_GUI_MASTER_CNTL,
 	    dp_gui_master_cntl | GMC_BRUSH_SOLID_COLOR | GMC_SRC_DATATYPE_COLOR);
 
 	radeonwaitfifo(scr, 7);
-	OUTREG((ulong)scr->mmio, DST_LINE_START,    0);
-	OUTREG((ulong)scr->mmio, DST_LINE_END,      0);
-	OUTREG((ulong)scr->mmio, DP_BRUSH_FRGD_CLR, ~0ul);
-	OUTREG((ulong)scr->mmio, DP_BRUSH_BKGD_CLR, 0);
-	OUTREG((ulong)scr->mmio, DP_SRC_FRGD_CLR,   ~0ul);
-	OUTREG((ulong)scr->mmio, DP_SRC_BKGD_CLR,   0);
-	OUTREG((ulong)scr->mmio, DP_WRITE_MASK,     ~0ul);
+	OUTREG(scr->mmio, DST_LINE_START,    0);
+	OUTREG(scr->mmio, DST_LINE_END,      0);
+	OUTREG(scr->mmio, DP_BRUSH_FRGD_CLR, ~0ul);
+	OUTREG(scr->mmio, DP_BRUSH_BKGD_CLR, 0);
+	OUTREG(scr->mmio, DP_SRC_FRGD_CLR,   ~0ul);
+	OUTREG(scr->mmio, DP_SRC_BKGD_CLR,   0);
+	OUTREG(scr->mmio, DP_WRITE_MASK,     ~0ul);
 
 	radeonwaitidle(scr);
 
diff --git a/sys/src/9/pc64/pc64 b/sys/src/9/pc64/pc64
--- a/sys/src/9/pc64/pc64
+++ b/sys/src/9/pc64/pc64
@@ -129,7 +129,7 @@
 #	vgamga4xx	+cur
 #	vganeomagic	+cur
 #	vganvidia	+cur
-#	vgaradeon	+cur
+	vgaradeon	+cur
 #	vgargb524	=cur
 #	vgas3		+cur vgasavage
 #	vgat2r4		+cur

[-- Attachment #3: 7515.patch --]
[-- Type: text/x-patch, Size: 2817 bytes --]

# HG changeset patch
# User Robert Ransom <rransom.8774@gmail.com>
# Date 1578147960 18000
# Node ID 48a158c0731b26c142a404cc3fdd04e679a3bca1
# Parent  939ab197463703d4835622103bde410bd0a2acd7
Add minimal CPU frequency support for AMD family 10h and later

This uses the 'hardware P-state control' present through the
current family 17h processors.  Family 10h also has the registers
for the older software COF/VID control mechanism required by family
0fh (and earlier?), so this really ought to be generalized to
support more than one type of CPU frequency control on the same
system.

diff --git a/sys/src/9/pc/cpufreq.c b/sys/src/9/pc/cpufreq.c
new file mode 100644
--- /dev/null
+++ b/sys/src/9/pc/cpufreq.c
@@ -0,0 +1,97 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+
+enum {
+	CMpowersave,
+};
+
+static Cmdtab amdpstatectlmsg[] = {
+	CMpowersave,	"powersave",	1,
+};
+
+static int
+amdpstatecpufreqok(void)
+{
+	ulong regs[4];
+
+	if(strcmp(m->cpuidid, "AuthenticAMD") == 0){
+		cpuid(0x80000007, regs);
+		return (regs[3] & (1 << 7)) != 0;
+	}
+	return 0;
+}
+
+static void
+amdpstateset(ulong pst)
+{
+	vlong cmdmsr;
+	long i;
+	Mach *w;
+
+	w = up->wired;
+	cmdmsr = pst & 15;
+	for(i = 0; i < conf.nmach; ++i){
+		procwired(up, i);
+		sched();
+		if(wrmsr(0xC0010062, cmdmsr) < 0)
+			print("error setting P-state %uld on mach %ld\n", pst, i);
+	}
+	up->wired = w;
+	sched();
+}
+
+static void
+amdpstatectl(Cmdbuf *cb)
+{
+	Cmdtab *ct;
+	vlong limmsr;
+	ulong PstateMaxVal;
+
+	ct = lookupcmd(cb, amdpstatectlmsg, nelem(amdpstatectlmsg));
+	switch(ct->index){
+	case CMpowersave:
+		if(rdmsr(0xC0010061, &limmsr) < 0){
+			cmderror(cb, "MSRC001_0061 unsupported?!");
+			return;
+		}
+		PstateMaxVal = (limmsr >> 4) & 15;
+		print("PStateMaxVal: %uld\n", PstateMaxVal);
+
+		amdpstateset(PstateMaxVal);
+
+		return;
+	}
+
+	cmderror(cb, "bad cpufreq control message");
+}
+
+static long
+amdpstatectlwrite(Chan *c, void *a, long n, vlong off)
+{
+	Cmdbuf *cb;
+
+	if(off || n >= READSTR)
+		error(Ebadarg);
+
+	cb = parsecmd(a, n);
+	if(waserror()){
+		free(cb);
+		nexterror();
+	}
+	amdpstatectl(cb);
+	poperror();
+	free(cb);
+	return n;
+}
+
+void
+cpufreqlink(void)
+{
+	if(amdpstatecpufreqok())
+		addarchfile("cpufreqctl", 0664, nil, amdpstatectlwrite);
+}
diff --git a/sys/src/9/pc/pc b/sys/src/9/pc/pc
--- a/sys/src/9/pc/pc
+++ b/sys/src/9/pc/pc
@@ -48,6 +48,7 @@
 	devpccard
 	devi82365
 	cputemp
+	cpufreq
 	apm		apmjump
 	ether2000	ether8390
 	ether2114x	pci
diff --git a/sys/src/9/pc64/pc64 b/sys/src/9/pc64/pc64
--- a/sys/src/9/pc64/pc64
+++ b/sys/src/9/pc64/pc64
@@ -47,6 +47,7 @@
 #	devpccard
 #	devi82365
 	cputemp
+	cpufreq
 #	ether2000	ether8390
 #	ether2114x	pci
 #	ether589	etherelnk3

[-- Attachment #4: 7517.patch --]
[-- Type: text/x-patch, Size: 691 bytes --]

# HG changeset patch
# User Robert Ransom <rransom.8774@gmail.com>
# Date 1578551612 18000
# Node ID 64f92cdc003b532a34e90fda087c7a59977058b2
# Parent  7d487cd61e9268bd7fd0d88e20f8479d6939e960
Reduce CPU power and heat early in bootrc if possible

diff -r 7d487cd61e92 -r 64f92cdc003b sys/src/9/boot/bootrc
--- a/sys/src/9/boot/bootrc	Thu Jan 09 01:28:02 2020 -0500
+++ b/sys/src/9/boot/bootrc	Thu Jan 09 01:33:32 2020 -0500
@@ -17,6 +17,10 @@
 for(i in I l^(0 1 2 3))
 	bind -qa '#'$i /net
 
+# cut CPU frequency back from maximum if possible/necessary
+if(test -e /dev/cpufreqctl)
+	echo 'powersave' >>/dev/cpufreqctl
+
 # usually better than 1970
 cat '#r/rtc' >/dev/time >[2]/dev/null
 

[-- Attachment #5: 7518.patch --]
[-- Type: text/x-patch, Size: 5417 bytes --]

# HG changeset patch
# User Robert Ransom <rransom.8774@gmail.com>
# Date 1578731009 18000
# Node ID 6fd1dc88184ef0db3b95278fc9e6fe0a987d22f3
# Parent  64f92cdc003b532a34e90fda087c7a59977058b2
Add support for setting any CPU frequency level to amdpstate driver

Not finished, but now the 'powersave' command can be undone.  Needs
to be extended to print out the frequency and other values of the
available P-states, and to check and print various other values in
the processor's PCI configuration spaces.

Reading the effective CPU frequency will take more work, including
two additional assembly routines.

diff -r 64f92cdc003b -r 6fd1dc88184e sys/src/9/pc/cpufreq.c
--- a/sys/src/9/pc/cpufreq.c	Thu Jan 09 01:33:32 2020 -0500
+++ b/sys/src/9/pc/cpufreq.c	Sat Jan 11 03:23:29 2020 -0500
@@ -6,12 +6,41 @@
 #include "io.h"
 #include "../port/error.h"
 
+/* Relevant hardware documentation for AMD "hardware P-state control":
+
+   AMD document 25481 - CPUID Specification
+     Fn0000_0006 - EffFreq bit (read effective frequency) - TODO   
+     Fn8000_0007 - HwPstate, VID, and FID bits
+
+   AMD document 31116 - AMD Family 10h BKDG
+     section 2.4.2.1.3 Core P-state Control (p. 54)
+     MSR reference MSRC001_0061 to _0063 (p. 427,428)
+     Note that MSRC001_0070 and _0071 (software low-level COF/VID control)
+       used on family 0Fh are still present; however, the processor's
+       "core performance boost" feature will clash with the older
+       mechanism unless CPB is disabled first.
+
+   AMD document 56255 - AMD Family 17h OSRR (cut-down version of BKDG)
+     confirms that this P-state mechanism is still in use;
+     specifies P-state bitfields as 3 bits wide;
+     MSRC001_0070 and _0071 are no longer documented as COF/VID control,
+       but not yet used for P-states.
+
+   AMD document 24593 Rev. 3.32 October 2019 - arch. manual vol 2 System Programming
+     specifies P-state bitfields as 4 bits wide; 
+     MSRC001_0070 and _0071 would fall within the range used by firmware
+       to provide supported P-state values to the processor.
+
+*/
+
 enum {
 	CMpowersave,
+	CMpstate,
 };
 
 static Cmdtab amdpstatectlmsg[] = {
 	CMpowersave,	"powersave",	1,
+	CMpstate,	"pstate",	2,
 };
 
 static int
@@ -26,44 +55,64 @@
 	return 0;
 }
 
-static void
+static int
 amdpstateset(ulong pst)
 {
 	vlong cmdmsr;
 	long i;
 	Mach *w;
+	int failed = 0;
 
 	w = up->wired;
 	cmdmsr = pst & 15;
 	for(i = 0; i < conf.nmach; ++i){
 		procwired(up, i);
 		sched();
-		if(wrmsr(0xC0010062, cmdmsr) < 0)
+		if(wrmsr(0xC0010062, cmdmsr) < 0){
 			print("error setting P-state %uld on mach %ld\n", pst, i);
+			failed = -1;
+		}
 	}
 	up->wired = w;
 	sched();
+
+	return failed;
 }
 
 static void
 amdpstatectl(Cmdbuf *cb)
 {
 	Cmdtab *ct;
+	char *p;
 	vlong limmsr;
-	ulong PstateMaxVal;
+	ulong pst;
 
 	ct = lookupcmd(cb, amdpstatectlmsg, nelem(amdpstatectlmsg));
 	switch(ct->index){
 	case CMpowersave:
 		if(rdmsr(0xC0010061, &limmsr) < 0){
-			cmderror(cb, "MSRC001_0061 unsupported?!");
+			cmderror(cb, "MSRC001_0061 (PState limits) unreadable");
 			return;
 		}
-		PstateMaxVal = (limmsr >> 4) & 15;
-		print("PStateMaxVal: %uld\n", PstateMaxVal);
+		pst = (limmsr >> 4) & 15;
+		print("PStateMaxVal: %uld\n", pst);
 
-		amdpstateset(PstateMaxVal);
+		if(amdpstateset(pst) < 0)
+			cmderror(cb, "error setting min-power P-state");
+		return;
+	case CMpstate:
+		p = cb->f[1];
+		if((*p == 'P') || (*p == 'p'))
+			++p;
 
+		pst = strtoul(p, &p, 10);
+		if(*p){
+			cmderror(cb, "invalid P-state format");
+			return;
+		}
+
+		if(amdpstateset(pst) < 0)
+			cmderror(cb, "error setting specified P-state");
 		return;
 	}
 
@@ -71,7 +120,65 @@
 }
 
 static long
-amdpstatectlwrite(Chan *c, void *a, long n, vlong off)
+amdpstatectlread(Chan *, void *a, long n, vlong off)
+{
+	char *p, *s, *e;
+	ulong offset = off;
+	int hwcrvalid, limmsrvalid;
+	ulong cpuidregs[4];
+	vlong hwcr, limmsr;
+	int cpuidCPB;
+	int CpbDis, PstateMaxVal, CurPstateLimit;
+
+	cpuid(0x80000007, cpuidregs);
+	hwcrvalid   = (rdmsr(0xC0010015, &hwcr)   >= 0);
+	limmsrvalid = (rdmsr(0xC0010061, &limmsr) >= 0);
+
+	cpuidCPB = ((cpuidregs[3] & (1 << 9)) != 0);
+
+	s = smalloc(READSTR);
+	if(waserror()){
+		free(s);
+		nexterror();
+	}
+	p = s; e = s+READSTR;
+	p = seprint(p, e, "type %s\n", "amdpstate");
+	p = seprint(p, e, "boostavail %s\n",
+		(cpuidCPB) ? "yes" : "no");
+	/* FIXME check bits in PCI config space too; requires ECAM */   
+
+	if(hwcrvalid){
+		CpbDis = ((ulong)hwcr & (1 << 25));
+		p = seprint(p, e, "boost %s\n",
+			CpbDis ? "disabled" : "enabled");
+	}else{
+		p = seprint(p, e, "ERROR MSRC001_0015 (HWCR) unreadable\n");
+	}
+
+	if(limmsrvalid){
+		PstateMaxVal = (limmsr >> 4) & 15;
+		CurPstateLimit = limmsr & 15;
+		p = seprint(p, e, "pstaterange %d %d\n", PstateMaxVal, CurPstateLimit);
+	}else{
+		PstateMaxVal = -1;
+		CurPstateLimit = 0;
+		p = seprint(p, e, "ERROR MSRC001_0061 (PState limits) unreadable\n");
+	}
+
+	/* TODO dump more data */   
+	USED(PstateMaxVal);
+	USED(CurPstateLimit);
+
+	USED(p);
+	n = readstr(offset, a, n, s);
+	poperror();
+	free(s);
+
+	return n;
+}
+
+static long
+amdpstatectlwrite(Chan *, void *a, long n, vlong off)
 {
 	Cmdbuf *cb;
 
@@ -93,5 +200,5 @@
 cpufreqlink(void)
 {
 	if(amdpstatecpufreqok())
-		addarchfile("cpufreqctl", 0664, nil, amdpstatectlwrite);
+		addarchfile("cpufreqctl", 0664, amdpstatectlread, amdpstatectlwrite);
 }

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-01-11 21:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-11  3:59 Kernel patches (cpufreqctl, Radeon on amd64, trivia) Robert Ransom
2020-01-11 20:33 ` [9front] " cinap_lenrek
2020-01-11 21:24   ` Robert Ransom

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).