acpitable.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:15k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1)
  3.  *
  4.  *  Copyright (C) 1999 Andrew Henroid
  5.  *  Copyright (C) 2001 Richard Schaal
  6.  *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  7.  *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
  8.  *  Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
  9.  *
  10.  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  11.  *
  12.  *  This program is free software; you can redistribute it and/or modify
  13.  *  it under the terms of the GNU General Public License as published by
  14.  *  the Free Software Foundation; either version 2 of the License, or
  15.  *  (at your option) any later version.
  16.  *
  17.  *  This program is distributed in the hope that it will be useful,
  18.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  *  GNU General Public License for more details.
  21.  *
  22.  *  You should have received a copy of the GNU General Public License
  23.  *  along with this program; if not, write to the Free Software
  24.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  25.  *
  26.  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  27.  *
  28.  * $Id: acpitable.c,v 1.7 2001/11/04 12:21:18 fenrus Exp $
  29.  */
  30. #include <linux/config.h>
  31. #include <linux/kernel.h>
  32. #include <linux/init.h>
  33. #include <linux/types.h>
  34. #include <linux/stddef.h>
  35. #include <linux/slab.h>
  36. #include <linux/pci.h>
  37. #include <asm/mpspec.h>
  38. #include <asm/io.h>
  39. #include <asm/apic.h>
  40. #include <asm/apicdef.h>
  41. #include <asm/page.h>
  42. #include <asm/pgtable.h>
  43. #include "acpitable.h"
  44. static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT];
  45. static unsigned char __init
  46. acpi_checksum(void *buffer, int length)
  47. {
  48. int i;
  49. unsigned char *bytebuffer;
  50. unsigned char sum = 0;
  51. if (!buffer || length <= 0)
  52. return 0;
  53. bytebuffer = (unsigned char *) buffer;
  54. for (i = 0; i < length; i++)
  55. sum += *(bytebuffer++);
  56. return sum;
  57. }
  58. static void __init
  59. acpi_print_table_header(acpi_table_header * header)
  60. {
  61. if (!header)
  62. return;
  63. printk(KERN_INFO "ACPI table found: %.4s v%d [%.6s %.8s %d.%d]n",
  64.        header->signature, header->revision, header->oem_id,
  65.        header->oem_table_id, header->oem_revision >> 16,
  66.        header->oem_revision & 0xffff);
  67. return;
  68. }
  69. /*******************************************************************************
  70.  *
  71.  * FUNCTION:    acpi_tb_scan_memory_for_rsdp
  72.  *
  73.  * PARAMETERS:  address       - Starting pointer for search
  74.  *              length        - Maximum length to search
  75.  *
  76.  * RETURN:      Pointer to the RSDP if found and valid, otherwise NULL.
  77.  *
  78.  * DESCRIPTION: Search a block of memory for the RSDP signature
  79.  *
  80.  ******************************************************************************/
  81. static void *__init
  82. acpi_tb_scan_memory_for_rsdp(void *address, int length)
  83. {
  84. u32 offset;
  85. if (length <= 0)
  86. return NULL;
  87. /* Search from given start addr for the requested length  */
  88. offset = 0;
  89. while (offset < length) {
  90. /* The signature must match and the checksum must be correct */
  91. if (strncmp(address, RSDP_SIG, sizeof(RSDP_SIG) - 1) == 0 &&
  92.     acpi_checksum(address, RSDP_CHECKSUM_LENGTH) == 0) {
  93. /* If so, we have found the RSDP */
  94. printk(KERN_INFO "ACPI: RSDP located at physical address %pn",
  95.        address);
  96. return address;
  97. }
  98. offset += RSDP_SCAN_STEP;
  99. address += RSDP_SCAN_STEP;
  100. }
  101. /* Searched entire block, no RSDP was found */
  102. printk(KERN_INFO "ACPI: Searched entire block, no RSDP was found.n");
  103. return NULL;
  104. }
  105. /*******************************************************************************
  106.  *
  107.  * FUNCTION:    acpi_find_root_pointer
  108.  *
  109.  * PARAMETERS:  none
  110.  *
  111.  * RETURN:      physical address of the RSDP 
  112.  *
  113.  * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
  114.  *              pointer structure.  If it is found, set *RSDP to point to it.
  115.  *
  116.  *              NOTE: The RSDP must be either in the first 1_k of the Extended
  117.  *              BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section
  118.  *              5.2.2; assertion #421).
  119.  *
  120.  ******************************************************************************/
  121. static struct acpi_table_rsdp * __init
  122. acpi_find_root_pointer(void)
  123. {
  124. struct acpi_table_rsdp * rsdp;
  125. /*
  126.  * Physical address is given
  127.  */
  128. /*
  129.  * Region 1) Search EBDA (low memory) paragraphs
  130.  */
  131. rsdp = acpi_tb_scan_memory_for_rsdp(__va(LO_RSDP_WINDOW_BASE),
  132.  LO_RSDP_WINDOW_SIZE);
  133. if (rsdp)
  134. return rsdp;
  135. /*
  136.  * Region 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
  137.  */
  138. rsdp = acpi_tb_scan_memory_for_rsdp(__va(HI_RSDP_WINDOW_BASE),
  139.        HI_RSDP_WINDOW_SIZE);
  140.      
  141. if (rsdp)
  142. return rsdp;
  143. printk(KERN_ERR "ACPI: System description tables not foundn");
  144. return NULL;
  145. }
  146. /*
  147.  * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
  148.  * to map the target physical address. The problem is that set_fixmap()
  149.  * provides a single page, and it is possible that the page is not
  150.  * sufficient.
  151.  * By using this area, we can map up to MAX_IO_APICS pages temporarily,
  152.  * i.e. until the next __va_range() call.
  153.  *
  154.  * Important Safety Note:  The fixed I/O APIC page numbers are *subtracted*
  155.  * from the fixed base.  That's why we start at FIX_IO_APIC_BASE_END and
  156.  * count idx down while incrementing the phys address.
  157.  */
  158. static __init char *
  159. __va_range(unsigned long phys, unsigned long size)
  160. {
  161. unsigned long base, offset, mapped_size;
  162. int idx;
  163. offset = phys & (PAGE_SIZE - 1);
  164. mapped_size = PAGE_SIZE - offset;
  165. set_fixmap(FIX_IO_APIC_BASE_END, phys);
  166. base = fix_to_virt(FIX_IO_APIC_BASE_END);
  167. dprintk("__va_range(0x%lx, 0x%lx): idx=%d mapped at %lxn", phys, size,
  168. FIX_IO_APIC_BASE_END, base);
  169. /*
  170.  * Most cases can be covered by the below.
  171.  */
  172. idx = FIX_IO_APIC_BASE_END;
  173. while (mapped_size < size) {
  174. if (--idx < FIX_IO_APIC_BASE_0)
  175. return 0; /* cannot handle this */
  176. phys += PAGE_SIZE;
  177. set_fixmap(idx, phys);
  178. mapped_size += PAGE_SIZE;
  179. }
  180. return ((unsigned char *) base + offset);
  181. }
  182. static int __init acpi_tables_init(void)
  183. {
  184. int result = -ENODEV;
  185. acpi_table_header *header = NULL;
  186. struct acpi_table_rsdp *rsdp = NULL;
  187. struct acpi_table_rsdt *rsdt = NULL;
  188. struct acpi_table_rsdt saved_rsdt;
  189. int tables = 0;
  190. int type = 0;
  191. int i = 0;
  192. rsdp = (struct acpi_table_rsdp *) acpi_find_root_pointer();
  193. if (!rsdp)
  194. return -ENODEV;
  195. printk(KERN_INFO "%.8s v%d [%.6s]n", rsdp->signature, rsdp->revision,
  196.        rsdp->oem_id);
  197.        
  198. if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) {
  199. printk(KERN_WARNING "RSDP table signature incorrectn");
  200. return -EINVAL;
  201. }
  202. rsdt = (struct acpi_table_rsdt *)
  203.     __va_range(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt));
  204. if (!rsdt) {
  205. printk(KERN_WARNING "ACPI: Invalid root system description tables (RSDT)n");
  206. return -ENODEV;
  207. }
  208. header = & rsdt->header;
  209. acpi_print_table_header(header);
  210. if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) {
  211. printk(KERN_WARNING "ACPI: RSDT signature incorrectn");
  212. return -ENODEV;
  213. }
  214. /* 
  215.  * The number of tables is computed by taking the 
  216.  * size of all entries (header size minus total 
  217.  * size of RSDT) divided by the size of each entry
  218.  * (4-byte table pointers).
  219.  */
  220. tables = (header->length - sizeof(acpi_table_header)) / 4;
  221.     
  222. memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
  223. if (saved_rsdt.header.length > sizeof(saved_rsdt)) {
  224. printk(KERN_WARNING "ACPI: Too big length in RSDT: %dn", saved_rsdt.header.length);
  225. return -ENODEV;
  226. }
  227. for (i = 0; i < tables; i++) {
  228. /* Map in header, then map in full table length. */
  229. header = (acpi_table_header *)
  230.     __va_range(saved_rsdt.entry[i],
  231.        sizeof(acpi_table_header));
  232. if (!header)
  233. break;
  234. header = (acpi_table_header *)
  235.     __va_range(saved_rsdt.entry[i], header->length);
  236. if (!header)
  237. break;
  238. acpi_print_table_header(header);
  239. if (acpi_checksum(header,header->length)) {
  240. printk(KERN_WARNING "ACPI %s has invalid checksumn", 
  241. acpi_table_signatures[i]);
  242. continue;
  243. }
  244. for (type = 0; type < ACPI_TABLE_COUNT; type++)
  245. if (!strncmp((char *) &header->signature,
  246.      acpi_table_signatures[type],strlen(acpi_table_signatures[type])))
  247. break;
  248. if (type >= ACPI_TABLE_COUNT) {
  249. printk(KERN_WARNING "ACPI: Unsupported table %.4sn",
  250.        header->signature);
  251. continue;
  252. }
  253. if (!acpi_boot_ops[type])
  254. continue;
  255. result = acpi_boot_ops[type] (header,
  256.  (unsigned long) saved_rsdt.
  257.  entry[i]);
  258. }
  259. return result;
  260. }
  261. static int total_cpus __initdata = 0;
  262. int have_acpi_tables;
  263. extern void __init MP_processor_info(struct mpc_config_processor *);
  264. static void __init
  265. acpi_parse_lapic(struct acpi_table_lapic *local_apic)
  266. {
  267. struct mpc_config_processor proc_entry;
  268. int ix = 0;
  269. if (!local_apic)
  270. return;
  271. printk(KERN_INFO "LAPIC (acpi_id[0x%04x] id[0x%x] enabled[%d])n",
  272. local_apic->acpi_id, local_apic->id, local_apic->flags.enabled);
  273. printk(KERN_INFO "CPU %d (0x%02x00)", total_cpus, local_apic->id);
  274. if (local_apic->flags.enabled) {
  275. printk(" enabled");
  276. ix = local_apic->id;
  277. if (ix >= MAX_APICS) {
  278. printk(KERN_WARNING
  279.        "Processor #%d INVALID - (Max ID: %d).n", ix,
  280.        MAX_APICS);
  281. return;
  282. }
  283. /* 
  284.  * Fill in the info we want to save.  Not concerned about 
  285.  * the processor ID.  Processor features aren't present in 
  286.  * the table.
  287.  */
  288. proc_entry.mpc_type = MP_PROCESSOR;
  289. proc_entry.mpc_apicid = local_apic->id;
  290. proc_entry.mpc_cpuflag = CPU_ENABLED;
  291. if (proc_entry.mpc_apicid == boot_cpu_physical_apicid) {
  292. printk(" (BSP)");
  293. proc_entry.mpc_cpuflag |= CPU_BOOTPROCESSOR;
  294. }
  295. proc_entry.mpc_cpufeature =
  296.     (boot_cpu_data.x86 << 8) | 
  297.     (boot_cpu_data.x86_model << 4) | 
  298.      boot_cpu_data.x86_mask;
  299. proc_entry.mpc_featureflag = boot_cpu_data.x86_capability[0];
  300. proc_entry.mpc_reserved[0] = 0;
  301. proc_entry.mpc_reserved[1] = 0;
  302. proc_entry.mpc_apicver = 0x10; /* integrated APIC */
  303. MP_processor_info(&proc_entry);
  304. } else {
  305. printk(" disabled");
  306. }
  307. printk("n");
  308. total_cpus++;
  309. return;
  310. }
  311. static void __init
  312. acpi_parse_ioapic(struct acpi_table_ioapic *ioapic)
  313. {
  314. if (!ioapic)
  315. return;
  316. printk(KERN_INFO
  317.        "IOAPIC (id[0x%x] address[0x%x] global_irq_base[0x%x])n",
  318.        ioapic->id, ioapic->address, ioapic->global_irq_base);
  319. if (nr_ioapics >= MAX_IO_APICS) {
  320. printk(KERN_WARNING
  321.        "Max # of I/O APICs (%d) exceeded (found %d).n",
  322.        MAX_IO_APICS, nr_ioapics);
  323. /* panic("Recompile kernel with bigger MAX_IO_APICS!n");   */
  324. }
  325. }
  326. /* Interrupt source overrides inform the machine about exceptions
  327.    to the normal "PIC" mode interrupt routing */
  328.    
  329. static void __init
  330. acpi_parse_int_src_ovr(struct acpi_table_int_src_ovr *intsrc)
  331. {
  332. if (!intsrc)
  333. return;
  334. printk(KERN_INFO
  335.        "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])n",
  336.        intsrc->bus, intsrc->bus_irq, intsrc->global_irq,
  337.        intsrc->flags.polarity, intsrc->flags.trigger);
  338. }
  339. /*
  340.  * At this point, we look at the interrupt assignment entries in the MPS
  341.  * table.
  342.  */ 
  343.  
  344. static void __init acpi_parse_nmi_src(struct acpi_table_nmi_src *nmisrc)
  345. {
  346. if (!nmisrc)
  347. return;
  348. printk(KERN_INFO
  349.        "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])n",
  350.        nmisrc->flags.polarity, nmisrc->flags.trigger,
  351.        nmisrc->global_irq);
  352. }
  353. static void __init
  354. acpi_parse_lapic_nmi(struct acpi_table_lapic_nmi *localnmi)
  355. {
  356. if (!localnmi)
  357. return;
  358. printk(KERN_INFO
  359.        "LAPIC_NMI (acpi_id[0x%04x] polarity[0x%x] trigger[0x%x] lint[0x%x])n",
  360.        localnmi->acpi_id, localnmi->flags.polarity,
  361.        localnmi->flags.trigger, localnmi->lint);
  362. }
  363. static void __init
  364. acpi_parse_lapic_addr_ovr(struct acpi_table_lapic_addr_ovr *lapic_addr_ovr)
  365. {
  366. if (!lapic_addr_ovr)
  367. return;
  368. printk(KERN_INFO "LAPIC_ADDR_OVR (address[0x%lx])n",
  369.        (unsigned long) lapic_addr_ovr->address);
  370. }
  371. static void __init
  372. acpi_parse_plat_int_src(struct acpi_table_plat_int_src *plintsrc)
  373. {
  374. if (!plintsrc)
  375. return;
  376. printk(KERN_INFO
  377.        "PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]n",
  378.        plintsrc->flags.polarity, plintsrc->flags.trigger,
  379.        plintsrc->type, plintsrc->id, plintsrc->eid,
  380.        plintsrc->iosapic_vector, plintsrc->global_irq);
  381. }
  382. static int __init
  383. acpi_parse_madt(acpi_table_header * header, unsigned long phys)
  384. {
  385. struct acpi_table_madt *madt;     
  386. acpi_madt_entry_header *entry_header;
  387. int table_size;
  388. madt = (struct acpi_table_madt *) __va_range(phys, header->length);
  389. if (!madt)
  390. return -EINVAL;
  391. table_size = (int) (header->length - sizeof(*madt));
  392. entry_header =
  393.     (acpi_madt_entry_header *) ((void *) madt + sizeof(*madt));
  394. while (entry_header && (table_size > 0)) {
  395. switch (entry_header->type) {
  396. case ACPI_MADT_LAPIC:
  397. acpi_parse_lapic((struct acpi_table_lapic *)
  398.  entry_header);
  399. break;
  400. case ACPI_MADT_IOAPIC:
  401. acpi_parse_ioapic((struct acpi_table_ioapic *)
  402.   entry_header);
  403. break;
  404. case ACPI_MADT_INT_SRC_OVR:
  405. acpi_parse_int_src_ovr((struct acpi_table_int_src_ovr *)
  406.        entry_header);
  407. break;
  408. case ACPI_MADT_NMI_SRC:
  409. acpi_parse_nmi_src((struct acpi_table_nmi_src *)
  410.    entry_header);
  411. break;
  412. case ACPI_MADT_LAPIC_NMI:
  413. acpi_parse_lapic_nmi((struct acpi_table_lapic_nmi *)
  414.      entry_header);
  415. break;
  416. case ACPI_MADT_LAPIC_ADDR_OVR:
  417. acpi_parse_lapic_addr_ovr((struct
  418.    acpi_table_lapic_addr_ovr *)
  419.   entry_header);
  420. break;
  421. case ACPI_MADT_PLAT_INT_SRC:
  422. acpi_parse_plat_int_src((struct acpi_table_plat_int_src
  423.  *) entry_header);
  424. break;
  425. default:
  426. printk(KERN_WARNING
  427.        "Unsupported MADT entry type 0x%xn",
  428.        entry_header->type);
  429. break;
  430. }
  431. table_size -= entry_header->length;
  432. entry_header =
  433.     (acpi_madt_entry_header *) ((void *) entry_header +
  434. entry_header->length);
  435. }
  436. if (!total_cpus) {
  437. printk("ACPI: No Processors found in the APCI table.n");
  438. return -EINVAL;
  439. }
  440. printk(KERN_INFO "%d CPUs totaln", total_cpus);
  441. if (madt->lapic_address)
  442. mp_lapic_addr = madt->lapic_address;
  443. else
  444. mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
  445. printk(KERN_INFO "Local APIC address %xn", madt->lapic_address);
  446. return 0;
  447. }
  448. extern int enable_acpi_smp_table;
  449. /*
  450.  * Configure the processor info using MADT in the ACPI tables. If we fail to
  451.  * configure that, then we use the MPS tables.
  452.  */
  453. void __init
  454. config_acpi_tables(void)
  455. {
  456. memset(&acpi_boot_ops, 0, sizeof(acpi_boot_ops));
  457. acpi_boot_ops[ACPI_APIC] = acpi_parse_madt;
  458. /*
  459.  * Only do this when requested, either because of CPU/Bios type or from the command line
  460.  */
  461. if (enable_acpi_smp_table && !acpi_tables_init()) {
  462. have_acpi_tables = 1;
  463. printk("Enabling the CPU's according to the ACPI tablen");
  464. }
  465. }