acpi: Add SPMI table
Add the SPMI table as defined in the IPMI spec v2: https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmi-second-gen-interface-spec-v2-rev1-1.pdf Tested on Wedge100s. Change-Id: Idff5134ce4c124f7e76acb0080da404b0c0dfffe Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/33487 Reviewed-by: Felix Held <felix-coreboot@felixheld.de> Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
		
				
					committed by
					
						
						Patrick Rudolph
					
				
			
			
				
	
			
			
			
						parent
						
							7752645041
						
					
				
				
					commit
					9d98e5ae0d
				
			@@ -772,6 +772,57 @@ void acpi_create_vfct(struct device *device,
 | 
				
			|||||||
	header->checksum = acpi_checksum((void *)vfct, header->length);
 | 
						header->checksum = acpi_checksum((void *)vfct, header->length);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void acpi_create_ipmi(struct device *device,
 | 
				
			||||||
 | 
							      struct acpi_spmi *spmi,
 | 
				
			||||||
 | 
							      const u16 ipmi_revision,
 | 
				
			||||||
 | 
							      const acpi_addr_t *addr,
 | 
				
			||||||
 | 
							      const enum acpi_ipmi_interface_type type,
 | 
				
			||||||
 | 
							      const s8 gpe_interrupt,
 | 
				
			||||||
 | 
							      const u32 apic_interrupt,
 | 
				
			||||||
 | 
							      const u32 uid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						acpi_header_t *header = &(spmi->header);
 | 
				
			||||||
 | 
						memset((void *)spmi, 0, sizeof(struct acpi_spmi));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Fill out header fields. */
 | 
				
			||||||
 | 
						memcpy(header->signature, "SPMI", 4);
 | 
				
			||||||
 | 
						memcpy(header->oem_id, OEM_ID, 6);
 | 
				
			||||||
 | 
						memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
 | 
				
			||||||
 | 
						memcpy(header->asl_compiler_id, ASLC, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						header->asl_compiler_revision = asl_revision;
 | 
				
			||||||
 | 
						header->length = sizeof(struct acpi_spmi);
 | 
				
			||||||
 | 
						header->revision = get_acpi_table_revision(SPMI);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spmi->reserved = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (device->path.type == DEVICE_PATH_PCI) {
 | 
				
			||||||
 | 
							spmi->pci_device_flag = ACPI_IPMI_PCI_DEVICE_FLAG;
 | 
				
			||||||
 | 
							spmi->pci_bus = device->bus->secondary;
 | 
				
			||||||
 | 
							spmi->pci_device = device->path.pci.devfn >> 3;
 | 
				
			||||||
 | 
							spmi->pci_function = device->path.pci.devfn & 0x7;
 | 
				
			||||||
 | 
						} else if (type != IPMI_INTERFACE_SSIF) {
 | 
				
			||||||
 | 
							memcpy(spmi->uid, &uid, sizeof(spmi->uid));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spmi->base_address = *addr;
 | 
				
			||||||
 | 
						spmi->specification_revision = ipmi_revision;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spmi->interface_type = type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gpe_interrupt >= 0 && gpe_interrupt < 32) {
 | 
				
			||||||
 | 
							spmi->gpe = gpe_interrupt;
 | 
				
			||||||
 | 
							spmi->interrupt_type |= ACPI_IPMI_INT_TYPE_SCI;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (apic_interrupt > 0) {
 | 
				
			||||||
 | 
							spmi->global_system_interrupt = apic_interrupt;
 | 
				
			||||||
 | 
							spmi->interrupt_type |= ACPI_IPMI_INT_TYPE_APIC;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Calculate checksum. */
 | 
				
			||||||
 | 
						header->checksum = acpi_checksum((void *)spmi, header->length);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void acpi_create_ivrs(acpi_ivrs_t *ivrs,
 | 
					void acpi_create_ivrs(acpi_ivrs_t *ivrs,
 | 
				
			||||||
		      unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct,
 | 
							      unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct,
 | 
				
			||||||
		      unsigned long current))
 | 
							      unsigned long current))
 | 
				
			||||||
@@ -1490,6 +1541,8 @@ int get_acpi_table_revision(enum acpi_tables table)
 | 
				
			|||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	case SLIT: /* ACPI 2.0 upto 6.3: 1 */
 | 
						case SLIT: /* ACPI 2.0 upto 6.3: 1 */
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
 | 
						case SPMI: /* IMPI 2.0 */
 | 
				
			||||||
 | 
							return 5;
 | 
				
			||||||
	case HPET: /* Currently 1. Table added in ACPI 2.0. */
 | 
						case HPET: /* Currently 1. Table added in ACPI 2.0. */
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	case VFCT: /* ACPI 2.0/3.0/4.0: 1 */
 | 
						case VFCT: /* ACPI 2.0/3.0/4.0: 1 */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -82,7 +82,7 @@ enum acpi_tables {
 | 
				
			|||||||
	BERT, DBG2, DMAR, DSDT, FACS, FADT, HEST, HPET, IVRS, MADT, MCFG,
 | 
						BERT, DBG2, DMAR, DSDT, FACS, FADT, HEST, HPET, IVRS, MADT, MCFG,
 | 
				
			||||||
	RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT,
 | 
						RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT,
 | 
				
			||||||
	/* Additional proprietary tables used by coreboot */
 | 
						/* Additional proprietary tables used by coreboot */
 | 
				
			||||||
	VFCT, NHLT
 | 
						VFCT, NHLT, SPMI
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* RSDP (Root System Description Pointer) */
 | 
					/* RSDP (Root System Description Pointer) */
 | 
				
			||||||
@@ -782,6 +782,43 @@ enum acpi_upc_type {
 | 
				
			|||||||
	UPC_TYPE_HUB
 | 
						UPC_TYPE_HUB
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum acpi_ipmi_interface_type {
 | 
				
			||||||
 | 
						IPMI_INTERFACE_RESERVED = 0,
 | 
				
			||||||
 | 
						IPMI_INTERFACE_KCS,
 | 
				
			||||||
 | 
						IPMI_INTERFACE_SMIC,
 | 
				
			||||||
 | 
						IPMI_INTERFACE_BT,
 | 
				
			||||||
 | 
						IPMI_INTERFACE_SSIF,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ACPI_IPMI_PCI_DEVICE_FLAG	(1 << 0)
 | 
				
			||||||
 | 
					#define ACPI_IPMI_INT_TYPE_SCI		(1 << 0)
 | 
				
			||||||
 | 
					#define ACPI_IPMI_INT_TYPE_APIC		(1 << 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ACPI IPMI 2.0 */
 | 
				
			||||||
 | 
					struct acpi_spmi {
 | 
				
			||||||
 | 
						struct acpi_table_header header;
 | 
				
			||||||
 | 
						u8 interface_type;
 | 
				
			||||||
 | 
						u8 reserved;
 | 
				
			||||||
 | 
						u16 specification_revision;
 | 
				
			||||||
 | 
						u8 interrupt_type;
 | 
				
			||||||
 | 
						u8 gpe;
 | 
				
			||||||
 | 
						u8 reserved2;
 | 
				
			||||||
 | 
						u8 pci_device_flag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 global_system_interrupt;
 | 
				
			||||||
 | 
						acpi_addr_t base_address;
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								u8 pci_segment_group;
 | 
				
			||||||
 | 
								u8 pci_bus;
 | 
				
			||||||
 | 
								u8 pci_device;
 | 
				
			||||||
 | 
								u8 pci_function;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							u8 uid[4];
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						u8 reserved3;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned long fw_cfg_acpi_tables(unsigned long start);
 | 
					unsigned long fw_cfg_acpi_tables(unsigned long start);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* These are implemented by the target port or north/southbridge. */
 | 
					/* These are implemented by the target port or north/southbridge. */
 | 
				
			||||||
@@ -834,6 +871,15 @@ void acpi_create_vfct(struct device *device,
 | 
				
			|||||||
				struct acpi_vfct *vfct_struct,
 | 
									struct acpi_vfct *vfct_struct,
 | 
				
			||||||
				unsigned long current));
 | 
									unsigned long current));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void acpi_create_ipmi(struct device *device,
 | 
				
			||||||
 | 
							      struct acpi_spmi *spmi,
 | 
				
			||||||
 | 
							      const u16 ipmi_revision,
 | 
				
			||||||
 | 
							      const acpi_addr_t *addr,
 | 
				
			||||||
 | 
							      const enum acpi_ipmi_interface_type type,
 | 
				
			||||||
 | 
							      const s8 gpe_interrupt,
 | 
				
			||||||
 | 
							      const u32 apic_interrupt,
 | 
				
			||||||
 | 
							      const u32 uid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void acpi_create_ivrs(acpi_ivrs_t *ivrs,
 | 
					void acpi_create_ivrs(acpi_ivrs_t *ivrs,
 | 
				
			||||||
		      unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct,
 | 
							      unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct,
 | 
				
			||||||
		      unsigned long current));
 | 
							      unsigned long current));
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user