blob: e714e28e2354a57513d545ee27b37274c397f305 [file] [log] [blame]
/*
* ACPI Table Definitions
*
* Copyright(c) 2013-2017 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#ifndef __ACPI_H__
#define __ACPI_H__
#include <stdint.h>
#include <linux/uuid.h>
static const uuid_le uuid_pmem = UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d,
0x33, 0x18, 0xb7, 0x8c, 0xdb);
static inline void nfit_spa_uuid_pm(void *uuid)
{
memcpy(uuid, &uuid_pmem, 16);
}
enum {
NFIT_TABLE_SPA = 0,
SRAT_TABLE_MEM = 1,
SRAT_MEM_ENABLED = (1<<0),
SRAT_MEM_HOT_PLUGGABLE = (1<<1),
SRAT_MEM_NON_VOLATILE = (1<<2),
};
/**
* struct nfit - Nvdimm Firmware Interface Table
* @signature: "ACPI"
* @length: sum of size of this table plus all appended subtables
*/
struct acpi_header {
uint8_t signature[4];
uint32_t length;
uint8_t revision;
uint8_t checksum;
uint8_t oemid[6];
uint64_t oem_tbl_id;
uint32_t oem_revision;
uint32_t asl_id;
uint32_t asl_revision;
} __attribute__((packed));
struct nfit {
struct acpi_header h;
uint32_t reserved;
} __attribute__((packed));
enum acpi_nfit_type {
ACPI_NFIT_TYPE_SYSTEM_ADDRESS = 0,
ACPI_NFIT_TYPE_MEMORY_MAP = 1,
ACPI_NFIT_TYPE_INTERLEAVE = 2,
ACPI_NFIT_TYPE_SMBIOS = 3,
ACPI_NFIT_TYPE_CONTROL_REGION = 4,
ACPI_NFIT_TYPE_DATA_REGION = 5,
ACPI_NFIT_TYPE_FLUSH_ADDRESS = 6,
ACPI_NFIT_TYPE_CAPABILITIES = 7,
ACPI_NFIT_TYPE_RESERVED = 8 /* 8 and greater are reserved */
};
/**
* struct nfit_spa - System Physical Address Range Descriptor Table
*/
struct nfit_spa {
uint16_t type;
uint16_t length;
uint16_t range_index;
uint16_t flags;
uint32_t reserved;
uint32_t proximity_domain;
uint8_t type_uuid[16];
uint64_t spa_base;
uint64_t spa_length;
uint64_t mem_attr;
} __attribute__((packed));
struct nfit_map {
uint16_t type;
uint16_t length;
uint32_t device_handle;
uint16_t physical_id;
uint16_t region_id;
uint16_t range_index;
uint16_t region_index;
uint64_t region_size;
uint64_t region_offset;
uint64_t address;
uint16_t interleave_index;
uint16_t interleave_ways;
uint16_t flags;
uint16_t reserved; /* Reserved, must be zero */
} __attribute__((packed));
struct srat {
struct acpi_header h;
uint32_t revision;
uint64_t reserved;
} __attribute__((packed));
enum acpi_srat_type {
ACPI_SRAT_TYPE_CPU_AFFINITY = 0,
ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1,
ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY = 2,
ACPI_SRAT_TYPE_GICC_AFFINITY = 3,
ACPI_SRAT_TYPE_GIC_ITS_AFFINITY = 4, /* ACPI 6.2 */
ACPI_SRAT_TYPE_GENERIC_AFFINITY = 5, /* ACPI 6.3 */
ACPI_SRAT_TYPE_RESERVED = 6 /* 5 and greater are reserved */
};
struct srat_cpu {
uint8_t type;
uint8_t length;
uint8_t proximity_domain_lo;
uint8_t apic_id;
uint32_t flags;
uint8_t local_sapic_eid;
uint8_t proximity_domain_hi[3];
uint32_t clock_domain;
} __attribute__((packed));
struct srat_generic {
uint8_t type;
uint8_t length;
uint8_t reserved;
uint8_t device_handle_type;
uint32_t proximity_domain;
uint8_t device_handle[16];
uint32_t flags;
uint32_t reserved1;
} __attribute__((packed));
struct srat_mem {
uint8_t type;
uint8_t length;
uint32_t proximity_domain;
uint16_t reserved;
uint64_t spa_base;
uint64_t spa_length;
uint32_t reserved1;
uint32_t flags;
uint64_t reserved2;
} __attribute__((packed));
struct acpi_subtable8 {
uint8_t type;
uint8_t length;
uint8_t buf[];
} __attribute__((packed));
struct acpi_subtable16 {
uint16_t type;
uint16_t length;
uint8_t buf[];
} __attribute__((packed));
struct slit {
struct acpi_header h;
uint64_t count;
uint8_t entry[]; /* size = count^2 */
} __attribute__((packed));
static inline unsigned char acpi_checksum(void *buf, size_t size)
{
unsigned char sum, *data = buf;
size_t i;
for (sum = 0, i = 0; i < size; i++)
sum += data[i];
return 0 - sum;
}
static inline void writeq(uint64_t v, void *a)
{
uint64_t *p = a;
*p = htole64(v);
}
static inline void writel(uint32_t v, void *a)
{
uint32_t *p = a;
*p = htole32(v);
}
static inline void writew(unsigned short v, void *a)
{
unsigned short *p = a;
*p = htole16(v);
}
static inline void writeb(unsigned char v, void *a)
{
unsigned char *p = a;
*p = v;
}
static inline uint64_t readq(void *a)
{
uint64_t *p = a;
return le64toh(*p);
}
static inline uint32_t readl(void *a)
{
uint32_t *p = a;
return le32toh(*p);
}
static inline uint16_t readw(void *a)
{
uint16_t *p = a;
return le16toh(*p);
}
static inline uint8_t readb(void *a)
{
uint8_t *p = a;
return *p;
}
#endif /* __ACPI_H__ */