]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/bcm64/archbcm4.c
bcm64: add support for more than 1GB of ram (untested)
[plan9front.git] / sys / src / 9 / bcm64 / archbcm4.c
1 /*
2  * bcm2711 (e.g.raspberry pi 4) 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 "sysreg.h"
13
14 typedef struct Mbox Mbox;
15 typedef struct Mboxes Mboxes;
16
17 #define POWERREGS       (VIRTIO+0x100000)
18
19 Soc soc = {
20         .dramsize       = 0xFC000000,
21         .busdram        = 0xC0000000,
22         .iosize         = 0x03000000,
23         .busio          = 0x7C000000,
24         .physio         = 0xFC000000,
25         .virtio         = VIRTIO2,
26         .armlocal       = 0xFF800000,
27         .pciwin         = 0x0600000000ULL,
28 };
29
30 enum {
31         Wdogfreq        = 65536,
32         Wdogtime        = 10,   /* seconds, ≤ 15 */
33 };
34
35 /*
36  * Power management / watchdog registers
37  */
38 enum {
39         Rstc            = 0x1c>>2,
40                 Password        = 0x5A<<24,
41                 CfgMask         = 0x03<<4,
42                 CfgReset        = 0x02<<4,
43         Rsts            = 0x20>>2,
44         Wdog            = 0x24>>2,
45 };
46
47 /*
48  * Arm local regs for smp
49  */
50 struct Mbox {
51         u32int  doorbell;
52         u32int  mbox1;
53         u32int  mbox2;
54         u32int  startcpu;
55 };
56 struct Mboxes {
57         Mbox    set[4];
58         Mbox    clr[4];
59 };
60
61 enum {
62         Mboxregs        = 0x80,
63 };
64
65 void
66 archreset(void)
67 {
68 }
69
70 void
71 archreboot(void)
72 {
73         u32int *r;
74
75         r = (u32int*)POWERREGS;
76         r[Wdog] = Password | 1;
77         r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
78         coherence();
79         for(;;)
80                 ;
81 }
82
83 void
84 wdogfeed(void)
85 {
86         u32int *r;
87
88         r = (u32int*)POWERREGS;
89         r[Wdog] = Password | (Wdogtime * Wdogfreq);
90         r[Rstc] = Password | (r[Rstc] & ~CfgMask) | CfgReset;
91 }
92
93 void
94 wdogoff(void)
95 {
96         u32int *r;
97
98         r = (u32int*)POWERREGS;
99         r[Rstc] = Password | (r[Rstc] & ~CfgMask);
100 }
101
102
103 char *
104 cputype2name(char *buf, int size)
105 {
106         u32int r, part;
107         char *p;
108
109         r = sysrd(MIDR_EL1);
110         part = (r >> 4) & 0xFFF;
111         switch(part){
112         case 0xc07:
113                 p = seprint(buf, buf + size, "Cortex-A7");
114                 break;
115         case 0xd03:
116                 p = seprint(buf, buf + size, "Cortex-A53");
117                 break;
118         case 0xd08:
119                 p = seprint(buf, buf + size, "Cortex-A72");
120                 break;
121         default:
122                 p = seprint(buf, buf + size, "Unknown-%#x", part);
123                 break;
124         }
125         seprint(p, buf + size, " r%udp%ud", (r >> 20) & 0xF, r & 0xF);
126         return buf;
127 }
128
129 void
130 cpuidprint(void)
131 {
132         char name[64];
133
134         cputype2name(name, sizeof name);
135         iprint("cpu%d: %dMHz ARM %s\n", m->machno, m->cpumhz, name);
136 }
137
138 int
139 getncpus(void)
140 {
141         int n, max;
142         char *p;
143
144         n = 4;
145         if(n > MAXMACH)
146                 n = MAXMACH;
147         p = getconf("*ncpu");
148         if(p && (max = atoi(p)) > 0 && n > max)
149                 n = max;
150         return n;
151 }
152
153 void
154 mboxclear(uint cpu)
155 {
156         Mboxes *mb;
157
158         mb = (Mboxes*)(ARMLOCAL + Mboxregs);
159         mb->clr[cpu].mbox1 = 1;
160 }
161
162 void
163 wakecpu(uint cpu)
164 {
165         Mboxes *mb;
166
167         mb = (Mboxes*)(ARMLOCAL + Mboxregs);
168         mb->set[cpu].mbox1 = 1;
169 }
170
171 void
172 archbcm4link(void)
173 {
174         // addclock0link(wdogfeed, HZ);
175 }