Sfoglia il codice sorgente

Added environment module for Raspberry Pi

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@6397 8c9fc860-2736-0410-a75d-ab315db34111
eth.negelef 9 anni fa
parent
commit
8cedf9f9e6
1 ha cambiato i file con 143 aggiunte e 0 eliminazioni
  1. 143 0
      source/RPI.Environment.Mod

+ 143 - 0
source/RPI.Environment.Mod

@@ -0,0 +1,143 @@
+(* Raspberry Pi environment *)
+(* Copyright (C) Florian Negele *)
+
+MODULE Environment;
+
+IMPORT SYSTEM, Activities, CPU, HeapManager, Interrupts, Trace, Processors;
+
+CONST Running = 0; Halting = 1; Resetting = 2;
+
+VAR heap: HeapManager.Heap;
+VAR clock := 0: LONGINT;
+VAR status* := Running: WORD;
+VAR uartInterruptInstalled := 0: SIZE;
+VAR timerInterruptInstalled := 0: SIZE;
+VAR uartInterrupt: Interrupts.Interrupt;
+VAR previousTimerHandler := NIL: CPU.InterruptHandler;
+VAR name- EXTERN "_environment": ARRAY MAX (SIZE) OF CHAR;
+
+PROCEDURE {NORETURN} Abort-;
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	Trace.StackFrames (2, 8, SIZE OF ADDRESS * 20);
+	IF SYSTEM.GetActivity () = NIL THEN Exit (Resetting) END;
+	Activities.TerminateCurrentActivity;
+END Abort;
+
+PROCEDURE Allocate- (size: SIZE): ADDRESS;
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	RETURN HeapManager.Allocate (size, heap);
+END Allocate;
+
+PROCEDURE Deallocate- (address: ADDRESS);
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	HeapManager.Deallocate (address, heap);
+END Deallocate;
+
+PROCEDURE Write- (character: CHAR);
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	WHILE CPU.TXFF IN CPU.ReadMask (CPU.UART_FR) DO END;
+	CPU.WriteWord (CPU.UART_DR, ORD (character));
+END Write;
+
+PROCEDURE Read- (VAR character: CHAR): BOOLEAN;
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	WHILE CPU.RXFE IN CPU.ReadMask (CPU.UART_FR) DO
+		IF CAS (uartInterruptInstalled, 0, 1) = 0 THEN
+			Interrupts.Install (uartInterrupt, CPU.IRQ);
+		END;
+		CPU.WriteMask (CPU.IRQEnable2, {25});
+		Interrupts.Await (uartInterrupt);
+		IF status # Running THEN RETURN FALSE END;
+	END;
+	character := CHR (CPU.ReadWord (CPU.UART_DR));
+	Write (character); RETURN TRUE;
+END Read;
+
+PROCEDURE Flush-;
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	REPEAT UNTIL CPU.TXFE IN CPU.ReadMask (CPU.UART_FR);
+END Flush
+
+PROCEDURE Sleep- (milliseconds: LONGINT);
+VAR interrupt: Interrupts.Interrupt;
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	ASSERT (milliseconds >= 0);
+	IF CAS (timerInterruptInstalled, 0, 1) = 0 THEN
+		previousTimerHandler := CPU.InstallInterrupt (HandleTimer, CPU.IRQ);
+		CPU.WriteWord (CPU.STC1, CPU.ReadWord (CPU.STCLO) + 1000);
+		CPU.WriteMask (CPU.IRQEnable1, {1});
+	END;
+	Interrupts.Install (interrupt, CPU.IRQ); INC (milliseconds, clock);
+	WHILE clock - milliseconds < 0 DO Interrupts.Await (interrupt) END;
+END Sleep;
+
+PROCEDURE HandleTimer (index: SIZE);
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	IF previousTimerHandler # NIL THEN previousTimerHandler (index) END;
+	IF 1 IN CPU.ReadMask (CPU.STCS) THEN
+		CPU.WriteWord (CPU.STC1, CPU.ReadWord (CPU.STCLO) + 1000);
+		CPU.WriteMask (CPU.STCS, {1}); INC (clock);
+		CPU.WriteMask (CPU.IRQEnable1, {1});
+	END;
+END HandleTimer;
+
+PROCEDURE LED- (status: BOOLEAN);
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	CPU.Mask (CPU.GPFSEL1, {18});
+	IF status THEN CPU.WriteMask (CPU.GPSET1, {15}) ELSE CPU.WriteMask (CPU.GPCLR1, {15}) END;
+END LED;
+
+PROCEDURE Halt*;
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	IF CAS (status, Running, Halting) # Running THEN RETURN END;
+	Trace.String ("system: halting..."); Trace.Ln;
+	IF uartInterruptInstalled # 0 THEN CPU.WriteMask (CPU.IRQDisable2, {25}); Interrupts.Cancel (uartInterrupt) END;
+	IF timerInterruptInstalled # 0 THEN CPU.WriteMask (CPU.IRQDisable1, {1}) END;
+END Halt;
+
+PROCEDURE Reset*;
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	Halt;
+	ASSERT (CAS (status, Halting, Resetting) = Halting);
+END Reset;
+
+PROCEDURE {NORETURN} Exit- (status: WORD);
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	Trace.String ("system: ");
+	IF status = Resetting THEN Trace.String ("resetting..."); Trace.Ln; Flush; CPU.Reset END;
+	Trace.String ("ready for power off or reset"); Trace.Ln; Flush; CPU.Halt;
+END Exit;
+
+PROCEDURE Initialize-;
+CONST BaudRate = 115200;
+VAR heapStart EXTERN "_heap_start": ADDRESS;
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	SYSTEM.SetActivity (NIL);
+	CPU.Initialize; LED (TRUE);
+	CPU.WriteMask (CPU.UART_CR, {CPU.UARTEN});
+	CPU.Unmask (CPU.GPPUD, {CPU.PUD}); CPU.Delay (150);
+	CPU.Mask (CPU.GPPUDCLK0, {14, 15}); CPU.Delay (150);
+	CPU.WriteMask (CPU.GPPUDCLK0, {});
+	CPU.WriteMask (CPU.UART_ICR, {1, 4..10});
+	CPU.WriteWord (CPU.UART_IBRD, CPU.FUARTCLK DIV (16 * BaudRate));
+	CPU.WriteWord (CPU.UART_FBRD, (CPU.FUARTCLK MOD (16 * BaudRate)) * 64 DIV (16 * BaudRate));
+	CPU.WriteMask (CPU.UART_LCRH, CPU.WLEN8);
+	CPU.WriteMask (CPU.UART_IMSC, {CPU.RXIM});
+	CPU.WriteMask (CPU.UART_CR, {CPU.UARTEN, CPU.TXE, CPU.RXE});
+	CPU.IdentityMapMemory; CPU.EnableMemoryManagementUnit;
+	HeapManager.Initialize (heap, heapStart, CPU.MemorySize);
+END Initialize;
+
+PROCEDURE Terminate-;
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	Interrupts.Terminate;
+	LED (FALSE);
+END Terminate;
+
+BEGIN {UNCHECKED}
+	Trace.String ("Version "); Trace.String (SYSTEM.Date); Trace.String (" (");
+	Trace.Int (CPU.MemorySize DIV (1024 * 1024), 0); Trace.String (" MB RAM, GC, ");
+	Trace.String ("GC, ");
+	Trace.Int (Processors.count, 0); Trace.String (" CPU");
+	IF Processors.count > 1 THEN Trace.Char ('s') END; Trace.Char (')'); Trace.Ln;
+END Environment.