123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810 |
- MODULE Machine;
- IMPORT CPU, Environment, Trace, Mutexes, Processors;
- CONST
- Version = "A2 Cooperative Revision 5791";
- MaxCPU* = Processors.Maximum; (* dummy definition to make GC for both Win32 and I386 work *)
- #IF UNIX THEN
- #IF AMD64 THEN
- DefaultObjectFileExtension* = ".GofUc";
- #ELSE
- DefaultObjectFileExtension* = ".GofU";
- #END
- #ELSE
- DefaultObjectFileExtension* = ".Obw";
- #END
- (** bits in features variable *)
- MTTR* = 12; MMX* = 23;
- debug* = FALSE; (** display more debug output during booting *)
- IsCooperative*= TRUE;
- CONST
- (** standard lock levels (in order) *) (* also refer to Traps.Show *)
- TraceOutput* = 0; (* Trace output *)
- Memory* = 1; (* Virtual memory management, stack and page allocation *)
- Heaps* = 2; (* Storage allocation and Garbage collection *)
- Interrupts* = 3; (* Interrupt handling. *)
- Modules* = 4; (* Module list *)
- Objects* = 5; (* Ready queue *)
- KernelLog* = 7; (* Atomic output *)
- GC* = 8;
- X11* = 9; (* XWindows I/O *)
- MaxLocks = 10; (* { <= 32 } *)
- (* error codes *)
- Ok* = 0;
- NilAdr* = -1; (* nil value for addresses (not same as pointer NIL value) *)
- IRQ0* = CPU.IRQ0;
- MaxIRQ* = CPU.IRQ15;
- TYPE
- Vendor* = ARRAY 13 OF CHAR;
- IDMap* = ARRAY 16 OF SHORTINT;
- Range* = RECORD
- adr*: ADDRESS; size*: SIZE;
- END;
- MemoryBlock* = POINTER TO MemoryBlockDesc;
- MemoryBlockDesc* = RECORD
- next- {UNTRACED}: MemoryBlock;
- startAdr-: ADDRESS; (* sort key in linked list of memory blocks *)
- size-: SIZE;
- beginBlockAdr-, endBlockAdr-: ADDRESS
- END;
- (* dummy definition to make GC work for both I386 and Win32 - copied from BIOS.I386.Machine.Mod, but not really used *)
- Stack* = RECORD (** values are read-only *)
- low: ADDRESS; (* lowest virtual address that may be allocated for stack *)
- adr*: ADDRESS; (* lowest address on allocated stack *) (* exported for Objects only *)
- high*: ADDRESS; (* next virtual address after stack *) (* exported for Objects only *)
- END;
-
- Address32* = LONGINT;
- VAR
- MMXSupport*: BOOLEAN;
- SSESupport*: BOOLEAN;
- SSE2Support*: BOOLEAN;
- SSE3Support-: BOOLEAN; (* PH 04/11*)
- SSSE3Support-: BOOLEAN;
- SSE41Support-: BOOLEAN;
- SSE42Support-: BOOLEAN;
- SSE5Support-: BOOLEAN;
- AVXSupport-: BOOLEAN;
- version*: ARRAY 64 OF CHAR; (** Aos version *)
- features*,features2*: SET; (** processor features *)
- fcr*: SET; (** default floating-point control register value (default rounding mode is towards -infinity, for ENTIER) *)
- mhz*: HUGEINT; (** clock rate of GetTimer() in MHz, or 0 if not known *)
- boottime-: HUGEINT; (** in timer units *)
- VAR
- lock-: ARRAY MaxLocks OF CHAR; (* not implemented as SET because of shared access *)
- mutex: ARRAY MaxLocks OF Mutexes.Mutex;
- memBlockHead-{UNTRACED}, memBlockTail-{UNTRACED}: MemoryBlock; (* head and tail of sorted list of memory blocks *)
- (** Convert a string to an integer. Parameter i specifies where in the string scanning should begin (usually 0 in the first call). Scanning stops at the first non-valid character, and i returns the updated position. Parameter s is the string to be scanned. The value is returned as result, or 0 if not valid. Syntax: number = ["-"] digit {digit} ["H" | "h"] . digit = "0" | ... "9" | "A" .. "F" | "a" .. "f" . If the number contains any hexdecimal letter, or if it ends in "H" or "h", it is interpreted as hexadecimal. *)
- PROCEDURE StrToInt*( VAR i: LONGINT; CONST s: ARRAY OF CHAR ): LONGINT;
- VAR vd, vh, sgn, d: LONGINT; hex: BOOLEAN;
- BEGIN
- vd := 0; vh := 0; hex := FALSE;
- IF s[i] = "-" THEN sgn := -1; INC( i ) ELSE sgn := 1 END;
- LOOP
- IF (s[i] >= "0") & (s[i] <= "9") THEN d := ORD( s[i] ) - ORD( "0" )
- ELSIF (CAP( s[i] ) >= "A") & (CAP( s[i] ) <= "F") THEN d := ORD( CAP( s[i] ) ) - ORD( "A" ) + 10; hex := TRUE
- ELSE EXIT
- END;
- vd := 10 * vd + d; vh := 16 * vh + d; INC( i )
- END;
- IF CAP( s[i] ) = "H" THEN hex := TRUE; INC( i ) END; (* optional H *)
- IF hex THEN vd := vh END;
- RETURN sgn * vd
- END StrToInt;
- (** -- Atomic operations -- *)
- (** This procedure should be called in all spin loops as a hint to the processor (e.g. Pentium 4). *)
- PROCEDURE -SpinHint*;
- CODE
- #IF I386 THEN
- PAUSE
- #ELSIF AMD64 THEN
- PAUSE
- #ELSE
- unimplemented
- #END
- END SpinHint;
- (* Return current instruction pointer *)
- PROCEDURE CurrentPC* (): ADDRESS;
- CODE
- #IF I386 THEN
- MOV EAX, [EBP+4]
- #ELSIF AMD64 THEN
- MOV RAX, [RBP + 8]
- #ELSE
- unimplemented
- #END
- END CurrentPC;
- PROCEDURE MapPhysical*(physAdr: ADDRESS; size: SIZE; VAR virtAdr: ADDRESS);
- BEGIN
- virtAdr := physAdr;
- END MapPhysical;
- (** Unmap an area previously mapped with MapPhysical. *)
- PROCEDURE UnmapPhysical*(virtAdr: ADDRESS; size: SIZE);
- END UnmapPhysical;
- (** Translate a virtual address range to num ranges of physical address. num returns 0 on error. *)
- PROCEDURE TranslateVirtual*(virtAdr: ADDRESS; size: SIZE; VAR num: LONGINT; VAR physAdr: ARRAY OF Range);
- CONST PS = 4096;
- VAR ofs, phys1: ADDRESS; size1: SIZE;
- BEGIN
- num := 0;
- LOOP
- IF size = 0 THEN EXIT END;
- IF num = LEN(physAdr) THEN num := 0; EXIT END; (* index check *)
- ofs := virtAdr MOD PS; (* offset in page *)
- size1 := PS - ofs; (* distance to next page boundary *)
- IF size1 > size THEN size1 := size END;
- phys1 := virtAdr - ofs;
- physAdr[num].adr := phys1 - phys1 MOD PS + ofs;
- physAdr[num].size := size1; INC(num);
- INC(virtAdr, size1); DEC(size, size1)
- END;
- IF num = 0 THEN physAdr[0].adr := NilAdr; physAdr[0].size := 0 END;
- END TranslateVirtual;
- PROCEDURE Ensure32BitAddress*(adr: ADDRESS): Address32;
- BEGIN
- ASSERT (Address32 (adr) = adr);
- RETURN Address32 (adr);
- END Ensure32BitAddress;
- PROCEDURE Is32BitAddress*(adr: ADDRESS): BOOLEAN;
- BEGIN RETURN Address32 (adr) = adr;
- END Is32BitAddress;
- (** Get parameter values from Init string. If n = 0, return val = ASH(bx, 16) + ax, and if n = 1, return val = ASH(dx, 16) + cx, where ax, bx, cx, dx are the register values after the OBL boot loader or noboot.exe have executed the 16-bit x86 code in the Init string. *)
- PROCEDURE GetInit* (n: LONGINT; VAR val: LONGINT);
- BEGIN Environment.GetInit (n, val);
- END GetInit;
- (** Fill "size" bytes at "destAdr" with "filler". "size" must be multiple of 4. *)
- PROCEDURE Fill32*(destAdr: ADDRESS; size: SIZE; filler: LONGINT);
- CODE
- #IF I386 THEN
- #IF COOP THEN
- PUSH ECX
- #END
- MOV EDI, [EBP+destAdr]
- MOV ECX, [EBP+size]
- MOV EAX, [EBP+filler]
- TEST ECX, 3
- JZ ok
- PUSH 8 ; ASSERT failure
- INT 3
- ok: SHR ECX, 2
- CLD
- REP STOSD
- #IF COOP THEN
- POP ECX
- #END
- #ELSIF AMD64 THEN
- MOV RDI, [RBP + destAdr]
- MOV RCX, [RBP + size]
- MOV EAX, [RBP + filler]
- TEST RCX, 3
- JZ ok
- PUSH 8 ; ASSERT failure
- INT 3
- ok: SHR RCX, 2
- CLD
- REP STOSD
- #ELSE
- unimplemented
- #END
- END Fill32;
- (** -- Processor initialization -- *)
- PROCEDURE -SetFCR( s: SET );
- CODE
- #IF I386 THEN
- FLDCW [ESP] ; parameter s
- POP EAX
- #ELSIF AMD64 THEN
- FLDCW WORD [RSP] ; parameter s
- POP RAX
- #ELSE
- unimplemented
- #END
- END SetFCR;
- PROCEDURE -FCR( ): SET;
- CODE
- #IF I386 THEN
- PUSH 0
- FNSTCW [ESP]
- FWAIT
- POP EAX
- #ELSIF AMD64 THEN
- PUSH 0
- FNSTCW WORD [RSP]
- FWAIT
- POP RAX
- #ELSE
- unimplemented
- #END
- END FCR;
- PROCEDURE -InitFPU;
- CODE
- #IF I386 THEN
- FNINIT
- #ELSIF AMD64 THEN
- FNINIT
- #ELSE
- unimplemented
- #END
- END InitFPU;
- (** CPU identification. *)
- PROCEDURE CPUID*( VAR vendor: Vendor; VAR version: LONGINT; VAR features1,features2: SET );
- CODE
- #IF I386 THEN
- #IF COOP THEN
- PUSH ECX
- #END
- MOV EAX, 0
- CPUID
- CMP EAX, 0
- JNE ok
- MOV ESI, [EBP+vendor]
- MOV [ESI], AL ; AL = 0
- MOV ESI, [EBP+version]
- MOV [ESI], EAX ; EAX = 0
- MOV ESI, [EBP+features1]
- MOV [ESI], EAX
- MOV ESI, [EBP+features2]
- MOV [ESI], EAX
- JMP end
- ok:
- MOV ESI, [EBP+vendor]
- MOV [ESI], EBX
- MOV [ESI+4], EDX
- MOV [ESI+8], ECX
- MOV BYTE [ESI+12], 0
- MOV EAX, 1
- CPUID
- MOV ESI, [EBP+version]
- MOV [ESI], EAX
- MOV ESI, [EBP+features1]
- MOV [ESI], EDX
- MOV ESI, [EBP+features2]
- MOV [ESI], ECX
- end:
- #IF COOP THEN
- POP ECX
- #END
- #ELSIF AMD64 THEN
- #IF COOP THEN
- PUSH RBX
- #END
- MOV EAX, 0
- CPUID
- CMP EAX, 0
- JNE ok
- MOV RSI, [RBP+vendor]
- MOV [RSI], AL ; AL = 0
- MOV RSI, [RBP+version]
- MOV [RSI], EAX ; EAX = 0
- MOV RSI, [RBP+features1]
- MOV [RSI], EAX
- MOV RSI, [RBP+features2]
- MOV [RSI], EAX
- JMP end
- ok:
- MOV RSI, [RBP+vendor]
- MOV [RSI], EBX
- MOV [RSI+4], EDX
- MOV [RSI+8], ECX
- MOV BYTE [RSI+12], 0
- MOV EAX, 1
- CPUID
- MOV RSI, [RBP+version]
- MOV [RSI], EAX
- MOV RSI, [RBP+features1]
- MOV [RSI], EDX
- MOV RSI, [RBP+features2]
- MOV [RSI], RCX
- end:
- #IF COOP THEN
- POP RBX
- #END
- #ELSE
- unimplemented
- #END
- END CPUID;
- PROCEDURE GetConfig* ( CONST name: ARRAY OF CHAR; VAR val: ARRAY OF CHAR );
- BEGIN Environment.GetString (name, val);
- END GetConfig;
- PROCEDURE Shutdown*( restart: BOOLEAN );
- BEGIN
- IF restart THEN Environment.Reboot ELSE Environment.Shutdown END;
- END Shutdown;
- PROCEDURE Cli*;
- BEGIN HALT (1234);
- END Cli;
- PROCEDURE Sti*;
- BEGIN HALT (1234);
- END Sti;
- (* Dan: from new Machine *)
- PROCEDURE -GetTimer*(): HUGEINT;
- CODE
- #IF I386 THEN
- RDTSC ; set EDX:EAX
- #ELSIF AMD64 THEN
- XOR RAX, RAX
- RDTSC ; set EDX:EAX
- SHL RDX, 32
- OR RAX, RDX
- #ELSE
- unimplemented
- #END
- END GetTimer;
- (** Disable interrupts and return old interrupt state. *)
- PROCEDURE -DisableInterrupts* (): SET;
- CODE
- #IF I386 THEN
- PUSHFD
- CLI
- POP EAX
- #ELSIF AMD64 THEN
- PUSHFQ
- CLI
- POP RAX
- #ELSE
- unimplemented
- #END
- END DisableInterrupts;
- (** Restore interrupt state. Parameter s must be return value of earlier DisableInterrupts call on same processor. *)
- PROCEDURE -RestoreInterrupts* (s: SET);
- CODE
- #IF I386 THEN
- POPFD
- #ELSIF AMD64 THEN
- POPFQ
- #ELSE
- unimplemented
- #END
- END RestoreInterrupts;
- PROCEDURE ID*(): SIZE;
- BEGIN
- RETURN Processors.GetCurrentIndex ();
- END ID;
- (* setup MMX, SSE and SSE2..SSE5 and AVX extension *)
- PROCEDURE -InitSSE;
- CODE
- #IF I386 THEN
- MOV EAX, CR4
- OR EAX, 00000200H ; set bit 9 (OSFXSR)
- AND EAX, 0FFFFFBFFH ; delete bit 10 (OSXMMEXCPT)
- MOV CR4, EAX
- #ELSIF AMD64 THEN
- MOV EAX, CR4
- OR EAX, 00000200H ; set bit 9 (OSFXSR)
- AND EAX, 0FFFFFBFFH ; delete bit 10 (OSXMMEXCPT)
- MOV CR4, EAX
- #ELSE
- unimplemented
- #END
- END InitSSE;
- PROCEDURE InitBootProcessor-;
- CONST
- MMXFlag=23;(*IN features from EBX*)
- FXSRFlag = 24;
- SSEFlag = 25;
- SSE2Flag = 26;
- SSE3Flag = 0; (*IN features2 from ECX*) (*PH 04/11*)
- SSSE3Flag =9;
- SSE41Flag =19;
- SSE42Flag =20;
- SSE5Flag = 11;
- AVXFlag = 28;
- VAR vendor: Vendor; ver: LONGINT;
- BEGIN {UNCOOPERATIVE, UNCHECKED}
- CPUID(vendor, ver, features,features2);
- MMXSupport := MMXFlag IN features;
- SSESupport := SSEFlag IN features;
- SSE2Support := SSESupport & (SSE2Flag IN features);
- SSE3Support := SSE2Support & (SSE3Flag IN features2);
- SSSE3Support := SSE3Support & (SSSE3Flag IN features2); (* PH 04/11*)
- SSE41Support := SSE3Support & (SSE41Flag IN features2);
- SSE42Support := SSE3Support & (SSE42Flag IN features2);
- SSE5Support := SSE3Support & (SSE5Flag IN features2);
- AVXSupport := SSE3Support & (AVXFlag IN features2);
- fcr := (FCR() - {0,2,3,10,11}) + {0..5,8,9}; (* default FCR RC=00B *)
- InitApplicationProcessor;
- END InitBootProcessor;
- PROCEDURE InitApplicationProcessor-;
- BEGIN {UNCOOPERATIVE, UNCHECKED}
- InitFPU; SetFCR( fcr );
- IF Environment.IsNative & SSESupport THEN
- InitSSE();
- END;
- END InitApplicationProcessor;
- (** Acquire a spin-lock. *)
- PROCEDURE Acquire*( level: LONGINT ); (* non reentrant lock (non reentrance "ensured" by ASSERT statement ), CriticalSections are reentrant *)
- BEGIN
- Mutexes.Acquire (mutex[level]);
- END Acquire;
- (** Release a spin-lock. *)
- PROCEDURE Release*( level: LONGINT ); (* release lock *)
- BEGIN
- Mutexes.Release (mutex[level]);
- END Release;
- (* returns if an address is a currently allocated heap address *)
- PROCEDURE ValidHeapAddress*(p: ADDRESS): BOOLEAN;
- BEGIN
- RETURN p # NIL;
- END ValidHeapAddress;
- PROCEDURE GetFreeK* (VAR total, lowFree, highFree: SIZE);
- BEGIN
- total := 0; lowFree := 0; highFree := 0;
- END GetFreeK;
- PROCEDURE PhysicalAdr*(adr: ADDRESS; size: SIZE): ADDRESS;
- BEGIN RETURN adr;
- END PhysicalAdr;
- (** -- Atomic operations -- *)
- (** Atomic INC(x). *)
- PROCEDURE -AtomicInc*( VAR x: LONGINT );
- CODE
- #IF I386 THEN
- POP EAX
- LOCK
- INC DWORD [EAX]
- #ELSIF AMD64 THEN
- POP RAX
- LOCK
- INC DWORD [RAX]
- #ELSE
- unimplemented
- #END
- END AtomicInc;
- (** Atomic DEC(x). *)
- PROCEDURE -AtomicDec*( VAR x: LONGINT );
- CODE
- #IF I386 THEN
- POP EAX
- LOCK
- DEC DWORD [EAX]
- #ELSIF AMD64 THEN
- POP RAX
- LOCK
- DEC DWORD [RAX]
- #ELSE
- unimplemented
- #END
- END AtomicDec;
- (** Atomic INC(x, y). *)
- PROCEDURE -AtomicAdd*( VAR x: LONGINT; y: LONGINT );
- CODE
- #IF I386 THEN
- POP EBX
- POP EAX
- LOCK
- ADD DWORD [EAX], EBX
- #ELSIF AMD64 THEN
- POP ECX
- POP RAX
- LOCK
- ADD DWORD [RAX], ECX
- #ELSE
- unimplemented
- #END
- END AtomicAdd;
- (** Atomic test-and-set. Set x = TRUE and return old value of x. *)
- PROCEDURE -AtomicTestSet*( VAR x: BOOLEAN ): BOOLEAN;
- CODE
- #IF I386 THEN
- POP EBX
- MOV AL, 1
- XCHG [EBX], AL
- #ELSIF AMD64 THEN
- POP RCX
- MOV AL, 1
- XCHG [RCX], AL
- #ELSE
- unimplemented
- #END
- END AtomicTestSet;
- (* Atomic compare-and-swap. Set x = new if x = old and return old value of x *)
- PROCEDURE -AtomicCAS* (VAR x: LONGINT; old, new: LONGINT): LONGINT;
- CODE
- #IF I386 THEN
- POP EBX ; new
- POP EAX ; old
- POP EDX ; address of x
- LOCK CMPXCHG [EDX], EBX ; atomicly compare x with old and set it to new if equal
- #ELSIF AMD64 THEN
- POP ECX ; new
- POP EAX ; old
- POP RDX ; address of x
- LOCK CMPXCHG [RDX], ECX ; atomicly compare x with old and set it to new if equal
- #ELSE
- unimplemented
- #END
- END AtomicCAS;
- (* function returning the number of processors that are available to Aos *)
- PROCEDURE NumberOfProcessors*( ): SIZE;
- BEGIN
- RETURN Processors.count;
- END NumberOfProcessors;
- (* function for changing byte order *)
- PROCEDURE ChangeByteOrder* (n: LONGINT): LONGINT;
- CODE
- #IF I386 THEN
- MOV EAX, [EBP+n] ; load n in eax
- BSWAP EAX ; swap byte order
- #ELSIF AMD64 THEN
- MOV EAX, [RBP+n] ; load n in eax
- BSWAP EAX ; swap byte order
- #ELSE
- unimplemented
- #END
- END ChangeByteOrder;
- #IF I386 THEN
- PROCEDURE -GetEAX*(): LONGINT;
- CODE
- END GetEAX;
- PROCEDURE -GetECX*(): LONGINT;
- CODE MOV EAX,ECX
- END GetECX;
- PROCEDURE -SetEAX*(n: LONGINT);
- CODE POP EAX
- END SetEAX;
- PROCEDURE -SetEBX*(n: LONGINT);
- CODE POP EBX
- END SetEBX;
- PROCEDURE -SetECX*(n: LONGINT);
- CODE POP ECX
- END SetECX;
- PROCEDURE -SetEDX*(n: LONGINT);
- CODE POP EDX
- END SetEDX;
- PROCEDURE -SetESI*(n: LONGINT);
- CODE POP ESI
- END SetESI;
- PROCEDURE -SetEDI*(n: LONGINT);
- CODE POP EDI
- END SetEDI;
- PROCEDURE Portin8*(port: LONGINT; VAR val: CHAR);
- CODE
- MOV EDX, [EBP+port]
- IN AL, DX
- MOV EBX, [EBP+val]
- MOV [EBX], AL
- END Portin8;
- PROCEDURE Portin16*(port: LONGINT; VAR val: INTEGER);
- CODE
- MOV EDX, [EBP+port]
- IN AX, DX
- MOV EBX, [EBP+val]
- MOV [EBX], AX
- END Portin16;
- PROCEDURE Portin32*(port: LONGINT; VAR val: LONGINT);
- CODE
- MOV EDX, [EBP+port]
- IN EAX, DX
- MOV EBX, [EBP+val]
- MOV [EBX], EAX
- END Portin32;
- PROCEDURE Portout8*(port: LONGINT; val: CHAR);
- CODE
- MOV AL, [EBP+val]
- MOV EDX, [EBP+port]
- OUT DX, AL
- END Portout8;
- PROCEDURE Portout16*(port: LONGINT; val: INTEGER);
- CODE
- MOV AX, [EBP+val]
- MOV EDX, [EBP+port]
- OUT DX, AX
- END Portout16;
- PROCEDURE Portout32*(port: LONGINT; val: LONGINT);
- CODE
- MOV EAX, [EBP+val]
- MOV EDX, [EBP+port]
- OUT DX, EAX
- END Portout32;
- #ELSIF AMD64 THEN
- PROCEDURE -GetRAX*(): HUGEINT;
- CODE
- END GetRAX;
- PROCEDURE -GetRCX*(): HUGEINT;
- CODE MOV RAX, RCX
- END GetRCX;
- PROCEDURE -SetRAX*(n: HUGEINT);
- CODE POP RAX
- END SetRAX;
- PROCEDURE -SetRBX*(n: HUGEINT);
- CODE POP RBX
- END SetRBX;
- PROCEDURE -SetRCX*(n: HUGEINT);
- CODE POP RCX
- END SetRCX;
- PROCEDURE -SetRDX*(n: HUGEINT);
- CODE POP RDX
- END SetRDX;
- PROCEDURE -SetRSI*(n: HUGEINT);
- CODE POP RSI
- END SetRSI;
- PROCEDURE -SetRDI*(n: HUGEINT);
- CODE POP EDI
- END SetRDI;
- PROCEDURE Portin8*(port: LONGINT; VAR val: CHAR);
- CODE
- MOV EDX, [RBP+port]
- IN AL, DX
- MOV RCX, [RBP+val]
- MOV [RCX], AL
- END Portin8;
- PROCEDURE Portin16*(port: LONGINT; VAR val: INTEGER);
- CODE
- MOV EDX, [RBP+port]
- IN AX, DX
- MOV RCX, [RBP+val]
- MOV [RCX], AX
- END Portin16;
- PROCEDURE Portin32*(port: LONGINT; VAR val: LONGINT);
- CODE
- MOV EDX, [RBP+port]
- IN EAX, DX
- MOV RCX, [RBP+val]
- MOV [RCX], EAX
- END Portin32;
- PROCEDURE Portout8*(port: LONGINT; val: CHAR);
- CODE
- MOV AL, [RBP+val]
- MOV EDX, [RBP+port]
- OUT DX, AL
- END Portout8;
- PROCEDURE Portout16*(port: LONGINT; val: INTEGER);
- CODE
- MOV AX, [RBP+val]
- MOV EDX, [RBP+port]
- OUT DX, AX
- END Portout16;
- PROCEDURE Portout32*(port: LONGINT; val: LONGINT);
- CODE
- MOV EAX, [RBP+val]
- MOV EDX, [RBP+port]
- OUT DX, EAX
- END Portout32;
- #END
- (* Delay for IO *)
- PROCEDURE -Wait*;
- CODE
- #IF I386 THEN
- JMP 0
- JMP 0
- JMP 0
- #ELSIF AMD64 THEN
- JMP 0
- JMP 0
- JMP 0
- #ELSE
- unimplemented
- #END
- END Wait;
- (** Read a byte from the non-volatile setup memory. *)
- PROCEDURE GetNVByte* (ofs: LONGINT): CHAR;
- VAR c: CHAR;
- BEGIN
- Portout8 (70H, CHR(ofs)); Wait; Portin8(71H, c);
- RETURN c
- END GetNVByte;
- (** Write a byte to the non-volatile setup memory. *)
- PROCEDURE PutNVByte* (ofs: LONGINT; val: CHAR);
- BEGIN
- Portout8 (70H, CHR(ofs)); Wait; Portout8 (71H, val)
- END PutNVByte;
- PROCEDURE InvalidateDCacheRange*(a: ADDRESS; s: SIZE);
- BEGIN
-
- END InvalidateDCacheRange;
- PROCEDURE FlushDCacheRange*(a: ADDRESS; s: SIZE);
- BEGIN
-
- END FlushDCacheRange;
- BEGIN
- Trace.String("Machine: "); Trace.Blue; Trace.StringLn (Version); Trace.Default;
- boottime:=GetTimer();
- COPY( Version, version );
- END Machine.
|