ACPI: Add code to include ATSR structure in DMAR table

DMAR tables can contain so called "Address Translation Service Reporting"
(ATSR) structure. It is applicable for platforms that support
Device-TLBs and describe PCI root ports that have this ability.
Add code to create this ATSR structure.

In addition, a function to fix up the size of the ATSR
structure is added as this is a new type and using the function
acpi_dmar_drhd_fixup() can lead to confusion.

Change-Id: Idc3f6025f597048151f0fd5ea6be04843041e1ab
Signed-off-by: Werner Zeh <werner.zeh@siemens.com>
Reviewed-on: https://review.coreboot.org/15911
Tested-by: build bot (Jenkins)
Reviewed-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Werner Zeh 2016-07-27 06:56:36 +02:00
parent b0afbad8e1
commit d4d76959c0
2 changed files with 32 additions and 0 deletions

View File

@ -7,6 +7,7 @@
* Copyright (C) 2004 SUSE LINUX AG * Copyright (C) 2004 SUSE LINUX AG
* Copyright (C) 2005-2009 coresystems GmbH * Copyright (C) 2005-2009 coresystems GmbH
* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
* Copyright (C) 2016 Siemens AG
* *
* ACPI FADT, FACS, and DSDT table support added by * ACPI FADT, FACS, and DSDT table support added by
* Nick Barker <nick.barker9@btinternet.com>, and those portions * Nick Barker <nick.barker9@btinternet.com>, and those portions
@ -433,12 +434,31 @@ unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags,
return drhd->length; return drhd->length;
} }
unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags,
u16 segment)
{
dmar_atsr_entry_t *atsr = (dmar_atsr_entry_t *)current;
memset(atsr, 0, sizeof(*atsr));
atsr->type = DMAR_ATSR;
atsr->length = sizeof(*atsr); /* will be fixed up later */
atsr->flags = flags;
atsr->segment = segment;
return atsr->length;
}
void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current) void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current)
{ {
dmar_entry_t *drhd = (dmar_entry_t *)base; dmar_entry_t *drhd = (dmar_entry_t *)base;
drhd->length = current - base; drhd->length = current - base;
} }
void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current)
{
dmar_atsr_entry_t *atsr = (dmar_atsr_entry_t *)base;
atsr->length = current - base;
}
static unsigned long acpi_create_dmar_drhd_ds(unsigned long current, static unsigned long acpi_create_dmar_drhd_ds(unsigned long current,
enum dev_scope_type type, u8 enumeration_id, u8 bus, u8 dev, u8 fn) enum dev_scope_type type, u8 enumeration_id, u8 bus, u8 dev, u8 fn)
{ {

View File

@ -5,6 +5,7 @@
* Copyright (C) 2004 Nick Barker * Copyright (C) 2004 Nick Barker
* Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2008-2009 coresystems GmbH
* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
* Copyright (C) 2016 Siemens AG
* (Written by Stefan Reinauer <stepan@coresystems.de>) * (Written by Stefan Reinauer <stepan@coresystems.de>)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -285,6 +286,14 @@ typedef struct dmar_entry {
u64 bar; u64 bar;
} __attribute__ ((packed)) dmar_entry_t; } __attribute__ ((packed)) dmar_entry_t;
typedef struct dmar_atsr_entry {
u16 type;
u16 length;
u8 flags;
u8 reserved;
u16 segment;
} __attribute__ ((packed)) dmar_atsr_entry_t;
/* DMAR (DMA Remapping Reporting Structure) */ /* DMAR (DMA Remapping Reporting Structure) */
typedef struct acpi_dmar { typedef struct acpi_dmar {
struct acpi_table_header header; struct acpi_table_header header;
@ -607,7 +616,10 @@ void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
unsigned long (*acpi_fill_dmar) (unsigned long)); unsigned long (*acpi_fill_dmar) (unsigned long));
unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags, unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags,
u16 segment, u32 bar); u16 segment, u32 bar);
unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags,
u16 segment);
void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current); void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current);
void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current);
unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current, unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current,
u8 bus, u8 dev, u8 fn); u8 bus, u8 dev, u8 fn);
unsigned long acpi_create_dmar_drhd_ds_ioapic(unsigned long current, unsigned long acpi_create_dmar_drhd_ds_ioapic(unsigned long current,