Skip to content

Commit 5130033

Browse files
author
Andre Beckus
committed
Reapply changes to the qtest framework
These changes were lost when merging in the changes from QEMU 2.1. Essentially just re-applying the changes that were there before the merge.
1 parent 8941290 commit 5130033

File tree

2 files changed

+242
-79
lines changed

2 files changed

+242
-79
lines changed

qtest.c

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,10 @@
2424

2525
bool qtest_allowed;
2626

27-
static DeviceState *irq_intercept_dev;
27+
static DeviceState *irq_intercept_dev = NULL;
2828
static FILE *qtest_log_fp;
2929
static CharDriverState *qtest_chr;
3030
static GString *inbuf;
31-
static int irq_levels[MAX_IRQ];
3231
static qemu_timeval start_time;
3332
static bool qtest_opened;
3433

@@ -123,22 +122,31 @@ static bool qtest_opened;
123122
*
124123
* IRQ management:
125124
*
126-
* > irq_intercept_in QOM-PATH
125+
* > irq_intercept_in QOM-PATH ID-NUM
127126
* < OK
128127
*
129-
* > irq_intercept_out QOM-PATH
128+
* > irq_intercept_out QOM-PATH ID-NUM
130129
* < OK
131130
*
132131
* Attach to the gpio-in (resp. gpio-out) pins exported by the device at
133132
* QOM-PATH. When the pin is triggered, one of the following async messages
134133
* will be printed to the qtest stream:
135134
*
136-
* IRQ raise NUM
137-
* IRQ lower NUM
135+
* IRQ raise GPIO-ID NUM
136+
* IRQ lower GPIO-ID NUM
138137
*
139138
* where NUM is an IRQ number. For the PC, interrupts can be intercepted
140139
* simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
141140
* NUM=0 even though it is remapped to GSI 2).
141+
*
142+
* A gpio-in IRQ mon an arbitrary device may be changed as follows:
143+
*
144+
* > set_irq_in QOM-PATH raise
145+
* < OK
146+
*
147+
* > set_irq_in QOM-PATH lower
148+
* < OK
149+
*
142150
*/
143151

144152
static int hex2nib(char ch)
@@ -197,16 +205,13 @@ static void GCC_FMT_ATTR(2, 3) qtest_send(CharDriverState *chr,
197205

198206
static void qtest_irq_handler(void *opaque, int n, int level)
199207
{
200-
qemu_irq *old_irqs = opaque;
208+
IRQInterceptData *intercept_data = opaque;
209+
qemu_irq *old_irqs = intercept_data->old_irqs;
201210
qemu_set_irq(old_irqs[n], level);
202-
203-
if (irq_levels[n] != level) {
204-
CharDriverState *chr = qtest_chr;
205-
irq_levels[n] = level;
206-
qtest_send_prefix(chr);
207-
qtest_send(chr, "IRQ %s %d\n",
208-
level ? "raise" : "lower", n);
209-
}
211+
CharDriverState *chr = qtest_chr;
212+
qtest_send_prefix(chr);
213+
qtest_send(chr, "IRQ %s %d %d\n",
214+
level ? "raise" : "lower", intercept_data->id, n);
210215
}
211216

212217
static void qtest_process_command(CharDriverState *chr, gchar **words)
@@ -235,6 +240,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
235240
|| strcmp(words[0], "irq_intercept_in") == 0) {
236241
DeviceState *dev;
237242
NamedGPIOList *ngl;
243+
int id;
238244

239245
g_assert(words[1]);
240246
dev = DEVICE(object_resolve_path(words[1], NULL));
@@ -244,14 +250,13 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
244250
return;
245251
}
246252

247-
if (irq_intercept_dev) {
253+
g_assert(words[2]);
254+
id = strtoul(words[2], NULL, 0);
255+
256+
if (irq_intercept_dev == dev) {
248257
qtest_send_prefix(chr);
249-
if (irq_intercept_dev != dev) {
250-
qtest_send(chr, "FAIL IRQ intercept already enabled\n");
251-
} else {
252-
qtest_send(chr, "OK\n");
253-
}
254-
return;
258+
qtest_send(chr, "OK\n");
259+
return;
255260
}
256261

257262
QLIST_FOREACH(ngl, &dev->gpios, node) {
@@ -261,16 +266,42 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
261266
}
262267
if (words[0][14] == 'o') {
263268
qemu_irq_intercept_out(&ngl->out, qtest_irq_handler,
264-
ngl->num_out);
269+
id, ngl->num_out);
265270
} else {
266271
qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
267-
ngl->num_in);
272+
id, ngl->num_in);
268273
}
269274
}
270275
irq_intercept_dev = dev;
271276
qtest_send_prefix(chr);
272277
qtest_send(chr, "OK\n");
273278

279+
} else if (strcmp(words[0], "set_irq_in") == 0) {
280+
DeviceState *dev;
281+
qemu_irq irq;
282+
unsigned n, level;
283+
284+
g_assert(words[1]);
285+
dev = DEVICE(object_resolve_path(words[1], NULL));
286+
if (!dev) {
287+
qtest_send_prefix(chr);
288+
qtest_send(chr, "FAIL Unknown device\n");
289+
return;
290+
}
291+
292+
g_assert(words[2]);
293+
n = strtoul(words[2], NULL, 0);
294+
irq = qdev_get_gpio_in(dev, n);
295+
296+
g_assert(words[3]);
297+
if (strcmp(words[3], "raise") == 0) {
298+
level = 1;
299+
} else {
300+
level = 0;
301+
}
302+
qemu_set_irq(irq, level);
303+
304+
qtest_send(chr, "OK\n");
274305
} else if (strcmp(words[0], "outb") == 0 ||
275306
strcmp(words[0], "outw") == 0 ||
276307
strcmp(words[0], "outl") == 0) {
@@ -475,8 +506,6 @@ static int qtest_can_read(void *opaque)
475506

476507
static void qtest_event(void *opaque, int event)
477508
{
478-
int i;
479-
480509
switch (event) {
481510
case CHR_EVENT_OPENED:
482511
/*
@@ -485,9 +514,6 @@ static void qtest_event(void *opaque, int event)
485514
* used. Injects an extra reset even when it's not used, and
486515
* that can mess up tests, e.g. -boot once.
487516
*/
488-
for (i = 0; i < ARRAY_SIZE(irq_levels); i++) {
489-
irq_levels[i] = 0;
490-
}
491517
qemu_gettimeofday(&start_time);
492518
qtest_opened = true;
493519
if (qtest_log_fp) {

0 commit comments

Comments
 (0)