debuggers.hg

view tools/firmware/hvmloader/acpi_madt.c @ 10986:49dcd838b7df

[HVMLOADER] HVM loader initialises hypercall shim and uses
it to interrogate Xen version information. Also add support
for HVM hypercall execution on 64-bit host.

Signed-off-by: Steven Smith <ssmith@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Aug 04 20:30:12 2006 +0100 (2006-08-04)
parents ae245d35457b
children 1bf4f15c5141
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"
23 #include "util.h"
24 #include <xen/hvm/hvm_info_table.h>
26 #define NULL ((void*)0)
28 static struct hvm_info_table *table = NULL;
30 static int validate_hvm_info(struct hvm_info_table *t)
31 {
32 char signature[] = "HVM INFO";
33 uint8_t *ptr = (uint8_t *)t;
34 uint8_t sum = 0;
35 int i;
37 /* strncmp(t->signature, "HVM INFO", 8) */
38 for (i = 0; i < 8; i++) {
39 if (signature[i] != t->signature[i]) {
40 puts("Bad hvm info signature\n");
41 return 0;
42 }
43 }
45 for (i = 0; i < t->length; i++)
46 sum += ptr[i];
48 return (sum == 0);
49 }
51 /* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
52 struct hvm_info_table *
53 get_hvm_info_table(void)
54 {
55 struct hvm_info_table *t;
57 if (table != NULL)
58 return table;
60 t = (struct hvm_info_table *)HVM_INFO_PADDR;
62 if (!validate_hvm_info(t)) {
63 puts("Bad hvm info table\n");
64 return NULL;
65 }
67 table = t;
69 return table;
70 }
72 int
73 get_vcpu_nr(void)
74 {
75 struct hvm_info_table *t = get_hvm_info_table();
76 return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
77 }
79 int
80 get_acpi_enabled(void)
81 {
82 struct hvm_info_table *t = get_hvm_info_table();
83 return (t ? t->acpi_enabled : 0); /* default no acpi */
84 }
87 static void *
88 acpi_madt_get_madt(unsigned char *acpi_start)
89 {
90 ACPI_2_0_RSDP *rsdp=NULL;
91 ACPI_2_0_RSDT *rsdt=NULL;
92 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
94 rsdp = (ACPI_2_0_RSDP *)(acpi_start + sizeof(ACPI_2_0_FACS));
95 if (rsdp->Signature != ACPI_2_0_RSDP_SIGNATURE) {
96 puts("Bad RSDP signature\n");
97 return NULL;
98 }
100 rsdt= (ACPI_2_0_RSDT *)
101 (acpi_start + rsdp->RsdtAddress - ACPI_PHYSICAL_ADDRESS);
102 if (rsdt->Header.Signature != ACPI_2_0_RSDT_SIGNATURE) {
103 puts("Bad RSDT signature\n");
104 return NULL;
105 }
107 madt = (ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *)
108 ( acpi_start+ rsdt->Entry[1] - ACPI_PHYSICAL_ADDRESS);
109 if (madt->Header.Header.Signature !=
110 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
111 puts("Bad MADT signature \n");
112 return NULL;
113 }
115 return madt;
116 }
118 static void
119 set_checksum(void *start, int checksum_offset, int len)
120 {
121 unsigned char sum = 0;
122 unsigned char *ptr;
124 ptr = start;
125 ptr[checksum_offset] = 0;
126 while (len--)
127 sum += *ptr++;
129 ptr = start;
130 ptr[checksum_offset] = -sum;
131 }
133 static int
134 acpi_madt_set_local_apics(
135 int nr_vcpu,
136 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt)
137 {
138 int i;
140 if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt)
141 return -1;
143 for (i = 0; i < nr_vcpu; i++) {
144 madt->LocalApic[i].Type = ACPI_PROCESSOR_LOCAL_APIC;
145 madt->LocalApic[i].Length = sizeof (ACPI_LOCAL_APIC_STRUCTURE);
146 madt->LocalApic[i].AcpiProcessorId = i;
147 madt->LocalApic[i].ApicId = i;
148 madt->LocalApic[i].Flags = 1;
149 }
151 madt->Header.Header.Length =
152 sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
153 (MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE);
155 return 0;
156 }
158 #define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
160 int acpi_madt_update(unsigned char *acpi_start)
161 {
162 int rc;
163 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
165 madt = acpi_madt_get_madt(acpi_start);
166 if (!madt)
167 return -1;
169 rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
170 if (rc != 0)
171 return rc;
173 set_checksum(
174 madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
175 madt->Header.Header.Length);
177 return 0;
178 }
180 /*
181 * Local variables:
182 * c-file-style: "linux"
183 * indent-tabs-mode: t
184 * c-indent-level: 8
185 * c-basic-offset: 8
186 * tab-width: 8
187 * End:
188 */