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