BIOS.ACPI.Mod 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. (* Runtime support for ACPI *)
  2. (* Copyright (C) Florian Negele *)
  3. MODULE ACPI;
  4. CONST HPETSignature* = 54455048H;
  5. CONST RDSPSignature* = 2052545020445352H;
  6. TYPE Address* = RECORD
  7. value: LONGINT;
  8. END;
  9. TYPE Header* = RECORD
  10. signature-: LONGINT;
  11. length-: LONGINT;
  12. revision-: SHORTINT;
  13. checksum-: SHORTINT;
  14. oemID-: ARRAY 6 OF CHAR;
  15. oemTableID-: ARRAY 8 OF CHAR;
  16. oemRevision-: LONGINT;
  17. creatorID-: LONGINT;
  18. creatorRevision-: LONGINT;
  19. END;
  20. TYPE HPET* = RECORD (Header)
  21. eventTimerBlockID-: LONGINT;
  22. baseAddress-: RECORD
  23. addressSpaceID-: SHORTINT;
  24. registerBitWidth-: SHORTINT;
  25. registerBitOffset-: SHORTINT;
  26. reserved-: SHORTINT;
  27. addressLow-: Address;
  28. addressHigh-: Address;
  29. END;
  30. hpetNumber-: SHORTINT;
  31. mainCounterMinimum-: INTEGER;
  32. oemAttribute-: SHORTINT;
  33. END;
  34. TYPE RDSP* = RECORD
  35. signature-: HUGEINT;
  36. checksum-: SHORTINT;
  37. oemID-: ARRAY 6 OF CHAR;
  38. revision-: SHORTINT;
  39. rsdtAddress-: Address;
  40. END;
  41. TYPE RSDT* = RECORD (Header)
  42. entry-: ARRAY 1024 OF Address;
  43. END;
  44. VAR rdsp- {UNTRACED} := NIL: POINTER {UNSAFE} TO RDSP;
  45. PROCEDURE Checksum (address: ADDRESS; size: SIZE): SHORTINT;
  46. VAR checksum := 0: SHORTINT; block {UNTRACED}: POINTER {UNSAFE} TO ARRAY OF SHORTINT;
  47. BEGIN {UNCOOPERATIVE, UNCHECKED} block := address; WHILE size # 0 DO DEC (size); INC (checksum, block[size]) END; RETURN checksum;
  48. END Checksum;
  49. PROCEDURE Convert- (CONST address: Address): ADDRESS;
  50. VAR result: ADDRESS; masked {UNTRACED}: POINTER {UNSAFE} TO RECORD value: SET END;
  51. BEGIN {UNCOOPERATIVE, UNCHECKED}
  52. result := address.value; masked := ADDRESS OF result;
  53. masked.value := masked.value * {0 .. SIZE OF LONGINT * 8 - 1};
  54. RETURN result;
  55. END Convert;
  56. PROCEDURE GetTable- (signature: LONGINT): ADDRESS;
  57. VAR address: ADDRESS; rsdt {UNTRACED}: POINTER {UNSAFE} TO RSDT; header {UNTRACED}: POINTER {UNSAFE} TO Header; i: SIZE;
  58. BEGIN {UNCOOPERATIVE, UNCHECKED}
  59. ASSERT (rdsp # NIL);
  60. address := Convert (rdsp.rsdtAddress); rsdt := address;
  61. ASSERT (Checksum (rsdt, rsdt.length) = 0);
  62. FOR i := 0 TO (rsdt.length - 36) DIV 4 DO
  63. address := Convert (rsdt.entry[i]); header := address;
  64. IF (header.signature = signature) & (Checksum (header, header.length) = 0) THEN RETURN header END;
  65. END;
  66. RETURN NIL;
  67. END GetTable;
  68. PROCEDURE Initialize-;
  69. TYPE BiosEBDA = POINTER {UNSAFE} TO RECORD val: INTEGER END;
  70. VAR address := 0E0000H: ADDRESS; size := 020000H: SIZE; biosEBDA {UNTRACED}: BiosEBDA;
  71. BEGIN {UNCOOPERATIVE, UNCHECKED}
  72. WHILE size # 0 DO
  73. rdsp := address;
  74. IF (rdsp.signature = RDSPSignature) & (Checksum (address, 20) = 0) THEN RETURN END;
  75. INC (address, 16); DEC (size, 16);
  76. END;
  77. biosEBDA := 40EH;
  78. (* try Extended Bios Data Area EBDA *)
  79. address := ADDRESS(biosEBDA.val) MOD 10000H * 16;
  80. size := 1024;
  81. WHILE size # 0 DO
  82. rdsp := address;
  83. IF (rdsp.signature = RDSPSignature) & (Checksum (address, 20) = 0) THEN RETURN END;
  84. INC (address, 16); DEC (size, 16);
  85. END;
  86. rdsp := NIL;
  87. END Initialize;
  88. END ACPI.