DMI.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Format.h>
  7. #include <AK/Singleton.h>
  8. #include <AK/StringView.h>
  9. #include <AK/Types.h>
  10. #include <Kernel/Arch/PC/BIOS.h>
  11. #include <Kernel/DMI.h>
  12. #include <Kernel/StdLib.h>
  13. #include <Kernel/VM/MappedROM.h>
  14. #include <Kernel/VM/TypedMapping.h>
  15. namespace Kernel {
  16. #define SMBIOS_BASE_SEARCH_ADDR 0xf0000
  17. #define SMBIOS_END_SEARCH_ADDR 0xfffff
  18. #define SMBIOS_SEARCH_AREA_SIZE (SMBIOS_END_SEARCH_ADDR - SMBIOS_BASE_SEARCH_ADDR)
  19. AK::Singleton<DMIExpose> s_the;
  20. UNMAP_AFTER_INIT void DMIExpose::set_64_bit_entry_initialization_values()
  21. {
  22. dbgln("DMIExpose: SMBIOS 64bit Entry point @ {}", m_entry_point);
  23. auto smbios_entry = map_typed<SMBIOS::EntryPoint64bit>(m_entry_point, SMBIOS_SEARCH_AREA_SIZE);
  24. m_structure_table = PhysicalAddress(smbios_entry.ptr()->table_ptr);
  25. m_entry_point_length = smbios_entry.ptr()->length;
  26. m_structure_table_length = smbios_entry.ptr()->table_maximum_size;
  27. }
  28. UNMAP_AFTER_INIT void DMIExpose::set_32_bit_entry_initialization_values()
  29. {
  30. dbgln("DMIExpose: SMBIOS 32bit Entry point @ {}", m_entry_point);
  31. auto smbios_entry = map_typed<SMBIOS::EntryPoint32bit>(m_entry_point, SMBIOS_SEARCH_AREA_SIZE);
  32. m_structure_table = PhysicalAddress(smbios_entry.ptr()->legacy_structure.smbios_table_ptr);
  33. m_entry_point_length = smbios_entry.ptr()->length;
  34. m_structure_table_length = smbios_entry.ptr()->legacy_structure.smboios_table_length;
  35. }
  36. UNMAP_AFTER_INIT void DMIExpose::initialize()
  37. {
  38. s_the.ensure_instance();
  39. }
  40. DMIExpose& DMIExpose::the()
  41. {
  42. return *s_the;
  43. }
  44. size_t DMIExpose::entry_point_length() const
  45. {
  46. return m_entry_point_length;
  47. }
  48. size_t DMIExpose::structure_table_length() const
  49. {
  50. return m_structure_table_length;
  51. }
  52. UNMAP_AFTER_INIT void DMIExpose::initialize_exposer()
  53. {
  54. VERIFY(!(m_entry_point.is_null()));
  55. if (m_using_64bit_entry_point) {
  56. set_64_bit_entry_initialization_values();
  57. } else {
  58. set_32_bit_entry_initialization_values();
  59. }
  60. dbgln("DMIExpose: Data table @ {}", m_structure_table);
  61. }
  62. OwnPtr<KBuffer> DMIExpose::entry_point() const
  63. {
  64. auto dmi_blob = map_typed<u8>((m_entry_point), m_entry_point_length);
  65. return KBuffer::try_create_with_bytes(Span<u8> { dmi_blob.ptr(), m_entry_point_length });
  66. }
  67. OwnPtr<KBuffer> DMIExpose::structure_table() const
  68. {
  69. auto dmi_blob = map_typed<u8>(m_structure_table, m_structure_table_length);
  70. return KBuffer::try_create_with_bytes(Span<u8> { dmi_blob.ptr(), m_structure_table_length });
  71. }
  72. UNMAP_AFTER_INIT DMIExpose::DMIExpose()
  73. {
  74. auto entry_32bit = find_entry32bit_point();
  75. m_entry_point = entry_32bit.value();
  76. auto entry_64bit = find_entry64bit_point();
  77. if (entry_64bit.has_value()) {
  78. m_entry_point = entry_64bit.value();
  79. m_using_64bit_entry_point = true;
  80. }
  81. if (m_entry_point.is_null())
  82. return;
  83. m_available = true;
  84. initialize_exposer();
  85. }
  86. UNMAP_AFTER_INIT Optional<PhysicalAddress> DMIExpose::find_entry64bit_point()
  87. {
  88. return map_bios().find_chunk_starting_with("_SM3_", 16);
  89. }
  90. UNMAP_AFTER_INIT Optional<PhysicalAddress> DMIExpose::find_entry32bit_point()
  91. {
  92. return map_bios().find_chunk_starting_with("_SM_", 16);
  93. }
  94. }