The Pedigree Project  0.1
main_beagle.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 // C++ entry point
21 
22 #include "Elf32.h"
23 #include "support.h"
24 
25 // autogen.h contains the full kernel binary in a char array
26 #include "autogen.h"
27 
28 extern "C" {
29 volatile unsigned char *uart1 = (volatile unsigned char *) 0x4806A000;
30 volatile unsigned char *uart2 = (volatile unsigned char *) 0x4806C000;
31 volatile unsigned char *uart3 = (volatile unsigned char *) 0x49020000;
32 };
33 
34 // http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html
35 // http://www.arm.linux.org.uk/developer/booting.php
36 
37 #define ATAG_NONE 0
38 #define ATAG_CORE 0x54410001
39 #define ATAG_MEM 0x54410002
40 #define ATAG_VIDEOTEXT 0x54410003
41 #define ATAG_RAMDISK 0x54410004
42 #define ATAG_INITRD2 0x54410005
43 #define ATAG_SERIAL 0x54410006
44 #define ATAG_REVISION 0x54410007
45 #define ATAG_VIDEOLFB 0x54410008
46 #define ATAG_CMDLINE 0x54410009
47 
49 {
50  uint32_t size;
51  uint32_t tag;
52 };
53 
54 struct atag_core
55 {
56  uint32_t flags;
57  uint32_t pagesize;
58  uint32_t rootdev;
59 };
60 
61 struct atag_mem
62 {
63  uint32_t size;
64  uint32_t start;
65 };
66 
68 {
69  unsigned char x;
70  unsigned char y;
71  unsigned short video_page;
72  unsigned char video_mode;
73  unsigned char video_cols;
74  unsigned short video_ega_bx;
75  unsigned char video_lines;
76  unsigned char video_isvga;
77  unsigned short video_points;
78 };
79 
81 {
82  uint32_t flags;
83  uint32_t size;
84  uint32_t start;
85 };
86 
88 {
89  uint32_t start;
90  uint32_t size;
91 };
92 
94 {
95  uint32_t low;
96  uint32_t high;
97 };
98 
100 {
101  uint32_t rev;
102 };
103 
105 {
106  unsigned short lfb_width;
107  unsigned short lfb_height;
108  unsigned short lfb_depth;
109  unsigned short lfb_linelength;
110  uint32_t lfb_base;
111  uint32_t lfb_size;
112  unsigned char red_size;
113  unsigned char red_pos;
114  unsigned char green_size;
115  unsigned char green_pos;
116  unsigned char blue_size;
117  unsigned char blue_pos;
118  unsigned char rsvd_size;
119  unsigned char rsvd_pos;
120 };
121 
123 {
124  char cmdline[1]; // Minimum size.
125 };
126 
127 struct atag
128 {
129  struct atag_header hdr;
130  union
131  {
132  struct atag_core core;
133  struct atag_mem mem;
134  struct atag_videotext videotext;
135  struct atag_ramdisk ramdisk;
136  struct atag_initrd2 initrd2;
137  struct atag_serialnr serialnr;
138  struct atag_revision revision;
139  struct atag_videolfb videolfb;
140  struct atag_cmdline cmdline;
141  } u;
142 };
143 
144 #define MULTIBOOT_FLAG_MEM 0x001
145 #define MULTIBOOT_FLAG_DEVICE 0x002
146 #define MULTIBOOT_FLAG_CMDLINE 0x004
147 #define MULTIBOOT_FLAG_MODS 0x008
148 #define MULTIBOOT_FLAG_AOUT 0x010
149 #define MULTIBOOT_FLAG_ELF 0x020
150 #define MULTIBOOT_FLAG_MMAP 0x040
151 #define MULTIBOOT_FLAG_CONFIG 0x080
152 #define MULTIBOOT_FLAG_LOADER 0x100
153 #define MULTIBOOT_FLAG_APM 0x200
154 #define MULTIBOOT_FLAG_VBE 0x400
155 
157 struct BootstrapStruct_t
158 {
159  uint32_t flags;
160 
161  uint32_t mem_lower;
162  uint32_t mem_upper;
163 
164  uint32_t boot_device;
165 
166  uint32_t cmdline;
167 
168  uint32_t mods_count;
169  uint32_t mods_addr;
170 
171  /* ELF information */
172  uint32_t num;
173  uint32_t size;
174  uint32_t addr;
175  uint32_t shndx;
176 
177  uint32_t mmap_length;
178  uint32_t mmap_addr;
179 
180  uint32_t drives_length;
181  uint32_t drives_addr;
182 
183  uint32_t config_table;
184 
185  uint32_t boot_loader_name;
186 
187  uint32_t apm_table;
188 
189  uint32_t vbe_control_info;
190  uint32_t vbe_mode_info;
191  uint32_t vbe_mode;
192  uint32_t vbe_interface_seg;
193  uint32_t vbe_interface_off;
194  uint32_t vbe_interface_len;
195 } __attribute__((packed));
196 
199 
201 #define DLL_REG 0x00 // R/W
202 #define RHR_REG 0x00 // R
203 #define THR_REG 0x00 // W
204 #define DLH_REG 0x04 // R/W
205 #define IER_REG 0x04 // R/W
206 #define IIR_REG 0x08 // R
207 #define FCR_REG 0x08 // W
208 #define EFR_REG 0x08 // RW
209 #define LCR_REG 0x0C // RW
210 #define MCR_REG 0x10 // RW
211 #define XON1_ADDR1_REG 0x10 // RW
212 #define LSR_REG 0x14 // R
213 #define XON2_ADDR2_REG 0x14 // RW
214 #define MSR_REG 0x18 // R
215 #define TCR_REG 0x18 // RW
216 #define XOFF1_REG 0x18 // RW
217 #define SPR_REG 0x1C // RW
218 #define TLR_REG 0x1C // RW
219 #define XOFF2_REG 0x1C // RW
220 #define MDR1_REG 0x20 // RW
221 #define MDR2_REG 0x24 // RW
222 
223 #define USAR_REG 0x38 // R
224 
225 #define SCR_REG 0x40 // RW
226 #define SSR_REG 0x44 // R
227 
228 #define MVR_REG 0x50 // R
229 #define SYSC_REG 0x54 // RW
230 #define SYSS_REG 0x58 // R
231 #define WER_REG 0x5C // RW
232 
234 extern "C" volatile unsigned char *uart_get(int n)
235 {
236  if (n == 1)
237  return uart1;
238  else if (n == 2)
239  return uart2;
240  else if (n == 3)
241  return uart3;
242  else
243  return 0;
244 }
245 
247 extern "C" bool uart_softreset(int n)
248 {
249  volatile unsigned char *uart = uart_get(n);
250  if (!uart)
251  return false;
252 
255  // 1. Initiate a software reset
256  uart[SYSC_REG] |= 0x2;
257 
258  // 2. Wait for the end of the reset operation
259  while (!(uart[SYSS_REG] & 0x1))
260  ;
261 
262  return true;
263 }
264 
266 extern "C" bool uart_fifodefaults(int n)
267 {
268  volatile unsigned char *uart = uart_get(n);
269  if (!uart)
270  return false;
271 
274  // 1. Switch to configuration mode B to access the EFR_REG register
275  unsigned char old_lcr_reg = uart[LCR_REG];
276  uart[LCR_REG] = 0xBF;
277 
278  // 2. Enable submode TCR_TLR to access TLR_REG (part 1 of 2)
279  unsigned char efr_reg = uart[EFR_REG];
280  unsigned char old_enhanced_en = efr_reg & 0x8;
281  if (!(efr_reg & 0x8)) // Set ENHANCED_EN (bit 4) if not set
282  efr_reg |= 0x8;
283  uart[EFR_REG] = efr_reg; // Write back to the register
284 
285  // 3. Switch to configuration mode A
286  uart[LCR_REG] = 0x80;
287 
288  // 4. Enable submode TCL_TLR to access TLR_REG (part 2 of 2)
289  unsigned char mcr_reg = uart[MCR_REG];
290  unsigned char old_tcl_tlr = mcr_reg & 0x20;
291  if (!(mcr_reg & 0x20))
292  mcr_reg |= 0x20;
293  uart[MCR_REG] = mcr_reg;
294 
295  // 5. Enable FIFO, load new FIFO triggers (part 1 of 3), and the new DMA
296  // mode (part 1 of 2)
297  uart[FCR_REG] = 1; // TX and RX FIFO triggers at 8 characters, no DMA mode
298 
299  // 6. Switch to configuration mode B to access EFR_REG
300  uart[LCR_REG] = 0xBF;
301 
302  // 7. Load new FIFO triggers (part 2 of 3)
303  uart[TLR_REG] = 0;
304 
305  // 8. Load new FIFO triggers (part 3 of 3) and the new DMA mode (part 2 of
306  // 2)
307  uart[SCR_REG] = 0;
308 
309  // 9. Restore the ENHANCED_EN value saved in step 2
310  if (!old_enhanced_en)
311  uart[EFR_REG] = uart[EFR_REG] ^ 0x8;
312 
313  // 10. Switch to configuration mode A to access the MCR_REG register
314  uart[LCR_REG] = 0x80;
315 
316  // 11. Restore the MCR_REG TCR_TLR value saved in step 4
317  if (!old_tcl_tlr)
318  uart[MCR_REG] = uart[MCR_REG] ^ 0x20;
319 
320  // 12. Restore the LCR_REG value stored in step 1
321  uart[LCR_REG] = old_lcr_reg;
322 
323  return true;
324 }
325 
329 extern "C" bool uart_protoconfig(int n)
330 {
331  volatile unsigned char *uart = uart_get(n);
332  if (!uart)
333  return false;
334 
337  // 1. Disable UART to access DLL_REG and DLH_REG
338  uart[MDR1_REG] = (uart[MDR1_REG] & ~0x7) | 0x7;
339 
340  // 2. Switch to configuration mode B to access the EFR_REG register
341  uart[LCR_REG] = 0xBF;
342 
343  // 3. Enable access to IER_REG
344  unsigned char efr_reg = uart[EFR_REG];
345  unsigned char old_enhanced_en = efr_reg & 0x8;
346  if (!(efr_reg & 0x8)) // Set ENHANCED_EN (bit 4) if not set
347  efr_reg |= 0x8;
348  uart[EFR_REG] = efr_reg; // Write back to the register
349 
350  // 4. Switch to operational mode to access the IER_REG register
351  uart[LCR_REG] = 0;
352 
353  // 5. Clear IER_REG
354  uart[IER_REG] = 0;
355 
356  // 6. Switch to configuration mode B to access DLL_REG and DLH_REG
357  uart[LCR_REG] = 0xBF;
358 
359  // 7. Load the new divisor value (looking for 115200 baud)
360  uart[0x0] = 0x1A; // divisor low byte
361  uart[0x4] = 0; // divisor high byte
362 
363  // 8. Switch to operational mode to access the IER_REG register
364  uart[LCR_REG] = 0;
365 
366  // 9. Load new interrupt configuration
367  uart[IER_REG] = 0; // No interrupts wanted at this stage
368 
369  // 10. Switch to configuration mode B to access the EFR_REG register
370  uart[LCR_REG] = 0xBF;
371 
372  // 11. Restore the ENHANCED_EN value saved in step 3
373  if (old_enhanced_en)
374  uart[EFR_REG] = uart[EFR_REG] ^ 0x8;
375 
376  // 12. Load the new protocol formatting (parity, stop bit, character length)
377  // and enter operational mode
378  uart[LCR_REG] = 0x3; // 8 bit characters, no parity, one stop bit
379 
380  // 13. Load the new UART mode
381  uart[MDR1_REG] = 0;
382 
383  return true;
384 }
385 
387 extern "C" bool uart_disableflowctl(int n)
388 {
389  volatile unsigned char *uart = uart_get(n);
390  if (!uart)
391  return false;
392 
395  // 1. Switch to configuration mode A to access the MCR_REG register
396  unsigned char old_lcr_reg = uart[LCR_REG];
397  uart[LCR_REG] = 0x80;
398 
399  // 2. Enable submode TCR_TLR to access TCR_REG (part 1 of 2)
400  unsigned char mcr_reg = uart[MCR_REG];
401  unsigned char old_tcl_tlr = mcr_reg & 0x20;
402  if (!(mcr_reg & 0x20))
403  mcr_reg |= 0x20;
404  uart[MCR_REG] = mcr_reg;
405 
406  // 3. Switch to configuration mode B to access the EFR_REG register
407  uart[LCR_REG] = 0xBF;
408 
409  // 4. Enable submode TCR_TLR to access the TCR_REG register (part 2 of 2)
410  unsigned char efr_reg = uart[EFR_REG];
411  unsigned char old_enhanced_en = efr_reg & 0x8;
412  if (!(efr_reg & 0x8)) // Set ENHANCED_EN (bit 4) if not set
413  efr_reg |= 0x8;
414  uart[EFR_REG] = efr_reg; // Write back to the register
415 
416  // 5. Load new start and halt trigger values
417  uart[TCR_REG] = 0;
418 
419  // 6. Disable RX/TX hardware flow control mode, and restore the ENHANCED_EN
420  // values stored in step 4
421  uart[EFR_REG] = 0;
422 
423  // 7. Switch to configuration mode A to access MCR_REG
424  uart[LCR_REG] = 0x80;
425 
426  // 8. Restore the MCR_REG TCR_TLR value stored in step 2
427  if (!old_tcl_tlr)
428  uart[MCR_REG] = uart[MCR_REG] ^ 0x20;
429 
430  // 9. Restore the LCR_REG value saved in step 1
431  uart[LCR_REG] = old_lcr_reg;
432 
433  return true;
434 }
435 
436 extern "C" void uart_write(int n, char c)
437 {
438  volatile unsigned char *uart = uart_get(n);
439  if (!uart)
440  return;
441 
442  // Wait until the hold register is empty
443  while (!(uart[LSR_REG] & 0x20))
444  ;
445  uart[THR_REG] = c;
446 }
447 
448 extern "C" char uart_read(int n)
449 {
450  volatile unsigned char *uart = uart_get(n);
451  if (!uart)
452  return 0;
453 
454  // Wait for data in the receive FIFO
455  while (!(uart[LSR_REG] & 0x1))
456  ;
457  return uart[RHR_REG];
458 }
459 
460 extern "C" inline void writeStr(int n, const char *str)
461 {
462  char c;
463  while ((c = *str++))
464  uart_write(n, c);
465 }
466 
467 extern "C" void writeHex(int uart, unsigned int n)
468 {
469  bool noZeroes = true;
470 
471  int i;
472  unsigned int tmp;
473  for (i = 28; i > 0; i -= 4)
474  {
475  tmp = (n >> i) & 0xF;
476  if (tmp == 0 && noZeroes)
477  continue;
478 
479  if (tmp >= 0xA)
480  {
481  noZeroes = false;
482  uart_write(uart, tmp - 0xA + 'a');
483  }
484  else
485  {
486  noZeroes = false;
487  uart_write(uart, tmp + '0');
488  }
489  }
490 
491  tmp = n & 0xF;
492  if (tmp >= 0xA)
493  uart_write(uart, tmp - 0xA + 'a');
494  else
495  uart_write(uart, tmp + '0');
496 }
497 
500 {
501  public:
502  BeagleGpio()
503  : m_gpio1(0), m_gpio2(0), m_gpio3(0), m_gpio4(0), m_gpio5(0), m_gpio6(0)
504  {
505  }
506  ~BeagleGpio()
507  {
508  }
509 
510  void initialise()
511  {
512  m_gpio1 = (volatile unsigned int *) 0x48310000;
513  initspecific(1, m_gpio1);
514  m_gpio2 = (volatile unsigned int *) 0x49050000;
515  initspecific(2, m_gpio2);
516  m_gpio3 = (volatile unsigned int *) 0x49052000;
517  initspecific(3, m_gpio3);
518  m_gpio4 = (volatile unsigned int *) 0x49054000;
519  initspecific(4, m_gpio4);
520  m_gpio5 = (volatile unsigned int *) 0x49056000;
521  initspecific(5, m_gpio5);
522  m_gpio6 = (volatile unsigned int *) 0x49058000;
523  initspecific(6, m_gpio6);
524  }
525 
526  void clearpin(int pin)
527  {
528  // Grab the GPIO MMIO range for the pin
529  int base = 0;
530  volatile unsigned int *gpio = getGpioForPin(pin, &base);
531  if (!gpio)
532  {
533  writeStr(3, "BeagleGpio::drivepin : No GPIO found for pin ");
534  writeHex(3, pin);
535  writeStr(3, "!\r\n");
536  return;
537  }
538 
539  // Write to the CLEARDATAOUT register
540  gpio[0x24] = (1 << base);
541  }
542 
543  void drivepin(int pin)
544  {
545  // Grab the GPIO MMIO range for the pin
546  int base = 0;
547  volatile unsigned int *gpio = getGpioForPin(pin, &base);
548  if (!gpio)
549  {
550  writeStr(3, "BeagleGpio::drivepin : No GPIO found for pin ");
551  writeHex(3, pin);
552  writeStr(3, "!\r\n");
553  return;
554  }
555 
556  // Write to the SETDATAOUT register. We can set a specific bit in
557  // this register without needing to maintain the state of a full
558  // 32-bit register (zeroes have no effect).
559  gpio[0x25] = (1 << base);
560  }
561 
562  bool pinstate(int pin)
563  {
564  // Grab the GPIO MMIO range for the pin
565  int base = 0;
566  volatile unsigned int *gpio = getGpioForPin(pin, &base);
567  if (!gpio)
568  {
569  writeStr(3, "BeagleGpio::pinstate : No GPIO found for pin ");
570  writeHex(3, pin);
571  writeStr(3, "!\r\n");
572  return false;
573  }
574 
575  return (gpio[0x25] & (1 << base));
576  }
577 
578  int capturepin(int pin)
579  {
580  // Grab the GPIO MMIO range for the pin
581  int base = 0;
582  volatile unsigned int *gpio = getGpioForPin(pin, &base);
583  if (!gpio)
584  {
585  writeStr(3, "BeagleGpio::capturepin :No GPIO found for pin ");
586  writeHex(3, pin);
587  writeStr(3, "!\r\n");
588  return 0;
589  }
590 
591  // Read the data from the pin
592  return (gpio[0xE] & (1 << base)) >> (base ? base - 1 : 0);
593  }
594 
595  void enableoutput(int pin)
596  {
597  // Grab the GPIO MMIO range for the pin
598  int base = 0;
599  volatile unsigned int *gpio = getGpioForPin(pin, &base);
600  if (!gpio)
601  {
602  writeStr(3, "BeagleGpio::enableoutput :No GPIO found for pin ");
603  writeHex(3, pin);
604  writeStr(3, "!\r\n");
605  return;
606  }
607 
608  // Set the pin as an output (if it's an input, the bit is set)
609  if (gpio[0xD] & (1 << base))
610  gpio[0xD] ^= (1 << base);
611  }
612 
613  private:
615  void initspecific(int n, volatile unsigned int *gpio)
616  {
617  if (!gpio)
618  return;
619 
620  // Write information about it
624  unsigned int rev = gpio[0];
625  writeStr(3, "GPIO");
626  writeHex(3, n);
627  writeStr(3, ": revision ");
628  writeHex(3, (rev & 0xF0) >> 4);
629  writeStr(3, ".");
630  writeHex(3, rev & 0x0F);
631  writeStr(3, " - initialising: ");
632 
633  // 1. Perform a software reset of the GPIO.
634  gpio[0x4] = 2;
635  while (!(gpio[0x5] & 1))
636  ; // Poll GPIO_SYSSTATUS, bit 0
637 
638  // 2. Disable all IRQs
639  gpio[0x7] = 0; // GPIO_IRQENABLE1
640  gpio[0xB] = 0; // GPIO_IRQENABLE2
641 
642  // 3. Enable the module
643  gpio[0xC] = 0;
644 
645  // Completed the reset and initialisation.
646  writeStr(3, "Done.\r\n");
647  }
648 
651  volatile unsigned int *getGpioForPin(int pin, int *bit)
652  {
653  volatile unsigned int *gpio = 0;
654  if (pin < 32)
655  {
656  *bit = pin;
657  gpio = m_gpio1;
658  }
659  else if ((pin >= 34) && (pin < 64))
660  {
661  *bit = pin - 34;
662  gpio = m_gpio2;
663  }
664  else if ((pin >= 64) && (pin < 96))
665  {
666  *bit = pin - 64;
667  gpio = m_gpio3;
668  }
669  else if ((pin >= 96) && (pin < 128))
670  {
671  *bit = pin - 96;
672  gpio = m_gpio4;
673  }
674  else if ((pin >= 128) && (pin < 160))
675  {
676  *bit = pin - 128;
677  gpio = m_gpio5;
678  }
679  else if ((pin >= 160) && (pin < 192))
680  {
681  *bit = pin - 160;
682  gpio = m_gpio6;
683  }
684  else
685  gpio = 0;
686  return gpio;
687  }
688 
689  volatile unsigned int *m_gpio1;
690  volatile unsigned int *m_gpio2;
691  volatile unsigned int *m_gpio3;
692  volatile unsigned int *m_gpio4;
693  volatile unsigned int *m_gpio5;
694  volatile unsigned int *m_gpio6;
695 };
696 
700 {
706 
707  union
708  {
709  struct
710  {
711  uint32_t type : 2;
712  uint32_t ignore : 30;
713  } PACKED fault;
714  struct
715  {
716  uint32_t type : 2;
717  uint32_t sbz1 : 1;
718  uint32_t ns : 1;
719  uint32_t sbz2 : 1;
720  uint32_t domain : 4;
721  uint32_t imp : 1;
722  uint32_t baseaddr : 22;
723  } PACKED pageTable;
724  struct
725  {
726  uint32_t type : 2;
727  uint32_t b : 1;
728  uint32_t c : 1;
729  uint32_t xn : 1;
730  uint32_t domain : 4;
731  uint32_t imp : 1;
732  uint32_t ap1 : 2;
733  uint32_t tex : 3;
734  uint32_t ap2 : 1;
735  uint32_t s : 1;
736  uint32_t nG : 1;
737  uint32_t sectiontype : 1;
738  uint32_t ns : 1;
739  uint32_t base : 12;
740  } PACKED section;
741 
742  uint32_t entry;
743  } descriptor;
744 } PACKED;
745 
749 {
754 
755  union
756  {
757  struct
758  {
759  uint32_t type : 2;
760  uint32_t ignore : 30;
761  } PACKED fault;
762  struct
763  {
764  uint32_t type : 2;
765  uint32_t b : 1;
766  uint32_t c : 1;
767  uint32_t ap1 : 2;
768  uint32_t sbz : 3;
769  uint32_t ap2 : 1;
770  uint32_t s : 1;
771  uint32_t nG : 1;
772  uint32_t tex : 3;
773  uint32_t xn : 1;
774  uint32_t base : 16;
775  } PACKED largepage;
776  struct
777  {
778  uint32_t type : 2;
779  uint32_t b : 1;
780  uint32_t c : 1;
781  uint32_t ap1 : 2;
782  uint32_t sbz : 3;
783  uint32_t ap2 : 1;
784  uint32_t s : 1;
785  uint32_t nG : 1;
786  uint32_t base : 20;
787  } PACKED smallpage;
788 
789  uint32_t entry;
790  } descriptor;
791 } PACKED;
792 
793 extern "C" void __start(uint32_t r0, uint32_t machineType, struct atag *tagList)
794  __attribute__((noreturn));
795 void __start(uint32_t r0, uint32_t machineType, struct atag *tagList)
796 {
797  BeagleGpio gpio;
798 
799  bool b = uart_softreset(3);
800  if (!b)
801  while (1)
802  ;
803  b = uart_fifodefaults(3);
804  if (!b)
805  while (1)
806  ;
807  b = uart_protoconfig(3);
808  if (!b)
809  while (1)
810  ;
811  b = uart_disableflowctl(3);
812  if (!b)
813  while (1)
814  ;
815 
816  writeStr(3, "Pedigree for the BeagleBoard\r\n\r\n");
817 
818  gpio.initialise();
819 
820  gpio.enableoutput(149);
821  gpio.enableoutput(150);
822 
823  gpio.drivepin(
824  149); // Switch on the USR1 LED to show we're active and thinking
825  gpio.clearpin(150);
826 
827  writeStr(
828  3, "\r\nPlease press the USER button on the board to continue.\r\n");
829 
830  while (!gpio.capturepin(7))
831  ;
832 
833  writeStr(3, "USER button pressed, continuing...\r\n\r\n");
834 
835  writeStr(
836  3, "Press 1 to toggle the USR0 LED, and 2 to toggle the USR1 "
837  "LED.\r\nPress 0 to clear both LEDs. Hit ENTER to boot the "
838  "kernel.\r\n");
839  while (1)
840  {
841  char c = uart_read(3);
842  if (c == '1')
843  {
844  writeStr(3, "Toggling USR0 LED\r\n");
845  if (gpio.pinstate(150))
846  gpio.clearpin(150);
847  else
848  gpio.drivepin(150);
849  }
850  else if (c == '2')
851  {
852  writeStr(3, "Toggling USR1 LED\r\n");
853  if (gpio.pinstate(149))
854  gpio.clearpin(149);
855  else
856  gpio.drivepin(149);
857  }
858  else if (c == '0')
859  {
860  writeStr(3, "Clearing both USR0 and USR1 LEDs\r\n");
861  gpio.clearpin(149);
862  gpio.clearpin(150);
863  }
864  else if ((c == 13) || (c == 10))
865  break;
866  }
867 
868  writeStr(3, "\r\n\r\nPlease wait while the kernel is loaded...\r\n");
869 
870  Elf32 elf("kernel");
871  writeStr(3, "Preparing file... ");
872  elf.load((uint8_t *) file, 0);
873  writeStr(3, "Done!\r\n");
874 
875  writeStr(3, "Loading file into memory (please wait) ");
876  elf.writeSections();
877  writeStr(3, " Done!\r\n");
878  int (*main)(struct BootstrapStruct_t *) =
879  (int (*)(struct BootstrapStruct_t *)) elf.getEntryPoint();
880 
881  struct BootstrapStruct_t *bs =
882  reinterpret_cast<struct BootstrapStruct_t *>(0x80008000);
883  writeStr(3, "Creating bootstrap information structure... ");
884  ByteSet(bs, 0, sizeof(*bs));
885  bs->shndx = elf.m_pHeader->shstrndx;
886  bs->num = elf.m_pHeader->shnum;
887  bs->size = elf.m_pHeader->shentsize;
888  bs->addr = (unsigned int) elf.m_pSectionHeaders;
889  bs->flags |= MULTIBOOT_FLAG_ELF;
890 
891  // Repurpose these variables a little....
892  bs->mods_addr = reinterpret_cast<uint32_t>(elf.m_pBuffer);
893  bs->mods_count = (sizeof file) + 0x1000;
894  bs->flags |= MULTIBOOT_FLAG_MODS;
895 
896  // For every section header, set .addr = .offset + m_pBuffer.
897  for (int i = 0; i < elf.m_pHeader->shnum; i++)
898  {
899  elf.m_pSectionHeaders[i].addr =
900  elf.m_pSectionHeaders[i].offset + (uint32_t) elf.m_pBuffer;
901  }
902  writeStr(3, "Done!\r\n");
903 
904  // Just before running the kernel proper, turn off both LEDs so we can use
905  // their states for debugging the kernel.
906  gpio.clearpin(149);
907  gpio.clearpin(150);
908 
909  // Run the kernel, finally
910  writeStr(
911  3, "Now starting the Pedigree kernel (can take a while, please "
912  "wait).\r\n\r\n");
913  main(bs);
914 
915  while (1)
916  {
917  asm volatile("wfi");
918  }
919 }
Bootstrap structure passed to the kernel entry point.
void initspecific(int n, volatile unsigned int *gpio)
Initialises a specific GPIO to a given set of defaults.
Definition: main_beagle.cc:615
uint32_t getEntryPoint()
uint8_t * m_pBuffer
Offset of the file in memory.
Definition: arm/Elf32.h:217
volatile unsigned int * getGpioForPin(int pin, int *bit)
Definition: main_beagle.cc:651
bool load(uint8_t *pBuffer, unsigned int nBufferLength)
bool writeSections()