direct-io.hg

view xen/arch/x86/platform_hypercall.c @ 15409:11bf94b2d51a

Rename ddc_info -> vbeddc_info in interface header.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Jun 20 19:31:37 2007 +0100 (2007-06-20)
parents cf846f4d756f
children
line source
1 /******************************************************************************
2 * platform_hypercall.c
3 *
4 * Hardware platform operations. Intended for use by domain-0 kernel.
5 *
6 * Copyright (c) 2002-2006, K Fraser
7 */
9 #include <xen/config.h>
10 #include <xen/types.h>
11 #include <xen/lib.h>
12 #include <xen/mm.h>
13 #include <xen/sched.h>
14 #include <xen/domain.h>
15 #include <xen/event.h>
16 #include <xen/domain_page.h>
17 #include <xen/trace.h>
18 #include <xen/console.h>
19 #include <xen/iocap.h>
20 #include <xen/guest_access.h>
21 #include <asm/current.h>
22 #include <public/platform.h>
23 #include <asm/edd.h>
24 #include <asm/mtrr.h>
25 #include "cpu/mtrr/mtrr.h"
27 extern uint16_t boot_edid_caps;
28 extern uint8_t boot_edid_info[];
30 #ifndef COMPAT
31 typedef long ret_t;
32 DEFINE_SPINLOCK(xenpf_lock);
33 # undef copy_from_compat
34 # define copy_from_compat copy_from_guest
35 # undef copy_to_compat
36 # define copy_to_compat copy_to_guest
37 #else
38 extern spinlock_t xenpf_lock;
39 #endif
41 ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
42 {
43 ret_t ret = 0;
44 struct xen_platform_op curop, *op = &curop;
46 if ( !IS_PRIV(current->domain) )
47 return -EPERM;
49 if ( copy_from_guest(op, u_xenpf_op, 1) )
50 return -EFAULT;
52 if ( op->interface_version != XENPF_INTERFACE_VERSION )
53 return -EACCES;
55 spin_lock(&xenpf_lock);
57 switch ( op->cmd )
58 {
59 case XENPF_settime:
60 {
61 do_settime(op->u.settime.secs,
62 op->u.settime.nsecs,
63 op->u.settime.system_time);
64 ret = 0;
65 }
66 break;
68 case XENPF_add_memtype:
69 {
70 ret = mtrr_add_page(
71 op->u.add_memtype.mfn,
72 op->u.add_memtype.nr_mfns,
73 op->u.add_memtype.type,
74 1);
75 if ( ret >= 0 )
76 {
77 op->u.add_memtype.handle = 0;
78 op->u.add_memtype.reg = ret;
79 ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0;
80 if ( ret != 0 )
81 mtrr_del_page(ret, 0, 0);
82 }
83 }
84 break;
86 case XENPF_del_memtype:
87 {
88 if (op->u.del_memtype.handle == 0
89 /* mtrr/main.c otherwise does a lookup */
90 && (int)op->u.del_memtype.reg >= 0)
91 {
92 ret = mtrr_del_page(op->u.del_memtype.reg, 0, 0);
93 if ( ret > 0 )
94 ret = 0;
95 }
96 else
97 ret = -EINVAL;
98 }
99 break;
101 case XENPF_read_memtype:
102 {
103 unsigned long mfn;
104 unsigned int nr_mfns;
105 mtrr_type type;
107 ret = -EINVAL;
108 if ( op->u.read_memtype.reg < num_var_ranges )
109 {
110 mtrr_if->get(op->u.read_memtype.reg, &mfn, &nr_mfns, &type);
111 op->u.read_memtype.mfn = mfn;
112 op->u.read_memtype.nr_mfns = nr_mfns;
113 op->u.read_memtype.type = type;
114 ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0;
115 }
116 }
117 break;
119 case XENPF_microcode_update:
120 {
121 extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len);
122 #ifndef COMPAT
123 ret = microcode_update(op->u.microcode.data,
124 op->u.microcode.length);
125 #else
126 XEN_GUEST_HANDLE(void) data;
128 guest_from_compat_handle(data, op->u.microcode.data);
129 ret = microcode_update(data, op->u.microcode.length);
130 #endif
131 }
132 break;
134 case XENPF_platform_quirk:
135 {
136 extern int opt_noirqbalance;
137 int quirk_id = op->u.platform_quirk.quirk_id;
138 switch ( quirk_id )
139 {
140 case QUIRK_NOIRQBALANCING:
141 printk("Platform quirk -- Disabling IRQ balancing/affinity.\n");
142 opt_noirqbalance = 1;
143 setup_ioapic_dest();
144 break;
145 case QUIRK_IOAPIC_BAD_REGSEL:
146 case QUIRK_IOAPIC_GOOD_REGSEL:
147 #ifndef sis_apic_bug
148 sis_apic_bug = (quirk_id == QUIRK_IOAPIC_BAD_REGSEL);
149 dprintk(XENLOG_INFO, "Domain 0 says that IO-APIC REGSEL is %s\n",
150 sis_apic_bug ? "bad" : "good");
151 #else
152 BUG_ON(sis_apic_bug != (quirk_id == QUIRK_IOAPIC_BAD_REGSEL));
153 #endif
154 break;
155 default:
156 ret = -EINVAL;
157 break;
158 }
159 }
160 break;
162 case XENPF_firmware_info:
163 switch ( op->u.firmware_info.type )
164 {
165 case XEN_FW_DISK_INFO: {
166 const struct edd_info *info;
167 u16 length;
169 ret = -ESRCH;
170 if ( op->u.firmware_info.index >= bootsym(boot_edd_info_nr) )
171 break;
173 info = bootsym(boot_edd_info) + op->u.firmware_info.index;
175 /* Transfer the EDD info block. */
176 ret = -EFAULT;
177 if ( copy_from_compat(&length, op->u.firmware_info.u.
178 disk_info.edd_params, 1) )
179 break;
180 if ( length > info->edd_device_params.length )
181 length = info->edd_device_params.length;
182 if ( copy_to_compat(op->u.firmware_info.u.disk_info.edd_params,
183 (u8 *)&info->edd_device_params,
184 length) )
185 break;
186 if ( copy_to_compat(op->u.firmware_info.u.disk_info.edd_params,
187 &length, 1) )
188 break;
190 /* Transfer miscellaneous other information values. */
191 #define C(x) op->u.firmware_info.u.disk_info.x = info->x
192 C(device);
193 C(version);
194 C(interface_support);
195 C(legacy_max_cylinder);
196 C(legacy_max_head);
197 C(legacy_sectors_per_track);
198 #undef C
200 ret = (copy_field_to_guest(u_xenpf_op, op,
201 u.firmware_info.u.disk_info)
202 ? -EFAULT : 0);
203 break;
204 }
205 case XEN_FW_DISK_MBR_SIGNATURE: {
206 const struct mbr_signature *sig;
208 ret = -ESRCH;
209 if ( op->u.firmware_info.index >= bootsym(boot_mbr_signature_nr) )
210 break;
212 sig = bootsym(boot_mbr_signature) + op->u.firmware_info.index;
214 op->u.firmware_info.u.disk_mbr_signature.device = sig->device;
215 op->u.firmware_info.u.disk_mbr_signature.mbr_signature =
216 sig->signature;
218 ret = (copy_field_to_guest(u_xenpf_op, op,
219 u.firmware_info.u.disk_mbr_signature)
220 ? -EFAULT : 0);
221 break;
222 }
223 case XEN_FW_VBEDDC_INFO:
224 ret = -ESRCH;
225 if ( op->u.firmware_info.index != 0 )
226 break;
227 if ( *(u32 *)bootsym(boot_edid_info) == 0x13131313 )
228 break;
230 op->u.firmware_info.u.vbeddc_info.capabilities =
231 bootsym(boot_edid_caps);
232 op->u.firmware_info.u.vbeddc_info.edid_transfer_time =
233 bootsym(boot_edid_caps) >> 8;
235 ret = 0;
236 if ( copy_field_to_guest(u_xenpf_op, op, u.firmware_info.
237 u.vbeddc_info.capabilities) ||
238 copy_field_to_guest(u_xenpf_op, op, u.firmware_info.
239 u.vbeddc_info.edid_transfer_time) ||
240 copy_to_compat(op->u.firmware_info.u.vbeddc_info.edid,
241 bootsym(boot_edid_info), 128) )
242 ret = -EFAULT;
243 break;
244 default:
245 ret = -EINVAL;
246 break;
247 }
248 break;
250 default:
251 ret = -ENOSYS;
252 break;
253 }
255 spin_unlock(&xenpf_lock);
257 return ret;
258 }
260 /*
261 * Local variables:
262 * mode: C
263 * c-set-style: "BSD"
264 * c-basic-offset: 4
265 * tab-width: 4
266 * indent-tabs-mode: nil
267 * End:
268 */