xref: /plan9-contrib/sys/src/9/bcm/archbcm.c (revision 5c47fe09a0cc86dfb02c0ea4a2b6aec7eda2361f)
1 /*
2  * bcm2835 (e.g. original raspberry pi) architecture-specific stuff
3  */
4 
5 #include "u.h"
6 #include "../port/lib.h"
7 #include "mem.h"
8 #include "dat.h"
9 #include "fns.h"
10 #include "../port/error.h"
11 #include "io.h"
12 #include "arm.h"
13 
14 #include "../port/netif.h"
15 #include "etherif.h"
16 
17 #define	POWERREGS	(VIRTIO+0x100000)
18 
19 Soc soc = {
20 	.dramsize	= 512*MiB,
21 	.physio		= 0x20000000,
22 	.busdram	= 0x40000000,
23 	.busio		= 0x7E000000,
24 	.armlocal	= 0,
25 	.l1ptedramattrs = Cached | Buffered,
26 	.l2ptedramattrs = Cached | Buffered,
27 };
28 
29 enum {
30 	Wdogfreq	= 65536,
31 	Wdogtime	= 10,	/* seconds, ≤ 15 */
32 };
33 
34 /*
35  * Power management / watchdog registers
36  */
37 enum {
38 	Rstc		= 0x1c>>2,
39 		Password	= 0x5A<<24,
40 		CfgMask		= 0x03<<4,
41 		CfgReset	= 0x02<<4,
42 	Rsts		= 0x20>>2,
43 	Wdog		= 0x24>>2,
44 };
45 
46 void
archreset(void)47 archreset(void)
48 {
49 	fpon();
50 }
51 
52 void
archreboot(void)53 archreboot(void)
54 {
55 	u32int *r;
56 
57 	r = (u32int*)POWERREGS;
58 	r[Wdog] = Password | 1;
59 	r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
60 	coherence();
61 	for(;;)
62 		;
63 }
64 
65 void
wdogfeed(void)66 wdogfeed(void)
67 {
68 	u32int *r;
69 
70 	r = (u32int*)POWERREGS;
71 	r[Wdog] = Password | (Wdogtime * Wdogfreq);
72 	r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
73 }
74 
75 void
wdogoff(void)76 wdogoff(void)
77 {
78 	u32int *r;
79 
80 	r = (u32int*)POWERREGS;
81 	r[Rstc] = Password | (r[Rstc] & ~CfgMask);
82 }
83 
84 char *
cputype2name(char * buf,int size)85 cputype2name(char *buf, int size)
86 {
87 	seprint(buf, buf + size, "1176JZF-S");
88 	return buf;
89 }
90 
91 void
cpuidprint(void)92 cpuidprint(void)
93 {
94 	char name[64];
95 
96 	cputype2name(name, sizeof name);
97 	delay(50);				/* let uart catch up */
98 	print("cpu%d: %dMHz ARM %s\n", m->machno, m->cpumhz, name);
99 }
100 
101 int
getncpus(void)102 getncpus(void)
103 {
104 	return 1;
105 }
106 
107 int
startcpus(uint)108 startcpus(uint)
109 {
110 	return 1;
111 }
112 
113 void
archbcmlink(void)114 archbcmlink(void)
115 {
116 	addclock0link(wdogfeed, HZ);
117 }
118 
119 int
archether(unsigned ctlrno,Ether * ether)120 archether(unsigned ctlrno, Ether *ether)
121 {
122 	ether->type = "usb";
123 	ether->ctlrno = ctlrno;
124 	ether->irq = -1;
125 	ether->nopt = 0;
126 	return 1;
127 }
128 
129 int
l2ap(int ap)130 l2ap(int ap)
131 {
132 	return (AP(3, (ap))|AP(2, (ap))|AP(1, (ap))|AP(0, (ap)));
133 }
134 
135 /*
136  * atomic ops
137  * make sure that we don't drag in the C library versions
138  */
139 
140 long
ainc(long * p)141 ainc(long *p)
142 {
143 	int s, v;
144 
145 	s = splhi();
146 	v = ++*p;
147 	splx(s);
148 	return v;
149 }
150 
151 long
adec(long * p)152 adec(long *p)
153 {
154 	int s, v;
155 
156 	s = splhi();
157 	v = --*p;
158 	splx(s);
159 	return v;
160 }
161 
162 int
cas32(void * addr,u32int old,u32int new)163 cas32(void* addr, u32int old, u32int new)
164 {
165 	int r, s;
166 
167 	s = splhi();
168 	if(r = (*(u32int*)addr == old))
169 		*(u32int*)addr = new;
170 	splx(s);
171 	if (r)
172 		coherence();
173 	return r;
174 }
175 
176 int
cmpswap(long * addr,long old,long new)177 cmpswap(long *addr, long old, long new)
178 {
179 	return cas32(addr, old, new);
180 }
181 
182