bootboot.c 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908
  1. /*
  2. * aarch64-rpi/bootboot.c
  3. *
  4. * Copyright (C) 2017 - 2021 bzt (bztsrc@gitlab)
  5. *
  6. * Permission is hereby granted, free of charge, to any person
  7. * obtaining a copy of this software and associated documentation
  8. * files (the "Software"), to deal in the Software without
  9. * restriction, including without limitation the rights to use, copy,
  10. * modify, merge, publish, distribute, sublicense, and/or sell copies
  11. * of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  21. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  22. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24. * DEALINGS IN THE SOFTWARE.
  25. *
  26. * This file is part of the BOOTBOOT Protocol package.
  27. * @brief Boot loader for the Raspberry Pi 3 and 4 ARMv8
  28. *
  29. */
  30. #define BBDEBUG 1
  31. //#define SD_DEBUG BBDEBUG
  32. //#define INITRD_DEBUG BBDEBUG
  33. //#define EXEC_DEBUG BBDEBUG
  34. //#define MEM_DEBUG BBDEBUG
  35. #define CONSOLE UART0
  36. #define NULL ((void*)0)
  37. #define PAGESIZE 4096
  38. #include "tinf.h"
  39. /* get BOOTBOOT structure */
  40. #include "../dist/bootboot.h"
  41. /* aligned buffers */
  42. volatile uint32_t __attribute__((aligned(16))) mbox[36];
  43. /* we place these manually in linker script, gcc would otherwise waste lots of memory */
  44. volatile uint8_t __attribute__((aligned(PAGESIZE))) __bootboot[PAGESIZE];
  45. volatile uint8_t __attribute__((aligned(PAGESIZE))) __environment[PAGESIZE];
  46. volatile uint8_t __attribute__((aligned(PAGESIZE))) __paging[50*PAGESIZE];
  47. volatile uint8_t __attribute__((aligned(PAGESIZE))) __corestack[16*PAGESIZE];
  48. #define __diskbuf __paging
  49. extern volatile uint8_t _data;
  50. extern volatile uint8_t _end;
  51. /* forward definitions */
  52. uint32_t color=0xC0C0C0;
  53. void putc(char c);
  54. void puts(char *s);
  55. /*** ELF64 defines and structs ***/
  56. #define ELFMAG "\177ELF"
  57. #define SELFMAG 4
  58. #define EI_CLASS 4 /* File class byte index */
  59. #define ELFCLASS64 2 /* 64-bit objects */
  60. #define EI_DATA 5 /* Data encoding byte index */
  61. #define ELFDATA2LSB 1 /* 2's complement, little endian */
  62. #define PT_LOAD 1 /* Loadable program segment */
  63. #define EM_AARCH64 183 /* ARM aarch64 architecture */
  64. typedef struct
  65. {
  66. unsigned char e_ident[16];/* Magic number and other info */
  67. uint16_t e_type; /* Object file type */
  68. uint16_t e_machine; /* Architecture */
  69. uint32_t e_version; /* Object file version */
  70. uint64_t e_entry; /* Entry point virtual address */
  71. uint64_t e_phoff; /* Program header table file offset */
  72. uint64_t e_shoff; /* Section header table file offset */
  73. uint32_t e_flags; /* Processor-specific flags */
  74. uint16_t e_ehsize; /* ELF header size in bytes */
  75. uint16_t e_phentsize; /* Program header table entry size */
  76. uint16_t e_phnum; /* Program header table entry count */
  77. uint16_t e_shentsize; /* Section header table entry size */
  78. uint16_t e_shnum; /* Section header table entry count */
  79. uint16_t e_shstrndx; /* Section header string table index */
  80. } Elf64_Ehdr;
  81. typedef struct
  82. {
  83. uint32_t p_type; /* Segment type */
  84. uint32_t p_flags; /* Segment flags */
  85. uint64_t p_offset; /* Segment file offset */
  86. uint64_t p_vaddr; /* Segment virtual address */
  87. uint64_t p_paddr; /* Segment physical address */
  88. uint64_t p_filesz; /* Segment size in file */
  89. uint64_t p_memsz; /* Segment size in memory */
  90. uint64_t p_align; /* Segment alignment */
  91. } Elf64_Phdr;
  92. typedef struct
  93. {
  94. uint32_t sh_name; /* Section name (string tbl index) */
  95. uint32_t sh_type; /* Section type */
  96. uint64_t sh_flags; /* Section flags */
  97. uint64_t sh_addr; /* Section virtual addr at execution */
  98. uint64_t sh_offset; /* Section file offset */
  99. uint64_t sh_size; /* Section size in bytes */
  100. uint32_t sh_link; /* Link to another section */
  101. uint32_t sh_info; /* Additional section information */
  102. uint64_t sh_addralign; /* Section alignment */
  103. uint64_t sh_entsize; /* Entry size if section holds table */
  104. } Elf64_Shdr;
  105. typedef struct
  106. {
  107. uint32_t st_name; /* Symbol name (string tbl index) */
  108. uint8_t st_info; /* Symbol type and binding */
  109. uint8_t st_other; /* Symbol visibility */
  110. uint16_t st_shndx; /* Section index */
  111. uint64_t st_value; /* Symbol value */
  112. uint64_t st_size; /* Symbol size */
  113. } Elf64_Sym;
  114. /*** PE32+ defines and structs ***/
  115. #define MZ_MAGIC 0x5a4d /* "MZ" */
  116. #define PE_MAGIC 0x00004550 /* "PE\0\0" */
  117. #define IMAGE_FILE_MACHINE_ARM64 0xaa64 /* ARM aarch64 architecture */
  118. #define PE_OPT_MAGIC_PE32PLUS 0x020b /* PE32+ format */
  119. typedef struct
  120. {
  121. uint16_t magic; /* MZ magic */
  122. uint16_t reserved[29]; /* reserved */
  123. uint32_t peaddr; /* address of pe header */
  124. } mz_hdr;
  125. typedef struct {
  126. uint32_t magic; /* PE magic */
  127. uint16_t machine; /* machine type */
  128. uint16_t sections; /* number of sections */
  129. uint32_t timestamp; /* time_t */
  130. uint32_t sym_table; /* symbol table offset */
  131. uint32_t numsym; /* number of symbols */
  132. uint16_t opt_hdr_size; /* size of optional header */
  133. uint16_t flags; /* flags */
  134. uint16_t file_type; /* file type, PE32PLUS magic */
  135. uint8_t ld_major; /* linker major version */
  136. uint8_t ld_minor; /* linker minor version */
  137. uint32_t text_size; /* size of text section(s) */
  138. uint32_t data_size; /* size of data section(s) */
  139. uint32_t bss_size; /* size of bss section(s) */
  140. int32_t entry_point; /* file offset of entry point */
  141. int32_t code_base; /* relative code addr in ram */
  142. } pe_hdr;
  143. typedef struct {
  144. uint32_t iszero; /* if this is not zero, then iszero+nameoffs gives UTF-8 string */
  145. uint32_t nameoffs;
  146. int32_t value; /* value of the symbol */
  147. uint16_t section; /* section it belongs to */
  148. uint16_t type; /* symbol type */
  149. uint8_t storclass; /* storage class */
  150. uint8_t auxsyms; /* number of pe_sym records following */
  151. } pe_sym;
  152. /*** Raspberry Pi specific defines ***/
  153. static uint64_t mmio_base, emmc_base;
  154. #define PM_RTSC ((volatile uint32_t*)(mmio_base+0x0010001c))
  155. #define PM_WATCHDOG ((volatile uint32_t*)(mmio_base+0x00100024))
  156. #define PM_WDOG_MAGIC 0x5a000000
  157. #define PM_RTSC_FULLRST 0x00000020
  158. #define GPFSEL0 ((volatile uint32_t*)(mmio_base+0x00200000))
  159. #define GPFSEL1 ((volatile uint32_t*)(mmio_base+0x00200004))
  160. #define GPFSEL2 ((volatile uint32_t*)(mmio_base+0x00200008))
  161. #define GPFSEL3 ((volatile uint32_t*)(mmio_base+0x0020000C))
  162. #define GPFSEL4 ((volatile uint32_t*)(mmio_base+0x00200010))
  163. #define GPFSEL5 ((volatile uint32_t*)(mmio_base+0x00200014))
  164. #define GPSET0 ((volatile uint32_t*)(mmio_base+0x0020001C))
  165. #define GPSET1 ((volatile uint32_t*)(mmio_base+0x00200020))
  166. #define GPCLR0 ((volatile uint32_t*)(mmio_base+0x00200028))
  167. #define GPLEV0 ((volatile uint32_t*)(mmio_base+0x00200034))
  168. #define GPLEV1 ((volatile uint32_t*)(mmio_base+0x00200038))
  169. #define GPEDS0 ((volatile uint32_t*)(mmio_base+0x00200040))
  170. #define GPEDS1 ((volatile uint32_t*)(mmio_base+0x00200044))
  171. #define GPHEN0 ((volatile uint32_t*)(mmio_base+0x00200064))
  172. #define GPHEN1 ((volatile uint32_t*)(mmio_base+0x00200068))
  173. #define GPPUD ((volatile uint32_t*)(mmio_base+0x00200094))
  174. #define GPPUDCLK0 ((volatile uint32_t*)(mmio_base+0x00200098))
  175. #define GPPUDCLK1 ((volatile uint32_t*)(mmio_base+0x0020009C))
  176. #define UART0 0
  177. #define UART0_DR ((volatile uint32_t*)(mmio_base+0x00201000))
  178. #define UART0_FR ((volatile uint32_t*)(mmio_base+0x00201018))
  179. #define UART0_IBRD ((volatile uint32_t*)(mmio_base+0x00201024))
  180. #define UART0_FBRD ((volatile uint32_t*)(mmio_base+0x00201028))
  181. #define UART0_LCRH ((volatile uint32_t*)(mmio_base+0x0020102C))
  182. #define UART0_CR ((volatile uint32_t*)(mmio_base+0x00201030))
  183. #define UART0_IMSC ((volatile uint32_t*)(mmio_base+0x00201038))
  184. #define UART0_ICR ((volatile uint32_t*)(mmio_base+0x00201044))
  185. #define UART1 1
  186. #define AUX_ENABLE ((volatile uint32_t*)(mmio_base+0x00215004))
  187. #define AUX_MU_IO ((volatile uint32_t*)(mmio_base+0x00215040))
  188. #define AUX_MU_IER ((volatile uint32_t*)(mmio_base+0x00215044))
  189. #define AUX_MU_IIR ((volatile uint32_t*)(mmio_base+0x00215048))
  190. #define AUX_MU_LCR ((volatile uint32_t*)(mmio_base+0x0021504C))
  191. #define AUX_MU_MCR ((volatile uint32_t*)(mmio_base+0x00215050))
  192. #define AUX_MU_LSR ((volatile uint32_t*)(mmio_base+0x00215054))
  193. #define AUX_MU_MSR ((volatile uint32_t*)(mmio_base+0x00215058))
  194. #define AUX_MU_SCRATCH ((volatile uint32_t*)(mmio_base+0x0021505C))
  195. #define AUX_MU_CNTL ((volatile uint32_t*)(mmio_base+0x00215060))
  196. #define AUX_MU_STAT ((volatile uint32_t*)(mmio_base+0x00215064))
  197. #define AUX_MU_BAUD ((volatile uint32_t*)(mmio_base+0x00215068))
  198. /* timing stuff */
  199. uint64_t cntfrq;
  200. /* delay cnt clockcycles */
  201. void delay(uint32_t cnt) { while(cnt--) { asm volatile("nop"); } }
  202. /* delay cnt microsec */
  203. void delaym(uint32_t cnt) {uint64_t t,r;asm volatile ("mrs %0, cntpct_el0" : "=r" (t));
  204. t+=((cntfrq/1000)*cnt)/1000;do{asm volatile ("mrs %0, cntpct_el0" : "=r" (r));}while(r<t);}
  205. /* UART stuff */
  206. void uart_send(uint32_t c) {
  207. #if CONSOLE == UART1
  208. do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20)); *AUX_MU_IO=c; *UART0_DR=c;
  209. #else
  210. do{asm volatile("nop");}while(*UART0_FR&0x20); *UART0_DR=c;
  211. #endif
  212. }
  213. char uart_getc() {char r = 0;
  214. #if CONSOLE == UART1
  215. do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x01));r=(char)(*AUX_MU_IO);
  216. #else
  217. do{asm volatile("nop");}while(*UART0_FR&0x10);r=(char)(*UART0_DR);
  218. #endif
  219. return r;
  220. }
  221. void uart_hex(uint64_t d,int c) { uint32_t n;c<<=3;c-=4;for(;c>=0;c-=4){n=(d>>c)&0xF;n+=n>9?0x37:0x30;uart_send(n);} }
  222. void uart_putc(char c) { if(c=='\n') uart_send((uint32_t)'\r'); uart_send((uint32_t)c); }
  223. void uart_puts(char *s) { while(*s) uart_putc(*s++); }
  224. void uart_dump(void *ptr,uint32_t l) {
  225. uint64_t a,b;
  226. unsigned char c;
  227. for(a=(uint64_t)ptr;a<(uint64_t)ptr+l*16;a+=16) {
  228. uart_hex(a,8); uart_puts(": ");
  229. for(b=0;b<16;b++) {
  230. uart_hex(*((unsigned char*)(a+b)),1);
  231. uart_putc(' ');
  232. if(b%4==3)
  233. uart_putc(' ');
  234. }
  235. for(b=0;b<16;b++) {
  236. c=*((unsigned char*)(a+b));
  237. uart_putc(c<32||c>=127?'.':c);
  238. }
  239. uart_putc('\n');
  240. }
  241. }
  242. void uart_exc(uint64_t idx, uint64_t esr, uint64_t elr, uint64_t spsr, uint64_t far, uint64_t sctlr, uint64_t tcr)
  243. {
  244. register uint64_t r;
  245. /* only report exceptions for the BSP */
  246. asm volatile ("mrs x8, mpidr_el1; and x8, x8, #3; cbz x8, 2f; 1: wfe; b 1b; 2:;" : : : "x8");
  247. asm volatile ("msr ttbr0_el1, %0;tlbi vmalle1" : : "r" ((uint64_t)&__paging+1));
  248. asm volatile ("dsb ish; isb; mrs %0, sctlr_el1" : "=r" (r));
  249. // set mandatory reserved bits
  250. r&=~((1<<12) | // clear I, no instruction cache
  251. (1<<2)); // clear C, no cache at all
  252. asm volatile ("msr sctlr_el1, %0; isb" : : "r" (r));
  253. puts("\nBOOTBOOT-EXCEPTION");
  254. uart_puts(" #");
  255. uart_hex(idx,1);
  256. uart_puts(":\n ESR_EL1 ");
  257. uart_hex(esr,8);
  258. uart_puts(" ELR_EL1 ");
  259. uart_hex(elr,8);
  260. uart_puts("\n SPSR_EL1 ");
  261. uart_hex(spsr,8);
  262. uart_puts(" FAR_EL1 ");
  263. uart_hex(far,8);
  264. uart_puts("\nSCTLR_EL1 ");
  265. uart_hex(sctlr,8);
  266. uart_puts(" TCR_EL1 ");
  267. uart_hex(tcr,8);
  268. uart_putc('\n');
  269. r=0; while(r!='\n' && r != '\r' && r!=' ') r=uart_getc();
  270. asm volatile("dsb sy; isb");
  271. *PM_WATCHDOG = PM_WDOG_MAGIC | 1;
  272. *PM_RTSC = PM_WDOG_MAGIC | PM_RTSC_FULLRST;
  273. while(1);
  274. }
  275. #define VIDEOCORE_MBOX (mmio_base+0x0000B880)
  276. #define MBOX_READ ((volatile uint32_t*)(VIDEOCORE_MBOX+0x0))
  277. #define MBOX_POLL ((volatile uint32_t*)(VIDEOCORE_MBOX+0x10))
  278. #define MBOX_SENDER ((volatile uint32_t*)(VIDEOCORE_MBOX+0x14))
  279. #define MBOX_STATUS ((volatile uint32_t*)(VIDEOCORE_MBOX+0x18))
  280. #define MBOX_CONFIG ((volatile uint32_t*)(VIDEOCORE_MBOX+0x1C))
  281. #define MBOX_WRITE ((volatile uint32_t*)(VIDEOCORE_MBOX+0x20))
  282. #define MBOX_REQUEST 0
  283. #define MBOX_RESPONSE 0x80000000
  284. #define MBOX_FULL 0x80000000
  285. #define MBOX_EMPTY 0x40000000
  286. #define MBOX_CH_POWER 0
  287. #define MBOX_CH_FB 1
  288. #define MBOX_CH_VUART 2
  289. #define MBOX_CH_VCHIQ 3
  290. #define MBOX_CH_LEDS 4
  291. #define MBOX_CH_BTNS 5
  292. #define MBOX_CH_TOUCH 6
  293. #define MBOX_CH_COUNT 7
  294. #define MBOX_CH_PROP 8
  295. /* mailbox functions */
  296. void mbox_write(uint8_t ch, volatile uint32_t *mbox)
  297. {
  298. do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL);
  299. *MBOX_WRITE = (((uint32_t)((uint64_t)mbox)&~0xF) | (ch&0xF));
  300. }
  301. uint32_t mbox_read(uint8_t ch)
  302. {
  303. uint32_t r;
  304. while(1) {
  305. do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY);
  306. r=*MBOX_READ;
  307. if((uint8_t)(r&0xF)==ch)
  308. return (r&~0xF);
  309. }
  310. }
  311. uint8_t mbox_call(uint8_t ch, volatile uint32_t *mbox)
  312. {
  313. mbox_write(ch,mbox);
  314. return mbox_read(ch)==(uint32_t)((uint64_t)mbox) && mbox[1]==MBOX_RESPONSE;
  315. }
  316. /* string.h */
  317. uint32_t strlen(unsigned char *s) { uint32_t n=0; while(*s++) n++; return n; }
  318. void memcpy(void *dst, void *src, uint32_t n){uint8_t *a=dst,*b=src;while(n--) *a++=*b++; }
  319. void memset(void *dst, uint8_t c, uint32_t n){uint8_t *a=dst;while(n--) *a++=c; }
  320. int memcmp(void *s1, void *s2, uint32_t n){uint8_t *a=s1,*b=s2;while(n--){if(*a!=*b){return *a-*b;}a++;b++;} return 0; }
  321. /* other string functions */
  322. int atoi(unsigned char *c) { int r=0;while(*c>='0'&&*c<='9') {r*=10;r+=*c++-'0';} return r; }
  323. int oct2bin(unsigned char *s, int n){ int r=0;while(n-->0){r<<=3;r+=*s++-'0';} return r; }
  324. int hex2bin(unsigned char *s, int n){ int r=0;while(n-->0){r<<=4;
  325. if(*s>='0' && *s<='9')r+=*s-'0';else if(*s>='A'&&*s<='F')r+=*s-'A'+10;s++;} return r; }
  326. #if BBDEBUG
  327. #define DBG(s) puts(s)
  328. #else
  329. #define DBG(s)
  330. #endif
  331. /* sdcard */
  332. #define EMMC_ARG2 ((volatile uint32_t*)(emmc_base+0x00000000))
  333. #define EMMC_BLKSIZECNT ((volatile uint32_t*)(emmc_base+0x00000004))
  334. #define EMMC_ARG1 ((volatile uint32_t*)(emmc_base+0x00000008))
  335. #define EMMC_CMDTM ((volatile uint32_t*)(emmc_base+0x0000000C))
  336. #define EMMC_RESP0 ((volatile uint32_t*)(emmc_base+0x00000010))
  337. #define EMMC_RESP1 ((volatile uint32_t*)(emmc_base+0x00000014))
  338. #define EMMC_RESP2 ((volatile uint32_t*)(emmc_base+0x00000018))
  339. #define EMMC_RESP3 ((volatile uint32_t*)(emmc_base+0x0000001C))
  340. #define EMMC_DATA ((volatile uint32_t*)(emmc_base+0x00000020))
  341. #define EMMC_STATUS ((volatile uint32_t*)(emmc_base+0x00000024))
  342. #define EMMC_CONTROL0 ((volatile uint32_t*)(emmc_base+0x00000028))
  343. #define EMMC_CONTROL1 ((volatile uint32_t*)(emmc_base+0x0000002C))
  344. #define EMMC_INTERRUPT ((volatile uint32_t*)(emmc_base+0x00000030))
  345. #define EMMC_INT_MASK ((volatile uint32_t*)(emmc_base+0x00000034))
  346. #define EMMC_INT_EN ((volatile uint32_t*)(emmc_base+0x00000038))
  347. #define EMMC_CONTROL2 ((volatile uint32_t*)(emmc_base+0x0000003C))
  348. #define EMMC_SLOTISR_VER ((volatile uint32_t*)(emmc_base+0x000000FC))
  349. // command flags
  350. #define CMD_NEED_APP 0x80000000
  351. #define CMD_RSPNS_48 0x00020000
  352. #define CMD_ERRORS_MASK 0xfff9c004
  353. #define CMD_RCA_MASK 0xffff0000
  354. // COMMANDs
  355. #define CMD_GO_IDLE 0x00000000
  356. #define CMD_ALL_SEND_CID 0x02010000
  357. #define CMD_SEND_REL_ADDR 0x03020000
  358. #define CMD_CARD_SELECT 0x07030000
  359. #define CMD_SEND_IF_COND 0x08020000
  360. #define CMD_STOP_TRANS 0x0C030000
  361. #define CMD_READ_SINGLE 0x11220010
  362. #define CMD_READ_MULTI 0x12220032
  363. #define CMD_SET_BLOCKCNT 0x17020000
  364. #define CMD_APP_CMD 0x37000000
  365. #define CMD_SET_BUS_WIDTH (0x06020000|CMD_NEED_APP)
  366. #define CMD_SEND_OP_COND (0x29020000|CMD_NEED_APP)
  367. #define CMD_SEND_SCR (0x33220010|CMD_NEED_APP)
  368. // STATUS register settings
  369. #define SR_READ_AVAILABLE 0x00000800
  370. #define SR_DAT_INHIBIT 0x00000002
  371. #define SR_CMD_INHIBIT 0x00000001
  372. #define SR_APP_CMD 0x00000020
  373. // INTERRUPT register settings
  374. #define INT_DATA_TIMEOUT 0x00100000
  375. #define INT_CMD_TIMEOUT 0x00010000
  376. #define INT_READ_RDY 0x00000020
  377. #define INT_CMD_DONE 0x00000001
  378. #define INT_ERROR_MASK 0x017E8000
  379. // CONTROL register settings
  380. #define C0_SPI_MODE_EN 0x00100000
  381. #define C0_HCTL_HS_EN 0x00000004
  382. #define C0_HCTL_DWITDH 0x00000002
  383. #define C1_SRST_DATA 0x04000000
  384. #define C1_SRST_CMD 0x02000000
  385. #define C1_SRST_HC 0x01000000
  386. #define C1_TOUNIT_DIS 0x000f0000
  387. #define C1_TOUNIT_MAX 0x000e0000
  388. #define C1_CLK_GENSEL 0x00000020
  389. #define C1_CLK_EN 0x00000004
  390. #define C1_CLK_STABLE 0x00000002
  391. #define C1_CLK_INTLEN 0x00000001
  392. // SLOTISR_VER values
  393. #define HOST_SPEC_NUM 0x00ff0000
  394. #define HOST_SPEC_NUM_SHIFT 16
  395. #define HOST_SPEC_V3 2
  396. #define HOST_SPEC_V2 1
  397. #define HOST_SPEC_V1 0
  398. // SCR flags
  399. #define SCR_SD_BUS_WIDTH_4 0x00000400
  400. #define SCR_SUPP_SET_BLKCNT 0x02000000
  401. // added by my driver
  402. #define SCR_SUPP_CCS 0x00000001
  403. #define ACMD41_VOLTAGE 0x00ff8000
  404. #define ACMD41_CMD_COMPLETE 0x80000000
  405. #define ACMD41_CMD_CCS 0x40000000
  406. #define ACMD41_ARG_HC 0x51ff8000
  407. #define SD_OK 0
  408. #define SD_TIMEOUT -1
  409. #define SD_ERROR -2
  410. uint32_t sd_scr[2], sd_ocr, sd_rca, sd_hv;
  411. int sd_err;
  412. /**
  413. * Wait for data or command ready
  414. */
  415. int sd_status(uint32_t mask)
  416. {
  417. int cnt = 500000; while((*EMMC_STATUS & mask) && !(*EMMC_INTERRUPT & INT_ERROR_MASK) && cnt--) delaym(1);
  418. return (cnt <= 0 || (*EMMC_INTERRUPT & INT_ERROR_MASK)) ? SD_ERROR : SD_OK;
  419. }
  420. /**
  421. * Wait for interrupt
  422. */
  423. int sd_int(uint32_t mask)
  424. {
  425. uint32_t r, m=mask | INT_ERROR_MASK;
  426. int cnt = 1000000; while(!(*EMMC_INTERRUPT & m) && cnt--) delaym(1);
  427. r=*EMMC_INTERRUPT;
  428. if(cnt<=0 || (r & INT_CMD_TIMEOUT) || (r & INT_DATA_TIMEOUT) ) { *EMMC_INTERRUPT=r; return SD_TIMEOUT; } else
  429. if(r & INT_ERROR_MASK) { *EMMC_INTERRUPT=r; return SD_ERROR; }
  430. *EMMC_INTERRUPT=mask;
  431. return 0;
  432. }
  433. /**
  434. * Send a command
  435. */
  436. int sd_cmd(uint32_t code, uint32_t arg)
  437. {
  438. uint32_t r=0;
  439. sd_err=SD_OK;
  440. if(code&CMD_NEED_APP) {
  441. r=sd_cmd(CMD_APP_CMD|(sd_rca?CMD_RSPNS_48:0),sd_rca);
  442. if(sd_rca && !r) { DBG("BOOTBOOT-ERROR: failed to send SD APP command\n"); sd_err=SD_ERROR;return 0;}
  443. code &= ~CMD_NEED_APP;
  444. }
  445. if(sd_status(SR_CMD_INHIBIT)) { DBG("BOOTBOOT-ERROR: EMMC busy\n"); sd_err= SD_TIMEOUT;return 0;}
  446. #if SD_DEBUG
  447. uart_puts("EMMC: Sending command ");uart_hex(code,4);uart_puts(" arg ");uart_hex(arg,4);uart_putc('\n');
  448. #endif
  449. *EMMC_INTERRUPT=*EMMC_INTERRUPT; *EMMC_ARG1=arg; *EMMC_CMDTM=code;
  450. if(code==CMD_SEND_OP_COND) delaym(1000); else
  451. if(code==CMD_SEND_IF_COND || code==CMD_APP_CMD) delaym(100);
  452. if((r=sd_int(INT_CMD_DONE))) {DBG("BOOTBOOT-ERROR: failed to send EMMC command\n");sd_err=r;return 0;}
  453. r=*EMMC_RESP0;
  454. if(code==CMD_GO_IDLE || code==CMD_APP_CMD) return 0; else
  455. if(code==(CMD_APP_CMD|CMD_RSPNS_48)) return r&SR_APP_CMD; else
  456. if(code==CMD_SEND_OP_COND) return r; else
  457. if(code==CMD_SEND_IF_COND) return r==arg? SD_OK : SD_ERROR; else
  458. if(code==CMD_ALL_SEND_CID) {r|=*EMMC_RESP3; r|=*EMMC_RESP2; r|=*EMMC_RESP1; return r; } else
  459. if(code==CMD_SEND_REL_ADDR) {
  460. sd_err=(((r&0x1fff))|((r&0x2000)<<6)|((r&0x4000)<<8)|((r&0x8000)<<8))&CMD_ERRORS_MASK;
  461. return r&CMD_RCA_MASK;
  462. }
  463. return r&CMD_ERRORS_MASK;
  464. // make gcc happy
  465. return 0;
  466. }
  467. /**
  468. * read a block from sd card and return the number of bytes read
  469. * returns 0 on error.
  470. */
  471. int sd_readblock(uint64_t lba, uint8_t *buffer, uint32_t num)
  472. {
  473. int r,c=0,d;
  474. if(num<1) num=1;
  475. #if SD_DEBUG
  476. uart_puts("sd_readblock lba ");uart_hex(lba,4);uart_puts(" num ");uart_hex(num,4);uart_putc('\n');
  477. #endif
  478. if(sd_status(SR_DAT_INHIBIT)) {sd_err=SD_TIMEOUT; return 0;}
  479. uint32_t *buf=(uint32_t *)buffer;
  480. if(sd_scr[0] & SCR_SUPP_CCS) {
  481. if(num > 1 && (sd_scr[0] & SCR_SUPP_SET_BLKCNT)) {
  482. sd_cmd(CMD_SET_BLOCKCNT,num);
  483. if(sd_err) return 0;
  484. }
  485. *EMMC_BLKSIZECNT = (num << 16) | 512;
  486. sd_cmd(num == 1 ? CMD_READ_SINGLE : CMD_READ_MULTI,lba);
  487. if(sd_err) return 0;
  488. } else {
  489. *EMMC_BLKSIZECNT = (1 << 16) | 512;
  490. }
  491. while( (uint32_t)c < num ) {
  492. if(!(sd_scr[0] & SCR_SUPP_CCS)) {
  493. sd_cmd(CMD_READ_SINGLE,(lba+c)*512);
  494. if(sd_err) return 0;
  495. }
  496. if((r=sd_int(INT_READ_RDY))){DBG("\rBOOTBOOT-ERROR: Timeout waiting for ready to read\n");sd_err=r;return 0;}
  497. for(d=0;d<128;d++) buf[d] = *EMMC_DATA;
  498. c++; buf+=128;
  499. }
  500. #if SD_DEBUG
  501. uart_dump(buffer,4);
  502. #endif
  503. if( num > 1 && !(sd_scr[0] & SCR_SUPP_SET_BLKCNT) && (sd_scr[0] & SCR_SUPP_CCS)) sd_cmd(CMD_STOP_TRANS,0);
  504. return sd_err!=SD_OK || (uint32_t)c!=num? 0 : num*512;
  505. }
  506. /**
  507. * set SD clock to frequency in Hz
  508. */
  509. int sd_clk(uint32_t f)
  510. {
  511. uint32_t d,c=41666666/f,x,s=32,h=0;
  512. int cnt = 100000;
  513. while((*EMMC_STATUS & (SR_CMD_INHIBIT|SR_DAT_INHIBIT)) && cnt--) delaym(1);
  514. if(cnt<=0) {
  515. DBG("BOOTBOOT-ERROR: timeout waiting for inhibit flag\n");
  516. return SD_ERROR;
  517. }
  518. *EMMC_CONTROL1 &= ~C1_CLK_EN; delaym(10);
  519. x=c-1; if(!x) s=0; else {
  520. if(!(x & 0xffff0000u)) { x <<= 16; s -= 16; }
  521. if(!(x & 0xff000000u)) { x <<= 8; s -= 8; }
  522. if(!(x & 0xf0000000u)) { x <<= 4; s -= 4; }
  523. if(!(x & 0xc0000000u)) { x <<= 2; s -= 2; }
  524. if(!(x & 0x80000000u)) { x <<= 1; s -= 1; }
  525. if(s>0) s--;
  526. if(s>7) s=7;
  527. }
  528. if(sd_hv>HOST_SPEC_V2) d=c; else d=(1<<s);
  529. if(d<=2) {d=2;s=0;}
  530. #if SD_DEBUG
  531. uart_puts("sd_clk divisor ");uart_hex(d,4);uart_puts(", shift ");uart_hex(s,4);uart_putc('\n');
  532. #endif
  533. if(sd_hv>HOST_SPEC_V2) h=(d&0x300)>>2;
  534. d=(((d&0x0ff)<<8)|h);
  535. *EMMC_CONTROL1=(*EMMC_CONTROL1&0xffff003f)|d; delaym(10);
  536. *EMMC_CONTROL1 |= C1_CLK_EN; delaym(10);
  537. cnt=10000; while(!(*EMMC_CONTROL1 & C1_CLK_STABLE) && cnt--) delaym(10);
  538. if(cnt<=0) {
  539. DBG("BOOTBOOT-ERROR: failed to get stable clock\n");
  540. return SD_ERROR;
  541. }
  542. return SD_OK;
  543. }
  544. /**
  545. * initialize EMMC to read SDHC card
  546. */
  547. int sd_init()
  548. {
  549. long r,cnt,ccs=0;
  550. // GPIO_CD
  551. r=*GPFSEL4; r&=~(7<<(7*3)); *GPFSEL4=r;
  552. *GPPUD=2; delay(150); *GPPUDCLK1=(1<<15); delay(150); *GPPUD=0; *GPPUDCLK1=0;
  553. r=*GPHEN1; r|=1<<15; *GPHEN1=r;
  554. // GPIO_CLK, GPIO_CMD
  555. r=*GPFSEL4; r|=(7<<(8*3))|(7<<(9*3)); *GPFSEL4=r;
  556. *GPPUD=2; delay(150); *GPPUDCLK1=(1<<16)|(1<<17); delay(150); *GPPUD=0; *GPPUDCLK1=0;
  557. // GPIO_DAT0, GPIO_DAT1, GPIO_DAT2, GPIO_DAT3
  558. r=*GPFSEL5; r|=(7<<(0*3)) | (7<<(1*3)) | (7<<(2*3)) | (7<<(3*3)); *GPFSEL5=r;
  559. *GPPUD=2; delay(150);
  560. *GPPUDCLK1=(1<<18) | (1<<19) | (1<<20) | (1<<21);
  561. delay(150); *GPPUD=0; *GPPUDCLK1=0;
  562. sd_hv = (*EMMC_SLOTISR_VER & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
  563. #if SD_DEBUG
  564. uart_puts("EMMC: GPIO set up\n");
  565. #endif
  566. // Reset the card.
  567. *EMMC_CONTROL0 = 0; *EMMC_CONTROL1 |= C1_SRST_HC;
  568. cnt=10000; do{delaym(10);} while( (*EMMC_CONTROL1 & C1_SRST_HC) && cnt-- );
  569. if(cnt<=0) {
  570. DBG("BOOTBOOT-ERROR: failed to reset EMMC\n");
  571. return SD_ERROR;
  572. }
  573. #if SD_DEBUG
  574. uart_puts("EMMC: reset OK\n");
  575. #endif
  576. *EMMC_CONTROL0 = 0xF << 8; // set voltage to 3.3
  577. *EMMC_CONTROL1 |= C1_CLK_INTLEN | C1_TOUNIT_MAX;
  578. delaym(10);
  579. // Set clock to setup frequency.
  580. if((r=sd_clk(400000))) return r;
  581. *EMMC_INT_EN = 0xffffffff;
  582. *EMMC_INT_MASK = 0xffffffff;
  583. sd_scr[0]=sd_scr[1]=sd_rca=sd_err=0;
  584. sd_cmd(CMD_GO_IDLE,0);
  585. if(sd_err) return sd_err;
  586. sd_cmd(CMD_SEND_IF_COND,0x000001AA);
  587. if(sd_err) return sd_err;
  588. cnt=6; r=0; while(!(r&ACMD41_CMD_COMPLETE) && cnt--) {
  589. delay(400);
  590. r=sd_cmd(CMD_SEND_OP_COND,ACMD41_ARG_HC);
  591. #if SD_DEBUG
  592. uart_puts("EMMC: CMD_SEND_OP_COND returned ");
  593. if(r&ACMD41_CMD_COMPLETE)
  594. uart_puts("COMPLETE ");
  595. if(r&ACMD41_VOLTAGE)
  596. uart_puts("VOLTAGE ");
  597. if(r&ACMD41_CMD_CCS)
  598. uart_puts("CCS ");
  599. uart_hex(r,8);
  600. uart_putc('\n');
  601. #endif
  602. if(sd_err!=SD_TIMEOUT && sd_err!=SD_OK ) {
  603. DBG("BOOTBOOT-ERROR: EMMC ACMD41 returned error\n");
  604. return sd_err;
  605. }
  606. }
  607. if(!(r&ACMD41_CMD_COMPLETE) || !cnt ) return SD_TIMEOUT;
  608. if(!(r&ACMD41_VOLTAGE)) return SD_ERROR;
  609. if(r&ACMD41_CMD_CCS) ccs=SCR_SUPP_CCS;
  610. sd_cmd(CMD_ALL_SEND_CID,0);
  611. sd_rca = sd_cmd(CMD_SEND_REL_ADDR,0);
  612. #if SD_DEBUG
  613. uart_puts("EMMC: CMD_SEND_REL_ADDR returned ");
  614. uart_hex(sd_rca,8);
  615. uart_putc('\n');
  616. #endif
  617. if(sd_err) return sd_err;
  618. if((r=sd_clk(25000000))) return r;
  619. sd_cmd(CMD_CARD_SELECT,sd_rca);
  620. if(sd_err) return sd_err;
  621. if(sd_status(SR_DAT_INHIBIT)) return SD_TIMEOUT;
  622. *EMMC_BLKSIZECNT = (1<<16) | 8;
  623. sd_cmd(CMD_SEND_SCR,0);
  624. if(sd_err) return sd_err;
  625. if(sd_int(INT_READ_RDY)) return SD_TIMEOUT;
  626. r=0; cnt=100000; while(r<2 && cnt) {
  627. if( *EMMC_STATUS & SR_READ_AVAILABLE )
  628. sd_scr[r++] = *EMMC_DATA;
  629. else
  630. delaym(1);
  631. }
  632. if(r!=2) return SD_TIMEOUT;
  633. if(sd_scr[0] & SCR_SD_BUS_WIDTH_4) {
  634. sd_cmd(CMD_SET_BUS_WIDTH,sd_rca|2);
  635. if(sd_err) return sd_err;
  636. *EMMC_CONTROL0 |= C0_HCTL_DWITDH;
  637. }
  638. // add software flag
  639. #ifdef SD_DEBUG
  640. uart_puts("EMMC: supports ");
  641. if(sd_scr[0] & SCR_SUPP_SET_BLKCNT)
  642. uart_puts("SET_BLKCNT ");
  643. if(ccs)
  644. uart_puts("CCS ");
  645. uart_putc('\n');
  646. #endif
  647. sd_scr[0]&=~SCR_SUPP_CCS;
  648. sd_scr[0]|=ccs;
  649. return SD_OK;
  650. }
  651. /*** other defines and structs ***/
  652. typedef struct {
  653. uint32_t type[4];
  654. uint8_t uuid[16];
  655. uint64_t start;
  656. uint64_t end;
  657. uint64_t flags;
  658. uint8_t name[72];
  659. } efipart_t;
  660. typedef struct {
  661. char jmp[3];
  662. char oem[8];
  663. uint16_t bps;
  664. uint8_t spc;
  665. uint16_t rsc;
  666. uint8_t nf;
  667. uint8_t nr0;
  668. uint8_t nr1;
  669. uint16_t ts16;
  670. uint8_t media;
  671. uint16_t spf16;
  672. uint16_t spt;
  673. uint16_t nh;
  674. uint32_t hs;
  675. uint32_t ts32;
  676. uint32_t spf32;
  677. uint32_t flg;
  678. uint32_t rc;
  679. char vol[6];
  680. char fst[8];
  681. char dmy[20];
  682. char fst2[8];
  683. } __attribute__((packed)) bpb_t;
  684. typedef struct {
  685. char name[8];
  686. char ext[3];
  687. char attr[9];
  688. uint16_t ch;
  689. uint32_t attr2;
  690. uint16_t cl;
  691. uint32_t size;
  692. } __attribute__((packed)) fatdir_t;
  693. typedef struct {
  694. uint32_t magic;
  695. uint32_t version;
  696. uint32_t headersize;/* offset of bitmaps in file */
  697. uint16_t flags; /* original PSF2 has 32 bit flags */
  698. uint8_t hotspot_x; /* addition to OS/Z */
  699. uint8_t hotspot_y;
  700. uint32_t numglyph;
  701. uint32_t bytesperglyph;
  702. uint32_t height;
  703. uint32_t width;
  704. uint8_t glyphs;
  705. } __attribute__((packed)) font_t;
  706. extern volatile unsigned char _binary_font_psf_start;
  707. /**
  708. * return type for fs drivers
  709. */
  710. typedef struct {
  711. uint8_t *ptr;
  712. uint64_t size;
  713. } file_t;
  714. /*** common variables ***/
  715. file_t env; // environment file descriptor
  716. file_t initrd; // initrd file descriptor
  717. file_t core; // kernel file descriptor
  718. BOOTBOOT *bootboot; // the BOOTBOOT structure
  719. uint64_t mm_addr = BOOTBOOT_MMIO; // virtual addresses
  720. uint64_t fb_addr = BOOTBOOT_FB;
  721. uint64_t bb_addr = BOOTBOOT_INFO;
  722. uint64_t env_addr= BOOTBOOT_ENV;
  723. uint64_t core_addr=BOOTBOOT_CORE;
  724. uint64_t initstack = 1024;
  725. // default environment variables. M$ states that 1024x768 must be supported
  726. unsigned int reqwidth = 1024, reqheight = 768;
  727. char *kernelname="sys/core";
  728. unsigned char *kne;
  729. // alternative environment name
  730. char *cfgname="sys/config";
  731. uint64_t entrypoint=0, bss=0, *paging, reg, pa;
  732. static volatile uint8_t bsp_done=0;
  733. /**
  734. * SHA-256
  735. */
  736. typedef struct {
  737. uint8_t d[64];
  738. uint32_t l;
  739. uint32_t b[2];
  740. uint32_t s[8];
  741. } SHA256_CTX;
  742. #define SHA_ADD(a,b,c) if(a>0xffffffff-(c))b++;a+=c;
  743. #define SHA_ROTL(a,b) (((a)<<(b))|((a)>>(32-(b))))
  744. #define SHA_ROTR(a,b) (((a)>>(b))|((a)<<(32-(b))))
  745. #define SHA_CH(x,y,z) (((x)&(y))^(~(x)&(z)))
  746. #define SHA_MAJ(x,y,z) (((x)&(y))^((x)&(z))^((y)&(z)))
  747. #define SHA_EP0(x) (SHA_ROTR(x,2)^SHA_ROTR(x,13)^SHA_ROTR(x,22))
  748. #define SHA_EP1(x) (SHA_ROTR(x,6)^SHA_ROTR(x,11)^SHA_ROTR(x,25))
  749. #define SHA_SIG0(x) (SHA_ROTR(x,7)^SHA_ROTR(x,18)^((x)>>3))
  750. #define SHA_SIG1(x) (SHA_ROTR(x,17)^SHA_ROTR(x,19)^((x)>>10))
  751. static uint32_t sha256_k[64]={
  752. 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
  753. 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
  754. 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
  755. 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
  756. 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
  757. 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
  758. 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
  759. 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
  760. };
  761. void sha256_t(SHA256_CTX *ctx)
  762. {
  763. uint32_t a,b,c,d,e,f,g,h,i,j,t1,t2,m[64];
  764. for(i=0,j=0;i<16;i++,j+=4) m[i]=(ctx->d[j]<<24)|(ctx->d[j+1]<<16)|(ctx->d[j+2]<<8)|(ctx->d[j+3]);
  765. for(;i<64;i++) m[i]=SHA_SIG1(m[i-2])+m[i-7]+SHA_SIG0(m[i-15])+m[i-16];
  766. a=ctx->s[0];b=ctx->s[1];c=ctx->s[2];d=ctx->s[3];
  767. e=ctx->s[4];f=ctx->s[5];g=ctx->s[6];h=ctx->s[7];
  768. for(i=0;i<64;i++) {
  769. t1=h+SHA_EP1(e)+SHA_CH(e,f,g)+sha256_k[i]+m[i];
  770. t2=SHA_EP0(a)+SHA_MAJ(a,b,c);h=g;g=f;f=e;e=d+t1;d=c;c=b;b=a;a=t1+t2;
  771. }
  772. ctx->s[0]+=a;ctx->s[1]+=b;ctx->s[2]+=c;ctx->s[3]+=d;
  773. ctx->s[4]+=e;ctx->s[5]+=f;ctx->s[6]+=g;ctx->s[7]+=h;
  774. }
  775. void SHA256_Init(SHA256_CTX *ctx)
  776. {
  777. ctx->l=0;ctx->b[0]=ctx->b[1]=0;
  778. ctx->s[0]=0x6a09e667;ctx->s[1]=0xbb67ae85;ctx->s[2]=0x3c6ef372;ctx->s[3]=0xa54ff53a;
  779. ctx->s[4]=0x510e527f;ctx->s[5]=0x9b05688c;ctx->s[6]=0x1f83d9ab;ctx->s[7]=0x5be0cd19;
  780. }
  781. void SHA256_Update(SHA256_CTX *ctx, const void *data, int len)
  782. {
  783. uint8_t *d=(uint8_t *)data;
  784. for(;len--;d++) {
  785. ctx->d[ctx->l++]=*d;
  786. if(ctx->l==64) {sha256_t(ctx);SHA_ADD(ctx->b[0],ctx->b[1],512);ctx->l=0;}
  787. }
  788. }
  789. void SHA256_Final(unsigned char *h, SHA256_CTX *ctx)
  790. {
  791. uint32_t i=ctx->l;
  792. ctx->d[i++]=0x80;
  793. if(ctx->l<56) {while(i<56) ctx->d[i++]=0x00;}
  794. else {while(i<64) ctx->d[i++]=0x00;sha256_t(ctx);memset(ctx->d,0,56);}
  795. SHA_ADD(ctx->b[0],ctx->b[1],ctx->l*8);
  796. ctx->d[63]=ctx->b[0];ctx->d[62]=ctx->b[0]>>8;ctx->d[61]=ctx->b[0]>>16;ctx->d[60]=ctx->b[0]>>24;
  797. ctx->d[59]=ctx->b[1];ctx->d[58]=ctx->b[1]>>8;ctx->d[57]=ctx->b[1]>>16;ctx->d[56]=ctx->b[1]>>24;
  798. sha256_t(ctx);
  799. for(i=0;i<4;i++) {
  800. h[i] =(ctx->s[0]>>(24-i*8)); h[i+4] =(ctx->s[1]>>(24-i*8));
  801. h[i+8] =(ctx->s[2]>>(24-i*8)); h[i+12]=(ctx->s[3]>>(24-i*8));
  802. h[i+16]=(ctx->s[4]>>(24-i*8)); h[i+20]=(ctx->s[5]>>(24-i*8));
  803. h[i+24]=(ctx->s[6]>>(24-i*8)); h[i+28]=(ctx->s[7]>>(24-i*8));
  804. }
  805. }
  806. /**
  807. * precalculated CRC32c lookup table for polynomial 0x1EDC6F41 (castagnoli-crc)
  808. */
  809. uint32_t crc32c_lookup[256]={
  810. 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
  811. 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
  812. 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
  813. 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
  814. 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
  815. 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
  816. 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
  817. 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
  818. 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
  819. 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
  820. 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
  821. 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
  822. 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
  823. 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
  824. 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
  825. 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
  826. 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
  827. 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
  828. 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
  829. 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
  830. 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
  831. 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
  832. 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
  833. 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
  834. 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
  835. 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
  836. 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
  837. 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
  838. 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
  839. 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
  840. 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
  841. 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
  842. };
  843. uint32_t crc32_calc(char *start,int length)
  844. {
  845. uint32_t crc32_val=0;
  846. while(length--) crc32_val=(crc32_val>>8)^crc32c_lookup[(crc32_val&0xff)^(unsigned char)*start++];
  847. return crc32_val;
  848. }
  849. /**
  850. * Read a line from UART
  851. */
  852. int ReadLine(unsigned char *buf, int l)
  853. {
  854. int i=0;
  855. char c;
  856. while(1) {
  857. c=uart_getc();
  858. if(c=='\n' || c=='\r') {
  859. break;
  860. } else
  861. if(c==8) {
  862. if(i) i--;
  863. buf[i]=0;
  864. continue;
  865. } else
  866. if(c==27) {
  867. buf[0]=0;
  868. return 0;
  869. } else
  870. if(c && i<l-1) {
  871. buf[i++]=c;
  872. buf[i]=0;
  873. }
  874. }
  875. return i;
  876. }
  877. // get filesystem drivers for initrd
  878. #include "fs.h"
  879. /* current cursor position */
  880. unsigned int kx, ky;
  881. /* maximum coordinates */
  882. unsigned int maxx, maxy;
  883. /**
  884. * Get a linear frame buffer
  885. */
  886. int GetLFB(uint32_t width, uint32_t height)
  887. {
  888. font_t *font = (font_t*)&_binary_font_psf_start;
  889. //query natural width, height if not given
  890. if(width==0 && height==0) {
  891. mbox[0] = 8*4;
  892. mbox[1] = MBOX_REQUEST;
  893. mbox[2] = 0x40003; //get phy wh
  894. mbox[3] = 8;
  895. mbox[4] = 8;
  896. mbox[5] = 0;
  897. mbox[6] = 0;
  898. mbox[7] = 0;
  899. if(mbox_call(MBOX_CH_PROP,mbox) && mbox[5]!=0) {
  900. width=mbox[5];
  901. height=mbox[6];
  902. }
  903. }
  904. //if we already have a framebuffer, release it
  905. if(bootboot->fb_ptr) {
  906. mbox[0] = 8*4;
  907. mbox[1] = MBOX_REQUEST;
  908. mbox[2] = 0x48001; //release buffer
  909. mbox[3] = 8;
  910. mbox[4] = 8;
  911. mbox[5] = (uint32_t)bootboot->fb_ptr;
  912. mbox[6] = 0;
  913. mbox[7] = 0;
  914. mbox_call(MBOX_CH_PROP,mbox);
  915. }
  916. //check minimum resolution
  917. if(width<640) width=640;
  918. if(height<480) height=480;
  919. mbox[0] = 35*4;
  920. mbox[1] = MBOX_REQUEST;
  921. mbox[2] = 0x48003; //set phy wh
  922. mbox[3] = 8;
  923. mbox[4] = 8;
  924. mbox[5] = width; //FrameBufferInfo.width
  925. mbox[6] = height; //FrameBufferInfo.height
  926. mbox[7] = 0x48004; //set virt wh
  927. mbox[8] = 8;
  928. mbox[9] = 8;
  929. mbox[10] = width; //FrameBufferInfo.virtual_width
  930. mbox[11] = height; //FrameBufferInfo.virtual_height
  931. mbox[12] = 0x48009; //set virt offset
  932. mbox[13] = 8;
  933. mbox[14] = 8;
  934. mbox[15] = 0; //FrameBufferInfo.x_offset
  935. mbox[16] = 0; //FrameBufferInfo.y.offset
  936. mbox[17] = 0x48005; //set depth
  937. mbox[18] = 4;
  938. mbox[19] = 4;
  939. mbox[20] = 32; //FrameBufferInfo.depth
  940. mbox[21] = 0x48006; //set pixel order
  941. mbox[22] = 4;
  942. mbox[23] = 4;
  943. mbox[24] = 0; //RGB, not BGR preferably
  944. mbox[25] = 0x40001; //get framebuffer, gets alignment on request
  945. mbox[26] = 8;
  946. mbox[27] = 8;
  947. mbox[28] = PAGESIZE; //FrameBufferInfo.pointer
  948. mbox[29] = 0; //FrameBufferInfo.size
  949. mbox[30] = 0x40008; //get pitch
  950. mbox[31] = 4;
  951. mbox[32] = 4;
  952. mbox[33] = 0; //FrameBufferInfo.pitch
  953. mbox[34] = 0; //Arnold Schwarzenegger
  954. if(mbox_call(MBOX_CH_PROP,mbox) && mbox[20]==32 && mbox[27]==(MBOX_RESPONSE|8) && mbox[28]!=0) {
  955. mbox[28]&=0x3FFFFFFF;
  956. bootboot->fb_width=mbox[5];
  957. bootboot->fb_height=mbox[6];
  958. bootboot->fb_scanline=mbox[33];
  959. bootboot->fb_ptr=(uint64_t)mbox[28];
  960. bootboot->fb_size=mbox[29];
  961. bootboot->fb_type=mbox[24]?FB_ABGR:FB_ARGB;
  962. kx=ky=0;
  963. maxx=bootboot->fb_width/(font->width+1);
  964. maxy=bootboot->fb_height/font->height;
  965. return 1;
  966. }
  967. return 0;
  968. }
  969. /**
  970. * display one literal unicode character
  971. */
  972. void putc(char c)
  973. {
  974. font_t *font = (font_t*)&_binary_font_psf_start;
  975. unsigned char *glyph = (unsigned char*)&_binary_font_psf_start +
  976. font->headersize + (c>0&&c<font->numglyph?c:0)*font->bytesperglyph;
  977. int offs = (ky * font->height * bootboot->fb_scanline) + (kx * (font->width+1) * 4);
  978. unsigned int x,y, line,mask;
  979. int bytesperline=(font->width+7)/8;
  980. if(c=='\r') {
  981. kx=0;
  982. } else
  983. if(c=='\n') {
  984. kx=0; ky++;
  985. } else {
  986. for(y=0;y<font->height;y++){
  987. line=offs;
  988. mask=1<<(font->width-1);
  989. for(x=0;x<font->width;x++){
  990. *((uint32_t*)(bootboot->fb_ptr + line))=((int)*glyph) & (mask)?color:0;
  991. mask>>=1;
  992. line+=4;
  993. }
  994. *((uint32_t*)(bootboot->fb_ptr + line))=0;
  995. glyph+=bytesperline;
  996. offs+=bootboot->fb_scanline;
  997. }
  998. kx++;
  999. if(kx>=maxx) {
  1000. kx=0; ky++;
  1001. }
  1002. }
  1003. // send it to serial too
  1004. uart_putc(c);
  1005. }
  1006. /**
  1007. * display a string
  1008. */
  1009. void puts(char *s) { while(*s) putc(*s++); }
  1010. /**
  1011. * Add a mapping to paging tables
  1012. */
  1013. int freep = 37;
  1014. void MapPage(uint64_t virt, uint64_t phys)
  1015. {
  1016. int i,j;
  1017. j = (virt>>(9+12)) & 0x1FF;
  1018. if(!paging[4*512 + j] || (paging[4*512 + j] & (2<<2))) {
  1019. if(freep == 50) return;
  1020. paging[4*512 + j]=(uint64_t)((uint8_t *)paging+freep*PAGESIZE)|0x03|(3<<8)|(1<<10);
  1021. freep++;
  1022. }
  1023. i = (paging[4*512 + j] - (uint64_t)((uint8_t *)paging)) >> 12;
  1024. j = (virt>>(12)) & 0x1FF;
  1025. paging[i*512 + j] = phys;
  1026. }
  1027. /**
  1028. * Parse FS0:\BOOTBOOT\CONFIG or /sys/config
  1029. */
  1030. void ParseEnvironment(uint8_t *env)
  1031. {
  1032. uint8_t *end=env+PAGESIZE, *start=env;
  1033. DBG(" * Environment\n");
  1034. env--; env[PAGESIZE]=0; kne=NULL;
  1035. while(env<end) {
  1036. env++;
  1037. // failsafe
  1038. if(env[0]==0)
  1039. break;
  1040. // skip white spaces
  1041. if(env[0]==' '||env[0]=='\t'||env[0]=='\r'||env[0]=='\n')
  1042. continue;
  1043. // skip comments
  1044. if((env[0]=='/'&&env[1]=='/')||env[0]=='#') {
  1045. while(env<end && env[0]!='\r' && env[0]!='\n' && env[0]!=0){
  1046. env++;
  1047. }
  1048. env--;
  1049. continue;
  1050. }
  1051. if(env[0]=='/'&&env[1]=='*') {
  1052. env+=2;
  1053. while(env[0]!=0 && env[-1]!='*' && env[0]!='/')
  1054. env++;
  1055. }
  1056. // only match on beginning of line
  1057. if(env>start && env[-1]!=' '&&env[-1]!='\t'&&env[-1]!='\r'&&env[-1]!='\n')
  1058. continue;
  1059. // parse screen dimensions
  1060. if(!memcmp(env,"screen=",7)){
  1061. env+=7;
  1062. reqwidth=atoi(env);
  1063. while(env<end && *env!=0 && *(env-1)!='x') env++;
  1064. reqheight=atoi(env);
  1065. }
  1066. // get kernel's filename
  1067. if(!memcmp(env,"kernel=",7)){
  1068. env+=7;
  1069. kernelname=(char*)env;
  1070. while(env<end && env[0]!='\r' && env[0]!='\n' &&
  1071. env[0]!=' ' && env[0]!='\t' && env[0]!=0)
  1072. env++;
  1073. kne=env;
  1074. *env=0;
  1075. env++;
  1076. }
  1077. }
  1078. }
  1079. /**
  1080. * bootboot entry point, run only on BSP core
  1081. */
  1082. int bootboot_main()
  1083. {
  1084. uint8_t *pe,bkp=0;
  1085. uint32_t np,sp,r,mp,j;
  1086. efipart_t *part;
  1087. volatile bpb_t *bpb;
  1088. MMapEnt *mmap;
  1089. /* first things first, get the base address */
  1090. asm volatile ("mrs %0, midr_el1" : "=r" (reg));
  1091. switch(reg&0xFFF0) {
  1092. case 0xD030: mmio_base = 0x3F000000; emmc_base = 0x3F300000; break; /* Raspberry Pi 3 */
  1093. default: mmio_base = 0xFE000000; emmc_base = 0xFE340000; break; /* Raspberry Pi 4 */
  1094. }
  1095. /* initialize UART */
  1096. *UART0_CR = 0; // turn off UART0
  1097. *AUX_ENABLE = 0; // turn off UART1
  1098. /* set up clock for consistent divisor values */
  1099. mbox[0] = 8*4;
  1100. mbox[1] = MBOX_REQUEST;
  1101. mbox[2] = 0x38002; // set clock rate
  1102. mbox[3] = 12;
  1103. mbox[4] = 8;
  1104. mbox[5] = 2; // UART clock
  1105. mbox[6] = 4000000; // 4Mhz
  1106. mbox[7] = 0; // set turbo
  1107. mbox_call(MBOX_CH_PROP,mbox);
  1108. #if CONSOLE == UART1
  1109. *AUX_ENABLE |=1; // enable UART1, AUX mini uart
  1110. *AUX_MU_CNTL = 0;
  1111. *AUX_MU_LCR = 3; // 8 bits
  1112. *AUX_MU_MCR = 0;
  1113. *AUX_MU_IER = 0;
  1114. *AUX_MU_IIR = 0xc6; // disable interrupts
  1115. *AUX_MU_BAUD = 270; // 115200 baud
  1116. r=*GPFSEL1;
  1117. r&=~((7<<12)|(7<<15)); // gpio14, gpio15
  1118. r|=(2<<12)|(2<<15); // alt5
  1119. *GPFSEL1 = r;
  1120. #else
  1121. r=*GPFSEL1;
  1122. r&=~((7<<12)|(7<<15)); // gpio14, gpio15
  1123. r|=(4<<12)|(4<<15); // alt0
  1124. *GPFSEL1 = r;
  1125. #endif
  1126. *GPPUD = 0; // enable pins 14 and 15
  1127. delay(150);
  1128. *GPPUDCLK0 = (1<<14)|(1<<15);
  1129. delay(150);
  1130. *GPPUDCLK0 = 0; // flush GPIO setup
  1131. #if CONSOLE == UART1
  1132. *AUX_MU_CNTL = 3; // enable Tx, Rx
  1133. #else
  1134. *UART0_ICR = 0x7FF; // clear interrupts
  1135. *UART0_IBRD = 2; // 115200 baud
  1136. *UART0_FBRD = 0xB;
  1137. *UART0_LCRH = 0x03<<5; // 8n1
  1138. // *UART0_IMSC = 0x7F2; // mask interrupts
  1139. *UART0_CR = 0x301; // enable Tx, Rx, FIFO
  1140. #endif
  1141. /* create bootboot structure */
  1142. bootboot = (BOOTBOOT*)&__bootboot;
  1143. memset(bootboot,0,PAGESIZE);
  1144. memcpy((void*)&bootboot->magic,BOOTBOOT_MAGIC,4);
  1145. bootboot->protocol = PROTOCOL_DYNAMIC | LOADER_RPI;
  1146. bootboot->size = 128;
  1147. bootboot->arch.aarch64.mmio_ptr = mmio_base;
  1148. // set up a framebuffer so that we can write on screen
  1149. if(!GetLFB(0, 0)) goto viderr;
  1150. puts("Booting OS...\n");
  1151. /* check for 4k granule and at least 36 bits address */
  1152. asm volatile ("mrs %0, id_aa64mmfr0_el1" : "=r" (reg));
  1153. pa=reg&0xF;
  1154. if(reg&(0xF<<28) || pa<1) {
  1155. puts("BOOTBOOT-PANIC: Hardware not supported\n");
  1156. uart_puts("ID_AA64MMFR0_EL1 ");
  1157. uart_hex(reg,8);
  1158. uart_putc('\n');
  1159. goto error;
  1160. }
  1161. /* initialize microsec delay */
  1162. asm volatile ("mrs %0, cntfrq_el0" : "=r" (cntfrq));
  1163. /* Raspbootin compatibility, see https://github.com/mrvn/raspbootin
  1164. * We can receive INITRD from raspbootcom */
  1165. uart_puts("\x03\x03\x03");
  1166. // wait reply with timeout
  1167. mp=10000;
  1168. #if CONSOLE == UART1
  1169. r=(char)(*AUX_MU_IO);do{asm volatile("nop");}while(--mp>0 && !(*AUX_MU_LSR&0x01));
  1170. #else
  1171. r=(char)(*UART0_DR);do{asm volatile("nop");}while(--mp>0 && *UART0_FR&0x10);
  1172. #endif
  1173. if(mp>0) {
  1174. // we got response from raspbootcom
  1175. sp=uart_getc(); sp|=uart_getc()<<8; sp|=uart_getc()<<16; sp|=uart_getc()<<24;
  1176. if(sp>0 && sp<INITRD_MAXSIZE*1024*1024) {
  1177. uart_puts("OK");
  1178. initrd.size=sp;
  1179. initrd.ptr=pe=(uint8_t*)&_end;
  1180. while(sp--) *pe++ = uart_getc();
  1181. goto gotinitrd;
  1182. } else
  1183. uart_puts("SE");
  1184. }
  1185. /* initialize SDHC card reader in EMMC */
  1186. if(sd_init()) {
  1187. puts("BOOTBOOT-PANIC: Unable to initialize SDHC card\n");
  1188. goto error;
  1189. }
  1190. /* read and parse GPT table */
  1191. r=sd_readblock(1,(unsigned char*)&__diskbuf,1);
  1192. if(r==0 || memcmp((void*)&__diskbuf, "EFI PART", 8)) {
  1193. gpterr:
  1194. puts("BOOTBOOT-PANIC: No GPT found\n");
  1195. goto error;
  1196. }
  1197. // get number of partitions and size of partition entry
  1198. np=*((uint32_t*)((char*)&__diskbuf+80)); sp=*((uint32_t*)((char*)&__diskbuf+84));
  1199. if(np>127) np=127;
  1200. // read GPT entries
  1201. r=sd_readblock(*((uint32_t*)((char*)&__diskbuf+72)),(unsigned char*)&__diskbuf,(np*sp+511)/512);
  1202. if(r==0) goto gpterr;
  1203. part=NULL;
  1204. // first, look for a partition with bootable flag
  1205. for(r=0;r<np;r++) {
  1206. part = (efipart_t*)((char*)&__diskbuf+r*sp);
  1207. if((part->type[0]==0 && part->type[1]==0 && part->type[2]==0 && part->type[3]==0) || part->start==0) {
  1208. r=np;
  1209. break;
  1210. }
  1211. // EFI_PART_USED_BY_OS?
  1212. if(part->flags&4) break;
  1213. }
  1214. // if none, look for specific partition types
  1215. if(part==NULL || r>=np) {
  1216. for(r=0;r<np;r++) {
  1217. part = (efipart_t*)((char*)&__diskbuf+r*sp);
  1218. if((part->type[0]==0 && part->type[1]==0 && part->type[2]==0 && part->type[3]==0) || part->start==0) {
  1219. r=np;
  1220. break;
  1221. }
  1222. // ESP?
  1223. if((part->type[0]==0xC12A7328 && part->type[1]==0x11D2F81F) ||
  1224. // or OS/Z root partition for this architecture?
  1225. (part->type[0]==0x5A2F534F && (part->type[1]&0xFFFF)==0xAA64 && part->type[3]==0x746F6F72))
  1226. break;
  1227. }
  1228. }
  1229. if(part==NULL || r>=np) {
  1230. diskerr:
  1231. puts("BOOTBOOT-PANIC: No boot partition\n");
  1232. goto error;
  1233. }
  1234. r=sd_readblock(part->start,(unsigned char*)&_end,1);
  1235. if(r==0) goto diskerr;
  1236. initrd.ptr=NULL; initrd.size=0;
  1237. // wait keypress with timeout, half a sec
  1238. mp=500;
  1239. #if CONSOLE == UART1
  1240. r=(char)(*AUX_MU_IO);do{delaym(1000);}while(--mp>0 && !(*AUX_MU_LSR&0x01));
  1241. #else
  1242. r=(char)(*UART0_DR);do{delaym(1000);}while(--mp>0 && *UART0_FR&0x10);
  1243. #endif
  1244. //if user pressed a key, fallback to backup initrd
  1245. if(mp>0) {
  1246. puts(" * Backup initrd\n");
  1247. bkp=1;
  1248. }
  1249. //is it a FAT partition?
  1250. bpb=(bpb_t*)&_end;
  1251. if(!memcmp((void*)bpb->fst,"FAT16",5) || !memcmp((void*)bpb->fst2,"FAT32",5)) {
  1252. // locate BOOTBOOT directory
  1253. uint64_t data_sec, root_sec, clu=0, cclu=0, s, s2, s3;
  1254. fatdir_t *dir;
  1255. uint32_t *fat32=(uint32_t*)((uint8_t*)&_end+512);
  1256. uint16_t *fat16=(uint16_t*)fat32;
  1257. uint8_t *ptr;
  1258. data_sec=root_sec=((bpb->spf16?bpb->spf16:bpb->spf32)*bpb->nf)+bpb->rsc;
  1259. //WARNING gcc generates a code for bpb->nr that cause unaligned exception
  1260. s=(bpb->nr0+(bpb->nr1<<8))*sizeof(fatdir_t);
  1261. if(bpb->spf16>0) {
  1262. data_sec+=(s+511)>>9;
  1263. } else {
  1264. root_sec+=(bpb->rc-2)*bpb->spc;
  1265. }
  1266. s3=bpb->spc*512;
  1267. // load fat table
  1268. r=sd_readblock(part->start+bpb->rsc,(unsigned char*)&_end+512,(bpb->spf16?bpb->spf16:bpb->spf32));
  1269. if(r==0) goto diskerr;
  1270. pe=(uint8_t*)&_end+512+r;
  1271. // load root directory
  1272. r=sd_readblock(part->start+root_sec,(unsigned char*)pe,s/512+1);
  1273. dir=(fatdir_t*)pe;
  1274. while(dir->name[0]!=0 && memcmp(dir->name,"BOOTBOOT ",11)) dir++;
  1275. if(dir->name[0]!='B') goto diskerr;
  1276. r=sd_readblock(part->start+(dir->cl+(dir->ch<<16)-2)*bpb->spc+data_sec,(unsigned char*)pe,bpb->spc);
  1277. if(r==0) goto diskerr;
  1278. dir=(fatdir_t*)pe;
  1279. // locate environment and initrd
  1280. while(dir->name[0]!=0) {
  1281. if(!memcmp(dir->name,"CONFIG ",11)) {
  1282. s=dir->size<PAGESIZE?dir->size:PAGESIZE;
  1283. cclu=dir->cl+(dir->ch<<16);
  1284. ptr=(void*)&__environment;
  1285. while(s>0) {
  1286. s2=s>s3?s3:s;
  1287. r=sd_readblock(part->start+(cclu-2)*bpb->spc+data_sec,ptr,bpb->spc);
  1288. cclu=bpb->spf16>0?fat16[cclu]:fat32[cclu];
  1289. ptr+=s2;
  1290. s-=s2;
  1291. }
  1292. } else
  1293. if(!memcmp(dir->name,bkp?"INITRD BAK":"INITRD ",11)) {
  1294. clu=dir->cl+(dir->ch<<16);
  1295. initrd.size=dir->size;
  1296. }
  1297. dir++;
  1298. }
  1299. // if initrd not found, try architecture specific name
  1300. if(clu==0) {
  1301. dir=(fatdir_t*)pe;
  1302. while(dir->name[0]!=0) {
  1303. if(!memcmp(dir->name,"AARCH64 ",11)) {
  1304. clu=dir->cl+(dir->ch<<16);
  1305. initrd.size=dir->size;
  1306. break;
  1307. }
  1308. dir++;
  1309. }
  1310. }
  1311. // walk through cluster chain to load initrd
  1312. if(clu!=0 && initrd.size!=0) {
  1313. initrd.ptr=ptr=pe;
  1314. s=initrd.size;
  1315. while(s>0) {
  1316. s2=s>s3?s3:s;
  1317. r=sd_readblock(part->start+(clu-2)*bpb->spc+data_sec,ptr,bpb->spc);
  1318. clu=bpb->spf16>0?fat16[clu]:fat32[clu];
  1319. ptr+=s2;
  1320. s-=s2;
  1321. }
  1322. }
  1323. } else {
  1324. // initrd is on the entire partition
  1325. r=sd_readblock(part->start,(unsigned char*)&_end+512,part->end-part->start+1);
  1326. if(r==0) goto diskerr;
  1327. initrd.ptr=(uint8_t*)&_end;
  1328. initrd.size=r;
  1329. }
  1330. gotinitrd:
  1331. if(initrd.ptr==NULL || initrd.size==0) {
  1332. puts("BOOTBOOT-PANIC: Initrd not found\n");
  1333. goto error;
  1334. }
  1335. #if INITRD_DEBUG
  1336. uart_puts("Initrd at ");uart_hex((uint64_t)initrd.ptr,4);uart_putc(' ');uart_hex(initrd.size,4);uart_putc('\n');
  1337. #endif
  1338. // uncompress if it's compressed
  1339. if(initrd.ptr[0]==0x1F && initrd.ptr[1]==0x8B) {
  1340. unsigned char *addr,f;
  1341. volatile TINF_DATA d;
  1342. DBG(" * Gzip compressed initrd\n");
  1343. // skip gzip header
  1344. addr=initrd.ptr+2;
  1345. if(*addr++!=8) goto gzerr;
  1346. f=*addr++; addr+=6;
  1347. if(f&4) { r=*addr++; r+=(*addr++ << 8); addr+=r; }
  1348. if(f&8) { while(*addr++ != 0); }
  1349. if(f&16) { while(*addr++ != 0); }
  1350. if(f&2) addr+=2;
  1351. d.source = addr;
  1352. memcpy((void*)&d.destSize,initrd.ptr+initrd.size-4,4);
  1353. // decompress
  1354. d.bitcount = 0;
  1355. d.bfinal = 0;
  1356. d.btype = -1;
  1357. d.curlen = 0;
  1358. if((uint8_t*)&_end+d.destSize<addr)
  1359. d.dest=(uint8_t*)&_end;
  1360. else
  1361. d.dest=(uint8_t*)((uint64_t)(initrd.ptr+initrd.size+PAGESIZE-1)&~(PAGESIZE-1));
  1362. initrd.ptr=(uint8_t*)d.dest;
  1363. initrd.size=d.destSize;
  1364. #if INITRD_DEBUG
  1365. uart_puts("Inflating to ");uart_hex((uint64_t)d.dest,4);uart_putc(' ');uart_hex(d.destSize,4);uart_putc('\n');
  1366. #endif
  1367. puts(" * Inflating image...\r");
  1368. do { r = uzlib_uncompress(&d); } while (!r);
  1369. puts(" \r");
  1370. if (r != TINF_DONE) {
  1371. gzerr: puts("BOOTBOOT-PANIC: Unable to uncompress\n");
  1372. goto error;
  1373. }
  1374. }
  1375. // copy the initrd to it's final position, making it properly aligned
  1376. if((uint64_t)initrd.ptr!=(uint64_t)&_end) {
  1377. memcpy((void*)&_end, initrd.ptr, initrd.size);
  1378. }
  1379. bootboot->initrd_ptr=(uint64_t)&_end;
  1380. // round up to page size
  1381. bootboot->initrd_size=(initrd.size+PAGESIZE-1)&~(PAGESIZE-1);
  1382. DBG(" * Initrd loaded\n");
  1383. #if INITRD_DEBUG
  1384. // dump initrd in memory
  1385. uart_dump((void*)bootboot->initrd_ptr,8);
  1386. #endif
  1387. // if no config, locate it in uncompressed initrd
  1388. if(*((uint8_t*)&__environment)==0) {
  1389. r=0; env.ptr=NULL;
  1390. while(env.ptr==NULL && fsdrivers[r]!=NULL) {
  1391. env=(*fsdrivers[r++])((unsigned char*)bootboot->initrd_ptr,cfgname);
  1392. }
  1393. if(env.ptr!=NULL)
  1394. memcpy((void*)&__environment,(void*)(env.ptr),env.size<PAGESIZE?env.size:PAGESIZE-1);
  1395. }
  1396. // parse config
  1397. ParseEnvironment((unsigned char*)&__environment);
  1398. // locate sys/core
  1399. entrypoint=0;
  1400. r=0; core.ptr=NULL;
  1401. while(core.ptr==NULL && fsdrivers[r]!=NULL) {
  1402. core=(*fsdrivers[r++])((unsigned char*)bootboot->initrd_ptr,kernelname);
  1403. }
  1404. if(kne!=NULL)
  1405. *kne='\n';
  1406. // scan for the first executable
  1407. if(core.ptr==NULL || core.size==0) {
  1408. DBG(" * Autodetecting kernel\n");
  1409. core.size=0;
  1410. r=bootboot->initrd_size;
  1411. core.ptr=(uint8_t*)bootboot->initrd_ptr;
  1412. while(r-->0) {
  1413. Elf64_Ehdr *ehdr=(Elf64_Ehdr *)(core.ptr);
  1414. pe_hdr *pehdr=(pe_hdr*)(core.ptr + ((mz_hdr*)(core.ptr))->peaddr);
  1415. if((!memcmp(ehdr->e_ident,ELFMAG,SELFMAG)||!memcmp(ehdr->e_ident,"OS/Z",4))&&
  1416. ehdr->e_ident[EI_CLASS]==ELFCLASS64&&
  1417. ehdr->e_ident[EI_DATA]==ELFDATA2LSB&&
  1418. ehdr->e_machine==EM_AARCH64&&
  1419. ehdr->e_phnum>0){
  1420. core.size=1;
  1421. break;
  1422. }
  1423. if(((mz_hdr*)(core.ptr))->magic==MZ_MAGIC && ((mz_hdr*)(core.ptr))->peaddr<65536 && pehdr->magic == PE_MAGIC &&
  1424. pehdr->machine == IMAGE_FILE_MACHINE_ARM64 && pehdr->file_type == PE_OPT_MAGIC_PE32PLUS) {
  1425. core.size=1;
  1426. break;
  1427. }
  1428. core.ptr++;
  1429. }
  1430. }
  1431. if(core.ptr==NULL || core.size==0) {
  1432. puts("BOOTBOOT-PANIC: Kernel not found in initrd\n");
  1433. goto error;
  1434. } else {
  1435. Elf64_Ehdr *ehdr=(Elf64_Ehdr *)(core.ptr);
  1436. pe_hdr *pehdr=(pe_hdr*)(core.ptr + ((mz_hdr*)(core.ptr))->peaddr);
  1437. if((!memcmp(ehdr->e_ident,ELFMAG,SELFMAG)||!memcmp(ehdr->e_ident,"OS/Z",4))&&
  1438. ehdr->e_ident[EI_CLASS]==ELFCLASS64&&
  1439. ehdr->e_ident[EI_DATA]==ELFDATA2LSB&&
  1440. ehdr->e_machine==EM_AARCH64&&
  1441. ehdr->e_phnum>0){
  1442. DBG(" * Parsing ELF64\n");
  1443. Elf64_Phdr *phdr=(Elf64_Phdr *)((uint8_t *)ehdr+ehdr->e_phoff);
  1444. for(r=0;r<ehdr->e_phnum;r++){
  1445. if(phdr->p_type==PT_LOAD && (phdr->p_vaddr >> 30) == 0x3FFFFFFFF) {
  1446. core.ptr += phdr->p_offset;
  1447. // hack to keep symtab and strtab for shared libraries
  1448. core.size = phdr->p_filesz + (ehdr->e_type==3?0x4000:0);
  1449. bss = phdr->p_memsz - core.size;
  1450. core_addr = phdr->p_vaddr;
  1451. entrypoint = ehdr->e_entry;
  1452. break;
  1453. }
  1454. phdr=(Elf64_Phdr *)((uint8_t *)phdr+ehdr->e_phentsize);
  1455. }
  1456. if(ehdr->e_shoff > 0) {
  1457. Elf64_Shdr *shdr=(Elf64_Shdr *)((uint8_t *)ehdr + ehdr->e_shoff), *sym_sh = NULL, *str_sh = NULL;
  1458. Elf64_Shdr *strt=(Elf64_Shdr *)((uint8_t *)shdr+(uint64_t)ehdr->e_shstrndx*(uint64_t)ehdr->e_shentsize);
  1459. Elf64_Sym *sym = NULL, *s;
  1460. char *strtable = (char *)ehdr + strt->sh_offset;
  1461. uint32_t strsz = 0, syment = 0, i;
  1462. for(i = 0; i < ehdr->e_shnum; i++){
  1463. /* checking shdr->sh_type is not enough, there can be multiple SHT_STRTAB records... */
  1464. if(!memcmp(strtable + shdr->sh_name, ".symtab", 8)) sym_sh = shdr;
  1465. if(!memcmp(strtable + shdr->sh_name, ".strtab", 8)) str_sh = shdr;
  1466. shdr = (Elf64_Shdr *)((uint8_t *)shdr + ehdr->e_shentsize);
  1467. }
  1468. if(str_sh && sym_sh) {
  1469. strtable = (char *)ehdr + str_sh->sh_offset; strsz = str_sh->sh_size;
  1470. sym = (Elf64_Sym *)((uint8_t*)ehdr + sym_sh->sh_offset); syment = sym_sh->sh_entsize;
  1471. if(str_sh->sh_offset && strsz > 0 && sym_sh->sh_offset && syment > 0)
  1472. for(s = sym, i = 0; i<(strtable-(char*)sym)/syment && s->st_name < strsz; i++, s++) {
  1473. if(!memcmp(strtable + s->st_name, "bootboot", 9)) bb_addr = s->st_value;
  1474. if(!memcmp(strtable + s->st_name, "environment", 12)) env_addr = s->st_value;
  1475. if(!memcmp(strtable + s->st_name, "mmio", 5)) mm_addr = s->st_value;
  1476. if(!memcmp(strtable + s->st_name, "fb", 3)) fb_addr = s->st_value;
  1477. if(!memcmp(strtable + s->st_name, "initstack", 10)) initstack = s->st_value;
  1478. }
  1479. }
  1480. }
  1481. } else
  1482. if(((mz_hdr*)(core.ptr))->magic==MZ_MAGIC && ((mz_hdr*)(core.ptr))->peaddr<65536 && pehdr->magic == PE_MAGIC &&
  1483. pehdr->machine == IMAGE_FILE_MACHINE_ARM64 && pehdr->file_type == PE_OPT_MAGIC_PE32PLUS &&
  1484. (pehdr->code_base & 0xC0000000)) {
  1485. DBG(" * Parsing PE32+\n");
  1486. core.size = (pehdr->entry_point-pehdr->code_base) + pehdr->text_size + pehdr->data_size;
  1487. bss = pehdr->bss_size;
  1488. core_addr = (int64_t)pehdr->code_base;
  1489. entrypoint = (int64_t)pehdr->entry_point;
  1490. if(pehdr->sym_table > 0 && pehdr->numsym > 0) {
  1491. pe_sym *s;
  1492. char *strtable = (char *)pehdr + pehdr->sym_table + pehdr->numsym * 18 + 4, *name;
  1493. uint32_t i;
  1494. for(i = 0; i < pehdr->numsym; i++) {
  1495. s = (pe_sym*)((uint8_t *)pehdr + pehdr->sym_table + i * 18);
  1496. name = !s->iszero ? (char*)&s->iszero : strtable + s->nameoffs;
  1497. if(!memcmp(name, "bootboot", 9)) bb_addr = (int64_t)s->value;
  1498. if(!memcmp(name, "environment", 12)) env_addr = (int64_t)s->value;
  1499. if(!memcmp(name, "mmio", 5)) mm_addr = (int64_t)s->value;
  1500. if(!memcmp(name, "fb", 3)) fb_addr = (int64_t)s->value;
  1501. if(!memcmp(name, "initstack", 10)) initstack = (int64_t)s->value;
  1502. i += s->auxsyms;
  1503. }
  1504. }
  1505. }
  1506. }
  1507. #if EXEC_DEBUG
  1508. uart_puts("Executable size ");
  1509. uart_hex((uint64_t)core.size,4);
  1510. uart_puts(" bss ");
  1511. uart_hex((uint64_t)bss,4);
  1512. uart_putc('\n');
  1513. uart_dump((void*)core.ptr,4);
  1514. #endif
  1515. if(core.ptr==NULL || core.size<2 || entrypoint==0 || (core_addr&(PAGESIZE-1)) || (bb_addr>>30)!=0x3FFFFFFFF ||
  1516. (bb_addr & (PAGESIZE-1)) || (env_addr>>30)!=0x3FFFFFFFF || (env_addr&(PAGESIZE-1)) || (fb_addr>>30)!=0x3FFFFFFFF ||
  1517. (fb_addr & (PAGESIZE-1)) || (mm_addr>>30)!=0x3FFFFFFFF || (mm_addr & (1024*1024*2-1))) {
  1518. puts("BOOTBOOT-PANIC: Kernel is not a valid executable\n");
  1519. goto error;
  1520. }
  1521. if(core.size+bss > 16*1024*1024) {
  1522. puts("BOOTBOOT-PANIC: Kernel is too big");
  1523. goto error;
  1524. }
  1525. if(initstack < 1024) initstack = 1024;
  1526. if(initstack > 16384) initstack = 16384;
  1527. // create core segment
  1528. memcpy((void*)(bootboot->initrd_ptr+bootboot->initrd_size), core.ptr, core.size);
  1529. core.ptr=(uint8_t*)(bootboot->initrd_ptr+bootboot->initrd_size);
  1530. if(bss>0)
  1531. memset(core.ptr + core.size, 0, bss);
  1532. core.size = (core.size+bss+PAGESIZE-1)&~(PAGESIZE-1);
  1533. #if EXEC_DEBUG
  1534. uart_puts("Core ");
  1535. uart_hex((uint64_t)core.ptr,4);
  1536. uart_puts(" to ");
  1537. uart_hex((uint64_t)core.ptr+core.size,4);
  1538. uart_putc('\n');
  1539. #endif
  1540. /* we have fixed number of cores, nothing to detect */
  1541. DBG(" * SMP numcores 4\n");
  1542. bootboot->numcores = 4;
  1543. /* generate memory map to bootboot struct */
  1544. DBG(" * Memory Map\n");
  1545. mmap=(MMapEnt *)&bootboot->mmap;
  1546. // everything before the bootboot struct is free
  1547. // leave out the first page. qemu crashes if we write at 0x100, there are some
  1548. // system variables there
  1549. mmap->ptr=4096; mmap->size=((uint64_t)&__bootboot-4096) | MMAP_FREE;
  1550. mmap++; bootboot->size+=sizeof(MMapEnt);
  1551. // mark bss reserved
  1552. mmap->ptr=(uint64_t)&__bootboot; mmap->size=((uint64_t)&_end-(uint64_t)&__bootboot) | MMAP_USED;
  1553. mmap++; bootboot->size+=sizeof(MMapEnt);
  1554. r=bootboot->initrd_size + core.size;
  1555. // after bss and before initrd is free
  1556. if(bootboot->initrd_ptr-(uint64_t)&_end) {
  1557. mmap->ptr=(uint64_t)&_end; mmap->size=(bootboot->initrd_ptr-(uint64_t)&_end) | MMAP_FREE;
  1558. mmap++; bootboot->size+=sizeof(MMapEnt);
  1559. // initrd is reserved (and add core's area to it)
  1560. mmap->ptr=bootboot->initrd_ptr; mmap->size=r | MMAP_USED;
  1561. mmap++; bootboot->size+=sizeof(MMapEnt);
  1562. } else {
  1563. mmap--; mmap->size+=r; mmap++;
  1564. }
  1565. r+=(uint32_t)bootboot->initrd_ptr;
  1566. mbox[0]=8*4;
  1567. mbox[1]=0;
  1568. mbox[2]=0x10005; // get memory size
  1569. mbox[3]=8;
  1570. mbox[4]=0;
  1571. mbox[5]=0;
  1572. mbox[6]=0;
  1573. mbox[7]=0;
  1574. if(!mbox_call(MBOX_CH_PROP, mbox))
  1575. // on failure (should never happen) assume 64Mb memory max
  1576. mbox[6]=64*1024*1024;
  1577. // everything after initrd to the top of memory is free
  1578. mp=mbox[6]-r;
  1579. mmap->ptr=r; mmap->size=mp | MMAP_FREE;
  1580. mmap++; bootboot->size+=sizeof(MMapEnt);
  1581. // MMIO area
  1582. mmap->ptr=mmio_base; mmap->size=((uint64_t)0x40200000-mmio_base) | MMAP_MMIO;
  1583. mmap++; bootboot->size+=sizeof(MMapEnt);
  1584. #if MEM_DEBUG
  1585. /* dump memory map */
  1586. mmap=(MMapEnt *)&bootboot->mmap;
  1587. for(r=128;r<bootboot->size;r+=sizeof(MMapEnt)) {
  1588. uart_hex(MMapEnt_Ptr(mmap),8);
  1589. uart_putc(' ');
  1590. uart_hex(MMapEnt_Ptr(mmap)+MMapEnt_Size(mmap)-1,8);
  1591. uart_putc(' ');
  1592. uart_hex(MMapEnt_Type(mmap),1);
  1593. uart_putc(' ');
  1594. switch(MMapEnt_Type(mmap)) {
  1595. case MMAP_USED: uart_puts("reserved"); break;
  1596. case MMAP_FREE: uart_puts("free"); break;
  1597. case MMAP_ACPI: uart_puts("acpi"); break;
  1598. case MMAP_MMIO: uart_puts("mmio"); break;
  1599. default: uart_puts("unknown"); break;
  1600. }
  1601. uart_putc('\n');
  1602. mmap++;
  1603. }
  1604. #endif
  1605. /* get linear framebuffer if requested resolution different than current */
  1606. DBG(" * Screen VideoCore\n");
  1607. if(reqwidth!=bootboot->fb_width || reqheight!=bootboot->fb_height) {
  1608. if(!GetLFB(reqwidth, reqheight)) {
  1609. viderr:
  1610. puts("BOOTBOOT-PANIC: VideoCore error, no framebuffer\n");
  1611. goto error;
  1612. }
  1613. }
  1614. /* clear the screen */
  1615. for(j=ky=0;ky<bootboot->fb_height;ky++) {
  1616. r=j;
  1617. for(kx=0;kx<bootboot->fb_width;kx+=2,r+=8)
  1618. *((uint64_t*)(bootboot->fb_ptr + r))=0;
  1619. j+=bootboot->fb_scanline;
  1620. }
  1621. kx=ky=0; color=0xFFDD33;
  1622. /* create MMU translation tables in __paging */
  1623. paging=(uint64_t*)&__paging;
  1624. memset(paging, 0, 50*PAGESIZE);
  1625. // TTBR0, identity L1
  1626. paging[0]=(uint64_t)((uint8_t*)&__paging+2*PAGESIZE)|0x03|(3<<8)|(1<<10); //AF=1,Block=1,Present=1, SH=3 ISH, RO
  1627. // identity L2
  1628. paging[2*512]=(uint64_t)((uint8_t*)&__paging+3*PAGESIZE)|0x03|(3<<8)|(1<<10); //AF=1,Block=1,Present=1
  1629. // identity L2 2M blocks
  1630. mp>>=21;
  1631. np=mmio_base>>21;
  1632. for(r=1;r<512;r++)
  1633. paging[2*512+r]=(uint64_t)(((uint64_t)r<<21))|0x01|(1<<10)|(r>=np?(2<<8)|(1<<2)|(1L<<54):(3<<8)); //device SH=2 OSH
  1634. // identity L3
  1635. for(r=0;r<512;r++)
  1636. paging[3*512+r]=(uint64_t)(r*PAGESIZE)|0x03|(1<<10);
  1637. // TTBR1, core L1
  1638. paging[512+511]=(uint64_t)((uint8_t*)&__paging+4*PAGESIZE)|0x03|(3<<8)|(1<<10); //AF=1,Block=1,Present=1
  1639. // core L2
  1640. // map MMIO in kernel space
  1641. j = (mm_addr>>(9+12)) & 0x1FF;
  1642. for(r=0;j+r < 511 && r<32;r++)
  1643. paging[4*512+j+r]=(uint64_t)(mmio_base+((uint64_t)r<<21))|0x01|(2<<8)|(1<<10)|(1<<2)|(1L<<54); //OSH, Attr=1, NX
  1644. // map framebuffer
  1645. j = (fb_addr>>(9+12)) & 0x1FF;
  1646. for(r=0;j+r < 511 && r<31;r++)
  1647. paging[4*512+j+r]=(uint64_t)((uint8_t*)&__paging+(5+r)*PAGESIZE)|0x03|(2<<8)|(1<<10)|(2<<2)|(1L<<54); //OSH, Attr=2
  1648. paging[4*512+511]=(uint64_t)((uint8_t*)&__paging+36*PAGESIZE)|0x03|(3<<8)|(1<<10);// pointer to core L3
  1649. j = (fb_addr>>(12)) & 0x1FF;
  1650. for(r=0;r<31*512;r++)
  1651. paging[5*512+j+r]=(uint64_t)(bootboot->fb_ptr+r*PAGESIZE)|0x03|(2<<8)|(1<<10)|(2<<2)|(1L<<54); //map framebuffer
  1652. // core L3
  1653. // dynamically map these. Main struct, environment string and code segment
  1654. for(r=0;r<(core.size/PAGESIZE);r++)
  1655. MapPage(core_addr+r*PAGESIZE,(uint64_t)((uint8_t *)core.ptr+(uint64_t)r*PAGESIZE)|0x03|(3<<8)|(1<<10));
  1656. #if MEM_DEBUG
  1657. reg=r;
  1658. #endif
  1659. MapPage(bb_addr,(uint64_t)((uint8_t*)&__bootboot)|0x03|(3<<8)|(1<<10)|(1L<<54)); // p, b, AF, ISH
  1660. MapPage(env_addr,(uint64_t)((uint8_t*)&__environment)|0x03|(3<<8)|(1<<10)|(1L<<54));
  1661. // stack at the top of the memory (1k each)
  1662. for(r=0;r<16;r++)
  1663. paging[36*512+496+r]=(uint64_t)((uint8_t*)&__corestack+(uint64_t)r*PAGESIZE)|0x03|(3<<8)|(1<<10)|(1L<<54);
  1664. #if MEM_DEBUG
  1665. /* dump page translation tables */
  1666. uart_puts("\nTTBR0\n L1 ");
  1667. uart_hex((uint64_t)&__paging,8);
  1668. uart_puts("\n ");
  1669. uart_hex((uint64_t)paging[0],8);
  1670. uart_puts(" ...\n L2 ");
  1671. uart_hex((uint64_t)&paging[2*512],8);
  1672. uart_puts("\n ");
  1673. for(r=0;r<4;r++) { uart_hex(paging[2*512+r],8); uart_putc(' '); }
  1674. uart_puts("...\n ... ");
  1675. for(r=mp-4;r<mp;r++) { uart_hex(paging[2*512+r],8); uart_putc(' '); }
  1676. uart_puts("...\n ... ");
  1677. for(r=np;r<np+4;r++) { uart_hex(paging[2*512+r],8); uart_putc(' '); }
  1678. uart_puts("...\n ... ");
  1679. for(r=508;r<512;r++) { uart_hex(paging[2*512+r],8); uart_putc(' '); }
  1680. uart_puts("\n L3 "); uart_hex((uint64_t)&paging[3*512],8); uart_puts("\n ");
  1681. for(r=0;r<4;r++) { uart_hex(paging[3*512+r],8); uart_putc(' '); }
  1682. uart_puts("...\n ... ");
  1683. for(r=127;r<131;r++) { uart_hex(paging[3*512+r],8); uart_putc(' '); }
  1684. uart_puts("...\n ... ");
  1685. for(r=508;r<512;r++) { uart_hex(paging[3*512+r],8); uart_putc(' '); }
  1686. uart_puts("\n\nTTBR1\n L1 ");
  1687. uart_hex((uint64_t)&paging[512],8);
  1688. uart_puts("\n ... ");
  1689. uart_hex((uint64_t)paging[512+511],8);
  1690. uart_puts("\n L2 ");
  1691. uart_hex((uint64_t)&paging[4*512],8);
  1692. uart_puts("\n ... (skipped 464) ... ");
  1693. for(r=448;r<451;r++) { uart_hex(paging[4*512+r],8); uart_putc(' '); }
  1694. uart_puts("...\n ... ");
  1695. for(r=480;r<484;r++) { uart_hex(paging[4*512+r],8); uart_putc(' '); }
  1696. uart_puts("...\n ... ");
  1697. for(r=508;r<512;r++) { uart_hex(paging[4*512+r],8); uart_putc(' '); }
  1698. uart_puts("\n L3 "); uart_hex((uint64_t)&paging[5*512],8); uart_puts("\n ");
  1699. for(r=0;r<4;r++) { uart_hex(paging[5*512+r],8); uart_putc(' '); }
  1700. uart_puts("...\n ... ");
  1701. for(r=reg;r<reg+4;r++) { uart_hex(paging[5*512+r],8); uart_putc(' '); }
  1702. uart_puts("...\n ... ");
  1703. for(r=508;r<512;r++) { uart_hex(paging[5*512+r],8); uart_putc(' '); }
  1704. uart_puts("\n\n");
  1705. #endif
  1706. #if BBDEBUG
  1707. uart_puts(" * mmio ");
  1708. uart_hex(mm_addr,8);
  1709. uart_putc('\n');
  1710. uart_puts(" * fb ");
  1711. uart_hex(fb_addr,8);
  1712. uart_putc('\n');
  1713. uart_puts(" * bootboot ");
  1714. uart_hex(bb_addr,8);
  1715. uart_putc('\n');
  1716. uart_puts(" * environment ");
  1717. uart_hex(env_addr,8);
  1718. uart_putc('\n');
  1719. uart_puts(" * Entry point ");
  1720. uart_hex(entrypoint,8);
  1721. uart_putc('\n');
  1722. if(initstack != 1024) {
  1723. uart_puts(" * Stack Size ");
  1724. uart_hex(initstack,8);
  1725. uart_putc('\n');
  1726. }
  1727. #endif
  1728. // release AP spinlock
  1729. bsp_done=1;
  1730. return 0;
  1731. // Wait until Enter or Space pressed, then reboot
  1732. error:
  1733. while(r!='\n' && r!='\r' && r!=' ') r=uart_getc();
  1734. uart_puts("\n\n");
  1735. // reset
  1736. asm volatile("dsb sy; isb");
  1737. *PM_WATCHDOG = PM_WDOG_MAGIC | 1;
  1738. *PM_RTSC = PM_WDOG_MAGIC | PM_RTSC_FULLRST;
  1739. while(1);
  1740. }
  1741. /**
  1742. * start kernel, runs on all cores
  1743. */
  1744. void bootboot_startcore()
  1745. {
  1746. // spinlock until BSP finishes
  1747. do { asm volatile ("dsb sy"); } while(!bsp_done);
  1748. // enable paging
  1749. reg=(0xFF << 0) | // Attr=0: normal, IWBWA, OWBWA, NTR
  1750. (0x04 << 8) | // Attr=1: device, nGnRE (must be OSH too)
  1751. (0x44 <<16); // Attr=2: non cacheable
  1752. asm volatile ("msr mair_el1, %0" : : "r" (reg));
  1753. reg=(0x00LL << 37) | // TBI=0, no tagging
  1754. ((uint64_t)pa << 32) | // IPS=autodetected
  1755. (0x02LL << 30) | // TG1=4k
  1756. (0x03LL << 28) | // SH1=3 inner
  1757. (0x01LL << 26) | // ORGN1=1 write back
  1758. (0x01LL << 24) | // IRGN1=1 write back
  1759. (0x00LL << 23) | // EPD1 undocumented by ARM DEN0024A Fig 12-5, 12-6
  1760. (25LL << 16) | // T1SZ=25, 3 levels (512G)
  1761. (0x00LL << 14) | // TG0=4k
  1762. (0x03LL << 12) | // SH0=3 inner
  1763. (0x01LL << 10) | // ORGN0=1 write back
  1764. (0x01LL << 8) | // IRGN0=1 write back
  1765. (0x00LL << 7) | // EPD0 undocumented by ARM DEN0024A Fig 12-5, 12-6
  1766. (25LL << 0); // T0SZ=25, 3 levels (512G)
  1767. asm volatile ("msr tcr_el1, %0; isb" : : "r" (reg));
  1768. asm volatile ("msr ttbr0_el1, %0" : : "r" ((uint64_t)&__paging+1));
  1769. asm volatile ("msr ttbr1_el1, %0" : : "r" ((uint64_t)&__paging+1+PAGESIZE));
  1770. asm volatile ("dsb ish; isb; mrs %0, sctlr_el1" : "=r" (reg));
  1771. // set mandatory reserved bits
  1772. reg|=0xC00800;
  1773. reg&=~( (1<<25) | // clear EE, little endian translation tables
  1774. (1<<24) | // clear E0E
  1775. (1<<19) | // clear WXN
  1776. (1<<12) | // clear I, no instruction cache
  1777. (1<<4) | // clear SA0
  1778. (1<<3) | // clear SA
  1779. (1<<2) | // clear C, no cache at all
  1780. (1<<1)); // clear A, no aligment check
  1781. reg|=(1<<0)/*|(1<<19)|(1<<12)|(1<<2)*/; // set M enable MMU, WXN, I instruction cache, C data cache
  1782. asm volatile ("msr sctlr_el1, %0; isb" : : "r" (reg));
  1783. // set stack and call _start() in sys/core
  1784. asm volatile ( "mrs x0, mpidr_el1;"
  1785. "and x0, x0, #3;"
  1786. "mul x2, x0, %1;"
  1787. "sub x2, xzr, x2;" // sp = core_num * -initstack
  1788. "mov sp, x2; mov x30, %0; ret" : : "r" (entrypoint), "r" (initstack) : "x0","x2");
  1789. }