raspi3.pp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. {
  2. Copyright (c) 1998-2022 by the Free Pascal development team
  3. Raspberry Pi 3 startup code for aarch64-embedded targets
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. {$IFNDEF FPC_DOTTEDUNITS}
  18. unit raspi3;
  19. {$ENDIF FPC_DOTTEDUNITS}
  20. {$goto on}
  21. {$INLINE ON}
  22. interface
  23. implementation
  24. {$IFDEF FPC_DOTTEDUNITS}
  25. uses
  26. EmbeddedApi.ConsoleIO, EmbeddedApi.mmio, EmbeddedApi.mailbox, EmbeddedApi.raspiuart, EmbeddedApi.gpio;
  27. {$ELSE FPC_DOTTEDUNITS}
  28. uses
  29. consoleio, mmio, mailbox, raspiuart, gpio;
  30. {$ENDIF FPC_DOTTEDUNITS}
  31. procedure _FPC_haltproc; assembler; nostackframe; public name '_haltproc';
  32. asm
  33. .Lhalt:
  34. wfe
  35. b .Lhalt
  36. end;
  37. function RaspiWrite(ACh: AnsiChar; AUserData: pointer): boolean;
  38. begin
  39. UARTPuts(PeripheralBase, ACh);
  40. RaspiWrite := true;
  41. end;
  42. function RaspiRead(var ACh: AnsiChar; AUserData: pointer): boolean;
  43. begin
  44. ACh := UARTGet(PeripheralBase);
  45. RaspiRead := true;
  46. end;
  47. {$ifndef CUSTOM_ENTRY}
  48. procedure PASCALMAIN; external name 'PASCALMAIN';
  49. var
  50. _stack_top: record end; external name '_stack_top';
  51. _bss_start: record end; external name '_bss_start';
  52. _bss_size: record end; external name '_bss_size';
  53. { This start makes sure we only execute on core 0 - the others will halt }
  54. procedure _FPC_start; assembler; nostackframe;
  55. label
  56. _start;
  57. asm
  58. .init
  59. .align 16
  60. .globl _start
  61. _start:
  62. // find core, only enable 0
  63. mrs x1, mpidr_el1
  64. and x1, x1, #3
  65. // cpu id > 0, stop
  66. cbz x1, .L2
  67. .L1:
  68. wfe
  69. b .L1
  70. .L2:
  71. // set up the stack
  72. ldr x0, .L_stack_top
  73. mov sp, x0
  74. // clear BSS here
  75. ldr x1, .L_bss_start
  76. ldr w2, .L_bss_size
  77. .L3:
  78. cbz w2, .L4
  79. str xzr, [x1], #8
  80. sub w2, w2, #1
  81. cbnz w2, .L3
  82. .L4:
  83. bl PASCALMAIN
  84. bl _FPC_haltproc
  85. .L_stack_top:
  86. .word _stack_top
  87. .L_bss_start:
  88. .word _bss_start
  89. .L_bss_size:
  90. .word _bss_size
  91. .text
  92. end;
  93. {$endif CUSTOM_ENTRY}
  94. begin
  95. UARTInit(PeripheralBase);
  96. OpenIO(Input, @RaspiWrite, @RaspiRead, fmInput, nil);
  97. OpenIO(Output, @RaspiWrite, @RaspiRead, fmOutput, nil);
  98. OpenIO(ErrOutput, @RaspiWrite, @RaspiRead, fmOutput, nil);
  99. OpenIO(StdOut, @RaspiWrite, @RaspiRead, fmOutput, nil);
  100. OpenIO(StdErr, @RaspiWrite, @RaspiRead, fmOutput, nil);
  101. end.