2
0

ipmi.c 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * IPMI ACPI firmware handling
  3. *
  4. * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC
  5. *
  6. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  7. * See the COPYING file in the top-level directory.
  8. */
  9. #include "qemu/osdep.h"
  10. #include "hw/ipmi/ipmi.h"
  11. #include "hw/acpi/aml-build.h"
  12. #include "hw/acpi/acpi.h"
  13. #include "hw/acpi/ipmi.h"
  14. static Aml *aml_ipmi_crs(IPMIFwInfo *info)
  15. {
  16. Aml *crs = aml_resource_template();
  17. /*
  18. * The base address is fixed and cannot change. That may be different
  19. * if someone does PCI, but we aren't there yet.
  20. */
  21. switch (info->memspace) {
  22. case IPMI_MEMSPACE_IO:
  23. aml_append(crs, aml_io(AML_DECODE16, info->base_address,
  24. info->base_address + info->register_length - 1,
  25. info->register_spacing, info->register_length));
  26. break;
  27. case IPMI_MEMSPACE_MEM32:
  28. aml_append(crs,
  29. aml_dword_memory(AML_POS_DECODE,
  30. AML_MIN_FIXED, AML_MAX_FIXED,
  31. AML_NON_CACHEABLE, AML_READ_WRITE,
  32. 0xffffffff,
  33. info->base_address,
  34. info->base_address + info->register_length - 1,
  35. info->register_spacing, info->register_length));
  36. break;
  37. case IPMI_MEMSPACE_MEM64:
  38. aml_append(crs,
  39. aml_qword_memory(AML_POS_DECODE,
  40. AML_MIN_FIXED, AML_MAX_FIXED,
  41. AML_NON_CACHEABLE, AML_READ_WRITE,
  42. 0xffffffffffffffffULL,
  43. info->base_address,
  44. info->base_address + info->register_length - 1,
  45. info->register_spacing, info->register_length));
  46. break;
  47. case IPMI_MEMSPACE_SMBUS:
  48. aml_append(crs, aml_i2c_serial_bus_device(info->base_address,
  49. "^"));
  50. break;
  51. default:
  52. abort();
  53. }
  54. if (info->interrupt_number) {
  55. aml_append(crs, aml_irq_no_flags(info->interrupt_number));
  56. }
  57. return crs;
  58. }
  59. void build_ipmi_dev_aml(AcpiDevAmlIf *adev, Aml *scope)
  60. {
  61. Aml *dev;
  62. IPMIFwInfo info = {};
  63. IPMIInterface *ii = IPMI_INTERFACE(adev);
  64. IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
  65. uint16_t version;
  66. iic->get_fwinfo(ii, &info);
  67. assert(info.ipmi_spec_minor_revision <= 15);
  68. version = ((info.ipmi_spec_major_revision << 8)
  69. | (info.ipmi_spec_minor_revision << 4));
  70. dev = aml_device("MI%d", info.uuid);
  71. aml_append(dev, aml_name_decl("_HID", aml_eisaid("IPI0001")));
  72. aml_append(dev, aml_name_decl("_STR", aml_string("ipmi_%s",
  73. info.interface_name)));
  74. aml_append(dev, aml_name_decl("_UID", aml_int(info.uuid)));
  75. aml_append(dev, aml_name_decl("_CRS", aml_ipmi_crs(&info)));
  76. aml_append(dev, aml_name_decl("_IFT", aml_int(info.interface_type)));
  77. aml_append(dev, aml_name_decl("_SRV", aml_int(version)));
  78. aml_append(scope, dev);
  79. }