15d9de2d3SDavid du Colombier /*
2*5c47fe09SDavid du Colombier * bcm2835 (e.g. original raspberry pi) architecture-specific stuff
35d9de2d3SDavid du Colombier */
45d9de2d3SDavid du Colombier
55d9de2d3SDavid du Colombier #include "u.h"
65d9de2d3SDavid du Colombier #include "../port/lib.h"
75d9de2d3SDavid du Colombier #include "mem.h"
85d9de2d3SDavid du Colombier #include "dat.h"
95d9de2d3SDavid du Colombier #include "fns.h"
105d9de2d3SDavid du Colombier #include "../port/error.h"
115d9de2d3SDavid du Colombier #include "io.h"
125d9de2d3SDavid du Colombier #include "arm.h"
135d9de2d3SDavid du Colombier
145d9de2d3SDavid du Colombier #include "../port/netif.h"
155d9de2d3SDavid du Colombier #include "etherif.h"
165d9de2d3SDavid du Colombier
175d9de2d3SDavid du Colombier #define POWERREGS (VIRTIO+0x100000)
185d9de2d3SDavid du Colombier
19*5c47fe09SDavid du Colombier Soc soc = {
20*5c47fe09SDavid du Colombier .dramsize = 512*MiB,
21*5c47fe09SDavid du Colombier .physio = 0x20000000,
22*5c47fe09SDavid du Colombier .busdram = 0x40000000,
23*5c47fe09SDavid du Colombier .busio = 0x7E000000,
24*5c47fe09SDavid du Colombier .armlocal = 0,
25*5c47fe09SDavid du Colombier .l1ptedramattrs = Cached | Buffered,
26*5c47fe09SDavid du Colombier .l2ptedramattrs = Cached | Buffered,
27*5c47fe09SDavid du Colombier };
28*5c47fe09SDavid du Colombier
295d9de2d3SDavid du Colombier enum {
305d9de2d3SDavid du Colombier Wdogfreq = 65536,
31*5c47fe09SDavid du Colombier Wdogtime = 10, /* seconds, ≤ 15 */
325d9de2d3SDavid du Colombier };
335d9de2d3SDavid du Colombier
345d9de2d3SDavid du Colombier /*
355d9de2d3SDavid du Colombier * Power management / watchdog registers
365d9de2d3SDavid du Colombier */
375d9de2d3SDavid du Colombier enum {
385d9de2d3SDavid du Colombier Rstc = 0x1c>>2,
395d9de2d3SDavid du Colombier Password = 0x5A<<24,
405d9de2d3SDavid du Colombier CfgMask = 0x03<<4,
415d9de2d3SDavid du Colombier CfgReset = 0x02<<4,
42da091934SDavid du Colombier Rsts = 0x20>>2,
435d9de2d3SDavid du Colombier Wdog = 0x24>>2,
445d9de2d3SDavid du Colombier };
455d9de2d3SDavid du Colombier
465d9de2d3SDavid du Colombier void
archreset(void)475d9de2d3SDavid du Colombier archreset(void)
485d9de2d3SDavid du Colombier {
495d9de2d3SDavid du Colombier fpon();
505d9de2d3SDavid du Colombier }
515d9de2d3SDavid du Colombier
525d9de2d3SDavid du Colombier void
archreboot(void)535d9de2d3SDavid du Colombier archreboot(void)
545d9de2d3SDavid du Colombier {
555d9de2d3SDavid du Colombier u32int *r;
565d9de2d3SDavid du Colombier
575d9de2d3SDavid du Colombier r = (u32int*)POWERREGS;
585d9de2d3SDavid du Colombier r[Wdog] = Password | 1;
595d9de2d3SDavid du Colombier r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
605d9de2d3SDavid du Colombier coherence();
615d9de2d3SDavid du Colombier for(;;)
625d9de2d3SDavid du Colombier ;
635d9de2d3SDavid du Colombier }
645d9de2d3SDavid du Colombier
65*5c47fe09SDavid du Colombier void
wdogfeed(void)66da091934SDavid du Colombier wdogfeed(void)
67da091934SDavid du Colombier {
68da091934SDavid du Colombier u32int *r;
69da091934SDavid du Colombier
70da091934SDavid du Colombier r = (u32int*)POWERREGS;
71da091934SDavid du Colombier r[Wdog] = Password | (Wdogtime * Wdogfreq);
72da091934SDavid du Colombier r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
73da091934SDavid du Colombier }
74da091934SDavid du Colombier
75da091934SDavid du Colombier void
wdogoff(void)76da091934SDavid du Colombier wdogoff(void)
77da091934SDavid du Colombier {
78da091934SDavid du Colombier u32int *r;
79da091934SDavid du Colombier
80da091934SDavid du Colombier r = (u32int*)POWERREGS;
81da091934SDavid du Colombier r[Rstc] = Password | (r[Rstc] & ~CfgMask);
82da091934SDavid du Colombier }
83da091934SDavid du Colombier
84*5c47fe09SDavid du Colombier char *
cputype2name(char * buf,int size)85*5c47fe09SDavid du Colombier cputype2name(char *buf, int size)
86*5c47fe09SDavid du Colombier {
87*5c47fe09SDavid du Colombier seprint(buf, buf + size, "1176JZF-S");
88*5c47fe09SDavid du Colombier return buf;
89*5c47fe09SDavid du Colombier }
90*5c47fe09SDavid du Colombier
915d9de2d3SDavid du Colombier void
cpuidprint(void)925d9de2d3SDavid du Colombier cpuidprint(void)
935d9de2d3SDavid du Colombier {
94*5c47fe09SDavid du Colombier char name[64];
95*5c47fe09SDavid du Colombier
96*5c47fe09SDavid du Colombier cputype2name(name, sizeof name);
97*5c47fe09SDavid du Colombier delay(50); /* let uart catch up */
98*5c47fe09SDavid du Colombier print("cpu%d: %dMHz ARM %s\n", m->machno, m->cpumhz, name);
99*5c47fe09SDavid du Colombier }
100*5c47fe09SDavid du Colombier
101*5c47fe09SDavid du Colombier int
getncpus(void)102*5c47fe09SDavid du Colombier getncpus(void)
103*5c47fe09SDavid du Colombier {
104*5c47fe09SDavid du Colombier return 1;
105*5c47fe09SDavid du Colombier }
106*5c47fe09SDavid du Colombier
107*5c47fe09SDavid du Colombier int
startcpus(uint)108*5c47fe09SDavid du Colombier startcpus(uint)
109*5c47fe09SDavid du Colombier {
110*5c47fe09SDavid du Colombier return 1;
1115d9de2d3SDavid du Colombier }
1125d9de2d3SDavid du Colombier
1135d9de2d3SDavid du Colombier void
archbcmlink(void)1145d9de2d3SDavid du Colombier archbcmlink(void)
1155d9de2d3SDavid du Colombier {
116da091934SDavid du Colombier addclock0link(wdogfeed, HZ);
1175d9de2d3SDavid du Colombier }
1185d9de2d3SDavid du Colombier
1195d9de2d3SDavid du Colombier int
archether(unsigned ctlrno,Ether * ether)1205d9de2d3SDavid du Colombier archether(unsigned ctlrno, Ether *ether)
1215d9de2d3SDavid du Colombier {
1225d9de2d3SDavid du Colombier ether->type = "usb";
1235d9de2d3SDavid du Colombier ether->ctlrno = ctlrno;
1245d9de2d3SDavid du Colombier ether->irq = -1;
1255d9de2d3SDavid du Colombier ether->nopt = 0;
1265d9de2d3SDavid du Colombier return 1;
1275d9de2d3SDavid du Colombier }
128*5c47fe09SDavid du Colombier
129*5c47fe09SDavid du Colombier int
l2ap(int ap)130*5c47fe09SDavid du Colombier l2ap(int ap)
131*5c47fe09SDavid du Colombier {
132*5c47fe09SDavid du Colombier return (AP(3, (ap))|AP(2, (ap))|AP(1, (ap))|AP(0, (ap)));
133*5c47fe09SDavid du Colombier }
134*5c47fe09SDavid du Colombier
135*5c47fe09SDavid du Colombier /*
136*5c47fe09SDavid du Colombier * atomic ops
137*5c47fe09SDavid du Colombier * make sure that we don't drag in the C library versions
138*5c47fe09SDavid du Colombier */
139*5c47fe09SDavid du Colombier
140*5c47fe09SDavid du Colombier long
ainc(long * p)141*5c47fe09SDavid du Colombier ainc(long *p)
142*5c47fe09SDavid du Colombier {
143*5c47fe09SDavid du Colombier int s, v;
144*5c47fe09SDavid du Colombier
145*5c47fe09SDavid du Colombier s = splhi();
146*5c47fe09SDavid du Colombier v = ++*p;
147*5c47fe09SDavid du Colombier splx(s);
148*5c47fe09SDavid du Colombier return v;
149*5c47fe09SDavid du Colombier }
150*5c47fe09SDavid du Colombier
151*5c47fe09SDavid du Colombier long
adec(long * p)152*5c47fe09SDavid du Colombier adec(long *p)
153*5c47fe09SDavid du Colombier {
154*5c47fe09SDavid du Colombier int s, v;
155*5c47fe09SDavid du Colombier
156*5c47fe09SDavid du Colombier s = splhi();
157*5c47fe09SDavid du Colombier v = --*p;
158*5c47fe09SDavid du Colombier splx(s);
159*5c47fe09SDavid du Colombier return v;
160*5c47fe09SDavid du Colombier }
161*5c47fe09SDavid du Colombier
162*5c47fe09SDavid du Colombier int
cas32(void * addr,u32int old,u32int new)163*5c47fe09SDavid du Colombier cas32(void* addr, u32int old, u32int new)
164*5c47fe09SDavid du Colombier {
165*5c47fe09SDavid du Colombier int r, s;
166*5c47fe09SDavid du Colombier
167*5c47fe09SDavid du Colombier s = splhi();
168*5c47fe09SDavid du Colombier if(r = (*(u32int*)addr == old))
169*5c47fe09SDavid du Colombier *(u32int*)addr = new;
170*5c47fe09SDavid du Colombier splx(s);
171*5c47fe09SDavid du Colombier if (r)
172*5c47fe09SDavid du Colombier coherence();
173*5c47fe09SDavid du Colombier return r;
174*5c47fe09SDavid du Colombier }
175*5c47fe09SDavid du Colombier
176*5c47fe09SDavid du Colombier int
cmpswap(long * addr,long old,long new)177*5c47fe09SDavid du Colombier cmpswap(long *addr, long old, long new)
178*5c47fe09SDavid du Colombier {
179*5c47fe09SDavid du Colombier return cas32(addr, old, new);
1805d9de2d3SDavid du Colombier }
1815d9de2d3SDavid du Colombier
182