Advertisement
Guest User

Untitled

a guest
Jun 5th, 2019
1,496
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.45 KB | None | 0 0
  1. // will lock your board immediate!! please provide your own correct rotpk key before running it!!!
  2.  
  3. typedef __builtin_va_list va_list;
  4. #define va_start(ap, param) __builtin_va_start(ap, param)
  5. #define va_end(ap) __builtin_va_end(ap)
  6. #define va_arg(ap, type) __builtin_va_arg(ap, type)
  7.  
  8.  
  9. void uart0_putc(char c);
  10.  
  11.  
  12. // from u-boot ctyp.h
  13.  
  14. /*
  15. * NOTE! This ctype does not handle EOF like the standard C
  16. * library is required to.
  17. */
  18.  
  19. #define _U 0x01 /* upper */
  20. #define _L 0x02 /* lower */
  21. #define _D 0x04 /* digit */
  22. #define _C 0x08 /* cntrl */
  23. #define _P 0x10 /* punct */
  24. #define _S 0x20 /* white space (space/lf/tab) */
  25. #define _X 0x40 /* hex digit */
  26. #define _SP 0x80 /* hard space (0x20) */
  27.  
  28. const unsigned char _ctype[] = {
  29. _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
  30. _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
  31. _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
  32. _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
  33. _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
  34. _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
  35. _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
  36. _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
  37. _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
  38. _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
  39. _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
  40. _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
  41. _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
  42. _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
  43. _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
  44. _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
  45. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
  46. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
  47. _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
  48. _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
  49. _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
  50. _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
  51. _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
  52. _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
  53.  
  54. #define __ismask(x) (_ctype[(int)(unsigned char)(x)])
  55.  
  56. #define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
  57.  
  58.  
  59.  
  60. // from u-boot printf
  61.  
  62.  
  63.  
  64. struct printf_info {
  65. char *bf; /* Digit buffer */
  66. char zs; /* non-zero if a digit has been written */
  67. char *outstr; /* Next output position for sprintf() */
  68.  
  69. /* Output a character */
  70. void (*putc)(struct printf_info *info, char ch);
  71. };
  72.  
  73. static void out(struct printf_info *info, char c)
  74. {
  75. *info->bf++ = c;
  76. }
  77.  
  78. static void out_dgt(struct printf_info *info, char dgt)
  79. {
  80. out(info, dgt + (dgt < 10 ? '0' : 'a' - 10));
  81. info->zs = 1;
  82. }
  83.  
  84. static void div_out(struct printf_info *info, unsigned long *num,
  85. unsigned long div)
  86. {
  87. unsigned char dgt = 0;
  88.  
  89. while (*num >= div) {
  90. *num -= div;
  91. dgt++;
  92. }
  93.  
  94. if (info->zs || dgt > 0)
  95. out_dgt(info, dgt);
  96. }
  97.  
  98. #ifdef CONFIG_SPL_NET_SUPPORT
  99. static void string(struct printf_info *info, char *s)
  100. {
  101. char ch;
  102.  
  103. while ((ch = *s++))
  104. out(info, ch);
  105. }
  106.  
  107. static const char hex_asc[] = "0123456789abcdef";
  108. #define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
  109. #define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4]
  110.  
  111. static inline char *pack_hex_byte(char *buf, u8 byte)
  112. {
  113. *buf++ = hex_asc_hi(byte);
  114. *buf++ = hex_asc_lo(byte);
  115. return buf;
  116. }
  117.  
  118. static void mac_address_string(struct printf_info *info, u8 *addr,
  119. bool separator)
  120. {
  121. /* (6 * 2 hex digits), 5 colons and trailing zero */
  122. char mac_addr[6 * 3];
  123. char *p = mac_addr;
  124. int i;
  125.  
  126. for (i = 0; i < 6; i++) {
  127. p = pack_hex_byte(p, addr[i]);
  128. if (separator && i != 5)
  129. *p++ = ':';
  130. }
  131. *p = '\0';
  132.  
  133. string(info, mac_addr);
  134. }
  135.  
  136. static char *put_dec_trunc(char *buf, unsigned int q)
  137. {
  138. unsigned int d3, d2, d1, d0;
  139. d1 = (q >> 4) & 0xf;
  140. d2 = (q >> 8) & 0xf;
  141. d3 = (q >> 12);
  142.  
  143. d0 = 6 * (d3 + d2 + d1) + (q & 0xf);
  144. q = (d0 * 0xcd) >> 11;
  145. d0 = d0 - 10 * q;
  146. *buf++ = d0 + '0'; /* least significant digit */
  147. d1 = q + 9 * d3 + 5 * d2 + d1;
  148. if (d1 != 0) {
  149. q = (d1 * 0xcd) >> 11;
  150. d1 = d1 - 10 * q;
  151. *buf++ = d1 + '0'; /* next digit */
  152.  
  153. d2 = q + 2 * d2;
  154. if ((d2 != 0) || (d3 != 0)) {
  155. q = (d2 * 0xd) >> 7;
  156. d2 = d2 - 10 * q;
  157. *buf++ = d2 + '0'; /* next digit */
  158.  
  159. d3 = q + 4 * d3;
  160. if (d3 != 0) {
  161. q = (d3 * 0xcd) >> 11;
  162. d3 = d3 - 10 * q;
  163. *buf++ = d3 + '0'; /* next digit */
  164. if (q != 0)
  165. *buf++ = q + '0'; /* most sign. digit */
  166. }
  167. }
  168. }
  169. return buf;
  170. }
  171.  
  172. static void ip4_addr_string(struct printf_info *info, u8 *addr)
  173. {
  174. /* (4 * 3 decimal digits), 3 dots and trailing zero */
  175. char ip4_addr[4 * 4];
  176. char temp[3]; /* hold each IP quad in reverse order */
  177. char *p = ip4_addr;
  178. int i, digits;
  179.  
  180. for (i = 0; i < 4; i++) {
  181. digits = put_dec_trunc(temp, addr[i]) - temp;
  182. /* reverse the digits in the quad */
  183. while (digits--)
  184. *p++ = temp[digits];
  185. if (i != 3)
  186. *p++ = '.';
  187. }
  188. *p = '\0';
  189.  
  190. string(info, ip4_addr);
  191. }
  192. #endif
  193.  
  194. /*
  195. * Show a '%p' thing. A kernel extension is that the '%p' is followed
  196. * by an extra set of characters that are extended format
  197. * specifiers.
  198. *
  199. * Right now we handle:
  200. *
  201. * - 'M' For a 6-byte MAC address, it prints the address in the
  202. * usual colon-separated hex notation.
  203. * - 'm' Same as above except there is no colon-separator.
  204. * - 'I4'for IPv4 addresses printed in the usual way (dot-separated
  205. * decimal).
  206. */
  207.  
  208. static void pointer(struct printf_info *info, const char *fmt, void *ptr)
  209. {
  210. #ifdef DEBUG
  211. unsigned long num = (uintptr_t)ptr;
  212. unsigned long div;
  213. #endif
  214.  
  215. switch (*fmt) {
  216. #ifdef DEBUG
  217. case 'a':
  218.  
  219. switch (fmt[1]) {
  220. case 'p':
  221. default:
  222. num = *(phys_addr_t *)ptr;
  223. break;
  224. }
  225. break;
  226. #endif
  227. #ifdef CONFIG_SPL_NET_SUPPORT
  228. case 'm':
  229. return mac_address_string(info, ptr, false);
  230. case 'M':
  231. return mac_address_string(info, ptr, true);
  232. case 'I':
  233. if (fmt[1] == '4')
  234. return ip4_addr_string(info, ptr);
  235. #endif
  236. default:
  237. break;
  238. }
  239. #ifdef DEBUG
  240. div = 1UL << (sizeof(long) * 8 - 4);
  241. for (; div; div /= 0x10)
  242. div_out(info, &num, div);
  243. #endif
  244. }
  245.  
  246. static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
  247. {
  248. char ch;
  249. char *p;
  250. unsigned long num;
  251. char buf[12];
  252. unsigned long div;
  253.  
  254. while ((ch = *(fmt++))) {
  255. if (ch != '%') {
  256. info->putc(info, ch);
  257. } else {
  258. int lz = 0;
  259. int width = 0;
  260. int islong = 0;
  261.  
  262. ch = *(fmt++);
  263. if (ch == '-')
  264. ch = *(fmt++);
  265.  
  266. if (ch == '0') {
  267. ch = *(fmt++);
  268. lz = 1;
  269. }
  270.  
  271. if (ch >= '0' && ch <= '9') {
  272. width = 0;
  273. while (ch >= '0' && ch <= '9') {
  274. width = (width * 10) + ch - '0';
  275. ch = *fmt++;
  276. }
  277. }
  278. if (ch == 'l') {
  279. ch = *(fmt++);
  280. islong = 1;
  281. }
  282.  
  283. info->bf = buf;
  284. p = info->bf;
  285. info->zs = 0;
  286.  
  287. switch (ch) {
  288. case '\0':
  289. goto abort;
  290. case 'u':
  291. case 'd':
  292. div = 1000000000;
  293. if (islong) {
  294. num = va_arg(va, unsigned long);
  295. if (sizeof(long) > 4)
  296. div *= div * 10;
  297. } else {
  298. num = va_arg(va, unsigned int);
  299. }
  300.  
  301. if (ch == 'd') {
  302. if (islong && (long)num < 0) {
  303. num = -(long)num;
  304. out(info, '-');
  305. } else if (!islong && (int)num < 0) {
  306. num = -(int)num;
  307. out(info, '-');
  308. }
  309. }
  310. if (!num) {
  311. out_dgt(info, 0);
  312. } else {
  313. /* HACK MANUEL!!!!!!!!!!!!!!!!!!!!!!!!!
  314. for (; div; div /= 10)
  315. div_out(info, &num, div);
  316. */
  317. }
  318. break;
  319. case 'x':
  320. if (islong) {
  321. num = va_arg(va, unsigned long);
  322. div = 1UL << (sizeof(long) * 8 - 4);
  323. } else {
  324. num = va_arg(va, unsigned int);
  325. div = 0x10000000;
  326. }
  327. if (!num) {
  328. out_dgt(info, 0);
  329. } else {
  330. for (; div; div /= 0x10)
  331. div_out(info, &num, div);
  332. }
  333. break;
  334. case 'c':
  335. out(info, (char)(va_arg(va, int)));
  336. break;
  337. case 's':
  338. p = va_arg(va, char*);
  339. break;
  340. case 'p':
  341. pointer(info, fmt, va_arg(va, void *));
  342. while (isalnum(fmt[0]))
  343. fmt++;
  344. break;
  345. case '%':
  346. out(info, '%');
  347. default:
  348. break;
  349. }
  350.  
  351. *info->bf = 0;
  352. info->bf = p;
  353. while (*info->bf++ && width > 0)
  354. width--;
  355. while (width-- > 0)
  356. info->putc(info, lz ? '0' : ' ');
  357. if (p) {
  358. while ((ch = *p++))
  359. info->putc(info, ch);
  360. }
  361. }
  362. }
  363.  
  364. abort:
  365. return 0;
  366. }
  367.  
  368.  
  369. static void putc_normal(struct printf_info *info, char ch)
  370. {
  371. //putc(ch);
  372. uart0_putc(ch);
  373. }
  374.  
  375. int vprintf(const char *fmt, va_list va)
  376. {
  377. struct printf_info info;
  378.  
  379. info.putc = putc_normal;
  380. return _vprintf(&info, fmt, va);
  381. }
  382.  
  383. int printf(const char *fmt, ...)
  384. {
  385. struct printf_info info;
  386.  
  387. va_list va;
  388. int ret;
  389.  
  390. info.putc = putc_normal;
  391. va_start(va, fmt);
  392. ret = _vprintf(&info, fmt, va);
  393. va_end(va);
  394.  
  395. return ret;
  396. }
  397.  
  398. static void putc_outstr(struct printf_info *info, char ch)
  399. {
  400. *info->outstr++ = ch;
  401. }
  402.  
  403. int sprintf(char *buf, const char *fmt, ...)
  404. {
  405. struct printf_info info;
  406. va_list va;
  407. int ret;
  408.  
  409. va_start(va, fmt);
  410. info.outstr = buf;
  411. info.putc = putc_outstr;
  412. ret = _vprintf(&info, fmt, va);
  413. va_end(va);
  414. *info.outstr = '\0';
  415.  
  416. return ret;
  417. }
  418.  
  419. /* Note that size is ignored */
  420. int snprintf(char *buf, int size, const char *fmt, ...)
  421. {
  422. struct printf_info info;
  423. va_list va;
  424. int ret;
  425.  
  426. va_start(va, fmt);
  427. info.outstr = buf;
  428. info.putc = putc_outstr;
  429. ret = _vprintf(&info, fmt, va);
  430. va_end(va);
  431. *info.outstr = '\0';
  432.  
  433. return ret;
  434. }
  435.  
  436.  
  437. /*
  438. * Copyright (C) 2016 Siarhei Siamashka <[email protected]>
  439. *
  440. * This program is free software: you can redistribute it and/or modify
  441. * it under the terms of the GNU General Public License as published by
  442. * the Free Software Foundation, either version 2 of the License, or
  443. * (at your option) any later version.
  444. *
  445. * This program is distributed in the hope that it will be useful,
  446. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  447. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  448. * GNU General Public License for more details.
  449. *
  450. * You should have received a copy of the GNU General Public License
  451. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  452. */
  453.  
  454. /*
  455. * Partially based on the uart code from ar100-info
  456. *
  457. * (C) Copyright 2013 Stefan Kristiansson <[email protected]>
  458. *
  459. * This program is free software; you can redistribute it and/or
  460. * modify it under the terms of the GNU General Public License as
  461. * published by the Free Software Foundation; either version 2 of
  462. * the License, or (at your option) any later version.
  463. *
  464. * This program is distributed in the hope that it will be useful,
  465. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  466. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  467. * GNU General Public License for more details.
  468. *
  469. * You should have received a copy of the GNU General Public License
  470. * along with this program; if not, write to the Free Software
  471. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  472. * MA 02111-1307 USA
  473. */
  474.  
  475. /*
  476. * Partially based on the sunxi gpio code from U-Boot
  477. *
  478. * (C) Copyright 2012 Henrik Nordstrom <[email protected]>
  479. *
  480. * Based on earlier arch/arm/cpu/armv7/sunxi/gpio.c:
  481. *
  482. * (C) Copyright 2007-2011
  483. * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
  484. * Tom Cubie <[email protected]>
  485. *
  486. * SPDX-License-Identifier: GPL-2.0+
  487. */
  488.  
  489. typedef unsigned int u32;
  490.  
  491. #define set_wbit(addr, v) (*((volatile unsigned long *)(addr)) |= (unsigned long)(v))
  492. #define readl(addr) (*((volatile unsigned long *)(addr)))
  493. #define writel(v, addr) (*((volatile unsigned long *)(addr)) = (unsigned long)(v))
  494.  
  495. #define SUNXI_UART0_BASE 0x01C28000
  496. #define SUNXI_PIO_BASE 0x01C20800
  497. #define AW_CCM_BASE 0x01c20000
  498. #define AW_SRAMCTRL_BASE 0x01c00000
  499.  
  500. /*****************************************************************************
  501. * GPIO code, borrowed from U-Boot *
  502. *****************************************************************************/
  503.  
  504. #define SUNXI_GPIO_A 0
  505. #define SUNXI_GPIO_B 1
  506. #define SUNXI_GPIO_C 2
  507. #define SUNXI_GPIO_D 3
  508. #define SUNXI_GPIO_E 4
  509. #define SUNXI_GPIO_F 5
  510. #define SUNXI_GPIO_G 6
  511. #define SUNXI_GPIO_H 7
  512. #define SUNXI_GPIO_I 8
  513.  
  514. struct sunxi_gpio {
  515. u32 cfg[4];
  516. u32 dat;
  517. u32 drv[2];
  518. u32 pull[2];
  519. };
  520.  
  521. struct sunxi_gpio_reg {
  522. struct sunxi_gpio gpio_bank[10];
  523. };
  524.  
  525. #define GPIO_BANK(pin) ((pin) >> 5)
  526. #define GPIO_NUM(pin) ((pin) & 0x1F)
  527.  
  528. #define GPIO_CFG_INDEX(pin) (((pin) & 0x1F) >> 3)
  529. #define GPIO_CFG_OFFSET(pin) ((((pin) & 0x1F) & 0x7) << 2)
  530.  
  531. #define GPIO_PULL_INDEX(pin) (((pin) & 0x1f) >> 4)
  532. #define GPIO_PULL_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1)
  533.  
  534. /* GPIO bank sizes */
  535. #define SUNXI_GPIO_A_NR (32)
  536. #define SUNXI_GPIO_B_NR (32)
  537. #define SUNXI_GPIO_C_NR (32)
  538. #define SUNXI_GPIO_D_NR (32)
  539. #define SUNXI_GPIO_E_NR (32)
  540. #define SUNXI_GPIO_F_NR (32)
  541. #define SUNXI_GPIO_G_NR (32)
  542. #define SUNXI_GPIO_H_NR (32)
  543. #define SUNXI_GPIO_I_NR (32)
  544.  
  545. #define SUNXI_GPIO_NEXT(__gpio) ((__gpio##_START) + (__gpio##_NR) + 0)
  546.  
  547. enum sunxi_gpio_number {
  548. SUNXI_GPIO_A_START = 0,
  549. SUNXI_GPIO_B_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_A),
  550. SUNXI_GPIO_C_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_B),
  551. SUNXI_GPIO_D_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_C),
  552. SUNXI_GPIO_E_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_D),
  553. SUNXI_GPIO_F_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_E),
  554. SUNXI_GPIO_G_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_F),
  555. SUNXI_GPIO_H_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_G),
  556. SUNXI_GPIO_I_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_H),
  557. };
  558.  
  559. /* SUNXI GPIO number definitions */
  560. #define SUNXI_GPA(_nr) (SUNXI_GPIO_A_START + (_nr))
  561. #define SUNXI_GPB(_nr) (SUNXI_GPIO_B_START + (_nr))
  562. #define SUNXI_GPC(_nr) (SUNXI_GPIO_C_START + (_nr))
  563. #define SUNXI_GPD(_nr) (SUNXI_GPIO_D_START + (_nr))
  564. #define SUNXI_GPE(_nr) (SUNXI_GPIO_E_START + (_nr))
  565. #define SUNXI_GPF(_nr) (SUNXI_GPIO_F_START + (_nr))
  566. #define SUNXI_GPG(_nr) (SUNXI_GPIO_G_START + (_nr))
  567. #define SUNXI_GPH(_nr) (SUNXI_GPIO_H_START + (_nr))
  568. #define SUNXI_GPI(_nr) (SUNXI_GPIO_I_START + (_nr))
  569.  
  570. /* GPIO pin function config */
  571. #define SUNXI_GPIO_INPUT (0)
  572. #define SUNXI_GPIO_OUTPUT (1)
  573. #define SUN4I_GPB_UART0 (2)
  574. #define SUN5I_GPB_UART0 (2)
  575. #define SUN6I_GPH_UART0 (2)
  576. #define SUN8I_H3_GPA_UART0 (2)
  577. #define SUN8I_V3S_GPB_UART0 (3)
  578. #define SUN50I_H5_GPA_UART0 (2)
  579. #define SUN50I_A64_GPB_UART0 (4)
  580. #define SUNXI_GPF_UART0 (4)
  581.  
  582. /* GPIO pin pull-up/down config */
  583. #define SUNXI_GPIO_PULL_DISABLE (0)
  584. #define SUNXI_GPIO_PULL_UP (1)
  585. #define SUNXI_GPIO_PULL_DOWN (2)
  586.  
  587. int sunxi_gpio_set_cfgpin(u32 pin, u32 val)
  588. {
  589. u32 cfg;
  590. u32 bank = GPIO_BANK(pin);
  591. u32 index = GPIO_CFG_INDEX(pin);
  592. u32 offset = GPIO_CFG_OFFSET(pin);
  593. struct sunxi_gpio *pio =
  594. &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
  595. cfg = readl(&pio->cfg[0] + index);
  596. cfg &= ~(0xf << offset);
  597. cfg |= val << offset;
  598. writel(cfg, &pio->cfg[0] + index);
  599. return 0;
  600. }
  601.  
  602. int sunxi_gpio_set_pull(u32 pin, u32 val)
  603. {
  604. u32 cfg;
  605. u32 bank = GPIO_BANK(pin);
  606. u32 index = GPIO_PULL_INDEX(pin);
  607. u32 offset = GPIO_PULL_OFFSET(pin);
  608. struct sunxi_gpio *pio =
  609. &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
  610. cfg = readl(&pio->pull[0] + index);
  611. cfg &= ~(0x3 << offset);
  612. cfg |= val << offset;
  613. writel(cfg, &pio->pull[0] + index);
  614. return 0;
  615. }
  616.  
  617. int sunxi_gpio_output(u32 pin, u32 val)
  618. {
  619. u32 dat;
  620. u32 bank = GPIO_BANK(pin);
  621. u32 num = GPIO_NUM(pin);
  622. struct sunxi_gpio *pio =
  623. &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
  624. dat = readl(&pio->dat);
  625. if(val)
  626. dat |= 1 << num;
  627. else
  628. dat &= ~(1 << num);
  629. writel(dat, &pio->dat);
  630. return 0;
  631. }
  632.  
  633. int sunxi_gpio_input(u32 pin)
  634. {
  635. u32 dat;
  636. u32 bank = GPIO_BANK(pin);
  637. u32 num = GPIO_NUM(pin);
  638. struct sunxi_gpio *pio =
  639. &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
  640. dat = readl(&pio->dat);
  641. dat >>= num;
  642. return (dat & 0x1);
  643. }
  644.  
  645. int gpio_direction_input(unsigned gpio)
  646. {
  647. sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT);
  648. return sunxi_gpio_input(gpio);
  649. }
  650.  
  651. int gpio_direction_output(unsigned gpio, int value)
  652. {
  653. sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT);
  654. return sunxi_gpio_output(gpio, value);
  655. }
  656.  
  657. /*****************************************************************************
  658. * Nearly all the Allwinner SoCs are using the same VER_REG register for *
  659. * runtime SoC type identification. For additional details see: *
  660. * *
  661. * https://linux-sunxi.org/SRAM_Controller_Register_Guide *
  662. * *
  663. * Allwinner A80 is an oddball and has a non-standard address of the VER_REG *
  664. * *
  665. * Allwinner A10s and A13 are using the same SoC type id, but they can be *
  666. * differentiated using a certain part of the SID register. *
  667. *****************************************************************************/
  668.  
  669. #define VER_REG (AW_SRAMCTRL_BASE + 0x24)
  670. #define SUN4I_SID_BASE 0x01C23800
  671. #define SUN8I_SID_BASE 0x01C14000
  672.  
  673. #define SID_PRCTL 0x40 /* SID program/read control register */
  674. #define SID_RDKEY 0x60 /* SID read key value register */
  675.  
  676. #define SID_OP_LOCK 0xAC /* Efuse operation lock value */
  677. #define SID_READ_START (1 << 1) /* bit 1 of SID_PRCTL, Software Read Start */
  678.  
  679. u32 sid_read_key(u32 sid_base, u32 offset)
  680. {
  681. u32 reg_val;
  682.  
  683. reg_val = (offset & 0x1FF) << 16; /* PG_INDEX value */
  684. reg_val |= (SID_OP_LOCK << 8) | SID_READ_START; /* request read access */
  685. writel(reg_val, sid_base + SID_PRCTL);
  686.  
  687. while (readl(sid_base + SID_PRCTL) & SID_READ_START) ; /* wait while busy */
  688.  
  689. reg_val = readl(sid_base + SID_RDKEY); /* read SID key value */
  690. writel(0, sid_base + SID_PRCTL); /* clear SID_PRCTL (removing SID_OP_LOCK) */
  691.  
  692. return reg_val;
  693. }
  694.  
  695.  
  696. /*****************************************************************************
  697. * UART is mostly the same on A10/A13/A20/A31/H3/A64, except that newer SoCs *
  698. * have changed the APB numbering scheme (A10/A13/A20 used to have APB0 and *
  699. * APB1 names, but newer SoCs just have renamed them into APB1 and APB2). *
  700. * The constants below are using the new APB numbering convention. *
  701. * Also the newer SoCs have introduced the APB2_RESET register, but writing *
  702. * to it effectively goes nowhere on older SoCs and is harmless. *
  703. *****************************************************************************/
  704.  
  705. #define CONFIG_CONS_INDEX 1
  706. #define APB2_CFG (AW_CCM_BASE + 0x058)
  707. #define APB2_GATE (AW_CCM_BASE + 0x06C)
  708. #define APB2_RESET (AW_CCM_BASE + 0x2D8)
  709. #define APB2_GATE_UART_SHIFT (16)
  710. #define APB2_RESET_UART_SHIFT (16)
  711.  
  712. void clock_init_uart(void)
  713. {
  714. /* Open the clock gate for UART0 */
  715. set_wbit(APB2_GATE, 1 << (APB2_GATE_UART_SHIFT + CONFIG_CONS_INDEX - 1));
  716. /* Deassert UART0 reset (only needed on A31/A64/H3) */
  717. set_wbit(APB2_RESET, 1 << (APB2_RESET_UART_SHIFT + CONFIG_CONS_INDEX - 1));
  718. }
  719.  
  720. /*****************************************************************************
  721. * UART0 pins muxing is different for different SoC variants. *
  722. * Allwinner A13 is a bit special, because there are no dedicated UART0 pins *
  723. * and they are shared with MMC0. *
  724. *****************************************************************************/
  725.  
  726. void gpio_init(void)
  727. {
  728. // soc is h3
  729. sunxi_gpio_set_cfgpin(SUNXI_GPA(4), SUN8I_H3_GPA_UART0);
  730. sunxi_gpio_set_cfgpin(SUNXI_GPA(5), SUN8I_H3_GPA_UART0);
  731. sunxi_gpio_set_pull(SUNXI_GPA(5), SUNXI_GPIO_PULL_UP);
  732. }
  733.  
  734. /*****************************************************************************/
  735.  
  736. #define UART0_RBR (SUNXI_UART0_BASE + 0x0) /* receive buffer register */
  737. #define UART0_THR (SUNXI_UART0_BASE + 0x0) /* transmit holding register */
  738. #define UART0_DLL (SUNXI_UART0_BASE + 0x0) /* divisor latch low register */
  739.  
  740. #define UART0_DLH (SUNXI_UART0_BASE + 0x4) /* divisor latch high register */
  741. #define UART0_IER (SUNXI_UART0_BASE + 0x4) /* interrupt enable reigster */
  742.  
  743. #define UART0_IIR (SUNXI_UART0_BASE + 0x8) /* interrupt identity register */
  744. #define UART0_FCR (SUNXI_UART0_BASE + 0x8) /* fifo control register */
  745.  
  746. #define UART0_LCR (SUNXI_UART0_BASE + 0xc) /* line control register */
  747.  
  748. #define UART0_LSR (SUNXI_UART0_BASE + 0x14) /* line status register */
  749.  
  750. #define BAUD_115200 (0xD) /* 24 * 1000 * 1000 / 16 / 115200 = 13 */
  751. #define NO_PARITY (0)
  752. #define ONE_STOP_BIT (0)
  753. #define DAT_LEN_8_BITS (3)
  754. #define LC_8_N_1 (NO_PARITY << 3 | ONE_STOP_BIT << 2 | DAT_LEN_8_BITS)
  755.  
  756. void uart0_init(void)
  757. {
  758. clock_init_uart();
  759.  
  760. /* select dll dlh */
  761. writel(0x80, UART0_LCR);
  762. /* set baudrate */
  763. writel(0, UART0_DLH);
  764. writel(BAUD_115200, UART0_DLL);
  765. /* set line control */
  766. writel(LC_8_N_1, UART0_LCR);
  767. }
  768.  
  769. void uart0_putc(char c)
  770. {
  771. while (!(readl(UART0_LSR) & (1 << 6))) {}
  772. writel(c, UART0_THR);
  773. }
  774.  
  775. void uart0_puts(const char *s)
  776. {
  777. while (*s) {
  778. if (*s == '\n')
  779. uart0_putc('\r');
  780. uart0_putc(*s++);
  781. }
  782. }
  783.  
  784.  
  785. /*****************************************************************************/
  786.  
  787. // A workaround for https://patchwork.ozlabs.org/patch/622173
  788. void __attribute__((section(".start"))) __attribute__((naked)) start(void)
  789. {
  790. asm volatile("b main \n"
  791. ".long 0xffffffff \n"
  792. ".long 0xffffffff \n"
  793. ".long 0xffffffff \n");
  794. }
  795.  
  796.  
  797.  
  798.  
  799. #define EFUSE_LCJS (0xF4)
  800. #define EFUSE_ROTPK (0x64)
  801. #define EFUSE_RSA_KEY_HASH (0x20)
  802. #define EFUSE_RSSK (0x94)
  803.  
  804. //#define SID_OP_LOCK (0xAC)
  805.  
  806. // allwinner H3 == sun8iw7p1
  807. #define SUNXI_SID_BASE_NEU 0X01C14000
  808. #define SID_PRCTL_NEU (SUNXI_SID_BASE_NEU + 0x40)
  809. #define SID_PRKEY_NEU (SUNXI_SID_BASE_NEU + 0x50)
  810. //#define SID_RDKEY_NEU (SUNXI_SID_BASE_NEU + 0x60)
  811.  
  812. static void sid_program_key(unsigned int key_index, unsigned int key_value)
  813. {
  814. unsigned int reg_val;
  815.  
  816. writel(key_value, SID_PRKEY_NEU);
  817.  
  818. reg_val = readl(SID_PRCTL_NEU);
  819. reg_val &= ~((0x1ff<<16)|0x3);
  820. reg_val |= key_index<<16;
  821. writel(reg_val, SID_PRCTL_NEU);
  822.  
  823. reg_val &= ~((0xff<<8)|0x3);
  824. reg_val |= (SID_OP_LOCK<<8) | 0x1;
  825. writel(reg_val, SID_PRCTL_NEU);
  826.  
  827. while(readl(SID_PRCTL_NEU)&0x1){};
  828.  
  829. reg_val &= ~((0x1ff<<16)|(0xff<<8)|0x3);
  830. writel(reg_val, SID_PRCTL_NEU);
  831.  
  832. return;
  833. }
  834.  
  835.  
  836.  
  837. //asm("smc #0");
  838.  
  839. /*asm volatile (
  840. ".arch_extension sec\n"
  841. "smc #0"
  842. );*/
  843.  
  844.  
  845. void print_chip_id() {
  846. printf("chip_id: ");
  847. u32 chip_id[4];
  848. for(u32 i=0; i < 4; i++) {
  849. chip_id[i] = sid_read_key(SUN8I_SID_BASE, 4*i);
  850. printf("%x:", chip_id[i]);
  851. }
  852. printf("\r\n");
  853. }
  854.  
  855. void print_rotpk() {
  856. printf("rotpk_hash: ");
  857. u32 rotpk_hash[8];
  858. for(u32 i=0; i < 8; i++) {
  859. rotpk_hash[i] = sid_read_key(SUN8I_SID_BASE, EFUSE_ROTPK+4*i);
  860. printf("%08x:", rotpk_hash[i]);
  861. }
  862. printf("\r\n");
  863. }
  864.  
  865. void print_lcjs() {
  866. printf("LCJS: ");
  867. u32 LCJS = sid_read_key(SUN8I_SID_BASE, EFUSE_LCJS);
  868. printf("%08x:", LCJS);
  869. printf("\r\n");
  870. }
  871.  
  872. void print_secure() {
  873.  
  874. printf("try read sram A2:");
  875. if (readl(0x40004) == 0) {
  876. printf("0x40004==0 non-secure\r\n");
  877. } else {
  878. printf("0x40004!=0 secure\r\n");
  879. }
  880. printf("\r\n");
  881. }
  882.  
  883. void print_stuff() {
  884. print_chip_id();
  885. print_rotpk();
  886. print_lcjs();
  887. print_secure();
  888. printf("\r\n");
  889. }
  890.  
  891.  
  892. void sid_set_security_mode(void)
  893. {
  894. unsigned int reg_val;
  895.  
  896. //reg_val = sid_read_key_version_x(EFUSE_LCJS);
  897. reg_val = (0x01 << 11); //ʹÄÜsecurebit
  898. sid_program_key(EFUSE_LCJS, reg_val);
  899. //reg_val = (sid_read_key_version_x(EFUSE_LCJS) >> 11) & 1;
  900.  
  901. return;
  902. }
  903.  
  904.  
  905. //******************************
  906. // sid_read_rotpk from https://github.com/BPI-SINOVOIP/BPI-M2U-bsp/blob/master/u-boot-sunxi/arch/arm/cpu/armv7/sun50iw1p1/spl/efuse_spl.c
  907.  
  908.  
  909. //#define SUNXI_SID_SRAM_BASE (0x01c14200L)
  910. #define SUNXI_SID_SRAM_BASE (0x01c14000L)
  911.  
  912. typedef unsigned int uint;
  913.  
  914. uint gitbpi_sid_read_key(uint key_index)
  915. {
  916. return readl(SUNXI_SID_SRAM_BASE + key_index);
  917. }
  918.  
  919. void gitbpi_sid_read_rotpk(void *dst)
  920. {
  921. uint chipid_index = 0x64;
  922. uint id_length = 32;
  923. uint i = 0;
  924. for(i = 0 ; i < id_length ;i+=4 )
  925. {
  926. *(u32*)dst = gitbpi_sid_read_key(chipid_index + i );
  927. //*(u32*)dst = sid_read_key(SUNXI_SID_SRAM_BASE, chipid_index + i );
  928. dst += 4 ;
  929. }
  930. return ;
  931. }
  932.  
  933. int __attribute__((section(".start"))) main(void)
  934. {
  935. gpio_init();
  936. uart0_init();
  937.  
  938. sid_set_security_mode();
  939.  
  940. unsigned char rotpk_bin[] = {
  941. 0xf6, 0xab, 0x5e, 0x33, 0x80, 0xd9, 0xdd, 0xa8, 0x82, 0x86, 0x85, 0x5f,
  942. 0x22, 0xdc, 0x9d, 0xc0, 0xf9, 0xa4, 0x2c, 0xbf, 0xec, 0x05, 0xd0, 0xcd,
  943. 0xcd, 0xa4, 0x9b, 0xf4, 0xb4, 0xba, 0xf8, 0x94
  944. };
  945. unsigned int rotpk_bin_len = 32;
  946.  
  947. // key must be written in little endian instead big endian!
  948. unsigned long rotpk[8];
  949. for(int i = 0; i < 8; i++) {
  950. int idx = 4*i;
  951. rotpk[i] = 0;
  952. rotpk[i] += rotpk_bin[idx];
  953. rotpk[i] += rotpk_bin[idx+1] << 8;
  954. rotpk[i] += rotpk_bin[idx+2] << 16;
  955. rotpk[i] += rotpk_bin[idx+3] << 24;
  956. //printf("%08x:", rotpk[i]);
  957. }
  958.  
  959. for(int i = 0; i < 8; i++) {
  960. //printf("%08x:", rotpk[i]);
  961. sid_program_key(EFUSE_ROTPK+4*i, rotpk[i]);
  962. }
  963.  
  964. printf("board locked!\r\n");
  965.  
  966. return 0;
  967.  
  968. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement