changelog shortlog tags branches changeset file revisions annotate raw help

Mercurial > hg > plan9front / sys/src/9/bcm64/archbcm4.c

revision 7319: f3966b67adc9
child 7332: 6c7fe2e27770
     1.1new file mode 100644
     1.2--- /dev/null
     1.3+++ b/sys/src/9/bcm64/archbcm4.c
     1.4@@ -0,0 +1,175 @@
     1.5+/*
     1.6+ * bcm2711 (e.g.raspberry pi 4) architecture-specific stuff
     1.7+ */
     1.8+
     1.9+#include "u.h"
    1.10+#include "../port/lib.h"
    1.11+#include "mem.h"
    1.12+#include "dat.h"
    1.13+#include "fns.h"
    1.14+#include "../port/error.h"
    1.15+#include "io.h"
    1.16+#include "sysreg.h"
    1.17+
    1.18+typedef struct Mbox Mbox;
    1.19+typedef struct Mboxes Mboxes;
    1.20+
    1.21+#define	POWERREGS	(VIRTIO+0x100000)
    1.22+
    1.23+Soc soc = {
    1.24+	.dramsize	= 0x40000000,
    1.25+	.busdram	= 0xC0000000,
    1.26+	.iosize		= 0x03000000,
    1.27+	.busio		= 0x7C000000,
    1.28+	.physio		= 0xFC000000,
    1.29+	.virtio		= VIRTIO2,
    1.30+	.armlocal	= 0xFF800000,
    1.31+	.pciwin		= 0x0600000000ULL,
    1.32+};
    1.33+
    1.34+enum {
    1.35+	Wdogfreq	= 65536,
    1.36+	Wdogtime	= 10,	/* seconds, ≤ 15 */
    1.37+};
    1.38+
    1.39+/*
    1.40+ * Power management / watchdog registers
    1.41+ */
    1.42+enum {
    1.43+	Rstc		= 0x1c>>2,
    1.44+		Password	= 0x5A<<24,
    1.45+		CfgMask		= 0x03<<4,
    1.46+		CfgReset	= 0x02<<4,
    1.47+	Rsts		= 0x20>>2,
    1.48+	Wdog		= 0x24>>2,
    1.49+};
    1.50+
    1.51+/*
    1.52+ * Arm local regs for smp
    1.53+ */
    1.54+struct Mbox {
    1.55+	u32int	doorbell;
    1.56+	u32int	mbox1;
    1.57+	u32int	mbox2;
    1.58+	u32int	startcpu;
    1.59+};
    1.60+struct Mboxes {
    1.61+	Mbox	set[4];
    1.62+	Mbox	clr[4];
    1.63+};
    1.64+
    1.65+enum {
    1.66+	Mboxregs	= 0x80,
    1.67+};
    1.68+
    1.69+void
    1.70+archreset(void)
    1.71+{
    1.72+}
    1.73+
    1.74+void
    1.75+archreboot(void)
    1.76+{
    1.77+	u32int *r;
    1.78+
    1.79+	r = (u32int*)POWERREGS;
    1.80+	r[Wdog] = Password | 1;
    1.81+	r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
    1.82+	coherence();
    1.83+	for(;;)
    1.84+		;
    1.85+}
    1.86+
    1.87+void
    1.88+wdogfeed(void)
    1.89+{
    1.90+	u32int *r;
    1.91+
    1.92+	r = (u32int*)POWERREGS;
    1.93+	r[Wdog] = Password | (Wdogtime * Wdogfreq);
    1.94+	r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
    1.95+}
    1.96+
    1.97+void
    1.98+wdogoff(void)
    1.99+{
   1.100+	u32int *r;
   1.101+
   1.102+	r = (u32int*)POWERREGS;
   1.103+	r[Rstc] = Password | (r[Rstc] & ~CfgMask);
   1.104+}
   1.105+
   1.106+
   1.107+char *
   1.108+cputype2name(char *buf, int size)
   1.109+{
   1.110+	u32int r, part;
   1.111+	char *p;
   1.112+
   1.113+	r = sysrd(MIDR_EL1);
   1.114+	part = (r >> 4) & 0xFFF;
   1.115+	switch(part){
   1.116+	case 0xc07:
   1.117+		p = seprint(buf, buf + size, "Cortex-A7");
   1.118+		break;
   1.119+	case 0xd03:
   1.120+		p = seprint(buf, buf + size, "Cortex-A53");
   1.121+		break;
   1.122+	case 0xd08:
   1.123+		p = seprint(buf, buf + size, "Cortex-A72");
   1.124+		break;
   1.125+	default:
   1.126+		p = seprint(buf, buf + size, "Unknown-%#x", part);
   1.127+		break;
   1.128+	}
   1.129+	seprint(p, buf + size, " r%udp%ud", (r >> 20) & 0xF, r & 0xF);
   1.130+	return buf;
   1.131+}
   1.132+
   1.133+void
   1.134+cpuidprint(void)
   1.135+{
   1.136+	char name[64];
   1.137+
   1.138+	cputype2name(name, sizeof name);
   1.139+	iprint("cpu%d: %dMHz ARM %s\n", m->machno, m->cpumhz, name);
   1.140+}
   1.141+
   1.142+int
   1.143+getncpus(void)
   1.144+{
   1.145+	int n, max;
   1.146+	char *p;
   1.147+
   1.148+	n = 4;
   1.149+	if(n > MAXMACH)
   1.150+		n = MAXMACH;
   1.151+	p = getconf("*ncpu");
   1.152+	if(p && (max = atoi(p)) > 0 && n > max)
   1.153+		n = max;
   1.154+	return n;
   1.155+}
   1.156+
   1.157+void
   1.158+mboxclear(uint cpu)
   1.159+{
   1.160+	Mboxes *mb;
   1.161+
   1.162+	mb = (Mboxes*)(ARMLOCAL + Mboxregs);
   1.163+	mb->clr[cpu].mbox1 = 1;
   1.164+}
   1.165+
   1.166+void
   1.167+wakecpu(uint cpu)
   1.168+{
   1.169+	Mboxes *mb;
   1.170+
   1.171+	mb = (Mboxes*)(ARMLOCAL + Mboxregs);
   1.172+	mb->set[cpu].mbox1 = 1;
   1.173+}
   1.174+
   1.175+void
   1.176+archbcm4link(void)
   1.177+{
   1.178+	// addclock0link(wdogfeed, HZ);
   1.179+}