Преглед изворни кода

ACPI: Examine bit width in Generic address structure before asserting

Also, the switch-case flow is simplified for IO access within a Generic
address strucuture's handling.
Liav A пре 5 година
родитељ
комит
b13417ddb4
3 измењених фајлова са 35 додато и 16 уклоњено
  1. 11 16
      Kernel/ACPI/ACPIStaticParser.cpp
  2. 7 0
      Kernel/ACPI/Definitions.h
  3. 17 0
      Libraries/LibBareMetal/IO.h

+ 11 - 16
Kernel/ACPI/ACPIStaticParser.cpp

@@ -154,29 +154,24 @@ namespace ACPI {
     {
         switch (structure.address_space) {
         case (u8)GenericAddressStructure::AddressSpace::SystemIO: {
-            dbg() << "ACPI: Sending value 0x" << String::format("%x", value) << " to " << IOAddress(structure.address);
+            IOAddress address(structure.address);
+            dbg() << "ACPI: Sending value 0x" << String::format("%x", value) << " to " << address;
             switch (structure.access_size) {
-            case (u8)GenericAddressStructure::AccessSize::Byte: {
-                IO::out8(structure.address, value);
-                break;
-            }
-            case (u8)GenericAddressStructure::AccessSize::Word: {
-                IO::out16(structure.address, value);
-                break;
-            }
-            case (u8)GenericAddressStructure::AccessSize::DWord: {
-                IO::out32(structure.address, value);
-                break;
-            }
             case (u8)GenericAddressStructure::AccessSize::QWord: {
                 dbg() << "Trying to send QWord to IO port";
                 ASSERT_NOT_REACHED();
                 break;
             }
-            default:
-                // FIXME: Determine if for reset register we can actually determine the right IO operation.
+            case (u8)GenericAddressStructure::AccessSize::Undefined: {
                 dbg() << "ACPI Warning: Unknown access size " << structure.access_size;
-                IO::out8(structure.address, value);
+                ASSERT(structure.bit_width != (u8)GenericAddressStructure::BitWidth::QWord);
+                ASSERT(structure.bit_width != (u8)GenericAddressStructure::BitWidth::Undefined);
+                dbg() << "ACPI: Bit Width - " << structure.bit_width << " bits";
+                address.out(value, structure.bit_width);
+                break;
+            }
+            default:
+                address.out(value, (8 << (structure.access_size - 1)));
                 break;
             }
             return;

+ 7 - 0
Kernel/ACPI/Definitions.h

@@ -122,6 +122,13 @@ namespace ACPI {
             DWord = 3,
             QWord = 4
         };
+        enum class BitWidth {
+            Undefined = 0,
+            Byte = 8,
+            Word = 16,
+            DWord = 32,
+            QWord = 64
+        };
     }
 
     namespace Structures {

+ 17 - 0
Libraries/LibBareMetal/IO.h

@@ -147,6 +147,23 @@ public:
         ASSERT_NOT_REACHED();
     }
 
+    inline void out(u32 value, u8 bit_width)
+    {
+        if (bit_width == 32) {
+            IO::out32(get(), value);
+            return;
+        }
+        if (bit_width == 16) {
+            IO::out16(get(), value);
+            return;
+        }
+        if (bit_width == 8) {
+            IO::out8(get(), value);
+            return;
+        }
+        ASSERT_NOT_REACHED();
+    }
+
     bool is_null() const { return m_address == 0; }
 
     bool operator==(const IOAddress& other) const { return m_address == other.m_address; }