ia64/xen-unstable

view tools/firmware/vmxassist/acpi_madt.c @ 8492:9fc306e40a7c

Move public hvm interfaces into xen/include/public/hvm.
Add new header hvm_info_table.h for defining location and
contents of acpi-style hvm_info_table. Remove duplicate
definition in vmxassist/acpi_madt.c.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Jan 03 14:58:34 2006 +0100 (2006-01-03)
parents 412995d28a07
children b29954d81e6d
line source
1 /*
2 * acpi_madt.c: Update ACPI MADT table for multiple processor guest.
3 *
4 * Yu Ke, ke.yu@intel.com
5 * Copyright (c) 2005, Intel Corporation.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 * Place - Suite 330, Boston, MA 02111-1307 USA.
19 */
21 #include "../acpi/acpi2_0.h"
22 #include "../acpi/acpi_madt.h"
24 #include <xen/hvm/hvm_info_table.h>
26 #define NULL ((void*)0)
28 extern int puts(const char *s);
30 static struct hvm_info_table *table = NULL;
32 static int validate_hvm_info(struct hvm_info_table *t)
33 {
34 char signature[] = "HVM INFO";
35 uint8_t *ptr = (uint8_t *)t;
36 uint8_t sum = 0;
37 int i;
39 /* strncmp(t->signature, "HVM INFO", 8) */
40 for (i = 0; i < 8; i++) {
41 if (signature[i] != t->signature[i]) {
42 puts("Bad hvm info signature\n");
43 return 0;
44 }
45 }
47 for (i = 0; i < t->length; i++)
48 sum += ptr[i];
50 return (sum == 0);
51 }
53 /* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
54 static struct hvm_info_table *
55 get_hvm_info_table(void)
56 {
57 struct hvm_info_table *t;
58 int i;
60 if (table != NULL)
61 return table;
63 t = (struct hvm_info_table *)HVM_INFO_PADDR;
65 if (!validate_hvm_info(t)) {
66 puts("Bad hvm info table\n");
67 return NULL;
68 }
70 table = t;
72 return table;
73 }
75 int
76 get_vcpu_nr(void)
77 {
78 struct hvm_info_table *t = get_hvm_info_table();
79 return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
80 }
82 int
83 get_acpi_enabled(void)
84 {
85 struct hvm_info_table *t = get_hvm_info_table();
86 return (t ? t->acpi_enabled : 0); /* default no acpi */
87 }
89 static void *
90 acpi_madt_get_madt(unsigned char *acpi_start)
91 {
92 ACPI_2_0_RSDP *rsdp=NULL;
93 ACPI_2_0_RSDT *rsdt=NULL;
94 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
96 rsdp = (ACPI_2_0_RSDP *)(acpi_start + sizeof(ACPI_2_0_FACS));
97 if (rsdp->Signature != ACPI_2_0_RSDP_SIGNATURE) {
98 puts("Bad RSDP signature\n");
99 return NULL;
100 }
102 rsdt= (ACPI_2_0_RSDT *)
103 (acpi_start + rsdp->RsdtAddress - ACPI_PHYSICAL_ADDRESS);
104 if (rsdt->Header.Signature != ACPI_2_0_RSDT_SIGNATURE) {
105 puts("Bad RSDT signature\n");
106 return NULL;
107 }
109 madt = (ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *)
110 ( acpi_start+ rsdt->Entry[1] - ACPI_PHYSICAL_ADDRESS);
111 if (madt->Header.Header.Signature !=
112 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
113 puts("Bad MADT signature \n");
114 return NULL;
115 }
117 return madt;
118 }
120 static void
121 set_checksum(void *start, int checksum_offset, int len)
122 {
123 unsigned char sum = 0;
124 unsigned char *ptr;
126 ptr = start;
127 ptr[checksum_offset] = 0;
128 while (len--)
129 sum += *ptr++;
131 ptr = start;
132 ptr[checksum_offset] = -sum;
133 }
135 static int
136 acpi_madt_set_local_apics(
137 int nr_vcpu,
138 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt)
139 {
140 int i;
142 if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt)
143 return -1;
145 for (i = 0; i < nr_vcpu; i++) {
146 madt->LocalApic[i].Type = ACPI_PROCESSOR_LOCAL_APIC;
147 madt->LocalApic[i].Length = sizeof (ACPI_LOCAL_APIC_STRUCTURE);
148 madt->LocalApic[i].AcpiProcessorId = i;
149 madt->LocalApic[i].ApicId = i;
150 madt->LocalApic[i].Flags = 1;
151 }
153 madt->Header.Header.Length =
154 sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
155 (MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE);
157 return 0;
158 }
160 #define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
162 int acpi_madt_update(unsigned char *acpi_start)
163 {
164 int rc;
165 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
167 madt = acpi_madt_get_madt(acpi_start);
168 if (!madt)
169 return -1;
171 rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
172 if (rc != 0)
173 return rc;
175 set_checksum(
176 madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
177 madt->Header.Header.Length);
179 return 0;
180 }
182 /*
183 * Local variables:
184 * c-file-style: "linux"
185 * indent-tabs-mode: t
186 * c-indent-level: 8
187 * c-basic-offset: 8
188 * tab-width: 8
189 * End:
190 */