17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * <Insert copyright here : it must be BSD-like so everyone can use it> 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * Author: Erich Boleyn <erich@uruk.org> http://www.uruk.org/~erich/ 57c478bd9Sstevel@tonic-gate * 67c478bd9Sstevel@tonic-gate * Header file implementing Intel MultiProcessor Specification (MPS) 77c478bd9Sstevel@tonic-gate * version 1.1 and 1.4 SMP hardware control for Intel Architecture CPUs, 87c478bd9Sstevel@tonic-gate * with hooks for running correctly on a standard PC without the hardware. 97c478bd9Sstevel@tonic-gate * 107c478bd9Sstevel@tonic-gate * This file was created from information in the Intel MPS version 1.4 117c478bd9Sstevel@tonic-gate * document, order number 242016-004, which can be ordered from the 127c478bd9Sstevel@tonic-gate * Intel literature center. 137c478bd9Sstevel@tonic-gate */ 147c478bd9Sstevel@tonic-gate 157c478bd9Sstevel@tonic-gate #ifndef _SMP_IMPS_H 167c478bd9Sstevel@tonic-gate #define _SMP_IMPS_H 177c478bd9Sstevel@tonic-gate 187c478bd9Sstevel@tonic-gate /* make sure "apic.h" is included */ 197c478bd9Sstevel@tonic-gate #ifndef _APIC_H 207c478bd9Sstevel@tonic-gate #error Must include "apic.h" before "smp-imps.h" 217c478bd9Sstevel@tonic-gate #endif /* !_APIC_H */ 227c478bd9Sstevel@tonic-gate 237c478bd9Sstevel@tonic-gate /* 247c478bd9Sstevel@tonic-gate * Defines used. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #ifdef IMPS_DEBUG 287c478bd9Sstevel@tonic-gate #define IMPS_DEBUG_PRINT(x) KERNEL_PRINT(x) 297c478bd9Sstevel@tonic-gate #else /* !IMPS_DEBUG */ 307c478bd9Sstevel@tonic-gate #define IMPS_DEBUG_PRINT(x) 317c478bd9Sstevel@tonic-gate #endif /* !IMPS_DEBUG */ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #define IMPS_MAX_CPUS APIC_BROADCAST_ID 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate /* 367c478bd9Sstevel@tonic-gate * Defines representing limitations on values usable in different 377c478bd9Sstevel@tonic-gate * situations. This mostly depends on whether the APICs are old 387c478bd9Sstevel@tonic-gate * (82489DX) or new (SIO or Pentium/Pentium Pro integrated APICs). 397c478bd9Sstevel@tonic-gate * 407c478bd9Sstevel@tonic-gate * NOTE: It appears that the APICs must either be all old or all new, 417c478bd9Sstevel@tonic-gate * or broadcasts won't work right. 427c478bd9Sstevel@tonic-gate * NOTE #2: Given that, the maximum ID which can be sent to predictably 437c478bd9Sstevel@tonic-gate * is 14 for new APICs and 254 for old APICs. So, this all implies that 447c478bd9Sstevel@tonic-gate * a maximum of 15 processors is supported with the new APICs, and a 457c478bd9Sstevel@tonic-gate * maximum of 255 processors with the old APICs. 467c478bd9Sstevel@tonic-gate */ 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate #define IMPS_APIC_ID(x) \ 497c478bd9Sstevel@tonic-gate ( imps_any_new_apics ? APIC_NEW_ID(x) : APIC_OLD_ID(x) ) 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate /* 527c478bd9Sstevel@tonic-gate * This is the value that must be in the "sig" member of the MP 537c478bd9Sstevel@tonic-gate * Floating Pointer Structure. 547c478bd9Sstevel@tonic-gate */ 557c478bd9Sstevel@tonic-gate #define IMPS_FPS_SIGNATURE ('_' | ('M'<<8) | ('P'<<16) | ('_'<<24)) 567c478bd9Sstevel@tonic-gate #define IMPS_FPS_IMCRP_BIT 0x80 577c478bd9Sstevel@tonic-gate #define IMPS_FPS_DEFAULT_MAX 7 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate /* 607c478bd9Sstevel@tonic-gate * This is the value that must be in the "sig" member of the MP 617c478bd9Sstevel@tonic-gate * Configuration Table Header. 627c478bd9Sstevel@tonic-gate */ 637c478bd9Sstevel@tonic-gate #define IMPS_CTH_SIGNATURE ('P' | ('C'<<8) | ('M'<<16) | ('P'<<24)) 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate /* 667c478bd9Sstevel@tonic-gate * These are the "type" values for Base MP Configuration Table entries. 677c478bd9Sstevel@tonic-gate */ 687c478bd9Sstevel@tonic-gate #define IMPS_FLAG_ENABLED 1 697c478bd9Sstevel@tonic-gate #define IMPS_BCT_PROCESSOR 0 707c478bd9Sstevel@tonic-gate #define IMPS_CPUFLAG_BOOT 2 717c478bd9Sstevel@tonic-gate #define IMPS_BCT_BUS 1 727c478bd9Sstevel@tonic-gate #define IMPS_BCT_IOAPIC 2 737c478bd9Sstevel@tonic-gate #define IMPS_BCT_IO_INTERRUPT 3 747c478bd9Sstevel@tonic-gate #define IMPS_BCT_LOCAL_INTERRUPT 4 757c478bd9Sstevel@tonic-gate #define IMPS_INT_INT 0 767c478bd9Sstevel@tonic-gate #define IMPS_INT_NMI 1 777c478bd9Sstevel@tonic-gate #define IMPS_INT_SMI 2 787c478bd9Sstevel@tonic-gate #define IMPS_INT_EXTINT 3 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate /* 827c478bd9Sstevel@tonic-gate * Typedefs and data item definitions done here. 837c478bd9Sstevel@tonic-gate */ 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate typedef struct imps_fps imps_fps; /* MP floating pointer structure */ 867c478bd9Sstevel@tonic-gate typedef struct imps_cth imps_cth; /* MP configuration table header */ 877c478bd9Sstevel@tonic-gate typedef struct imps_processor imps_processor; 887c478bd9Sstevel@tonic-gate typedef struct imps_bus imps_bus; 897c478bd9Sstevel@tonic-gate typedef struct imps_ioapic imps_ioapic; 907c478bd9Sstevel@tonic-gate typedef struct imps_interrupt imps_interrupt; 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate /* 947c478bd9Sstevel@tonic-gate * Data structures defined here 957c478bd9Sstevel@tonic-gate */ 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate /* 987c478bd9Sstevel@tonic-gate * MP Floating Pointer Structure (fps) 997c478bd9Sstevel@tonic-gate * 1007c478bd9Sstevel@tonic-gate * Look at page 4-3 of the MP spec for the starting definitions of 1017c478bd9Sstevel@tonic-gate * this structure. 1027c478bd9Sstevel@tonic-gate */ 1037c478bd9Sstevel@tonic-gate struct imps_fps 1047c478bd9Sstevel@tonic-gate { 1057c478bd9Sstevel@tonic-gate unsigned sig; 1067c478bd9Sstevel@tonic-gate imps_cth *cth_ptr; 1077c478bd9Sstevel@tonic-gate unsigned char length; 1087c478bd9Sstevel@tonic-gate unsigned char spec_rev; 1097c478bd9Sstevel@tonic-gate unsigned char checksum; 1107c478bd9Sstevel@tonic-gate unsigned char feature_info[5]; 1117c478bd9Sstevel@tonic-gate }; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate /* 1147c478bd9Sstevel@tonic-gate * MP Configuration Table Header (cth) 1157c478bd9Sstevel@tonic-gate * 1167c478bd9Sstevel@tonic-gate * Look at page 4-5 of the MP spec for the starting definitions of 1177c478bd9Sstevel@tonic-gate * this structure. 1187c478bd9Sstevel@tonic-gate */ 1197c478bd9Sstevel@tonic-gate struct imps_cth 1207c478bd9Sstevel@tonic-gate { 1217c478bd9Sstevel@tonic-gate unsigned sig; 1227c478bd9Sstevel@tonic-gate unsigned short base_length; 1237c478bd9Sstevel@tonic-gate unsigned char spec_rev; 1247c478bd9Sstevel@tonic-gate unsigned char checksum; 1257c478bd9Sstevel@tonic-gate char oem_id[8]; 1267c478bd9Sstevel@tonic-gate char prod_id[12]; 1277c478bd9Sstevel@tonic-gate unsigned oem_table_ptr; 1287c478bd9Sstevel@tonic-gate unsigned short oem_table_size; 1297c478bd9Sstevel@tonic-gate unsigned short entry_count; 1307c478bd9Sstevel@tonic-gate unsigned lapic_addr; 1317c478bd9Sstevel@tonic-gate unsigned short extended_length; 1327c478bd9Sstevel@tonic-gate unsigned char extended_checksum; 1337c478bd9Sstevel@tonic-gate char reserved[1]; 1347c478bd9Sstevel@tonic-gate }; 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate /* 1377c478bd9Sstevel@tonic-gate * Base MP Configuration Table Types. They are sorted according to 1387c478bd9Sstevel@tonic-gate * type (i.e. all of type 0 come first, etc.). Look on page 4-6 for 1397c478bd9Sstevel@tonic-gate * the start of the descriptions. 1407c478bd9Sstevel@tonic-gate */ 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate struct imps_processor 1437c478bd9Sstevel@tonic-gate { 1447c478bd9Sstevel@tonic-gate unsigned char type; /* must be 0 */ 1457c478bd9Sstevel@tonic-gate unsigned char apic_id; 1467c478bd9Sstevel@tonic-gate unsigned char apic_ver; 1477c478bd9Sstevel@tonic-gate unsigned char flags; 1487c478bd9Sstevel@tonic-gate unsigned signature; 1497c478bd9Sstevel@tonic-gate unsigned features; 1507c478bd9Sstevel@tonic-gate char reserved[8]; 1517c478bd9Sstevel@tonic-gate }; 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate struct imps_bus 1547c478bd9Sstevel@tonic-gate { 1557c478bd9Sstevel@tonic-gate unsigned char type; /* must be 1 */ 1567c478bd9Sstevel@tonic-gate unsigned char id; 1577c478bd9Sstevel@tonic-gate char bus_type[6]; 1587c478bd9Sstevel@tonic-gate }; 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate struct imps_ioapic 1617c478bd9Sstevel@tonic-gate { 1627c478bd9Sstevel@tonic-gate unsigned char type; /* must be 2 */ 1637c478bd9Sstevel@tonic-gate unsigned char id; 1647c478bd9Sstevel@tonic-gate unsigned char ver; 1657c478bd9Sstevel@tonic-gate unsigned char flags; 1667c478bd9Sstevel@tonic-gate unsigned addr; 1677c478bd9Sstevel@tonic-gate }; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate struct imps_interrupt 1707c478bd9Sstevel@tonic-gate { 1717c478bd9Sstevel@tonic-gate unsigned char type; /* must be 3 or 4 */ 1727c478bd9Sstevel@tonic-gate unsigned char int_type; 1737c478bd9Sstevel@tonic-gate unsigned short flags; 1747c478bd9Sstevel@tonic-gate unsigned char source_bus_id; 1757c478bd9Sstevel@tonic-gate unsigned char source_bus_irq; 1767c478bd9Sstevel@tonic-gate unsigned char dest_apic_id; 1777c478bd9Sstevel@tonic-gate unsigned char dest_apic_intin; 1787c478bd9Sstevel@tonic-gate }; 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate /* 1827c478bd9Sstevel@tonic-gate * Exported globals here. 1837c478bd9Sstevel@tonic-gate */ 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate /* 1867c478bd9Sstevel@tonic-gate * This is the primary function for probing for Intel MPS 1.1/1.4 1877c478bd9Sstevel@tonic-gate * compatible hardware and BIOS information. While probing the CPUs 1887c478bd9Sstevel@tonic-gate * information returned from the BIOS, this also starts up each CPU 1897c478bd9Sstevel@tonic-gate * and gets it ready for use. 1907c478bd9Sstevel@tonic-gate * 1917c478bd9Sstevel@tonic-gate * Call this during the early stages of OS startup, before memory can 1927c478bd9Sstevel@tonic-gate * be messed up. 1937c478bd9Sstevel@tonic-gate * 1947c478bd9Sstevel@tonic-gate * Returns 1 if IMPS information was found and is valid, else 0. 1957c478bd9Sstevel@tonic-gate */ 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate int imps_probe (void); 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate /* 2017c478bd9Sstevel@tonic-gate * Defines that use variables 2027c478bd9Sstevel@tonic-gate */ 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate #define IMPS_LAPIC_READ(x) (*((volatile unsigned *) (imps_lapic_addr+(x)))) 2057c478bd9Sstevel@tonic-gate #define IMPS_LAPIC_WRITE(x, y) \ 2067c478bd9Sstevel@tonic-gate (*((volatile unsigned *) (imps_lapic_addr+(x))) = (y)) 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate #endif /* !_SMP_IMPS_H */ 209