/*++

  Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent



Module Name:

  Madt3.0.c

Abstract:

  This file contains a structure definition for the ACPI 2.0 Multiple APIC
  Description Table (MADT).  Any changes to the MADT table require updating the
  respective structure count in Madt.h and then adding the structure to the
  MADT defined in this file.  The table layout is defined in Madt.h and the
  table contents are defined in Acpi3_0.h and Madt.h.

--*/

//
// Statements that include other files
//
#include "Madt.h"
#include <IndustryStandard/Acpi50.h>

//
// Multiple APIC Description Table
//
EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE  Madt = {
  EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, // **Signatures are the same 1.0-3.0 because it says "APIC".
  sizeof (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE),  // **Length
  EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
  //
  // EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,  // **Table Revision must be 2.0 for ACPI 3.0
  // Checksum will be updated at runtime
  //
  0x00, // **Check sum
  //
  // It is expected that these values will be programmed at runtime
  //
  ' ',                        // OEMID
  ' ',                        // Creative way to
  ' ',                        // make six bytes
  ' ',                        // of space in
  ' ',                        // a table for
  ' ',                        // **OEMID
  0,                          // **OEM Table ID
  EFI_ACPI_OEM_MADT_REVISION, // **OEM Revision
  0,                          // **Creator ID
  0,                          // **Creator Revision
  //
  // MADT specific fields
  //
  LOCAL_APIC_ADDRESS,               // **Local APIC Address
  EFI_ACPI_4_0_MULTIPLE_APIC_FLAGS, // **Flags
  //
  // Processor Local APIC Structure
  // Correct processor order, Primary threads first then Hyper threads
  // And correct APIC-ids
  // This text below is included as a reference until Thurley is 100%:
  // According to EDS the Local APIC ID is determined based of a bit structure
  // Bit 24: Core ID Bit 25: Core Pair ID Bit 26-27: Reserved Bit 28-30: Socket ID Bit 31: Reserved
  // 4 Sockets and 4 Cores per Socket.
  // So possible LAPIC IDs 00, 01, 02, 03, 10, 11, 12, 13, 20, 21, 22, 23, 30, 31, 32, 33
  // Static Entries 00, 10, 20, 30, 01, 11, 21, 31, 02, 12, 22, 32, 03, 13, 23, 33
  // BSP needs to be first entry in table. Check before boot. If BSP non zero need to rotate the entries.
  // Suppore BSP is LAPIC ID xy. Rotate the table by using formula [x + (y * 4)]
  // So if BSP LAPIC ID is 21 then table rotated 6 times.
  // End of Reference Text.
  // Thurley is supposed to be 2 sockets, 4 cores, and hyperthreading available per each core.
  // 2 (sockets) x 4 (cores) = 8 (processors non-HT), 8 (processors non-HT) x 2 (HT/proc) = 16 (HT procs)
  // Rhyme & reason of the ordering below.  This is a best guess ordering for now,
  // Thurley EPS may give better info on LAPIC numbers.
  // Ordering was established to help dissipate heat across two sockets evenly.
  // Since logical processor number only has to be unique, I followed
  // a similar approach to high end servers and have the first digit of the LAPIC
  // id the socket number.
  //
  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type 0x00
  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
  0x01,                                                 // Processor ID
  0x00,                                                 // Local APIC ID
  0x00000001,                                           // Flags - Disabled (until initialized by platform driver)
  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type
  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
  0x02,                                                 // Processor ID
  0x04,                                                 // Local APIC ID 
  0x00000001,                                           // Flags - Disabled (until initialized by platform driver)
  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type
  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
  0x03,                                                 // Processor ID
  0x02,                                                 // Local APIC ID
  0x00000001,                                           // Flags - Disabled (until initialized by platform driver)
  EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC,                    // Type
  sizeof (EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE), // Length
  0x04,                                                 // Processor ID
  0x06,                                                 // Local APIC ID
  0x00000001,                                           // Flags - Disabled (until initialized by platform driver)
  //
  // ***************   IO APIC Structure ******************
  //
  //
  //
  // **************************  I/O APIC  **************
  //
  EFI_ACPI_3_0_IO_APIC,                     // Type 0x01
  sizeof (EFI_ACPI_3_0_IO_APIC_STRUCTURE),  // Length
  ICH_IOAPIC_ID,                            // IO APIC ID
  EFI_ACPI_RESERVED_BYTE,                   // Reserved    EFI_ACPI_RESERVED_BYTE
  IO_APIC_ADDRESS,                          // IO APIC Address (physical)   0xFEC00000
  0x18 * 0,                                 // Global System Interrupt Base

  //
  // Interrupt Source Override Structure: Sample
  //
  // EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE,                   // Type  0x02
  // sizeof (EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE),// Length
  // 0x00,                                                     // Bus
  // 0x00,                                                     // Source
  // 0x00000000,                                               // Global System Interrupt
  // 0x0000,                                                   // Flags
  //
  // IRQ0=>IRQ2 Interrupt Source Override Structure
  //
  EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE, // Type  0x02
  sizeof (EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE),  // Length
  0x00,       // Bus - ISA
  0x00,       // Source - IRQ0
  0x00000002, // Global System Interrupt - IRQ2
  0x0000,     // Flags - Conforms to specifications of the bus
  //
  // ISO (SCI Active High) Interrupt Source Override Structure
  //
  EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE, // Type  0x02
  sizeof (EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE),  // Length
  0x00,       // Bus - ISA
  0x09,       // Source - IRQ0
  0x00000009, // Global System Interrupt - IRQ2
  0x000D,     // Flags - Level-tiggered, Active High



  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
  0x01,                                           // ACPI Processor ID
  0x000D,                                         // Flags - Level-tiggered, Active High
  0x01,                                           // Local APIC LINT#
  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
  0x02,                                           // ACPI Processor ID
  0x000D,                                         // Flags - Level-tiggered, Active High
  0x01,                                           // Local APIC LINT#
  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
  0x03,                                           // ACPI Processor ID
  0x000D,                                         // Flags - Level-tiggered, Active High
  0x01,                                           // Local APIC LINT#
  EFI_ACPI_3_0_LOCAL_APIC_NMI,                    // Type
  sizeof (EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE), // Length
  0x04,                                           // ACPI Processor ID
  0x000D,                                         // Flags - Level-tiggered, Active High
  0x01,                                           // Local APIC LINT#
};

VOID*
ReferenceAcpiTable (
  VOID
  )
{
  //
  // Reference the table being generated to prevent the optimizer from
  // removing the data structure from the executable
  //
  return (VOID*)&Madt;
}
