mbr.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * mbr - the initial 512 byte bootstrap program
  3. *
  4. * Copyright (c) 2009 Openmoko Inc.
  5. *
  6. * Authors Daniel Mack <daniel@caiaq.de>
  7. * Christopher Hall <hsw@openmoko.com>
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. #define APPLICATION_TITLE "mbr"
  23. #include "application.h"
  24. #define RAM_SIZE 8192
  25. #define RAM_LOAD_ADDRESS 0x200
  26. #define EEPROM_CODE_OFFSET 0x300
  27. #define EEPROM_PAYLOAD_SIZE (RAM_SIZE - EEPROM_CODE_OFFSET)
  28. #define APPLICATION_RAM_START ((uint8_t *)RAM_LOAD_ADDRESS)
  29. #define APPLICATION ((application *)RAM_LOAD_ADDRESS)
  30. // this is actually local
  31. uint8_t SPI_exchange(uint8_t out);
  32. // this defines the entry points to the MBR code
  33. // and the SPI_exchange code
  34. // uint32_t is used to keep the compiler from generating extraneous code
  35. uint32_t start(uint32_t out)
  36. {
  37. asm volatile (
  38. "jp\tmaster_boot \n\t" // location 0 - boot
  39. "jp\tFLASH_read \n\t" // location 2 - so eeprom_load can be reused
  40. "SPI_exchange: " // location 4 - so SPI_exchange can be reused
  41. );
  42. // start of code for: uint8_t SPI_exchange(uint8_t out)
  43. REG_SPI_TXD = out;
  44. do {} while (~REG_SPI_STAT & RDFF);
  45. return REG_SPI_RXD;
  46. }
  47. bool FLASH_read(void *buffer, size_t size, uint32_t ROMAddress)
  48. {
  49. EEPROM_CS_HI();
  50. SPI_exchange(0x00);
  51. EEPROM_CS_LO();
  52. #if EEPROM_SST25VF040 || EEPROM_PM25LV512
  53. /* read high-speed */
  54. SPI_exchange(0x0b);
  55. #define REQUIRES_DUMMY_CYCLE 1
  56. #elif EEPROM_MP45PE80
  57. /* read normal-speed */
  58. SPI_exchange(0x03);
  59. #define REQUIRES_DUMMY_CYCLE 0
  60. #else
  61. #error "Unsupported EEPROM"
  62. #endif
  63. SPI_exchange(ROMAddress >> 16);
  64. SPI_exchange(ROMAddress >> 8);
  65. SPI_exchange(ROMAddress);
  66. #if REQUIRES_DUMMY_CYCLE
  67. /* dummy cycle */
  68. SPI_exchange(0x00);
  69. #endif
  70. uint8_t *bytes = (uint8_t *)buffer;
  71. while (size--) {
  72. *bytes++ = SPI_exchange(0x00);
  73. }
  74. EEPROM_CS_HI();
  75. return true;
  76. }
  77. __attribute__ ((noreturn))
  78. void master_boot(void)
  79. {
  80. asm volatile ("xld.w %r15, __dp");
  81. {
  82. register ReturnType rc = { 0, 0xffffffff };
  83. for (;;) {
  84. asm volatile ("xld.w %r15, __dp");
  85. init_pins();
  86. init_rs232_ch0();
  87. //init_ram(); // but will be too big
  88. // enable SPI
  89. REG_SPI_CTL1 =
  90. BPT_8_BITS |
  91. //CPHA |
  92. //CPOL |
  93. MCBR_MCLK_DIV_4 |
  94. //TXDE |
  95. //RXDE |
  96. MODE_MASTER |
  97. ENA |
  98. 0;
  99. FLASH_read(APPLICATION_RAM_START, EEPROM_PAYLOAD_SIZE, (rc.block << 13) | EEPROM_CODE_OFFSET);
  100. rc = (APPLICATION)(rc.block, rc.status);
  101. }
  102. }
  103. }