Zynq.Environment.Mod 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. (* Zynq environment *)
  2. (* Copyright (C) Florian Negele *)
  3. MODULE Environment;
  4. IMPORT SYSTEM, Activities, CPU, HeapManager, Interrupts, Trace, Processors, Timer;
  5. CONST Running* = 0; ShuttingDown* = 1; Rebooting* = 2;
  6. VAR memory: SIZE;
  7. VAR heap: HeapManager.Heap;
  8. VAR frequency: Timer.Counter;
  9. VAR status* := Running: WORD;
  10. PROCEDURE {NORETURN} Abort-;
  11. BEGIN {UNCOOPERATIVE, UNCHECKED}
  12. IF SYSTEM.GetActivity () # NIL THEN Activities.TerminateCurrentActivity END;
  13. Activities.TerminateCurrentActivity;
  14. END Abort;
  15. PROCEDURE Allocate- (size: SIZE): ADDRESS;
  16. VAR result, address: ADDRESS;
  17. BEGIN {UNCOOPERATIVE, UNCHECKED}
  18. result := HeapManager.Allocate (size, heap);
  19. IF result = NIL THEN RETURN NIL END;
  20. FOR address := result TO result + size - 1 DO SYSTEM.PUT8 (address, 0) END;
  21. RETURN result;
  22. END Allocate;
  23. PROCEDURE Deallocate- (address: ADDRESS);
  24. BEGIN {UNCOOPERATIVE, UNCHECKED}
  25. HeapManager.Deallocate (address, heap);
  26. END Deallocate;
  27. PROCEDURE Write- (character: CHAR);
  28. BEGIN {UNCOOPERATIVE, UNCHECKED}
  29. WHILE CPU.TXFULL IN CPU.ReadMask (CPU.UART1 + CPU.Channel_sts_reg0) DO END;
  30. CPU.WriteWord (CPU.UART1 + CPU.TX_RX_FIFO0, LSH (ORD (character), CPU.FIFO));
  31. END Write;
  32. PROCEDURE Flush-;
  33. BEGIN {UNCOOPERATIVE, UNCHECKED}
  34. REPEAT UNTIL CPU.TXEMPTY IN CPU.ReadMask (CPU.UART1 + CPU.Channel_sts_reg0);
  35. END Flush;
  36. PROCEDURE GetString- (CONST name: ARRAY OF CHAR; VAR result: ARRAY OF CHAR);
  37. BEGIN {UNCOOPERATIVE, UNCHECKED}
  38. result[0] := 0X
  39. END GetString;
  40. PROCEDURE Clock- (): LONGINT;
  41. BEGIN RETURN Timer.GetCounter () DIV frequency;
  42. END Clock;
  43. PROCEDURE Sleep- (milliseconds: LONGINT);
  44. VAR clock: Timer.Counter;
  45. BEGIN {UNCOOPERATIVE, UNCHECKED}
  46. ASSERT (milliseconds >= 0);
  47. clock := Timer.GetCounter () + milliseconds * frequency;
  48. WHILE Timer.GetCounter () - clock < 0 DO Activities.Switch END;
  49. END Sleep;
  50. PROCEDURE Shutdown*;
  51. BEGIN {UNCOOPERATIVE, UNCHECKED}
  52. IF CAS (status, Running, ShuttingDown) # Running THEN RETURN END;
  53. Trace.StringLn ("system: shutting down...");
  54. END Shutdown;
  55. PROCEDURE Reboot*;
  56. BEGIN {UNCOOPERATIVE, UNCHECKED}
  57. Shutdown;
  58. ASSERT (CAS (status, ShuttingDown, Rebooting) = ShuttingDown);
  59. END Reboot;
  60. PROCEDURE {NORETURN} Exit- (status: WORD);
  61. BEGIN {UNCOOPERATIVE, UNCHECKED}
  62. Trace.String ("system: ");
  63. IF status = Rebooting THEN Trace.StringLn ("rebooting..."); CPU.Reset END;
  64. Trace.StringLn ("ready for power off or restart"); Flush; CPU.Halt;
  65. END Exit;
  66. PROCEDURE InitTrace;
  67. CONST BaudRate = 115200;
  68. CONST BDIV = 6; CD = CPU.UART_REF_CLK DIV BaudRate DIV (BDIV + 1);
  69. BEGIN {UNCOOPERATIVE, UNCHECKED}
  70. CPU.WriteMask (CPU.UART_RST_CTRL, {CPU.UART1_REF_RST, CPU.UART1_CPU1X_RST});
  71. CPU.WriteMask (CPU.UART1 + CPU.mode_reg0, {CPU.PAR + 2});
  72. CPU.WriteMask (CPU.UART1 + CPU.Intrpt_dis_reg0, {0..12});
  73. (* commented out to reuse UART settings from bootloader
  74. CPU.WriteMask (CPU.UART1 + CPU.Control_reg0, {CPU.RXDIS, CPU.TXDIS});
  75. CPU.WriteWord (CPU.UART1 + CPU.Baud_rate_gen_reg0, LSH (CD, CPU.CD));
  76. CPU.WriteWord (CPU.UART1 + CPU.Baud_rate_divider_reg0, LSH (BDIV, CPU.BDIV));
  77. CPU.WriteMask (CPU.UART1 + CPU.Control_reg0, {CPU.RXRST, CPU.TXRST});
  78. CPU.WriteMask (CPU.UART1 + CPU.Control_reg0, {CPU.RXEN, CPU.TXEN});
  79. *)
  80. Trace.Init; Trace.Char := Write;
  81. END InitTrace;
  82. PROCEDURE InitMemory;
  83. CONST MemorySize = 512 * 1024 * 1024;
  84. BEGIN {UNCOOPERATIVE, UNCHECKED}
  85. HeapManager.Initialize (heap, ADDRESS OF KernelEnd, MemorySize);
  86. memory := MemorySize - ADDRESS OF KernelEnd;
  87. END InitMemory;
  88. PROCEDURE StoreActivity-;
  89. BEGIN {UNCOOPERATIVE, UNCHECKED}
  90. END StoreActivity;
  91. PROCEDURE RestoreActivity-;
  92. BEGIN {UNCOOPERATIVE, UNCHECKED}
  93. END RestoreActivity;
  94. PROCEDURE Initialize-;
  95. BEGIN {UNCOOPERATIVE, UNCHECKED}
  96. CPU.Initialize; InitTrace; InitMemory;
  97. frequency := Timer.GetFrequency () DIV 1000;
  98. END Initialize;
  99. PROCEDURE Terminate-;
  100. BEGIN {UNCOOPERATIVE, UNCHECKED}
  101. Interrupts.Terminate;
  102. END Terminate;
  103. PROCEDURE {NOPAF, INITIAL, FIXED(100000H)} KernelBegin;
  104. CODE
  105. ; initialize SP
  106. MOV SP, #0x8000
  107. MRC P15, 0, R0, C0, C0, 5
  108. AND R0, R0, #0x1
  109. SUB SP, SP, R0, LSL #13
  110. ; filter CPU
  111. CMP R0, #0
  112. BEQ skip
  113. WFE
  114. B @Processors.Boot
  115. skip:
  116. END KernelBegin;
  117. PROCEDURE {NOPAF, FINAL, ALIGNED(32)} KernelEnd;
  118. CODE
  119. END KernelEnd;
  120. BEGIN {UNCHECKED}
  121. Trace.String ("Version "); Trace.String (SYSTEM.Date); Trace.String (" (");
  122. Trace.Int (memory DIV (1024 * 1024), 0); Trace.String (" MB RAM, GC, ");
  123. Trace.Int (Processors.count, 0); Trace.String (" CPU");
  124. IF Processors.count > 1 THEN Trace.Char ('s') END; Trace.Char (')'); Trace.Ln;
  125. END Environment.