direct-io.hg

view tools/firmware/vmxassist/acpi_madt.c @ 7477:5a7baecb1c70

Fix an issue for passing arguement from control panel to deivce model
for some arguemnt like 'localtime', 'isa', device model need an argument
"-localtime", instead of "-localtime 1"
Signed-off-by: Xiaofeng Ling <xiaofeng.ling@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun Oct 23 16:51:47 2005 +0100 (2005-10-23)
parents e398a9797c4c
children 121ff5042eb3
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 */
20 #include "../acpi/acpi2_0.h"
21 #include "../acpi/acpi_madt.h"
23 #define NULL ((void*)0)
25 extern int puts(const char *s);
27 #define VCPU_NR_PAGE 0x0009F000
28 #define VCPU_NR_OFFSET 0x00000800
29 #define VCPU_MAGIC 0x76637075 /* "vcpu" */
31 /* xc_vmx_builder wrote vcpu block at 0x9F800. Return it. */
32 static int
33 get_vcpu_nr(void)
34 {
35 unsigned int *vcpus;
37 vcpus = (unsigned int *)(VCPU_NR_PAGE + VCPU_NR_OFFSET);
38 if (vcpus[0] != VCPU_MAGIC) {
39 puts("Bad vcpus magic, set vcpu number to 1 by default.\n");
40 return 1;
41 }
43 return vcpus[1];
44 }
46 static void *
47 acpi_madt_get_madt(unsigned char *acpi_start)
48 {
49 ACPI_2_0_RSDP *rsdp=NULL;
50 ACPI_2_0_RSDT *rsdt=NULL;
51 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
53 rsdp = (ACPI_2_0_RSDP *)(acpi_start + sizeof(ACPI_2_0_FACS));
54 if (rsdp->Signature != ACPI_2_0_RSDP_SIGNATURE) {
55 puts("Bad RSDP signature\n");
56 return NULL;
57 }
59 rsdt= (ACPI_2_0_RSDT *)
60 (acpi_start + rsdp->RsdtAddress - ACPI_PHYSICAL_ADDRESS);
61 if (rsdt->Header.Signature != ACPI_2_0_RSDT_SIGNATURE) {
62 puts("Bad RSDT signature\n");
63 return NULL;
64 }
66 madt = (ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *)
67 ( acpi_start+ rsdt->Entry[1] - ACPI_PHYSICAL_ADDRESS);
68 if (madt->Header.Header.Signature !=
69 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
70 puts("Bad MADT signature \n");
71 return NULL;
72 }
74 return madt;
75 }
77 static void
78 set_checksum(void *start, int checksum_offset, int len)
79 {
80 unsigned char sum = 0;
81 unsigned char *ptr;
83 ptr = start;
84 ptr[checksum_offset] = 0;
85 while (len--)
86 sum += *ptr++;
88 ptr = start;
89 ptr[checksum_offset] = -sum;
90 }
92 static int
93 acpi_madt_set_local_apics(
94 int nr_vcpu,
95 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt)
96 {
97 int i;
99 if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt)
100 return -1;
102 for (i = 0; i < nr_vcpu; i++) {
103 madt->LocalApic[i].Type = ACPI_PROCESSOR_LOCAL_APIC;
104 madt->LocalApic[i].Length = sizeof (ACPI_LOCAL_APIC_STRUCTURE);
105 madt->LocalApic[i].AcpiProcessorId = i;
106 madt->LocalApic[i].ApicId = i;
107 madt->LocalApic[i].Flags = 1;
108 }
110 madt->Header.Header.Length =
111 sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
112 (MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE);
114 return 0;
115 }
117 #define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
119 int acpi_madt_update(unsigned char *acpi_start)
120 {
121 int rc;
122 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
124 madt = acpi_madt_get_madt(acpi_start);
125 if (!madt)
126 return -1;
128 rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
129 if (rc != 0)
130 return rc;
132 set_checksum(
133 madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
134 madt->Header.Header.Length);
136 return 0;
137 }
139 /*
140 * Local variables:
141 * c-file-style: "linux"
142 * indent-tabs-mode: t
143 * c-indent-level: 8
144 * c-basic-offset: 8
145 * tab-width: 8
146 * End:
147 */