changelog shortlog tags branches changeset file revisions annotate raw help

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

revision 7199: ba62683c0e2d
child 7235: b1dc95374307
     1.1new file mode 100644
     1.2--- /dev/null
     1.3+++ b/sys/src/9/bcm64/archbcm3.c
     1.4@@ -0,0 +1,168 @@
     1.5+/*
     1.6+ * bcm2836 (e.g.raspberry pi 3) 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	= GiB,
    1.25+	.physio		= 0x3F000000,
    1.26+	.busdram	= 0xC0000000,
    1.27+	.busio		= 0x7E000000,
    1.28+	.armlocal	= 0x40000000,
    1.29+};
    1.30+
    1.31+enum {
    1.32+	Wdogfreq	= 65536,
    1.33+	Wdogtime	= 10,	/* seconds, ≤ 15 */
    1.34+};
    1.35+
    1.36+/*
    1.37+ * Power management / watchdog registers
    1.38+ */
    1.39+enum {
    1.40+	Rstc		= 0x1c>>2,
    1.41+		Password	= 0x5A<<24,
    1.42+		CfgMask		= 0x03<<4,
    1.43+		CfgReset	= 0x02<<4,
    1.44+	Rsts		= 0x20>>2,
    1.45+	Wdog		= 0x24>>2,
    1.46+};
    1.47+
    1.48+/*
    1.49+ * Arm local regs for smp
    1.50+ */
    1.51+struct Mbox {
    1.52+	u32int	doorbell;
    1.53+	u32int	mbox1;
    1.54+	u32int	mbox2;
    1.55+	u32int	startcpu;
    1.56+};
    1.57+struct Mboxes {
    1.58+	Mbox	set[4];
    1.59+	Mbox	clr[4];
    1.60+};
    1.61+
    1.62+enum {
    1.63+	Mboxregs	= 0x80,
    1.64+};
    1.65+
    1.66+void
    1.67+archreset(void)
    1.68+{
    1.69+}
    1.70+
    1.71+void
    1.72+archreboot(void)
    1.73+{
    1.74+	u32int *r;
    1.75+
    1.76+	r = (u32int*)POWERREGS;
    1.77+	r[Wdog] = Password | 1;
    1.78+	r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
    1.79+	coherence();
    1.80+	for(;;)
    1.81+		;
    1.82+}
    1.83+
    1.84+void
    1.85+wdogfeed(void)
    1.86+{
    1.87+	u32int *r;
    1.88+
    1.89+	r = (u32int*)POWERREGS;
    1.90+	r[Wdog] = Password | (Wdogtime * Wdogfreq);
    1.91+	r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
    1.92+}
    1.93+
    1.94+void
    1.95+wdogoff(void)
    1.96+{
    1.97+	u32int *r;
    1.98+
    1.99+	r = (u32int*)POWERREGS;
   1.100+	r[Rstc] = Password | (r[Rstc] & ~CfgMask);
   1.101+}
   1.102+
   1.103+
   1.104+char *
   1.105+cputype2name(char *buf, int size)
   1.106+{
   1.107+	u32int r, part;
   1.108+	char *p;
   1.109+
   1.110+	r = sysrd(MIDR_EL1);
   1.111+	part = (r >> 4) & 0xFFF;
   1.112+	switch(part){
   1.113+	case 0xc07:
   1.114+		p = seprint(buf, buf + size, "Cortex-A7");
   1.115+		break;
   1.116+	case 0xd03:
   1.117+		p = seprint(buf, buf + size, "Cortex-A53");
   1.118+		break;
   1.119+	default:
   1.120+		p = seprint(buf, buf + size, "Unknown-%#x", part);
   1.121+		break;
   1.122+	}
   1.123+	seprint(p, buf + size, " r%udp%ud", (r >> 20) & 0xF, r & 0xF);
   1.124+	return buf;
   1.125+}
   1.126+
   1.127+void
   1.128+cpuidprint(void)
   1.129+{
   1.130+	char name[64];
   1.131+
   1.132+	cputype2name(name, sizeof name);
   1.133+	iprint("cpu%d: %dMHz ARM %s\n", m->machno, m->cpumhz, name);
   1.134+}
   1.135+
   1.136+int
   1.137+getncpus(void)
   1.138+{
   1.139+	int n, max;
   1.140+	char *p;
   1.141+	n = 4;
   1.142+	if(n > MAXMACH)
   1.143+		n = MAXMACH;
   1.144+	p = getconf("*ncpu");
   1.145+	if(p && (max = atoi(p)) > 0 && n > max)
   1.146+		n = max;
   1.147+	return n;
   1.148+}
   1.149+
   1.150+void
   1.151+mboxclear(uint cpu)
   1.152+{
   1.153+	Mboxes *mb;
   1.154+
   1.155+	mb = (Mboxes*)(ARMLOCAL + Mboxregs);
   1.156+	mb->clr[cpu].mbox1 = 1;
   1.157+}
   1.158+
   1.159+void
   1.160+wakecpu(uint cpu)
   1.161+{
   1.162+	Mboxes *mb;
   1.163+
   1.164+	mb = (Mboxes*)(ARMLOCAL + Mboxregs);
   1.165+	mb->set[cpu].mbox1 = 1;
   1.166+}
   1.167+
   1.168+void
   1.169+archbcm3link(void)
   1.170+{
   1.171+//	addclock0link(wdogfeed, HZ);
   1.172+}