+/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
+/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+
#include <devices/8254.h>
#include <palacios/vmm.h>
#include <palacios/vmm_time.h>
#include <palacios/vmm_util.h>
+#include <palacios/vmm_intr.h>
-
+#ifndef DEBUG_PIT
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
ushort_t latched_value;
- enum {NOTLATCHED,LATCHED} latch_state;
+ enum {NOTLATCHED, LATCHED} latch_state;
- enum {LSB,MSB} read_state;
+ enum {LSB, MSB} read_state;
uint_t output_pin : 1;
uint_t gate_input_pin : 1;
if (handle_crystal_tics(dev, &(state->ch_0), oscillations) == 1) {
// raise interrupt
PrintDebug("8254 PIT: Injecting Timer interrupt to guest\n");
- dev->vm->vm_ops.raise_irq(dev->vm, 0);
+ v3_raise_irq(dev->vm, 0);
}
//handle_crystal_tics(dev, &(state->ch_1), oscillations);
static int handle_channel_read(struct channel * ch, char * val) {
- ushort_t *myval;
+ ushort_t * myval;
- if (ch->latch_state==NOTLATCHED) {
+ if (ch->latch_state == NOTLATCHED) {
myval = &(ch->counter);
} else {
myval = &(ch->latched_value);
}
- if (ch->read_state==LSB) {
+ if (ch->read_state == LSB) {
*val = ((char*)myval)[0]; // little endian
- ch->read_state=MSB;
+ ch->read_state = MSB;
} else {
*val = ((char*)myval)[1];
- ch->read_state=LSB;
- if (ch->latch_state==LATCHED) {
- ch->latch_state=NOTLATCHED;
+ ch->read_state = LSB;
+ if (ch->latch_state == LATCHED) {
+ ch->latch_state = NOTLATCHED;
}
}
switch (cmd.access_mode) {
case LATCH_COUNT:
- if (ch->latch_state==NOTLATCHED) {
- ch->latched_value=ch->counter;
- ch->latch_state=LATCHED;
+ if (ch->latch_state == NOTLATCHED) {
+ ch->latched_value = ch->counter;
+ ch->latch_state = LATCHED;
}
break;
case HIBYTE_ONLY:
char * val = (char *)dst;
if (length != 1) {
- PrintDebug("8254 PIT: Invalid Read Write length \n");
+ PrintError("8254 PIT: Invalid Read Write length \n");
return -1;
}
}
break;
default:
- PrintDebug("8254 PIT: Read from invalid port (%d)\n", port);
+ PrintError("8254 PIT: Read from invalid port (%d)\n", port);
return -1;
}
char val = *(char *)src;
if (length != 1) {
- PrintDebug("8254 PIT: Invalid Write Length\n");
+ PrintError("8254 PIT: Invalid Write Length\n");
return -1;
}
}
break;
default:
- PrintDebug("8254 PIT: Write to invalid port (%d)\n", port);
+ PrintError("8254 PIT: Write to invalid port (%d)\n", port);
return -1;
}
PrintDebug("8254 PIT: Write to PIT Command port\n");
PrintDebug("8254 PIT: Writing to channel %d (access_mode = %d, op_mode = %d)\n", cmd->channel, cmd->access_mode, cmd->op_mode);
if (length != 1) {
- PrintDebug("8254 PIT: Write of Invalid length to command port\n");
+ PrintError("8254 PIT: Write of Invalid length to command port\n");
return -1;
}
ch->output_pin = 0;
ch->gate_input_pin = 0;
- ch->latched_value=0;
- ch->latch_state=NOTLATCHED;
- ch->read_state=LSB;
+ ch->latched_value = 0;
+ ch->latch_state = NOTLATCHED;
+ ch->read_state = LSB;
return;
}
dev_hook_io(dev, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel);
dev_hook_io(dev, COMMAND_PORT, NULL, &pit_write_command);
+#ifdef DEBUG_PIT
PrintDebug("8254 PIT: OSC_HZ=%d, reload_val=", OSC_HZ);
PrintTraceLL(reload_val);
PrintDebug("\n");
-
+#endif
v3_add_timer(dev->vm, &timer_ops, dev);
init_channel(&(state->ch_1));
init_channel(&(state->ch_2));
+#ifdef DEBUG_PIT
PrintDebug("8254 PIT: CPU MHZ=%d -- pit count=", cpu_khz / 1000);
PrintTraceLL(state->pit_counter);
PrintDebug("\n");
+#endif
return 0;
}