1 /*
2 * Copyright 2018 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "crosvm.h"
13
main(int argc,char ** argv)14 int main(int argc, char** argv) {
15 struct crosvm *crosvm;
16 int ret = crosvm_connect(&crosvm);
17 if (ret) {
18 fprintf(stderr, "failed to connect to crosvm: %d\n", ret);
19 return 1;
20 }
21
22 struct kvm_pic_state pic_state;
23 ret = crosvm_get_pic_state(crosvm, false, &pic_state);
24 if (ret < 0) {
25 fprintf(stderr, "failed to get initial PIC1 state: %d\n", ret);
26 return 1;
27 }
28
29 if (pic_state.auto_eoi) {
30 fprintf(stderr, "unexpected value of auto_eoi flag\n");
31 return 1;
32 }
33
34 pic_state.auto_eoi = true;
35 ret = crosvm_set_pic_state(crosvm, false, &pic_state);
36 if (ret < 0) {
37 fprintf(stderr, "failed to update PIC1 state: %d\n", ret);
38 return 1;
39 }
40
41 ret = crosvm_get_pic_state(crosvm, false, &pic_state);
42 if (ret < 0) {
43 fprintf(stderr, "failed to get updated PIC1 state: %d\n", ret);
44 return 1;
45 }
46
47 if (!pic_state.auto_eoi) {
48 fprintf(stderr, "unexpected value of auto_eoi flag after update\n");
49 return 1;
50 }
51
52 // Test retrieving and setting IOAPIC state.
53 struct kvm_ioapic_state ioapic_state;
54 ret = crosvm_get_ioapic_state(crosvm, &ioapic_state);
55 if (ret < 0) {
56 fprintf(stderr, "failed to get initial PIC1 state: %d\n", ret);
57 return 1;
58 }
59
60 fprintf(stderr, "IOAPIC ID: %d\n", ioapic_state.id);
61
62 if (ioapic_state.id != 0) {
63 fprintf(stderr, "unexpected value of IOAPIC ID: %d\n", ioapic_state.id);
64 return 1;
65 }
66
67 ioapic_state.id = 1;
68 ret = crosvm_set_ioapic_state(crosvm, &ioapic_state);
69 if (ret < 0) {
70 fprintf(stderr, "failed to update PIC1 state: %d\n", ret);
71 return 1;
72 }
73
74 ret = crosvm_get_ioapic_state(crosvm, &ioapic_state);
75 if (ret < 0) {
76 fprintf(stderr, "failed to get updated PIC1 state: %d\n", ret);
77 return 1;
78 }
79
80 if (ioapic_state.id != 1) {
81 fprintf(stderr, "unexpected value of IOAPIC ID after update: %d\n",
82 ioapic_state.id);
83 return 1;
84 }
85
86 // Test retrieving and setting PIT state.
87 struct kvm_pit_state2 pit_state;
88 ret = crosvm_get_pit_state(crosvm, &pit_state);
89 if (ret < 0) {
90 fprintf(stderr, "failed to get initial PIT state: %d\n", ret);
91 return 1;
92 }
93
94 if (pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY) {
95 fprintf(stderr, "unexpected value of KVM_PIT_FLAGS_HPET_LEGACY flag\n");
96 return 1;
97 }
98
99 pit_state.flags |= KVM_PIT_FLAGS_HPET_LEGACY;
100 ret = crosvm_set_pit_state(crosvm, &pit_state);
101 if (ret < 0) {
102 fprintf(stderr, "failed to update PIT state: %d\n", ret);
103 return 1;
104 }
105
106 ret = crosvm_get_pit_state(crosvm, &pit_state);
107 if (ret < 0) {
108 fprintf(stderr, "failed to get updated PIT state: %d\n", ret);
109 return 1;
110 }
111
112 if (!(pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY)) {
113 fprintf(stderr,
114 "unexpected value of KVM_PIT_FLAGS_HPET_LEGACY after update\n");
115 return 1;
116 }
117
118 // Test retrieving and setting clock state.
119 struct kvm_clock_data clock_data = { .clock = 0, .flags = -1U, };
120 ret = crosvm_get_clock(crosvm, &clock_data);
121 if (ret < 0) {
122 fprintf(stderr, "failed to get initial clock state: %d\n", ret);
123 return 1;
124 }
125
126 if (clock_data.clock == 0 || clock_data.flags != 0) {
127 fprintf(stderr, "invalid clock data returned (%llu, %u)\n",
128 clock_data.clock, clock_data.flags);
129 }
130
131 clock_data.clock += 10000000;
132
133 ret = crosvm_set_clock(crosvm, &clock_data);
134 if (ret < 0) {
135 fprintf(stderr, "failed to update clock: %d\n", ret);
136 return 1;
137 }
138
139 clock_data.flags = -1U;
140 ret = crosvm_set_clock(crosvm, &clock_data);
141 if (ret >= 0) {
142 fprintf(stderr, "unexpected success updating clock\n");
143 return 1;
144 }
145
146 return 0;
147 }
148