The PCI Routing Table (_PRT) for Juno does not specify the Interrupt trigger type and polarity. In the absence of this information, the kernel uses PCI default interrupt type (level triggered, active low) which is incompatible with GICv2 compliant interrupt controller such as on Juno.
Absence of interrupt type leads to errors such as following in kernel boot log -
[ 1.353696] genirq: Setting trigger mode 8 for irq 9 failed (gic_set_type+0x0/0x5c) [ 1.478286] genirq: Setting trigger mode 8 for irq 17 failed (gic_set_type+0x0/0x5c) [ 1.563723] genirq: Setting trigger mode 8 for irq 18 failed (gic_set_type+0x0/0x5c)
Fix this issue by providing the correct information (level triggered, active high) to the kernel by using the PCI Link device.
Signed-off-by: Punit Agrawal punit.agrawal@arm.com --- Hi,
This patch to the OpenPlatformPkg for Juno ACPI tables fixes an issue I reported earlier[0].
All feedback welcome.
Thanks, Punit
[0] https://lists.linaro.org/pipermail/linaro-uefi/2016-April/001776.html
Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl | 60 +++++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl index 800d2cb..55b76d6 100644 --- a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl +++ b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl @@ -15,20 +15,43 @@ #include "ArmPlatform.h"
/* - See Reference [1] 6.2.12 - "There are two ways that _PRT can be used. ... - In the second model, the PCI interrupts are hardwired to specific interrupt - inputs on the interrupt controller and are not configurable. In this case, - the Source field in _PRT does not reference a device, but instead contains - the value zero, and the Source Index field contains the global system - interrupt to which the PCI interrupt is hardwired." + See ACPI 6.1 Section 6.2.13 + + There are two ways that _PRT can be used. ... + + In the first model, a PCI Link device is used to provide additional + configuration information such as whether the interrupt is Level or + Edge triggered, it is active High or Low, Shared or Exclusive, etc. + + In the second model, the PCI interrupts are hardwired to specific + interrupt inputs on the interrupt controller and are not + configurable. In this case, the Source field in _PRT does not + reference a device, but instead contains the value zero, and the + Source Index field contains the global system interrupt to which the + PCI interrupt is hardwired. + + We use the first model with link indirection to set the correct + interrupt type as PCI defaults (Level Triggered, Active Low) are not + compatible with GICv2. */ -#define PRT_ENTRY(Address, Pin, Interrupt) \ - Package (4) { \ +#define LNK_DEVICE(Unique_Id, Link_Name, irq) \ + Device(Link_Name) { \ + Name(_HID, EISAID("PNP0C0F")) \ + Name(_UID, Unique_Id) \ + Name(_PRS, ResourceTemplate() { \ + Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) { irq } \ + }) \ + Method (_CRS, 0) { Return (_PRS) } \ + Method (_SRS, 1) { } \ + Method (_DIS) { } \ + } + +#define PRT_ENTRY(Address, Pin, Link) \ + Package (4) { \ Address, /* uses the same format as _ADR */ \ Pin, /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD). */ \ - Zero, /* allocated from the global interrupt pool. */ \ - Interrupt /* global system interrupt number */ \ + Link, /* Interrupt allocated via Link device. */ \ + Zero /* global system interrupt number (no used) */ \ }
/* @@ -36,7 +59,7 @@ "High word–Device #, Low word–Function #. (for example, device 3, function 2 is 0x00030002). To refer to all the functions on a device #, use a function number of FFFF)." */ -#define ROOT_PRT_ENTRY(Pin, Interrupt) PRT_ENTRY(0x0000FFFF, Pin, Interrupt) +#define ROOT_PRT_ENTRY(Pin, Link) PRT_ENTRY(0x0000FFFF, Pin, Link) // Device 0 for Bridge.
@@ -45,6 +68,11 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM // // PCI Root Complex // + LNK_DEVICE(1, LNKA, 168) + LNK_DEVICE(2, LNKB, 169) + LNK_DEVICE(3, LNKC, 170) + LNK_DEVICE(4, LNKD, 171) + Device(PCI0) { Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge @@ -60,10 +88,10 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM
// PCI Routing Table Name(_PRT, Package() { - ROOT_PRT_ENTRY(0, 168), // INTA - ROOT_PRT_ENTRY(1, 169), // INTB - ROOT_PRT_ENTRY(2, 170), // INTC - ROOT_PRT_ENTRY(3, 171), // INTD + ROOT_PRT_ENTRY(0, LNKA), // INTA + ROOT_PRT_ENTRY(1, LNKB), // INTB + ROOT_PRT_ENTRY(2, LNKC), // INTC + ROOT_PRT_ENTRY(3, LNKD), // INTD }) // Root complex resources Method (_CRS, 0, Serialized) {
The PCI Routing Table (_PRT) for Juno does not specify the Interrupt trigger type and polarity. In the absence of this information, the kernel uses PCI default interrupt type (level triggered, active low) which is incompatible with GICv2 compliant interrupt controller such as on Juno.
Absence of interrupt type leads to errors such as following in kernel boot log -
[ 1.353696] genirq: Setting trigger mode 8 for irq 9 failed (gic_set_type+0x0/0x5c) [ 1.478286] genirq: Setting trigger mode 8 for irq 17 failed (gic_set_type+0x0/0x5c) [ 1.563723] genirq: Setting trigger mode 8 for irq 18 failed (gic_set_type+0x0/0x5c)
Fix this issue by providing the correct information (level triggered, active high) to the kernel by using the PCI Link device.
Signed-off-by: Punit Agrawal punit.agrawal@arm.com ---
( Resending as I seem to have accidentally cancelled the post to linaro-acpi. Apologies for the duplicate. )
Hi,
This patch to the OpenPlatformPkg for Juno ACPI tables fixes an issue I reported earlier[0].
All feedback welcome.
Thanks, Punit
Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl | 60 +++++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl index 800d2cb..55b76d6 100644 --- a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl +++ b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl @@ -15,20 +15,43 @@ #include "ArmPlatform.h"
/* - See Reference [1] 6.2.12 - "There are two ways that _PRT can be used. ... - In the second model, the PCI interrupts are hardwired to specific interrupt - inputs on the interrupt controller and are not configurable. In this case, - the Source field in _PRT does not reference a device, but instead contains - the value zero, and the Source Index field contains the global system - interrupt to which the PCI interrupt is hardwired." + See ACPI 6.1 Section 6.2.13 + + There are two ways that _PRT can be used. ... + + In the first model, a PCI Link device is used to provide additional + configuration information such as whether the interrupt is Level or + Edge triggered, it is active High or Low, Shared or Exclusive, etc. + + In the second model, the PCI interrupts are hardwired to specific + interrupt inputs on the interrupt controller and are not + configurable. In this case, the Source field in _PRT does not + reference a device, but instead contains the value zero, and the + Source Index field contains the global system interrupt to which the + PCI interrupt is hardwired. + + We use the first model with link indirection to set the correct + interrupt type as PCI defaults (Level Triggered, Active Low) are not + compatible with GICv2. */ -#define PRT_ENTRY(Address, Pin, Interrupt) \ - Package (4) { \ +#define LNK_DEVICE(Unique_Id, Link_Name, irq) \ + Device(Link_Name) { \ + Name(_HID, EISAID("PNP0C0F")) \ + Name(_UID, Unique_Id) \ + Name(_PRS, ResourceTemplate() { \ + Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) { irq } \ + }) \ + Method (_CRS, 0) { Return (_PRS) } \ + Method (_SRS, 1) { } \ + Method (_DIS) { } \ + } + +#define PRT_ENTRY(Address, Pin, Link) \ + Package (4) { \ Address, /* uses the same format as _ADR */ \ Pin, /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD). */ \ - Zero, /* allocated from the global interrupt pool. */ \ - Interrupt /* global system interrupt number */ \ + Link, /* Interrupt allocated via Link device. */ \ + Zero /* global system interrupt number (no used) */ \ }
/* @@ -36,7 +59,7 @@ "High word–Device #, Low word–Function #. (for example, device 3, function 2 is 0x00030002). To refer to all the functions on a device #, use a function number of FFFF)." */ -#define ROOT_PRT_ENTRY(Pin, Interrupt) PRT_ENTRY(0x0000FFFF, Pin, Interrupt) +#define ROOT_PRT_ENTRY(Pin, Link) PRT_ENTRY(0x0000FFFF, Pin, Link) // Device 0 for Bridge.
@@ -45,6 +68,11 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM // // PCI Root Complex // + LNK_DEVICE(1, LNKA, 168) + LNK_DEVICE(2, LNKB, 169) + LNK_DEVICE(3, LNKC, 170) + LNK_DEVICE(4, LNKD, 171) + Device(PCI0) { Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge @@ -60,10 +88,10 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM
// PCI Routing Table Name(_PRT, Package() { - ROOT_PRT_ENTRY(0, 168), // INTA - ROOT_PRT_ENTRY(1, 169), // INTB - ROOT_PRT_ENTRY(2, 170), // INTC - ROOT_PRT_ENTRY(3, 171), // INTD + ROOT_PRT_ENTRY(0, LNKA), // INTA + ROOT_PRT_ENTRY(1, LNKB), // INTB + ROOT_PRT_ENTRY(2, LNKC), // INTC + ROOT_PRT_ENTRY(3, LNKD), // INTD }) // Root complex resources Method (_CRS, 0, Serialized) {
[ + Graeme to help review ACPI changes ]
On 04/05/16 10:00, Punit Agrawal wrote:
The PCI Routing Table (_PRT) for Juno does not specify the Interrupt trigger type and polarity. In the absence of this information, the kernel uses PCI default interrupt type (level triggered, active low) which is incompatible with GICv2 compliant interrupt controller such as on Juno.
Absence of interrupt type leads to errors such as following in kernel boot log -
[ 1.353696] genirq: Setting trigger mode 8 for irq 9 failed (gic_set_type+0x0/0x5c) [ 1.478286] genirq: Setting trigger mode 8 for irq 17 failed (gic_set_type+0x0/0x5c) [ 1.563723] genirq: Setting trigger mode 8 for irq 18 failed (gic_set_type+0x0/0x5c)
Fix this issue by providing the correct information (level triggered, active high) to the kernel by using the PCI Link device.
Signed-off-by: Punit Agrawal punit.agrawal@arm.com
( Resending as I seem to have accidentally cancelled the post to linaro-acpi. Apologies for the duplicate. )
Hi,
This patch to the OpenPlatformPkg for Juno ACPI tables fixes an issue I reported earlier[0].
Graeme, Ryan,
Any comments?
All feedback welcome.
Thanks, Punit
Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl | 60 +++++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl index 800d2cb..55b76d6 100644 --- a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl +++ b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl @@ -15,20 +15,43 @@ #include "ArmPlatform.h"
/*
- See Reference [1] 6.2.12
- "There are two ways that _PRT can be used. ...
- In the second model, the PCI interrupts are hardwired to specific interrupt
- inputs on the interrupt controller and are not configurable. In this case,
- the Source field in _PRT does not reference a device, but instead contains
- the value zero, and the Source Index field contains the global system
- interrupt to which the PCI interrupt is hardwired."
- See ACPI 6.1 Section 6.2.13
- There are two ways that _PRT can be used. ...
- In the first model, a PCI Link device is used to provide additional
- configuration information such as whether the interrupt is Level or
- Edge triggered, it is active High or Low, Shared or Exclusive, etc.
- In the second model, the PCI interrupts are hardwired to specific
- interrupt inputs on the interrupt controller and are not
- configurable. In this case, the Source field in _PRT does not
- reference a device, but instead contains the value zero, and the
- Source Index field contains the global system interrupt to which the
- PCI interrupt is hardwired.
- We use the first model with link indirection to set the correct
- interrupt type as PCI defaults (Level Triggered, Active Low) are not
- compatible with GICv2. */
-#define PRT_ENTRY(Address, Pin, Interrupt) \
Package (4) { \
+#define LNK_DEVICE(Unique_Id, Link_Name, irq) \
Device(Link_Name) { \
Name(_HID, EISAID("PNP0C0F")) \
Name(_UID, Unique_Id) \
Name(_PRS, ResourceTemplate() { \
Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) { irq } \
}) \
Method (_CRS, 0) { Return (_PRS) } \
Method (_SRS, 1) { } \
Method (_DIS) { } \
}
+#define PRT_ENTRY(Address, Pin, Link) \
Package (4) { \ Address, /* uses the same format as _ADR */ \ Pin, /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD). */ \
Zero, /* allocated from the global interrupt pool. */ \
Interrupt /* global system interrupt number */ \
Link, /* Interrupt allocated via Link device. */ \
Zero /* global system interrupt number (no used) */ \ }
/*
@@ -36,7 +59,7 @@ "High word–Device #, Low word–Function #. (for example, device 3, function 2 is 0x00030002). To refer to all the functions on a device #, use a function number of FFFF)." */ -#define ROOT_PRT_ENTRY(Pin, Interrupt) PRT_ENTRY(0x0000FFFF, Pin, Interrupt) +#define ROOT_PRT_ENTRY(Pin, Link) PRT_ENTRY(0x0000FFFF, Pin, Link) // Device 0 for Bridge.
@@ -45,6 +68,11 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM // // PCI Root Complex //
LNK_DEVICE(1, LNKA, 168)
LNK_DEVICE(2, LNKB, 169)
LNK_DEVICE(3, LNKC, 170)
LNK_DEVICE(4, LNKD, 171)
Device(PCI0) { Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
@@ -60,10 +88,10 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM
// PCI Routing Table Name(_PRT, Package() {
ROOT_PRT_ENTRY(0, 168), // INTA
ROOT_PRT_ENTRY(1, 169), // INTB
ROOT_PRT_ENTRY(2, 170), // INTC
ROOT_PRT_ENTRY(3, 171), // INTD
ROOT_PRT_ENTRY(0, LNKA), // INTA
ROOT_PRT_ENTRY(1, LNKB), // INTB
ROOT_PRT_ENTRY(2, LNKC), // INTC
ROOT_PRT_ENTRY(3, LNKD), // INTD }) // Root complex resources Method (_CRS, 0, Serialized) {
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
On Wed, May 11, 2016 at 05:11:18PM +0100, Punit Agrawal wrote:
[ + Graeme to help review ACPI changes ]
On 04/05/16 10:00, Punit Agrawal wrote:
The PCI Routing Table (_PRT) for Juno does not specify the Interrupt trigger type and polarity. In the absence of this information, the kernel uses PCI default interrupt type (level triggered, active low) which is incompatible with GICv2 compliant interrupt controller such as on Juno.
Absence of interrupt type leads to errors such as following in kernel boot log -
[ 1.353696] genirq: Setting trigger mode 8 for irq 9 failed (gic_set_type+0x0/0x5c) [ 1.478286] genirq: Setting trigger mode 8 for irq 17 failed (gic_set_type+0x0/0x5c) [ 1.563723] genirq: Setting trigger mode 8 for irq 18 failed (gic_set_type+0x0/0x5c)
Fix this issue by providing the correct information (level triggered, active high) to the kernel by using the PCI Link device.
Signed-off-by: Punit Agrawal punit.agrawal@arm.com
( Resending as I seem to have accidentally cancelled the post to linaro-acpi. Apologies for the duplicate. )
Hi,
This patch to the OpenPlatformPkg for Juno ACPI tables fixes an issue I reported earlier[0].
Graeme, Ryan,
Any comments?
PCI is not my expertise but I think you are correct based on my reading of parts of ACPI spec.
Reviewed-by: Graeme Gregory graeme.gregory@linaro.org
All feedback welcome.
Thanks, Punit
Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl | 60 +++++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl index 800d2cb..55b76d6 100644 --- a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl +++ b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl @@ -15,20 +15,43 @@ #include "ArmPlatform.h"
/*
- See Reference [1] 6.2.12
- "There are two ways that _PRT can be used. ...
- In the second model, the PCI interrupts are hardwired to specific interrupt
- inputs on the interrupt controller and are not configurable. In this case,
- the Source field in _PRT does not reference a device, but instead contains
- the value zero, and the Source Index field contains the global system
- interrupt to which the PCI interrupt is hardwired."
- See ACPI 6.1 Section 6.2.13
- There are two ways that _PRT can be used. ...
- In the first model, a PCI Link device is used to provide additional
- configuration information such as whether the interrupt is Level or
- Edge triggered, it is active High or Low, Shared or Exclusive, etc.
- In the second model, the PCI interrupts are hardwired to specific
- interrupt inputs on the interrupt controller and are not
- configurable. In this case, the Source field in _PRT does not
- reference a device, but instead contains the value zero, and the
- Source Index field contains the global system interrupt to which the
- PCI interrupt is hardwired.
- We use the first model with link indirection to set the correct
- interrupt type as PCI defaults (Level Triggered, Active Low) are not
- compatible with GICv2. */
-#define PRT_ENTRY(Address, Pin, Interrupt) \
Package (4) { \
+#define LNK_DEVICE(Unique_Id, Link_Name, irq) \
Device(Link_Name) { \
Name(_HID, EISAID("PNP0C0F")) \
Name(_UID, Unique_Id) \
Name(_PRS, ResourceTemplate() { \
Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) { irq } \
}) \
Method (_CRS, 0) { Return (_PRS) } \
Method (_SRS, 1) { } \
Method (_DIS) { } \
}
+#define PRT_ENTRY(Address, Pin, Link) \
Package (4) { \ Address, /* uses the same format as _ADR */ \ Pin, /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD). */ \
Zero, /* allocated from the global interrupt pool. */ \
Interrupt /* global system interrupt number */ \
Link, /* Interrupt allocated via Link device. */ \
Zero /* global system interrupt number (no used) */ \ }
/*
@@ -36,7 +59,7 @@ "High word–Device #, Low word–Function #. (for example, device 3, function 2 is 0x00030002). To refer to all the functions on a device #, use a function number of FFFF)." */ -#define ROOT_PRT_ENTRY(Pin, Interrupt) PRT_ENTRY(0x0000FFFF, Pin, Interrupt) +#define ROOT_PRT_ENTRY(Pin, Link) PRT_ENTRY(0x0000FFFF, Pin, Link) // Device 0 for Bridge.
@@ -45,6 +68,11 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM // // PCI Root Complex //
LNK_DEVICE(1, LNKA, 168)
LNK_DEVICE(2, LNKB, 169)
LNK_DEVICE(3, LNKC, 170)
LNK_DEVICE(4, LNKD, 171)
Device(PCI0) { Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
@@ -60,10 +88,10 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM
// PCI Routing Table Name(_PRT, Package() {
ROOT_PRT_ENTRY(0, 168), // INTA
ROOT_PRT_ENTRY(1, 169), // INTB
ROOT_PRT_ENTRY(2, 170), // INTC
ROOT_PRT_ENTRY(3, 171), // INTD
ROOT_PRT_ENTRY(0, LNKA), // INTA
ROOT_PRT_ENTRY(1, LNKB), // INTB
ROOT_PRT_ENTRY(2, LNKC), // INTC
ROOT_PRT_ENTRY(3, LNKD), // INTD }) // Root complex resources Method (_CRS, 0, Serialized) {
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
On 11 May 2016 at 18:40, Graeme Gregory graeme.gregory@linaro.org wrote:
On Wed, May 11, 2016 at 05:11:18PM +0100, Punit Agrawal wrote:
[ + Graeme to help review ACPI changes ]
On 04/05/16 10:00, Punit Agrawal wrote:
The PCI Routing Table (_PRT) for Juno does not specify the Interrupt trigger type and polarity. In the absence of this information, the kernel uses PCI default interrupt type (level triggered, active low) which is incompatible with GICv2 compliant interrupt controller such as on Juno.
Absence of interrupt type leads to errors such as following in kernel boot log -
[ 1.353696] genirq: Setting trigger mode 8 for irq 9 failed (gic_set_type+0x0/0x5c) [ 1.478286] genirq: Setting trigger mode 8 for irq 17 failed (gic_set_type+0x0/0x5c) [ 1.563723] genirq: Setting trigger mode 8 for irq 18 failed (gic_set_type+0x0/0x5c)
Fix this issue by providing the correct information (level triggered, active high) to the kernel by using the PCI Link device.
Signed-off-by: Punit Agrawal punit.agrawal@arm.com
( Resending as I seem to have accidentally cancelled the post to linaro-acpi. Apologies for the duplicate. )
Hi,
This patch to the OpenPlatformPkg for Juno ACPI tables fixes an issue I reported earlier[0].
Graeme, Ryan,
Any comments?
It's ACPI. I know nothing.
PCI is not my expertise but I think you are correct based on my reading of parts of ACPI spec.
Reviewed-by: Graeme Gregory graeme.gregory@linaro.org
All feedback welcome.
Thanks, Punit
Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl | 60 +++++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl index 800d2cb..55b76d6 100644 --- a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl +++ b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl @@ -15,20 +15,43 @@ #include "ArmPlatform.h"
/*
- See Reference [1] 6.2.12
- "There are two ways that _PRT can be used. ...
- In the second model, the PCI interrupts are hardwired to specific interrupt
- inputs on the interrupt controller and are not configurable. In this case,
- the Source field in _PRT does not reference a device, but instead contains
- the value zero, and the Source Index field contains the global system
- interrupt to which the PCI interrupt is hardwired."
- See ACPI 6.1 Section 6.2.13
- There are two ways that _PRT can be used. ...
- In the first model, a PCI Link device is used to provide additional
- configuration information such as whether the interrupt is Level or
- Edge triggered, it is active High or Low, Shared or Exclusive, etc.
- In the second model, the PCI interrupts are hardwired to specific
- interrupt inputs on the interrupt controller and are not
- configurable. In this case, the Source field in _PRT does not
- reference a device, but instead contains the value zero, and the
- Source Index field contains the global system interrupt to which the
- PCI interrupt is hardwired.
- We use the first model with link indirection to set the correct
- interrupt type as PCI defaults (Level Triggered, Active Low) are not
- compatible with GICv2. */
-#define PRT_ENTRY(Address, Pin, Interrupt) \
Package (4) { \
+#define LNK_DEVICE(Unique_Id, Link_Name, irq) \
Device(Link_Name) { \
Name(_HID, EISAID("PNP0C0F")) \
Name(_UID, Unique_Id) \
Name(_PRS, ResourceTemplate() { \
Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) { irq } \
}) \
Method (_CRS, 0) { Return (_PRS) } \
Method (_SRS, 1) { } \
Method (_DIS) { } \
}
+#define PRT_ENTRY(Address, Pin, Link) \
Package (4) { \ Address, /* uses the same format as _ADR */ \ Pin, /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD). */ \
Zero, /* allocated from the global interrupt pool. */ \
Interrupt /* global system interrupt number */ \
Link, /* Interrupt allocated via Link device. */ \
Zero /* global system interrupt number (no used) */ \ }
/*
@@ -36,7 +59,7 @@ "High word–Device #, Low word–Function #. (for example, device 3, function 2 is 0x00030002). To refer to all the functions on a device #, use a function number of FFFF)." */ -#define ROOT_PRT_ENTRY(Pin, Interrupt) PRT_ENTRY(0x0000FFFF, Pin, Interrupt) +#define ROOT_PRT_ENTRY(Pin, Link) PRT_ENTRY(0x0000FFFF, Pin, Link) // Device 0 for Bridge.
@@ -45,6 +68,11 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM // // PCI Root Complex //
LNK_DEVICE(1, LNKA, 168)
LNK_DEVICE(2, LNKB, 169)
LNK_DEVICE(3, LNKC, 170)
LNK_DEVICE(4, LNKD, 171)
Device(PCI0) { Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
@@ -60,10 +88,10 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM
// PCI Routing Table Name(_PRT, Package() {
ROOT_PRT_ENTRY(0, 168), // INTA
ROOT_PRT_ENTRY(1, 169), // INTB
ROOT_PRT_ENTRY(2, 170), // INTC
ROOT_PRT_ENTRY(3, 171), // INTD
ROOT_PRT_ENTRY(0, LNKA), // INTA
ROOT_PRT_ENTRY(1, LNKB), // INTB
ROOT_PRT_ENTRY(2, LNKC), // INTC
ROOT_PRT_ENTRY(3, LNKD), // INTD }) // Root complex resources Method (_CRS, 0, Serialized) {
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
On 11/05/16 18:40, Graeme Gregory wrote:
On Wed, May 11, 2016 at 05:11:18PM +0100, Punit Agrawal wrote:
[ + Graeme to help review ACPI changes ]
On 04/05/16 10:00, Punit Agrawal wrote:
The PCI Routing Table (_PRT) for Juno does not specify the Interrupt trigger type and polarity. In the absence of this information, the kernel uses PCI default interrupt type (level triggered, active low) which is incompatible with GICv2 compliant interrupt controller such as on Juno.
Absence of interrupt type leads to errors such as following in kernel boot log -
[ 1.353696] genirq: Setting trigger mode 8 for irq 9 failed (gic_set_type+0x0/0x5c) [ 1.478286] genirq: Setting trigger mode 8 for irq 17 failed (gic_set_type+0x0/0x5c) [ 1.563723] genirq: Setting trigger mode 8 for irq 18 failed (gic_set_type+0x0/0x5c)
Fix this issue by providing the correct information (level triggered, active high) to the kernel by using the PCI Link device.
Signed-off-by: Punit Agrawal punit.agrawal@arm.com
( Resending as I seem to have accidentally cancelled the post to linaro-acpi. Apologies for the duplicate. )
Hi,
This patch to the OpenPlatformPkg for Juno ACPI tables fixes an issue I reported earlier[0].
Graeme, Ryan,
Any comments?
PCI is not my expertise but I think you are correct based on my reading of parts of ACPI spec.
Reviewed-by: Graeme Gregory graeme.gregory@linaro.org
Thanks Graeme.
With neither PCI nor ACPI experience, I wanted to make sure I've not made a complete hash.
Cheers, Punit
All feedback welcome.
Thanks, Punit
Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl | 60 +++++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl index 800d2cb..55b76d6 100644 --- a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl +++ b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl @@ -15,20 +15,43 @@ #include "ArmPlatform.h"
/*
- See Reference [1] 6.2.12
- "There are two ways that _PRT can be used. ...
- In the second model, the PCI interrupts are hardwired to specific interrupt
- inputs on the interrupt controller and are not configurable. In this case,
- the Source field in _PRT does not reference a device, but instead contains
- the value zero, and the Source Index field contains the global system
- interrupt to which the PCI interrupt is hardwired."
- See ACPI 6.1 Section 6.2.13
- There are two ways that _PRT can be used. ...
- In the first model, a PCI Link device is used to provide additional
- configuration information such as whether the interrupt is Level or
- Edge triggered, it is active High or Low, Shared or Exclusive, etc.
- In the second model, the PCI interrupts are hardwired to specific
- interrupt inputs on the interrupt controller and are not
- configurable. In this case, the Source field in _PRT does not
- reference a device, but instead contains the value zero, and the
- Source Index field contains the global system interrupt to which the
- PCI interrupt is hardwired.
- We use the first model with link indirection to set the correct
- interrupt type as PCI defaults (Level Triggered, Active Low) are not
- compatible with GICv2. */
-#define PRT_ENTRY(Address, Pin, Interrupt) \
Package (4) { \
+#define LNK_DEVICE(Unique_Id, Link_Name, irq) \
Device(Link_Name) { \
Name(_HID, EISAID("PNP0C0F")) \
Name(_UID, Unique_Id) \
Name(_PRS, ResourceTemplate() { \
Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) { irq } \
}) \
Method (_CRS, 0) { Return (_PRS) } \
Method (_SRS, 1) { } \
Method (_DIS) { } \
}
+#define PRT_ENTRY(Address, Pin, Link) \
Package (4) { \ Address, /* uses the same format as _ADR */ \ Pin, /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD). */ \
Zero, /* allocated from the global interrupt pool. */ \
Interrupt /* global system interrupt number */ \
Link, /* Interrupt allocated via Link device. */ \
Zero /* global system interrupt number (no used) */ \ }
/*
@@ -36,7 +59,7 @@ "High word–Device #, Low word–Function #. (for example, device 3, function 2 is 0x00030002). To refer to all the functions on a device #, use a function number of FFFF)." */ -#define ROOT_PRT_ENTRY(Pin, Interrupt) PRT_ENTRY(0x0000FFFF, Pin, Interrupt) +#define ROOT_PRT_ENTRY(Pin, Link) PRT_ENTRY(0x0000FFFF, Pin, Link) // Device 0 for Bridge.
@@ -45,6 +68,11 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM // // PCI Root Complex //
LNK_DEVICE(1, LNKA, 168)
LNK_DEVICE(2, LNKB, 169)
LNK_DEVICE(3, LNKC, 170)
LNK_DEVICE(4, LNKD, 171)
Device(PCI0) { Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
@@ -60,10 +88,10 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM
// PCI Routing Table Name(_PRT, Package() {
ROOT_PRT_ENTRY(0, 168), // INTA
ROOT_PRT_ENTRY(1, 169), // INTB
ROOT_PRT_ENTRY(2, 170), // INTC
ROOT_PRT_ENTRY(3, 171), // INTD
ROOT_PRT_ENTRY(0, LNKA), // INTA
ROOT_PRT_ENTRY(1, LNKB), // INTB
ROOT_PRT_ENTRY(2, LNKC), // INTC
ROOT_PRT_ENTRY(3, LNKD), // INTD }) // Root complex resources Method (_CRS, 0, Serialized) {
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Thanks Graeme,
Punit - contributions to OpenPlatformPkg/edk2 also require a Contributed-under: TianoCore Contribution Agreement 1.0 statement
Are you happy for me to add this on commit?
On 11 May 2016 at 18:40, Graeme Gregory graeme.gregory@linaro.org wrote:
On Wed, May 11, 2016 at 05:11:18PM +0100, Punit Agrawal wrote:
[ + Graeme to help review ACPI changes ]
On 04/05/16 10:00, Punit Agrawal wrote:
The PCI Routing Table (_PRT) for Juno does not specify the Interrupt trigger type and polarity. In the absence of this information, the kernel uses PCI default interrupt type (level triggered, active low) which is incompatible with GICv2 compliant interrupt controller such as on Juno.
Absence of interrupt type leads to errors such as following in kernel boot log -
[ 1.353696] genirq: Setting trigger mode 8 for irq 9 failed (gic_set_type+0x0/0x5c) [ 1.478286] genirq: Setting trigger mode 8 for irq 17 failed (gic_set_type+0x0/0x5c) [ 1.563723] genirq: Setting trigger mode 8 for irq 18 failed (gic_set_type+0x0/0x5c)
Fix this issue by providing the correct information (level triggered, active high) to the kernel by using the PCI Link device.
Signed-off-by: Punit Agrawal punit.agrawal@arm.com
( Resending as I seem to have accidentally cancelled the post to linaro-acpi. Apologies for the duplicate. )
Hi,
This patch to the OpenPlatformPkg for Juno ACPI tables fixes an issue I reported earlier[0].
Graeme, Ryan,
Any comments?
PCI is not my expertise but I think you are correct based on my reading of parts of ACPI spec.
Reviewed-by: Graeme Gregory graeme.gregory@linaro.org
All feedback welcome.
Thanks, Punit
Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl | 60 +++++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl index 800d2cb..55b76d6 100644 --- a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl +++ b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl @@ -15,20 +15,43 @@ #include "ArmPlatform.h"
/*
- See Reference [1] 6.2.12
- "There are two ways that _PRT can be used. ...
- In the second model, the PCI interrupts are hardwired to specific interrupt
- inputs on the interrupt controller and are not configurable. In this case,
- the Source field in _PRT does not reference a device, but instead contains
- the value zero, and the Source Index field contains the global system
- interrupt to which the PCI interrupt is hardwired."
- See ACPI 6.1 Section 6.2.13
- There are two ways that _PRT can be used. ...
- In the first model, a PCI Link device is used to provide additional
- configuration information such as whether the interrupt is Level or
- Edge triggered, it is active High or Low, Shared or Exclusive, etc.
- In the second model, the PCI interrupts are hardwired to specific
- interrupt inputs on the interrupt controller and are not
- configurable. In this case, the Source field in _PRT does not
- reference a device, but instead contains the value zero, and the
- Source Index field contains the global system interrupt to which the
- PCI interrupt is hardwired.
- We use the first model with link indirection to set the correct
- interrupt type as PCI defaults (Level Triggered, Active Low) are not
- compatible with GICv2. */
-#define PRT_ENTRY(Address, Pin, Interrupt) \
Package (4) { \
+#define LNK_DEVICE(Unique_Id, Link_Name, irq) \
Device(Link_Name) { \
Name(_HID, EISAID("PNP0C0F")) \
Name(_UID, Unique_Id) \
Name(_PRS, ResourceTemplate() { \
Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) { irq } \
}) \
Method (_CRS, 0) { Return (_PRS) } \
Method (_SRS, 1) { } \
Method (_DIS) { } \
}
+#define PRT_ENTRY(Address, Pin, Link) \
Package (4) { \ Address, /* uses the same format as _ADR */ \ Pin, /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD). */ \
Zero, /* allocated from the global interrupt pool. */ \
Interrupt /* global system interrupt number */ \
Link, /* Interrupt allocated via Link device. */ \
Zero /* global system interrupt number (no used) */ \ }
/*
@@ -36,7 +59,7 @@ "High word–Device #, Low word–Function #. (for example, device 3, function 2 is 0x00030002). To refer to all the functions on a device #, use a function number of FFFF)." */ -#define ROOT_PRT_ENTRY(Pin, Interrupt) PRT_ENTRY(0x0000FFFF, Pin, Interrupt) +#define ROOT_PRT_ENTRY(Pin, Link) PRT_ENTRY(0x0000FFFF, Pin, Link) // Device 0 for Bridge.
@@ -45,6 +68,11 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM // // PCI Root Complex //
LNK_DEVICE(1, LNKA, 168)
LNK_DEVICE(2, LNKB, 169)
LNK_DEVICE(3, LNKC, 170)
LNK_DEVICE(4, LNKD, 171)
Device(PCI0) { Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
@@ -60,10 +88,10 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM
// PCI Routing Table Name(_PRT, Package() {
ROOT_PRT_ENTRY(0, 168), // INTA
ROOT_PRT_ENTRY(1, 169), // INTB
ROOT_PRT_ENTRY(2, 170), // INTC
ROOT_PRT_ENTRY(3, 171), // INTD
ROOT_PRT_ENTRY(0, LNKA), // INTA
ROOT_PRT_ENTRY(1, LNKB), // INTB
ROOT_PRT_ENTRY(2, LNKC), // INTC
ROOT_PRT_ENTRY(3, LNKD), // INTD }) // Root complex resources Method (_CRS, 0, Serialized) {
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
On 12/05/16 12:09, Leif Lindholm wrote:
Thanks Graeme,
Punit - contributions to OpenPlatformPkg/edk2 also require a Contributed-under: TianoCore Contribution Agreement 1.0 statement
Are you happy for me to add this on commit?
Yes please.
I will try and remember to add the C-u tag for future patches.
On 11 May 2016 at 18:40, Graeme Gregory graeme.gregory@linaro.org wrote:
On Wed, May 11, 2016 at 05:11:18PM +0100, Punit Agrawal wrote:
[ + Graeme to help review ACPI changes ]
On 04/05/16 10:00, Punit Agrawal wrote:
The PCI Routing Table (_PRT) for Juno does not specify the Interrupt trigger type and polarity. In the absence of this information, the kernel uses PCI default interrupt type (level triggered, active low) which is incompatible with GICv2 compliant interrupt controller such as on Juno.
Absence of interrupt type leads to errors such as following in kernel boot log -
[ 1.353696] genirq: Setting trigger mode 8 for irq 9 failed (gic_set_type+0x0/0x5c) [ 1.478286] genirq: Setting trigger mode 8 for irq 17 failed (gic_set_type+0x0/0x5c) [ 1.563723] genirq: Setting trigger mode 8 for irq 18 failed (gic_set_type+0x0/0x5c)
Fix this issue by providing the correct information (level triggered, active high) to the kernel by using the PCI Link device.
Signed-off-by: Punit Agrawal punit.agrawal@arm.com
( Resending as I seem to have accidentally cancelled the post to linaro-acpi. Apologies for the duplicate. )
Hi,
This patch to the OpenPlatformPkg for Juno ACPI tables fixes an issue I reported earlier[0].
Graeme, Ryan,
Any comments?
PCI is not my expertise but I think you are correct based on my reading of parts of ACPI spec.
Reviewed-by: Graeme Gregory graeme.gregory@linaro.org
All feedback welcome.
Thanks, Punit
Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl | 60 +++++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl index 800d2cb..55b76d6 100644 --- a/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl +++ b/Platforms/ARM/Juno/AcpiTables/AcpiSsdtRootPci.asl @@ -15,20 +15,43 @@ #include "ArmPlatform.h"
/*
- See Reference [1] 6.2.12
- "There are two ways that _PRT can be used. ...
- In the second model, the PCI interrupts are hardwired to specific interrupt
- inputs on the interrupt controller and are not configurable. In this case,
- the Source field in _PRT does not reference a device, but instead contains
- the value zero, and the Source Index field contains the global system
- interrupt to which the PCI interrupt is hardwired."
- See ACPI 6.1 Section 6.2.13
- There are two ways that _PRT can be used. ...
- In the first model, a PCI Link device is used to provide additional
- configuration information such as whether the interrupt is Level or
- Edge triggered, it is active High or Low, Shared or Exclusive, etc.
- In the second model, the PCI interrupts are hardwired to specific
- interrupt inputs on the interrupt controller and are not
- configurable. In this case, the Source field in _PRT does not
- reference a device, but instead contains the value zero, and the
- Source Index field contains the global system interrupt to which the
- PCI interrupt is hardwired.
- We use the first model with link indirection to set the correct
- interrupt type as PCI defaults (Level Triggered, Active Low) are not
- compatible with GICv2. */
-#define PRT_ENTRY(Address, Pin, Interrupt) \
Package (4) { \
+#define LNK_DEVICE(Unique_Id, Link_Name, irq) \
Device(Link_Name) { \
Name(_HID, EISAID("PNP0C0F")) \
Name(_UID, Unique_Id) \
Name(_PRS, ResourceTemplate() { \
Interrupt(ResourceProducer, Level, ActiveHigh, Exclusive) { irq } \
}) \
Method (_CRS, 0) { Return (_PRS) } \
Method (_SRS, 1) { } \
Method (_DIS) { } \
}
+#define PRT_ENTRY(Address, Pin, Link) \
Package (4) { \ Address, /* uses the same format as _ADR */ \ Pin, /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD). */ \
Zero, /* allocated from the global interrupt pool. */ \
Interrupt /* global system interrupt number */ \
Link, /* Interrupt allocated via Link device. */ \
Zero /* global system interrupt number (no used) */ \ }
/*
@@ -36,7 +59,7 @@ "High word–Device #, Low word–Function #. (for example, device 3, function 2 is 0x00030002). To refer to all the functions on a device #, use a function number of FFFF)." */ -#define ROOT_PRT_ENTRY(Pin, Interrupt) PRT_ENTRY(0x0000FFFF, Pin, Interrupt) +#define ROOT_PRT_ENTRY(Pin, Link) PRT_ENTRY(0x0000FFFF, Pin, Link) // Device 0 for Bridge.
@@ -45,6 +68,11 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM // // PCI Root Complex //
LNK_DEVICE(1, LNKA, 168)
LNK_DEVICE(2, LNKB, 169)
LNK_DEVICE(3, LNKC, 170)
LNK_DEVICE(4, LNKD, 171)
Device(PCI0) { Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
@@ -60,10 +88,10 @@ DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM
// PCI Routing Table Name(_PRT, Package() {
ROOT_PRT_ENTRY(0, 168), // INTA
ROOT_PRT_ENTRY(1, 169), // INTB
ROOT_PRT_ENTRY(2, 170), // INTC
ROOT_PRT_ENTRY(3, 171), // INTD
ROOT_PRT_ENTRY(0, LNKA), // INTA
ROOT_PRT_ENTRY(1, LNKB), // INTB
ROOT_PRT_ENTRY(2, LNKC), // INTC
ROOT_PRT_ENTRY(3, LNKD), // INTD }) // Root complex resources Method (_CRS, 0, Serialized) {
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.