2
0

Zynq.SdControllers.Mod 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. MODULE SdControllers;
  2. (**
  3. AUTHOR Timothée Martiel, 12/2015
  4. PURPOSE SD Host Controller Initialization for Zynq SoC.
  5. *)
  6. IMPORT
  7. Platform, Modules, Objects, Commands,
  8. Sd, SdDisks, SdEnvironment, Log := SdEnvironment;
  9. CONST
  10. Ready = 0;
  11. Running = 1;
  12. Stopped = 2;
  13. Error = 3;
  14. TYPE
  15. HostController * = OBJECT
  16. VAR
  17. hc: Sd.HostController;
  18. handler: InterruptHandler;
  19. state, event: LONGINT;
  20. card: Sd.Card;
  21. halted: BOOLEAN;
  22. PROCEDURE & Init (base: ADDRESS; int: LONGINT; clock: HUGEINT);
  23. VAR
  24. result: LONGINT;
  25. BEGIN
  26. NEW(hc);
  27. Sd.InitHostController(hc, base);
  28. IF ~Sd.SetExternalClock(hc, clock, clock, result) THEN
  29. Log.String("[SD] Failed to initialize host controller: error code ");
  30. Log.Int(result, 0);
  31. Log.Ln;
  32. state := Error;
  33. RETURN
  34. END;
  35. state := Ready; (* Do not put this later, as events might be triggered in the constructor *)
  36. NEW(handler, SELF);
  37. SdEnvironment.InstallHandler(handler.Handle, int);
  38. END Init;
  39. PROCEDURE HandleEvent (card: Sd.Card; event: LONGINT; param: ANY);
  40. BEGIN {EXCLUSIVE}
  41. AWAIT(state # Running);
  42. SELF.event := event;
  43. SELF.card := card;
  44. IF state = Ready THEN state := Running END
  45. END HandleEvent;
  46. PROCEDURE Stop;
  47. BEGIN {EXCLUSIVE}
  48. IF state < Stopped THEN state := Stopped END;
  49. AWAIT(halted)
  50. END Stop;
  51. PROCEDURE WaitForEventCompletion;
  52. BEGIN {EXCLUSIVE}
  53. AWAIT(state # Running)
  54. END WaitForEventCompletion;
  55. BEGIN {ACTIVE}
  56. LOOP
  57. BEGIN {EXCLUSIVE}
  58. AWAIT(state # Ready);
  59. IF state >= Stopped THEN EXIT END;
  60. END;
  61. SdDisks.HandleSdEvent(card, event);
  62. BEGIN {EXCLUSIVE}
  63. state := Ready
  64. END
  65. END
  66. FINALLY
  67. BEGIN {EXCLUSIVE} halted := TRUE END
  68. END HostController;
  69. InterruptHandler * = OBJECT
  70. VAR
  71. hc: Sd.HostController;
  72. timer: Objects.Timer;
  73. mask: SET;
  74. blocked: BOOLEAN;
  75. PROCEDURE & Init (hc: HostController);
  76. BEGIN
  77. SELF.hc := hc.hc;
  78. NEW(timer);
  79. blocked := FALSE
  80. END Init;
  81. PROCEDURE Block (hc: Sd.HostController; mask: SET; timeout: LONGINT): BOOLEAN;
  82. VAR
  83. irqs: SET;
  84. BEGIN {EXCLUSIVE}
  85. ASSERT(hc = SELF.hc);
  86. blocked := TRUE;
  87. irqs := hc.regs.InterruptSignalEnable;
  88. hc.regs.InterruptSignalEnable := irqs + mask;
  89. SELF.mask := mask;
  90. Objects.SetTimeout(timer, Unblock, timeout);
  91. AWAIT(~blocked);
  92. hc.regs.InterruptSignalEnable := irqs;
  93. RETURN mask * hc.regs.InterruptStatus # {}
  94. END Block;
  95. PROCEDURE Unblock;
  96. BEGIN {EXCLUSIVE}
  97. blocked := FALSE
  98. END Unblock;
  99. PROCEDURE Handle;
  100. BEGIN
  101. IF hc.regs.InterruptStatus * mask # {} THEN
  102. Unblock;
  103. Objects.CancelTimeout(timer);
  104. END;
  105. Sd.HandleInterrupt(hc);
  106. END Handle;
  107. END InterruptHandler;
  108. VAR
  109. hc: ARRAY 2 OF HostController;
  110. PROCEDURE Init;
  111. VAR
  112. i: LONGINT;
  113. BEGIN
  114. Modules.InstallTermHandler(Cleanup);
  115. FOR i := 0 TO Platform.SdNb - 1 DO
  116. IF SdEnvironment.Enable(i) THEN
  117. IF Sd.EnableTrace THEN
  118. Log.String("[SD] Enabling controller "); Log.Int(i, 0); Log.Ln;
  119. Log.String("[SD] register base = "); Log.Address(Platform.SdBase[i]); Log.Ln;
  120. Log.String("[SD] base clock = "); Log.Int(SdEnvironment.HcClock(i), 0); Log.String(" Hz"); Log.Ln;
  121. Log.String("[SD] irq = "); Log.Int(Platform.SdIrq[i], 0); Log.Ln;
  122. END;
  123. NEW(hc[i], Platform.SdBase[i], Platform.SdIrq[i], SdEnvironment.HcClock(i));
  124. Sd.SetEventHandler(hc[i].hc, hc[i].HandleEvent, NIL);
  125. hc[i].WaitForEventCompletion;
  126. (* Sd.SetBlocker(hc[i].hc, hc[i].handler.Block)*)
  127. ELSE
  128. IF Sd.EnableTrace THEN
  129. Log.String("[SD] Not Enabling controller "); Log.Int(i, 0); Log.Ln
  130. END;
  131. END
  132. END
  133. END Init;
  134. PROCEDURE Cleanup;
  135. VAR
  136. i: LONGINT;
  137. BEGIN
  138. FOR i := 0 TO LEN(hc) - 1 DO
  139. IF hc[i] # NIL THEN hc[i].Stop END
  140. END
  141. END Cleanup;
  142. PROCEDURE Statistics * (c: Commands.Context);
  143. VAR
  144. accesses: LONGINT;
  145. byteRead, byteWritten, read, write: HUGEINT;
  146. tread, twrite: HUGEINT;
  147. speedR, speedW: LONGREAL;
  148. BEGIN
  149. byteRead := Sd.NbyteRead;
  150. byteWritten := Sd.NbyteWritten;
  151. read := Sd.Nread;
  152. write := Sd.Nwrite;
  153. tread := SdEnvironment.ToMicro(Sd.Tread);
  154. twrite := SdEnvironment.ToMicro(Sd.Twrite);
  155. IF read > 0 THEN
  156. speedR := LONGREAL(byteRead) / LONGREAL(tread);
  157. c.out.String("SD Statistics:"); c.out.Ln;
  158. c.out.String(" Bytes read: "); c.out.Int(byteRead, 0); c.out.Ln;
  159. c.out.String(" Number of reads: "); c.out.Int(read, 0); c.out.Ln;
  160. c.out.String(" Read time: "); c.out.Int(tread, 0); c.out.String(" us"); c.out.Ln;
  161. c.out.String(" Average read size: "); c.out.Int(byteRead DIV read, 0); c.out.String(" bytes"); c.out.Ln;
  162. c.out.String(" Read speed: "); c.out.FloatFix(speedR, 0, 3, 0); c.out.String(" Mb/s"); c.out.Ln;
  163. c.out.String(" Average read time: "); c.out.FloatFix(LONGREAL(tread) / LONGREAL(read), 0, 3, 0); c.out.String(" us"); c.out.Ln;
  164. ELSE
  165. c.out.String("No read statistics");
  166. c.out.Ln
  167. END;
  168. IF write > 0 THEN
  169. speedW := LONGREAL(byteWritten) / LONGREAL(twrite);
  170. c.out.String(" Bytes written: "); c.out.Int(byteWritten, 0); c.out.Ln;
  171. c.out.String(" Number of writes: "); c.out.Int(write, 0); c.out.Ln;
  172. c.out.String(" Write time: "); c.out.Int(twrite, 0); c.out.String(" us"); c.out.Ln;
  173. c.out.String(" Average write size: "); c.out.Int(byteWritten DIV write, 0); c.out.String(" bytes"); c.out.Ln;
  174. c.out.String(" Write speed: "); c.out.FloatFix(speedW, 0, 3, 0); c.out.String(" Mb/s"); c.out.Ln;
  175. c.out.String(" Average write time: "); c.out.FloatFix(LONGREAL(twrite) / LONGREAL(write), 0, 3, 0); c.out.String(" us"); c.out.Ln;
  176. ELSE
  177. c.out.String("No write statistics");
  178. c.out.Ln
  179. END;
  180. accesses := SdDisks.NcacheHits + SdDisks.NcacheMiss;
  181. c.out.String("SD Disks Cache Statistics"); c.out.Ln;
  182. c.out.String(" Number of accesses: "); c.out.Int(accesses, 0); c.out.Ln;
  183. c.out.String(" Number of hits: "); c.out.Int(SdDisks.NcacheHits, 0); c.out.String(" ("); c.out.FloatFix(SdDisks.NcacheHits / accesses * 100.0, 0, 2, 0); c.out.String(" %)"); c.out.Ln;
  184. c.out.String(" Number of misses: "); c.out.Int(SdDisks.NcacheMiss, 0); c.out.String(" ("); c.out.FloatFix(SdDisks.NcacheMiss / accesses * 100.0, 0, 2, 0); c.out.String(" %)"); c.out.Ln;
  185. c.out.String(" Number of evictions: "); c.out.Int(SdDisks.NcacheEvict, 0); c.out.String(" ("); c.out.FloatFix(SdDisks.NcacheEvict / SdDisks.NcacheMiss * 100.0, 0, 2, 0); c.out.String(" %)"); c.out.Ln;
  186. c.out.String("SD Disks Write Buffer Statistics"); c.out.Ln;
  187. c.out.String(" Average write size: "); c.out.FloatFix(SdDisks.NbufferSize / SdDisks.NbufferWrites, 0, 2, 0); c.out.String(" bytes"); c.out.Ln;
  188. c.out.String(" Average queue length: "); c.out.FloatFix(SdDisks.NbufferQueueSize / SdDisks.NbufferQueueSamples, 0, 2, 0); c.out.Ln;
  189. c.out.Update;
  190. END Statistics;
  191. BEGIN
  192. Init
  193. END SdControllers.