-
Notifications
You must be signed in to change notification settings - Fork 146
Expand file tree
/
Copy pathraspi3.c
More file actions
370 lines (320 loc) · 9.48 KB
/
raspi3.c
File metadata and controls
370 lines (320 loc) · 9.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
/* raspi3.c
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <target.h>
#include "image.h"
#include "printf.h"
#ifndef ARCH_AARCH64
# error "wolfBoot raspi3 HAL: wrong architecture selected. Please compile with ARCH=AARCH64."
#endif
#define TEST_ENCRYPT
#if defined(DEBUG_UART)
#define PRINTF_ENABLED
#endif
#define CORTEXA53_0_CPU_CLK_FREQ_HZ 1099989014
#define CORTEXA53_0_TIMESTAMP_CLK_FREQ 99998999
#define MMIO_BASE 0x3F000000
#define GPIO_BASE MMIO_BASE + 0x200000
#define GPFSEL1 ((volatile unsigned int*)(GPIO_BASE+0x04))
#define GPPUD ((volatile unsigned int*)(GPIO_BASE+0x94))
#define GPPUDCLK0 ((volatile unsigned int*)(GPIO_BASE+0x98))
/* PL011 UART registers */
#define UART0_BASE GPIO_BASE + 0x1000
#define UART0_DR ((volatile unsigned int*)(UART0_BASE+0x00))
#define UART0_FR ((volatile unsigned int*)(UART0_BASE+0x18))
#define UART0_IBRD ((volatile unsigned int*)(UART0_BASE+0x24))
#define UART0_FBRD ((volatile unsigned int*)(UART0_BASE+0x28))
#define UART0_LCRH ((volatile unsigned int*)(UART0_BASE+0x2C))
#define UART0_CR ((volatile unsigned int*)(UART0_BASE+0x30))
#define UART0_IMSC ((volatile unsigned int*)(UART0_BASE+0x38))
#define UART0_ICR ((volatile unsigned int*)(UART0_BASE+0x44))
/* mail box message buffer */
volatile unsigned int __attribute__((aligned(16))) mbox[36];
#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
#define MBOX_RESPONSE 0x80000000
#define MBOX_FULL 0x80000000
#define MBOX_EMPTY 0x40000000
#define MBOX_REQUEST 0
/* channels */
#define MBOX_CH_POWER 0
#define MBOX_CH_FB 1
#define MBOX_CH_VUART 2
#define MBOX_CH_VCHIQ 3
#define MBOX_CH_LEDS 4
#define MBOX_CH_BTNS 5
#define MBOX_CH_TOUCH 6
#define MBOX_CH_COUNT 7
#define MBOX_CH_PROP 8
/* tags */
#define MBOX_TAG_GETBRDVERSION 0x10002
#define MBOX_TAG_GETSERIAL 0x10004
#define MBOX_TAG_GET_CLOCK_RATE 0x30002
#define MBOX_TAG_SETCLKRATE 0x38002
#define MBOX_TAG_LAST 0
/* Fixed addresses */
extern void *kernel_addr, *update_addr, *dts_addr;
/* Loop <delay> times */
static inline void delay(int32_t count)
{
register unsigned int c;
c = count;
while (c--) {
asm volatile("nop");
}
}
#if defined(DEBUG_UART)
/**
* write message to mailbox
*/
static void mailbox_write(uint8_t chan)
{
uint32_t ch = (((uint32_t)((unsigned long)&mbox) & ~0xf)
| (chan & 0xf));
/* wait until mail box becomes ready to write */
while ((*MBOX_STATUS & MBOX_FULL) != 0) { }
/* write the address of the message to mail-box channel */
*MBOX_WRITE = ch;
}
/**
* read message from mailbox
*/
static int mailbox_read(uint8_t chan)
{
uint32_t ch = (((uint32_t)((unsigned long)&mbox) & ~0xf)
| (chan & 0xf));
/* now wait for the response */
while(1) {
while ((*MBOX_STATUS & MBOX_EMPTY) != 0) { }
if(ch == *MBOX_READ)
/* is it a valid successful response */
return mbox[1] == MBOX_RESPONSE;
}
return 0;
}
/* UART functions for Raspberry Pi 3 UART */
void uart_tx(char c)
{
/* wait until uart channel is ready to send */
do{
asm volatile("nop");
} while(*UART0_FR & 0x20);
*UART0_DR = c;
}
char uart_read(void)
{
char c;
/* wait until data is comming */
do{
asm volatile("nop");
} while(*UART0_FR & 0x10);
/* read it and return */
c = (char)(*UART0_DR);
return c;
}
/**
* Send string to UART
*/
void uart_write(const char* buf, uint32_t sz) {
uint32_t len = sz;
while (len > 0 && *buf) {
uart_tx(*buf++);
len--;
}
}
void uart_init()
{
register unsigned int c;
/* initialize UART. turn off UART 0*/
*UART0_CR = 0;
/* set up clock for consistent divisor values */
mbox[0] = 9 * 4;
mbox[1] = MBOX_REQUEST;
/* tag for setting clock rate */
mbox[2] = MBOX_TAG_SETCLKRATE;
mbox[3] = 12;
mbox[4] = 8;
/* specify UART clock channel */
mbox[5] = 2;
/* UART clock rate in hz(4Mhz)*/
mbox[6] = 4000000;
/* not use turbo */
mbox[7] = 0;
mbox[8] = MBOX_TAG_LAST;
mailbox_write(MBOX_CH_PROP);
mailbox_read(MBOX_CH_PROP);
/* disable pull up/down for all GPIO pins */
*GPPUD = 0;
delay(150);
/* Disable pull up/down for pin 14 and 15 */
*GPPUDCLK0 = (1<<14)|(1<<15);
delay(150);
/* flush GPIO setting to make it take effect */
*GPPUDCLK0 = 0;
/* clear pending interrupts */
*UART0_ICR = 0x7FF;
/* select 115200 baud rate */
/* divider = 4000000 / (16 * 115200) = 2.17 = ~2 */
*UART0_IBRD = 2;
/* Fractional part register = (.17013 * 64) + 0.5 = 11.38 = ~11 */
*UART0_FBRD = 0xB;
/* Enable fifo, 8bit data transmission (1 stop bit, no parity) */
*UART0_LCRH = (1 << 4) | (1 << 5) | (1 << 6);
/* enable UART0 transfer & receive*/
*UART0_CR = (1 << 0) | (1 << 8) | (1 << 9);
}
#endif
void* hal_get_primary_address(void)
{
return (void*)&kernel_addr;
}
void* hal_get_update_address(void)
{
return (void*)&update_addr;
}
void* hal_get_dts_address(void)
{
return (void*)&dts_addr;
}
#ifdef EXT_FLASH
int ext_flash_read(unsigned long address, uint8_t *data, int len)
{
XMEMCPY(data, (void *)address, len);
return len;
}
int ext_flash_erase(unsigned long address, int len)
{
XMEMSET((void *)address, 0xFF, len);
return len;
}
int ext_flash_write(unsigned long address, const uint8_t *data, int len)
{
XMEMCPY((void *)address, data, len);
return len;
}
void ext_flash_lock(void)
{
}
void ext_flash_unlock(void)
{
}
#endif
void* hal_get_dts_update_address(void)
{
return NULL; /* Not yet supported */
}
#if defined(DISPLAY_CLOCKS)
static uint32_t getclocks(uint8_t cid)
{
/* Retrive clock rate */
/* length of the message */
mbox[0] = 8 * 4;
mbox[1] = MBOX_REQUEST;
/* tag for get board version */
mbox[2] = MBOX_TAG_GET_CLOCK_RATE;
/* buffer size */
mbox[3] = 8;
mbox[4] = 8;
/* clock id CORE*/
mbox[5] = cid;
/* clock frequency */
mbox[6] = 0;
mbox[7] = MBOX_TAG_LAST;
mailbox_write(MBOX_CH_PROP);
if (mailbox_read(MBOX_CH_PROP)) {
return mbox[6];
}
else {
return 0;
}
}
#endif /* DISPLAY clocks */
/* public HAL functions */
void hal_init(void)
{
#if defined(TEST_ENCRYPT) && defined (EXT_ENCRYPTED)
char enc_key[] = "0123456789abcdef0123456789abcdef"
"0123456789abcdef";
wolfBoot_set_encrypt_key((uint8_t *)enc_key,(uint8_t *)(enc_key + 32));
#endif
#if defined(DEBUG_UART)
uart_init();
/* length of the message */
mbox[0] = 7 * 4;
mbox[1] = MBOX_REQUEST;
/* tag for get board version */
mbox[2] = MBOX_TAG_GETBRDVERSION;
/* buffer size */
mbox[3] = 4;
mbox[4] = 0;
mbox[5] = 0;
mbox[6] = MBOX_TAG_LAST;
/* send the message to the GPU */
mailbox_write(MBOX_CH_PROP);
if (mailbox_read(MBOX_CH_PROP)) {
wolfBoot_printf("My board version is: 0x%08x", mbox[5]);
wolfBoot_printf("\n");
} else {
wolfBoot_printf("Unable to query board version!\n");
}
#if defined(DISPLAY_CLOCKS) && defined(PRINTF_ENABLED)
/* Get clocks */
wolfBoot_printf("\n EMMC clock : %d Hz", getclocks(1));
wolfBoot_printf("\n UART clock : %d Hz", getclocks(2));
wolfBoot_printf("\n ARM clock : %d Hz", getclocks(3));
wolfBoot_printf("\n CORE clock : %d Hz", getclocks(4));
wolfBoot_printf("\n V3D clock : %d Hz", getclocks(5));
wolfBoot_printf("\n H264 clock : %d Hz", getclocks(6));
wolfBoot_printf("\n ISP clock : %d Hz", getclocks(7));
wolfBoot_printf("\n SDRAM clock : %d Hz", getclocks(8));
wolfBoot_printf("\n PIXEL clock : %d Hz", getclocks(9));
wolfBoot_printf("\n PWM clock : %d Hz", getclocks(10));
wolfBoot_printf("\n HEVC clock : %d Hz", getclocks(11));
wolfBoot_printf("\n EMMC2 clock : %d Hz", getclocks(12));
wolfBoot_printf("\n M2MC clock : %d Hz", getclocks(13));
wolfBoot_printf("\n PIXEL_BVB clock : %d Hz\n", getclocks(14));
#endif
#endif
}
void hal_prepare_boot(void)
{
}
int RAMFUNCTION hal_flash_write(uintptr_t address, const uint8_t *data, int len)
{
return 0;
}
void RAMFUNCTION hal_flash_unlock(void)
{
}
void RAMFUNCTION hal_flash_lock(void)
{
}
int RAMFUNCTION hal_flash_erase(uintptr_t address, int len)
{
return 0;
}