From: Jack Lange Date: Tue, 3 Mar 2009 23:39:16 +0000 (-0600) Subject: reformatted device source files X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=4bc3ee757b44d3e466fd89e348106c47fa5511ee reformatted device source files --- diff --git a/palacios/src/devices/8237_dma.c b/palacios/src/devices/8237_dma.c index 5748d85..40787a7 100644 --- a/palacios/src/devices/8237_dma.c +++ b/palacios/src/devices/8237_dma.c @@ -23,33 +23,31 @@ struct dma_state { - int tmp; - + int tmp }; static int dma_init(struct vm_device * dev) { - - return 0; + return 0; } static struct vm_device_ops dev_ops = { - .init = dma_init, - .deinit = NULL, - .reset = NULL, - .start = NULL, - .stop = NULL, + .init = dma_init, + .deinit = NULL, + .reset = NULL, + .start = NULL, + .stop = NULL, }; struct vm_device * v3_create_dma() { - struct dma_state * dma = NULL; + struct dma_state * dma = NULL; - dma = (struct dma_state *)V3_Malloc(sizeof(struct dma_state)); - V3_ASSERT(dma != NULL); + dma = (struct dma_state *)V3_Malloc(sizeof(struct dma_state)); + V3_ASSERT(dma != NULL); - struct vm_device * dev = v3_create_device("DMA", &dev_ops, dma); + struct vm_device * dev = v3_create_device("DMA", &dev_ops, dma); - return dma; + return dma; } diff --git a/palacios/src/devices/8254.c b/palacios/src/devices/8254.c index f0c063b..fd9ab38 100644 --- a/palacios/src/devices/8254.c +++ b/palacios/src/devices/8254.c @@ -55,64 +55,64 @@ typedef enum {IRQ_ON_TERM_CNT, ONE_SHOT, RATE_GEN, SQR_WAVE, SW_STROBE, HW_STROB struct channel { - channel_access_mode_t access_mode; - channel_access_state_t access_state; - channel_run_state_t run_state; + channel_access_mode_t access_mode; + channel_access_state_t access_state; + channel_run_state_t run_state; - channel_op_mode_t op_mode; + channel_op_mode_t op_mode; - // Time til interrupt trigger + // Time til interrupt trigger - ushort_t counter; - ushort_t reload_value; + ushort_t counter; + ushort_t reload_value; - ushort_t latched_value; + 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; + uint_t output_pin : 1; + uint_t gate_input_pin : 1; }; struct pit { - ullong_t pit_counter; - ullong_t pit_reload; + ullong_t pit_counter; + ullong_t pit_reload; - struct channel ch_0; - struct channel ch_1; - struct channel ch_2; + struct channel ch_0; + struct channel ch_1; + struct channel ch_2; }; struct pit_cmd_word { - uint_t bcd_mode : 1; - uint_t op_mode : 3; - uint_t access_mode : 2; - uint_t channel : 2; + uint_t bcd_mode : 1; + uint_t op_mode : 3; + uint_t access_mode : 2; + uint_t channel : 2; }; struct pit_rdb_cmd_word { - uint_t rsvd : 1; // SBZ - uint_t ch_0 : 1; - uint_t ch_1 : 1; - uint_t ch_2 : 1; - uint_t latch_status : 1; - uint_t latch_count : 1; - uint_t readback_cmd : 2; // Must Be 0x3 + uint_t rsvd : 1; // SBZ + uint_t ch_0 : 1; + uint_t ch_1 : 1; + uint_t ch_2 : 1; + uint_t latch_status : 1; + uint_t latch_count : 1; + uint_t readback_cmd : 2; // Must Be 0x3 }; struct pit_rdb_status_word { - uint_t bcd_mode : 1; - uint_t op_mode : 3; - uint_t access_mode : 2; - uint_t null_count : 1; - uint_t pin_state : 1; + uint_t bcd_mode : 1; + uint_t op_mode : 3; + uint_t access_mode : 2; + uint_t null_count : 1; + uint_t pin_state : 1; }; @@ -122,179 +122,179 @@ struct pit_rdb_status_word { */ // Returns true if the the output signal changed state static int handle_crystal_tics(struct vm_device * dev, struct channel * ch, uint_t oscillations) { - uint_t channel_cycles = 0; - uint_t output_changed = 0; + uint_t channel_cycles = 0; + uint_t output_changed = 0; - // PrintDebug("8254 PIT: %d crystal tics\n", oscillations); - if (ch->run_state == PENDING) { - oscillations--; - ch->counter = ch->reload_value; + // PrintDebug("8254 PIT: %d crystal tics\n", oscillations); + if (ch->run_state == PENDING) { + oscillations--; + ch->counter = ch->reload_value; - if (ch->op_mode == SQR_WAVE) { - ch->counter -= ch->counter % 2; - } - - ch->run_state = RUNNING; - } else if (ch->run_state != RUNNING) { - return output_changed; - } - - /* - PrintDebug("8254 PIT: Channel Run State = %d, counter=", ch->run_state); - PrintTraceLL(ch->counter); - PrintDebug("\n"); - */ - if (ch->op_mode == SQR_WAVE) { - oscillations *= 2; - } - - if (ch->counter > oscillations) { - ch->counter -= oscillations; - return output_changed; - } else { - ushort_t reload_val = ch->reload_value; + if (ch->op_mode == SQR_WAVE) { + ch->counter -= ch->counter % 2; + } - // TODO: Check this.... - // Is this correct??? - if (reload_val == 0) { - reload_val = 1; + ch->run_state = RUNNING; + } else if (ch->run_state != RUNNING) { + return output_changed; } - oscillations -= ch->counter; - ch->counter = 0; - channel_cycles = 1; - + /* + PrintDebug("8254 PIT: Channel Run State = %d, counter=", ch->run_state); + PrintTraceLL(ch->counter); + PrintDebug("\n"); + */ if (ch->op_mode == SQR_WAVE) { - reload_val -= reload_val % 2; + oscillations *= 2; } - channel_cycles += oscillations / reload_val; - oscillations = oscillations % reload_val; + if (ch->counter > oscillations) { + ch->counter -= oscillations; + return output_changed; + } else { + ushort_t reload_val = ch->reload_value; - ch->counter = reload_val - oscillations; - } + // TODO: Check this.... + // Is this correct??? + if (reload_val == 0) { + reload_val = 1; + } - // PrintDebug("8254 PIT: Channel Cycles: %d\n", channel_cycles); - + oscillations -= ch->counter; + ch->counter = 0; + channel_cycles = 1; + if (ch->op_mode == SQR_WAVE) { + reload_val -= reload_val % 2; + } - switch (ch->op_mode) { - case IRQ_ON_TERM_CNT: - if ((channel_cycles > 0) && (ch->output_pin == 0)) { - ch->output_pin = 1; - output_changed = 1; - } - break; - case ONE_SHOT: - if ((channel_cycles > 0) && (ch->output_pin == 0)) { - ch->output_pin = 1; - output_changed = 1; - } - break; - case RATE_GEN: - // See the data sheet: we ignore the output pin cycle... - if (channel_cycles > 0) { - output_changed = 1; + channel_cycles += oscillations / reload_val; + oscillations = oscillations % reload_val; + + ch->counter = reload_val - oscillations; } - break; - case SQR_WAVE: - ch->output_pin = (ch->output_pin + 1) % 2; - if (ch->output_pin == 1) { - output_changed = 1; + // PrintDebug("8254 PIT: Channel Cycles: %d\n", channel_cycles); + + + + switch (ch->op_mode) { + case IRQ_ON_TERM_CNT: + if ((channel_cycles > 0) && (ch->output_pin == 0)) { + ch->output_pin = 1; + output_changed = 1; + } + break; + case ONE_SHOT: + if ((channel_cycles > 0) && (ch->output_pin == 0)) { + ch->output_pin = 1; + output_changed = 1; + } + break; + case RATE_GEN: + // See the data sheet: we ignore the output pin cycle... + if (channel_cycles > 0) { + output_changed = 1; + } + break; + case SQR_WAVE: + ch->output_pin = (ch->output_pin + 1) % 2; + + if (ch->output_pin == 1) { + output_changed = 1; + } + + break; + case SW_STROBE: + return -1; + break; + case HW_STROBE: + return -1; + break; + default: + break; } - break; - case SW_STROBE: - return -1; - break; - case HW_STROBE: - return -1; - break; - default: - break; - } - - return output_changed; + return output_changed; } static void pit_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * private_data) { - struct vm_device * dev = (struct vm_device *)private_data; - struct pit * state = (struct pit *)dev->private_data; - // ullong_t tmp_ctr = state->pit_counter; - ullong_t tmp_cycles; - uint_t oscillations = 0; + struct vm_device * dev = (struct vm_device *)private_data; + struct pit * state = (struct pit *)dev->private_data; + // ullong_t tmp_ctr = state->pit_counter; + ullong_t tmp_cycles; + uint_t oscillations = 0; - /* - PrintDebug("updating cpu_cycles="); - PrintTraceLL(cpu_cycles); - PrintDebug("\n"); + /* + PrintDebug("updating cpu_cycles="); + PrintTraceLL(cpu_cycles); + PrintDebug("\n"); - PrintDebug("pit_counter="); - PrintTraceLL(state->pit_counter); - PrintDebug("\n"); + PrintDebug("pit_counter="); + PrintTraceLL(state->pit_counter); + PrintDebug("\n"); - PrintDebug("pit_reload="); - PrintTraceLL(state->pit_reload); - PrintDebug("\n"); - */ - - if (state->pit_counter > cpu_cycles) { - // Easy... - state->pit_counter -= cpu_cycles; - } else { - ushort_t reload_val = state->pit_reload; - // Take off the first part - cpu_cycles -= state->pit_counter; - state->pit_counter = 0; - oscillations = 1; + PrintDebug("pit_reload="); + PrintTraceLL(state->pit_reload); + PrintDebug("\n"); + */ + + if (state->pit_counter > cpu_cycles) { + // Easy... + state->pit_counter -= cpu_cycles; + } else { + ushort_t reload_val = state->pit_reload; + // Take off the first part + cpu_cycles -= state->pit_counter; + state->pit_counter = 0; + oscillations = 1; - if (cpu_cycles > state->pit_reload) { - // how many full oscillations + if (cpu_cycles > state->pit_reload) { + // how many full oscillations - //PrintError("cpu_cycles = %p, reload = %p...\n", - // (void *)(addr_t)cpu_cycles, - // (void *)(addr_t)state->pit_reload); + //PrintError("cpu_cycles = %p, reload = %p...\n", + // (void *)(addr_t)cpu_cycles, + // (void *)(addr_t)state->pit_reload); - // How do we check for a one shot.... - if (state->pit_reload == 0) { - reload_val = 1; - } + // How do we check for a one shot.... + if (state->pit_reload == 0) { + reload_val = 1; + } - tmp_cycles = cpu_cycles; + tmp_cycles = cpu_cycles; #ifdef __V3_64BIT__ - cpu_cycles = tmp_cycles % state->pit_reload; - tmp_cycles = tmp_cycles / state->pit_reload; + cpu_cycles = tmp_cycles % state->pit_reload; + tmp_cycles = tmp_cycles / state->pit_reload; #else - cpu_cycles = do_divll(tmp_cycles, state->pit_reload); + cpu_cycles = do_divll(tmp_cycles, state->pit_reload); #endif - oscillations += tmp_cycles; - } + oscillations += tmp_cycles; + } - // update counter with remainder (mod reload) - state->pit_counter = state->pit_reload - cpu_cycles; + // update counter with remainder (mod reload) + state->pit_counter = state->pit_reload - cpu_cycles; - //PrintDebug("8254 PIT: Handling %d crystal tics\n", oscillations); - if (handle_crystal_tics(dev, &(state->ch_0), oscillations) == 1) { - // raise interrupt - PrintDebug("8254 PIT: Injecting Timer interrupt to guest\n"); - v3_raise_irq(dev->vm, 0); - } + //PrintDebug("8254 PIT: Handling %d crystal tics\n", oscillations); + if (handle_crystal_tics(dev, &(state->ch_0), oscillations) == 1) { + // raise interrupt + PrintDebug("8254 PIT: Injecting Timer interrupt to guest\n"); + v3_raise_irq(dev->vm, 0); + } - //handle_crystal_tics(dev, &(state->ch_1), oscillations); - //handle_crystal_tics(dev, &(state->ch_2), oscillations); - } + //handle_crystal_tics(dev, &(state->ch_1), oscillations); + //handle_crystal_tics(dev, &(state->ch_2), oscillations); + } - return; + return; } @@ -304,88 +304,88 @@ static void pit_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * priva static int handle_channel_write(struct channel * ch, char val) { switch (ch->access_state) { - case WAITING_HIBYTE: - { - ushort_t tmp_val = ((ushort_t)val) << 8; - ch->reload_value &= 0x00ff; - ch->reload_value |= tmp_val; + case WAITING_HIBYTE: + { + ushort_t tmp_val = ((ushort_t)val) << 8; + ch->reload_value &= 0x00ff; + ch->reload_value |= tmp_val; - if ((ch->op_mode != RATE_GEN) || (ch->run_state != RUNNING)){ - ch->run_state = PENDING; - } + if ((ch->op_mode != RATE_GEN) || (ch->run_state != RUNNING)){ + ch->run_state = PENDING; + } - if (ch->access_mode == LOBYTE_HIBYTE) { - ch->access_state = WAITING_LOBYTE; - } - - PrintDebug("8254 PIT: updated channel counter: %d\n", ch->reload_value); - PrintDebug("8254 PIT: Channel Run State=%d\n", ch->run_state); - break; - } - case WAITING_LOBYTE: - ch->reload_value &= 0xff00; - ch->reload_value |= val; + if (ch->access_mode == LOBYTE_HIBYTE) { + ch->access_state = WAITING_LOBYTE; + } + + PrintDebug("8254 PIT: updated channel counter: %d\n", ch->reload_value); + PrintDebug("8254 PIT: Channel Run State=%d\n", ch->run_state); + break; + } + case WAITING_LOBYTE: + ch->reload_value &= 0xff00; + ch->reload_value |= val; - if (ch->access_mode == LOBYTE_HIBYTE) { - ch->access_state = WAITING_HIBYTE; - } else if ((ch->op_mode != RATE_GEN) || (ch->run_state != RUNNING)) { - ch->run_state = PENDING; - } + if (ch->access_mode == LOBYTE_HIBYTE) { + ch->access_state = WAITING_HIBYTE; + } else if ((ch->op_mode != RATE_GEN) || (ch->run_state != RUNNING)) { + ch->run_state = PENDING; + } - PrintDebug("8254 PIT: updated channel counter: %d\n", ch->reload_value); - PrintDebug("8254 PIT: Channel Run State=%d\n", ch->run_state); - break; - default: - return -1; + PrintDebug("8254 PIT: updated channel counter: %d\n", ch->reload_value); + PrintDebug("8254 PIT: Channel Run State=%d\n", ch->run_state); + break; + default: + return -1; } switch (ch->op_mode) { - case IRQ_ON_TERM_CNT: - ch->output_pin = 0; - break; - case ONE_SHOT: - ch->output_pin = 1; - break; - case RATE_GEN: - ch->output_pin = 1; - break; - case SQR_WAVE: - ch->output_pin = 1; - break; - default: - return -1; - break; + case IRQ_ON_TERM_CNT: + ch->output_pin = 0; + break; + case ONE_SHOT: + ch->output_pin = 1; + break; + case RATE_GEN: + ch->output_pin = 1; + break; + case SQR_WAVE: + ch->output_pin = 1; + break; + default: + return -1; + break; } - return 0; + return 0; } static int handle_channel_read(struct channel * ch, char * val) { - ushort_t * myval; + ushort_t * myval; - if (ch->latch_state == NOTLATCHED) { - myval = &(ch->counter); - } else { - myval = &(ch->latched_value); - } + if (ch->latch_state == NOTLATCHED) { + myval = &(ch->counter); + } else { + myval = &(ch->latched_value); + } - if (ch->read_state == LSB) { - *val = ((char*)myval)[0]; // little endian - ch->read_state = MSB; - } else { - *val = ((char*)myval)[1]; - ch->read_state = LSB; - if (ch->latch_state == LATCHED) { - ch->latch_state = NOTLATCHED; + if (ch->read_state == LSB) { + *val = ((char*)myval)[0]; // little endian + ch->read_state = MSB; + } else { + *val = ((char*)myval)[1]; + ch->read_state = LSB; + if (ch->latch_state == LATCHED) { + ch->latch_state = NOTLATCHED; + } } - } - return 0; + return 0; } @@ -394,47 +394,47 @@ static int handle_channel_read(struct channel * ch, char * val) { static int handle_channel_cmd(struct channel * ch, struct pit_cmd_word cmd) { - ch->op_mode = cmd.op_mode; - ch->access_mode = cmd.access_mode; - - + ch->op_mode = cmd.op_mode; + ch->access_mode = cmd.access_mode; + + + + + switch (cmd.access_mode) { + case LATCH_COUNT: + if (ch->latch_state == NOTLATCHED) { + ch->latched_value = ch->counter; + ch->latch_state = LATCHED; + } + break; + case HIBYTE_ONLY: + ch->access_state = WAITING_HIBYTE; + break; + case LOBYTE_ONLY: + case LOBYTE_HIBYTE: + ch->access_state = WAITING_LOBYTE; + break; + } - switch (cmd.access_mode) { - case LATCH_COUNT: - if (ch->latch_state == NOTLATCHED) { - ch->latched_value = ch->counter; - ch->latch_state = LATCHED; + switch (cmd.op_mode) { + case IRQ_ON_TERM_CNT: + ch->output_pin = 0; + break; + case ONE_SHOT: + ch->output_pin = 1; + break; + case RATE_GEN: + ch->output_pin = 1; + break; + case SQR_WAVE: + ch->output_pin = 1; + break; + default: + return -1; } - break; - case HIBYTE_ONLY: - ch->access_state = WAITING_HIBYTE; - break; - case LOBYTE_ONLY: - case LOBYTE_HIBYTE: - ch->access_state = WAITING_LOBYTE; - break; - } - - - switch (cmd.op_mode) { - case IRQ_ON_TERM_CNT: - ch->output_pin = 0; - break; - case ONE_SHOT: - ch->output_pin = 1; - break; - case RATE_GEN: - ch->output_pin = 1; - break; - case SQR_WAVE: - ch->output_pin = 1; - break; - default: - return -1; - } - - return 0; + + return 0; } @@ -442,208 +442,208 @@ static int handle_channel_cmd(struct channel * ch, struct pit_cmd_word cmd) { static int pit_read_channel(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct pit * state = (struct pit *)dev->private_data; - char * val = (char *)dst; - - if (length != 1) { - PrintError("8254 PIT: Invalid Read Write length \n"); - return -1; - } + struct pit * state = (struct pit *)dev->private_data; + char * val = (char *)dst; - PrintDebug("8254 PIT: Read of PIT Channel %d\n", port - CHANNEL0_PORT); - - switch (port) { - case CHANNEL0_PORT: - if (handle_channel_read(&(state->ch_0), val) == -1) { - return -1; - } - break; - case CHANNEL1_PORT: - if (handle_channel_read(&(state->ch_1), val) == -1) { - return -1; + if (length != 1) { + PrintError("8254 PIT: Invalid Read Write length \n"); + return -1; } - break; - case CHANNEL2_PORT: - if (handle_channel_read(&(state->ch_2), val) == -1) { - return -1; + + PrintDebug("8254 PIT: Read of PIT Channel %d\n", port - CHANNEL0_PORT); + + switch (port) { + case CHANNEL0_PORT: + if (handle_channel_read(&(state->ch_0), val) == -1) { + return -1; + } + break; + case CHANNEL1_PORT: + if (handle_channel_read(&(state->ch_1), val) == -1) { + return -1; + } + break; + case CHANNEL2_PORT: + if (handle_channel_read(&(state->ch_2), val) == -1) { + return -1; + } + break; + default: + PrintError("8254 PIT: Read from invalid port (%d)\n", port); + return -1; } - break; - default: - PrintError("8254 PIT: Read from invalid port (%d)\n", port); - return -1; - } - return length; + return length; } static int pit_write_channel(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct pit * state = (struct pit *)dev->private_data; - char val = *(char *)src; - - if (length != 1) { - PrintError("8254 PIT: Invalid Write Length\n"); - return -1; - } - - PrintDebug("8254 PIT: Write to PIT Channel %d (%x)\n", port - CHANNEL0_PORT, *(char*)src); - - - switch (port) { - case CHANNEL0_PORT: - if (handle_channel_write(&(state->ch_0), val) == -1) { - return -1; - } - break; - case CHANNEL1_PORT: - if (handle_channel_write(&(state->ch_1), val) == -1) { - return -1; + struct pit * state = (struct pit *)dev->private_data; + char val = *(char *)src; + + if (length != 1) { + PrintError("8254 PIT: Invalid Write Length\n"); + return -1; } - break; - case CHANNEL2_PORT: - if (handle_channel_write(&(state->ch_2), val) == -1) { - return -1; + + PrintDebug("8254 PIT: Write to PIT Channel %d (%x)\n", port - CHANNEL0_PORT, *(char*)src); + + + switch (port) { + case CHANNEL0_PORT: + if (handle_channel_write(&(state->ch_0), val) == -1) { + return -1; + } + break; + case CHANNEL1_PORT: + if (handle_channel_write(&(state->ch_1), val) == -1) { + return -1; + } + break; + case CHANNEL2_PORT: + if (handle_channel_write(&(state->ch_2), val) == -1) { + return -1; + } + break; + default: + PrintError("8254 PIT: Write to invalid port (%d)\n", port); + return -1; } - break; - default: - PrintError("8254 PIT: Write to invalid port (%d)\n", port); - return -1; - } - return length; + return length; } static int pit_write_command(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct pit * state = (struct pit *)dev->private_data; - struct pit_cmd_word * cmd = (struct pit_cmd_word *)src; - - 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) { - PrintError("8254 PIT: Write of Invalid length to command port\n"); - return -1; - } - - switch (cmd->channel) { - case 0: - if (handle_channel_cmd(&(state->ch_0), *cmd) == -1) { - return -1; - } - break; - case 1: - if (handle_channel_cmd(&(state->ch_1), *cmd) == -1) { - return -1; + struct pit * state = (struct pit *)dev->private_data; + struct pit_cmd_word * cmd = (struct pit_cmd_word *)src; + + 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) { + PrintError("8254 PIT: Write of Invalid length to command port\n"); + return -1; } - break; - case 2: - if (handle_channel_cmd(&(state->ch_2), *cmd) == -1) { - return -1; + + switch (cmd->channel) { + case 0: + if (handle_channel_cmd(&(state->ch_0), *cmd) == -1) { + return -1; + } + break; + case 1: + if (handle_channel_cmd(&(state->ch_1), *cmd) == -1) { + return -1; + } + break; + case 2: + if (handle_channel_cmd(&(state->ch_2), *cmd) == -1) { + return -1; + } + break; + case 3: + // Read Back command + return -1; + break; + default: + break; } - break; - case 3: - // Read Back command - return -1; - break; - default: - break; - } - return length; + return length; } static struct vm_timer_ops timer_ops = { - .update_time = pit_update_time, + .update_time = pit_update_time, }; static void init_channel(struct channel * ch) { - ch->run_state = NOT_RUNNING; - ch->access_state = NOT_WAITING; - ch->access_mode = 0; - ch->op_mode = 0; + ch->run_state = NOT_RUNNING; + ch->access_state = NOT_WAITING; + ch->access_mode = 0; + ch->op_mode = 0; - ch->counter = 0; - ch->reload_value = 0; - ch->output_pin = 0; - ch->gate_input_pin = 0; + ch->counter = 0; + ch->reload_value = 0; + 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; + return; } static int pit_init(struct vm_device * dev) { - struct pit * state = (struct pit *)dev->private_data; - uint_t cpu_khz = V3_CPU_KHZ(); - ullong_t reload_val = (ullong_t)cpu_khz * 1000; + struct pit * state = (struct pit *)dev->private_data; + uint_t cpu_khz = V3_CPU_KHZ(); + ullong_t reload_val = (ullong_t)cpu_khz * 1000; - v3_dev_hook_io(dev, CHANNEL0_PORT, &pit_read_channel, &pit_write_channel); - v3_dev_hook_io(dev, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel); - v3_dev_hook_io(dev, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel); - v3_dev_hook_io(dev, COMMAND_PORT, NULL, &pit_write_command); + v3_dev_hook_io(dev, CHANNEL0_PORT, &pit_read_channel, &pit_write_channel); + v3_dev_hook_io(dev, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel); + v3_dev_hook_io(dev, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel); + v3_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"); + PrintDebug("8254 PIT: OSC_HZ=%d, reload_val=", OSC_HZ); + PrintTraceLL(reload_val); + PrintDebug("\n"); #endif - v3_add_timer(dev->vm, &timer_ops, dev); + v3_add_timer(dev->vm, &timer_ops, dev); - // Get cpu frequency and calculate the global pit oscilattor counter/cycle + // Get cpu frequency and calculate the global pit oscilattor counter/cycle - do_divll(reload_val, OSC_HZ); - state->pit_counter = reload_val; - state->pit_reload = reload_val; + do_divll(reload_val, OSC_HZ); + state->pit_counter = reload_val; + state->pit_reload = reload_val; - init_channel(&(state->ch_0)); - init_channel(&(state->ch_1)); - init_channel(&(state->ch_2)); + init_channel(&(state->ch_0)); + 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"); + PrintDebug("8254 PIT: CPU MHZ=%d -- pit count=", cpu_khz / 1000); + PrintTraceLL(state->pit_counter); + PrintDebug("\n"); #endif - return 0; + return 0; } static int pit_deinit(struct vm_device * dev) { - return 0; + return 0; } static struct vm_device_ops dev_ops = { - .init = pit_init, - .deinit = pit_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, + .init = pit_init, + .deinit = pit_deinit, + .reset = NULL, + .start = NULL, + .stop = NULL, }; struct vm_device * v3_create_pit() { - struct pit * pit_state = NULL; - pit_state = (struct pit *)V3_Malloc(sizeof(struct pit)); - V3_ASSERT(pit_state != NULL); + struct pit * pit_state = NULL; + pit_state = (struct pit *)V3_Malloc(sizeof(struct pit)); + V3_ASSERT(pit_state != NULL); - struct vm_device * dev = v3_create_device("PIT", &dev_ops, pit_state); + struct vm_device * dev = v3_create_device("PIT", &dev_ops, pit_state); - return dev; + return dev; } diff --git a/palacios/src/devices/8259a.c b/palacios/src/devices/8259a.c index c088a0d..03b8a55 100644 --- a/palacios/src/devices/8259a.c +++ b/palacios/src/devices/8259a.c @@ -42,285 +42,285 @@ static const uint_t SLAVE_PORT2 = 0xA1; struct icw1 { - uint_t ic4 : 1; // ICW4 has to be read - uint_t sngl : 1; // single (only one PIC) - uint_t adi : 1; // call address interval - uint_t ltim : 1; // level interrupt mode - uint_t one : 1; - uint_t rsvd : 3; + uint_t ic4 : 1; // ICW4 has to be read + uint_t sngl : 1; // single (only one PIC) + uint_t adi : 1; // call address interval + uint_t ltim : 1; // level interrupt mode + uint_t one : 1; + uint_t rsvd : 3; }; struct icw2 { - uint_t rsvd : 3; - uint_t vector : 5; + uint_t rsvd : 3; + uint_t vector : 5; }; // Each bit that is set indicates that the IR input has a slave struct icw3_master { - uint_t S0 : 1; - uint_t S1 : 1; - uint_t S2 : 1; - uint_t S3 : 1; - uint_t S4 : 1; - uint_t S5 : 1; - uint_t S6 : 1; - uint_t S7 : 1; + uint_t S0 : 1; + uint_t S1 : 1; + uint_t S2 : 1; + uint_t S3 : 1; + uint_t S4 : 1; + uint_t S5 : 1; + uint_t S6 : 1; + uint_t S7 : 1; }; // The ID is the Slave device ID struct icw3_slave { - uint_t id : 3; - uint_t zeroes : 5; + uint_t id : 3; + uint_t zeroes : 5; }; struct icw4 { - uint_t uPM : 1; // 1=x86 - uint_t AEOI : 1; // Automatic End of Interrupt - uint_t M_S : 1; // only if buffered 1=master,0=slave - uint_t BUF : 1; // buffered mode - uint_t SFNM : 1; // special fully nexted mode - uint_t zeroes : 3; + uint_t uPM : 1; // 1=x86 + uint_t AEOI : 1; // Automatic End of Interrupt + uint_t M_S : 1; // only if buffered 1=master,0=slave + uint_t BUF : 1; // buffered mode + uint_t SFNM : 1; // special fully nexted mode + uint_t zeroes : 3; }; struct ocw1 { - uint_t m0 : 1; - uint_t m1 : 1; - uint_t m2 : 1; - uint_t m3 : 1; - uint_t m4 : 1; - uint_t m5 : 1; - uint_t m6 : 1; - uint_t m7 : 1; + uint_t m0 : 1; + uint_t m1 : 1; + uint_t m2 : 1; + uint_t m3 : 1; + uint_t m4 : 1; + uint_t m5 : 1; + uint_t m6 : 1; + uint_t m7 : 1; }; struct ocw2 { - uint_t level : 3; - uint_t cw_code : 2; // should be 00 - uint_t EOI : 1; - uint_t SL : 1; - uint_t R : 1; + uint_t level : 3; + uint_t cw_code : 2; // should be 00 + uint_t EOI : 1; + uint_t SL : 1; + uint_t R : 1; }; struct ocw3 { - uint_t RIS : 1; - uint_t RR : 1; - uint_t P : 1; - uint_t cw_code : 2; // should be 01 - uint_t smm : 1; - uint_t esmm : 1; - uint_t zero2 : 1; + uint_t RIS : 1; + uint_t RR : 1; + uint_t P : 1; + uint_t cw_code : 2; // should be 01 + uint_t smm : 1; + uint_t esmm : 1; + uint_t zero2 : 1; }; struct pic_internal { - uchar_t master_irr; - uchar_t slave_irr; + uchar_t master_irr; + uchar_t slave_irr; - uchar_t master_isr; - uchar_t slave_isr; + uchar_t master_isr; + uchar_t slave_isr; - uchar_t master_icw1; - uchar_t master_icw2; - uchar_t master_icw3; - uchar_t master_icw4; + uchar_t master_icw1; + uchar_t master_icw2; + uchar_t master_icw3; + uchar_t master_icw4; - uchar_t slave_icw1; - uchar_t slave_icw2; - uchar_t slave_icw3; - uchar_t slave_icw4; + uchar_t slave_icw1; + uchar_t slave_icw2; + uchar_t slave_icw3; + uchar_t slave_icw4; - uchar_t master_imr; - uchar_t slave_imr; - uchar_t master_ocw2; - uchar_t master_ocw3; - uchar_t slave_ocw2; - uchar_t slave_ocw3; + uchar_t master_imr; + uchar_t slave_imr; + uchar_t master_ocw2; + uchar_t master_ocw3; + uchar_t slave_ocw2; + uchar_t slave_ocw3; - pic_state_t master_state; - pic_state_t slave_state; + pic_state_t master_state; + pic_state_t slave_state; }; static void DumpPICState(struct pic_internal *p) { - PrintDebug("8259 PIC: master_state=0x%x\n",p->master_state); - PrintDebug("8259 PIC: master_irr=0x%x\n",p->master_irr); - PrintDebug("8259 PIC: master_isr=0x%x\n",p->master_isr); - PrintDebug("8259 PIC: master_imr=0x%x\n",p->master_imr); + PrintDebug("8259 PIC: master_state=0x%x\n",p->master_state); + PrintDebug("8259 PIC: master_irr=0x%x\n",p->master_irr); + PrintDebug("8259 PIC: master_isr=0x%x\n",p->master_isr); + PrintDebug("8259 PIC: master_imr=0x%x\n",p->master_imr); - PrintDebug("8259 PIC: master_ocw2=0x%x\n",p->master_ocw2); - PrintDebug("8259 PIC: master_ocw3=0x%x\n",p->master_ocw3); + PrintDebug("8259 PIC: master_ocw2=0x%x\n",p->master_ocw2); + PrintDebug("8259 PIC: master_ocw3=0x%x\n",p->master_ocw3); - PrintDebug("8259 PIC: master_icw1=0x%x\n",p->master_icw1); - PrintDebug("8259 PIC: master_icw2=0x%x\n",p->master_icw2); - PrintDebug("8259 PIC: master_icw3=0x%x\n",p->master_icw3); - PrintDebug("8259 PIC: master_icw4=0x%x\n",p->master_icw4); + PrintDebug("8259 PIC: master_icw1=0x%x\n",p->master_icw1); + PrintDebug("8259 PIC: master_icw2=0x%x\n",p->master_icw2); + PrintDebug("8259 PIC: master_icw3=0x%x\n",p->master_icw3); + PrintDebug("8259 PIC: master_icw4=0x%x\n",p->master_icw4); - PrintDebug("8259 PIC: slave_state=0x%x\n",p->slave_state); - PrintDebug("8259 PIC: slave_irr=0x%x\n",p->slave_irr); - PrintDebug("8259 PIC: slave_isr=0x%x\n",p->slave_isr); - PrintDebug("8259 PIC: slave_imr=0x%x\n",p->slave_imr); + PrintDebug("8259 PIC: slave_state=0x%x\n",p->slave_state); + PrintDebug("8259 PIC: slave_irr=0x%x\n",p->slave_irr); + PrintDebug("8259 PIC: slave_isr=0x%x\n",p->slave_isr); + PrintDebug("8259 PIC: slave_imr=0x%x\n",p->slave_imr); - PrintDebug("8259 PIC: slave_ocw2=0x%x\n",p->slave_ocw2); - PrintDebug("8259 PIC: slave_ocw3=0x%x\n",p->slave_ocw3); + PrintDebug("8259 PIC: slave_ocw2=0x%x\n",p->slave_ocw2); + PrintDebug("8259 PIC: slave_ocw3=0x%x\n",p->slave_ocw3); - PrintDebug("8259 PIC: slave_icw1=0x%x\n",p->slave_icw1); - PrintDebug("8259 PIC: slave_icw2=0x%x\n",p->slave_icw2); - PrintDebug("8259 PIC: slave_icw3=0x%x\n",p->slave_icw3); - PrintDebug("8259 PIC: slave_icw4=0x%x\n",p->slave_icw4); + PrintDebug("8259 PIC: slave_icw1=0x%x\n",p->slave_icw1); + PrintDebug("8259 PIC: slave_icw2=0x%x\n",p->slave_icw2); + PrintDebug("8259 PIC: slave_icw3=0x%x\n",p->slave_icw3); + PrintDebug("8259 PIC: slave_icw4=0x%x\n",p->slave_icw4); } static int pic_raise_intr(void * private_data, int irq) { - struct pic_internal * state = (struct pic_internal*)private_data; + struct pic_internal * state = (struct pic_internal*)private_data; - if (irq == 2) { - irq = 9; - state->master_irr |= 0x04; // PAD - } + if (irq == 2) { + irq = 9; + state->master_irr |= 0x04; // PAD + } - PrintDebug("8259 PIC: Raising irq %d in the PIC\n", irq); + PrintDebug("8259 PIC: Raising irq %d in the PIC\n", irq); - if (irq <= 7) { - state->master_irr |= 0x01 << irq; - } else if ((irq > 7) && (irq < 16)) { - state->slave_irr |= 0x01 << (irq - 8); // PAD if -7 then irq 15=no irq - } else { - PrintError("8259 PIC: Invalid IRQ raised (%d)\n", irq); - return -1; - } + if (irq <= 7) { + state->master_irr |= 0x01 << irq; + } else if ((irq > 7) && (irq < 16)) { + state->slave_irr |= 0x01 << (irq - 8); // PAD if -7 then irq 15=no irq + } else { + PrintError("8259 PIC: Invalid IRQ raised (%d)\n", irq); + return -1; + } - return 0; + return 0; } static int pic_lower_intr(void *private_data, int irq) { - struct pic_internal *state = (struct pic_internal*)private_data; + struct pic_internal *state = (struct pic_internal*)private_data; - PrintDebug("[pic_lower_intr] IRQ line %d now low\n", irq); - if (irq <= 7) { + PrintDebug("[pic_lower_intr] IRQ line %d now low\n", irq); + if (irq <= 7) { - state->master_irr &= ~(1 << irq); - if ((state->master_irr & ~(state->master_imr)) == 0) { - PrintDebug("\t\tFIXME: Master maybe should do sth\n"); - } - } else if ((irq > 7) && (irq < 16)) { + state->master_irr &= ~(1 << irq); + if ((state->master_irr & ~(state->master_imr)) == 0) { + PrintDebug("\t\tFIXME: Master maybe should do sth\n"); + } + } else if ((irq > 7) && (irq < 16)) { - state->slave_irr &= ~(1 << (irq - 8)); - if ((state->slave_irr & (~(state->slave_imr))) == 0) { - PrintDebug("\t\tFIXME: Slave maybe should do sth\n"); + state->slave_irr &= ~(1 << (irq - 8)); + if ((state->slave_irr & (~(state->slave_imr))) == 0) { + PrintDebug("\t\tFIXME: Slave maybe should do sth\n"); + } } - } - return 0; + return 0; } static int pic_intr_pending(void * private_data) { - struct pic_internal * state = (struct pic_internal*)private_data; + struct pic_internal * state = (struct pic_internal*)private_data; - if ((state->master_irr & ~(state->master_imr)) || - (state->slave_irr & ~(state->slave_imr))) { - return 1; - } + if ((state->master_irr & ~(state->master_imr)) || + (state->slave_irr & ~(state->slave_imr))) { + return 1; + } - return 0; + return 0; } static int pic_get_intr_number(void * private_data) { - struct pic_internal * state = (struct pic_internal *)private_data; - int i = 0; - int irq = -1; - - PrintDebug("8259 PIC: getnum: master_irr: 0x%x master_imr: 0x%x\n", state->master_irr, state->master_imr); - PrintDebug("8259 PIC: getnum: slave_irr: 0x%x slave_imr: 0x%x\n", state->slave_irr, state->slave_imr); - - for (i = 0; i < 16; i++) { - if (i <= 7) { - if (((state->master_irr & ~(state->master_imr)) >> i) == 0x01) { - //state->master_isr |= (0x1 << i); - // reset the irr - //state->master_irr &= ~(0x1 << i); - PrintDebug("8259 PIC: IRQ: %d, master_icw2: %x\n", i, state->master_icw2); - irq= i + state->master_icw2; - break; - } - } else { - if (((state->slave_irr & ~(state->slave_imr)) >> (i - 8)) == 0x01) { - //state->slave_isr |= (0x1 << (i - 8)); - //state->slave_irr &= ~(0x1 << (i - 8)); - PrintDebug("8259 PIC: IRQ: %d, slave_icw2: %x\n", i, state->slave_icw2); - irq= (i - 8) + state->slave_icw2; - break; - } + struct pic_internal * state = (struct pic_internal *)private_data; + int i = 0; + int irq = -1; + + PrintDebug("8259 PIC: getnum: master_irr: 0x%x master_imr: 0x%x\n", state->master_irr, state->master_imr); + PrintDebug("8259 PIC: getnum: slave_irr: 0x%x slave_imr: 0x%x\n", state->slave_irr, state->slave_imr); + + for (i = 0; i < 16; i++) { + if (i <= 7) { + if (((state->master_irr & ~(state->master_imr)) >> i) == 0x01) { + //state->master_isr |= (0x1 << i); + // reset the irr + //state->master_irr &= ~(0x1 << i); + PrintDebug("8259 PIC: IRQ: %d, master_icw2: %x\n", i, state->master_icw2); + irq= i + state->master_icw2; + break; + } + } else { + if (((state->slave_irr & ~(state->slave_imr)) >> (i - 8)) == 0x01) { + //state->slave_isr |= (0x1 << (i - 8)); + //state->slave_irr &= ~(0x1 << (i - 8)); + PrintDebug("8259 PIC: IRQ: %d, slave_icw2: %x\n", i, state->slave_icw2); + irq= (i - 8) + state->slave_icw2; + break; + } + } } - } - if ((i == 15) || (i == 6)) { - DumpPICState(state); - } + if ((i == 15) || (i == 6)) { + DumpPICState(state); + } - if (i == 16) { - return -1; - } else { - return irq; - } + if (i == 16) { + return -1; + } else { + return irq; + } } /* The IRQ number is the number returned by pic_get_intr_number(), not the pin number */ static int pic_begin_irq(void * private_data, int irq) { - struct pic_internal * state = (struct pic_internal*)private_data; - - if ((irq >= state->master_icw2) && (irq <= state->master_icw2 + 7)) { - irq &= 0x7; - } else if ((irq >= state->slave_icw2) && (irq <= state->slave_icw2 + 7)) { - irq &= 0x7; - irq += 8; - } else { - // PrintError("8259 PIC: Could not find IRQ (0x%x) to Begin\n",irq); - return -1; - } + struct pic_internal * state = (struct pic_internal*)private_data; - if (irq <= 7) { - if (((state->master_irr & ~(state->master_imr)) >> irq) == 0x01) { - state->master_isr |= (0x1 << irq); - state->master_irr &= ~(0x1 << irq); + if ((irq >= state->master_icw2) && (irq <= state->master_icw2 + 7)) { + irq &= 0x7; + } else if ((irq >= state->slave_icw2) && (irq <= state->slave_icw2 + 7)) { + irq &= 0x7; + irq += 8; + } else { + // PrintError("8259 PIC: Could not find IRQ (0x%x) to Begin\n",irq); + return -1; } - } else { - state->slave_isr |= (0x1 << (irq - 8)); - state->slave_irr &= ~(0x1 << (irq - 8)); - } - return 0; + if (irq <= 7) { + if (((state->master_irr & ~(state->master_imr)) >> irq) == 0x01) { + state->master_isr |= (0x1 << irq); + state->master_irr &= ~(0x1 << irq); + } + } else { + state->slave_isr |= (0x1 << (irq - 8)); + state->slave_irr &= ~(0x1 << (irq - 8)); + } + + return 0; } /* -static int pic_end_irq(void * private_data, int irq) { + static int pic_end_irq(void * private_data, int irq) { return 0; -} + } */ static struct intr_ctrl_ops intr_ops = { - .intr_pending = pic_intr_pending, - .get_intr_number = pic_get_intr_number, - .raise_intr = pic_raise_intr, - .begin_irq = pic_begin_irq, - .lower_intr = pic_lower_intr, + .intr_pending = pic_intr_pending, + .get_intr_number = pic_get_intr_number, + .raise_intr = pic_raise_intr, + .begin_irq = pic_begin_irq, + .lower_intr = pic_lower_intr, }; @@ -328,131 +328,131 @@ static struct intr_ctrl_ops intr_ops = { static int read_master_port1(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct pic_internal * state = (struct pic_internal*)dev->private_data; + struct pic_internal * state = (struct pic_internal*)dev->private_data; - if (length != 1) { - PrintError("8259 PIC: Invalid Read length (rd_Master1)\n"); - return -1; - } + if (length != 1) { + PrintError("8259 PIC: Invalid Read length (rd_Master1)\n"); + return -1; + } - if ((state->master_ocw3 & 0x03) == 0x02) { - *(uchar_t *)dst = state->master_irr; - } else if ((state->master_ocw3 & 0x03) == 0x03) { - *(uchar_t *)dst = state->master_isr; - } else { - *(uchar_t *)dst = 0; - } + if ((state->master_ocw3 & 0x03) == 0x02) { + *(uchar_t *)dst = state->master_irr; + } else if ((state->master_ocw3 & 0x03) == 0x03) { + *(uchar_t *)dst = state->master_isr; + } else { + *(uchar_t *)dst = 0; + } - return 1; + return 1; } static int read_master_port2(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct pic_internal * state = (struct pic_internal*)dev->private_data; + struct pic_internal * state = (struct pic_internal*)dev->private_data; - if (length != 1) { - PrintError("8259 PIC: Invalid Read length (rd_Master2)\n"); - return -1; - } + if (length != 1) { + PrintError("8259 PIC: Invalid Read length (rd_Master2)\n"); + return -1; + } - *(uchar_t *)dst = state->master_imr; + *(uchar_t *)dst = state->master_imr; - return 1; + return 1; } static int read_slave_port1(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct pic_internal * state = (struct pic_internal*)dev->private_data; + struct pic_internal * state = (struct pic_internal*)dev->private_data; - if (length != 1) { - PrintError("8259 PIC: Invalid Read length (rd_Slave1)\n"); - return -1; - } + if (length != 1) { + PrintError("8259 PIC: Invalid Read length (rd_Slave1)\n"); + return -1; + } - if ((state->slave_ocw3 & 0x03) == 0x02) { - *(uchar_t*)dst = state->slave_irr; - } else if ((state->slave_ocw3 & 0x03) == 0x03) { - *(uchar_t *)dst = state->slave_isr; - } else { - *(uchar_t *)dst = 0; - } + if ((state->slave_ocw3 & 0x03) == 0x02) { + *(uchar_t*)dst = state->slave_irr; + } else if ((state->slave_ocw3 & 0x03) == 0x03) { + *(uchar_t *)dst = state->slave_isr; + } else { + *(uchar_t *)dst = 0; + } - return 1; + return 1; } static int read_slave_port2(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct pic_internal * state = (struct pic_internal*)dev->private_data; + struct pic_internal * state = (struct pic_internal*)dev->private_data; - if (length != 1) { - PrintError("8259 PIC: Invalid Read length (rd_Slave2)\n"); - return -1; - } + if (length != 1) { + PrintError("8259 PIC: Invalid Read length (rd_Slave2)\n"); + return -1; + } - *(uchar_t *)dst = state->slave_imr; + *(uchar_t *)dst = state->slave_imr; - return 1; + return 1; } static int write_master_port1(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct pic_internal * state = (struct pic_internal*)dev->private_data; - uchar_t cw = *(uchar_t *)src; + struct pic_internal * state = (struct pic_internal*)dev->private_data; + uchar_t cw = *(uchar_t *)src; - PrintDebug("8259 PIC: Write master port 1 with 0x%x\n",cw); + PrintDebug("8259 PIC: Write master port 1 with 0x%x\n",cw); - if (length != 1) { - PrintError("8259 PIC: Invalid Write length (wr_Master1)\n"); - return -1; - } + if (length != 1) { + PrintError("8259 PIC: Invalid Write length (wr_Master1)\n"); + return -1; + } - if (IS_ICW1(cw)) { + if (IS_ICW1(cw)) { - PrintDebug("8259 PIC: Setting ICW1 = %x (wr_Master1)\n", cw); + PrintDebug("8259 PIC: Setting ICW1 = %x (wr_Master1)\n", cw); - state->master_icw1 = cw; - state->master_state = ICW2; + state->master_icw1 = cw; + state->master_state = ICW2; - } else if (state->master_state == READY) { - if (IS_OCW2(cw)) { - // handle the EOI here - struct ocw2 * cw2 = (struct ocw2*)&cw; + } else if (state->master_state == READY) { + if (IS_OCW2(cw)) { + // handle the EOI here + struct ocw2 * cw2 = (struct ocw2*)&cw; - PrintDebug("8259 PIC: Handling OCW2 = %x (wr_Master1)\n", cw); + PrintDebug("8259 PIC: Handling OCW2 = %x (wr_Master1)\n", cw); - if ((cw2->EOI) && (!cw2->R) && (cw2->SL)) { - // specific EOI; - state->master_isr &= ~(0x01 << cw2->level); - } else if ((cw2->EOI) & (!cw2->R) && (!cw2->SL)) { - int i; - // Non-specific EOI - PrintDebug("8259 PIC: Pre ISR = %x (wr_Master1)\n", state->master_isr); - for (i = 0; i < 8; i++) { - if (state->master_isr & (0x01 << i)) { - state->master_isr &= ~(0x01 << i); - break; - } - } - PrintDebug("8259 PIC: Post ISR = %x (wr_Master1)\n", state->master_isr); - } else { - PrintError("8259 PIC: Command not handled, or in error (wr_Master1)\n"); - return -1; - } - - state->master_ocw2 = cw; - } else if (IS_OCW3(cw)) { - PrintDebug("8259 PIC: Handling OCW3 = %x (wr_Master1)\n", cw); - state->master_ocw3 = cw; + if ((cw2->EOI) && (!cw2->R) && (cw2->SL)) { + // specific EOI; + state->master_isr &= ~(0x01 << cw2->level); + } else if ((cw2->EOI) & (!cw2->R) && (!cw2->SL)) { + int i; + // Non-specific EOI + PrintDebug("8259 PIC: Pre ISR = %x (wr_Master1)\n", state->master_isr); + for (i = 0; i < 8; i++) { + if (state->master_isr & (0x01 << i)) { + state->master_isr &= ~(0x01 << i); + break; + } + } + PrintDebug("8259 PIC: Post ISR = %x (wr_Master1)\n", state->master_isr); + } else { + PrintError("8259 PIC: Command not handled, or in error (wr_Master1)\n"); + return -1; + } + + state->master_ocw2 = cw; + } else if (IS_OCW3(cw)) { + PrintDebug("8259 PIC: Handling OCW3 = %x (wr_Master1)\n", cw); + state->master_ocw3 = cw; + } else { + PrintError("8259 PIC: Invalid OCW to PIC (wr_Master1)\n"); + PrintError("8259 PIC: CW=%x\n", cw); + return -1; + } } else { - PrintError("8259 PIC: Invalid OCW to PIC (wr_Master1)\n"); - PrintError("8259 PIC: CW=%x\n", cw); - return -1; + PrintError("8259 PIC: Invalid PIC State (wr_Master1)\n"); + PrintError("8259 PIC: CW=%x\n", cw); + return -1; } - } else { - PrintError("8259 PIC: Invalid PIC State (wr_Master1)\n"); - PrintError("8259 PIC: CW=%x\n", cw); - return -1; - } - return 1; + return 1; } static int write_master_port2(ushort_t port, void * src, uint_t length, struct vm_device * dev) { @@ -462,110 +462,110 @@ static int write_master_port2(ushort_t port, void * src, uint_t length, struct v PrintDebug("8259 PIC: Write master port 2 with 0x%x\n",cw); if (length != 1) { - PrintError("8259 PIC: Invalid Write length (wr_Master2)\n"); - return -1; + PrintError("8259 PIC: Invalid Write length (wr_Master2)\n"); + return -1; } if (state->master_state == ICW2) { - struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1); + struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1); - PrintDebug("8259 PIC: Setting ICW2 = %x (wr_Master2)\n", cw); - state->master_icw2 = cw; + PrintDebug("8259 PIC: Setting ICW2 = %x (wr_Master2)\n", cw); + state->master_icw2 = cw; - if (cw1->sngl == 0) { - state->master_state = ICW3; - } else if (cw1->ic4 == 1) { - state->master_state = ICW4; - } else { - state->master_state = READY; - } + if (cw1->sngl == 0) { + state->master_state = ICW3; + } else if (cw1->ic4 == 1) { + state->master_state = ICW4; + } else { + state->master_state = READY; + } } else if (state->master_state == ICW3) { - struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1); + struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1); - PrintDebug("8259 PIC: Setting ICW3 = %x (wr_Master2)\n", cw); + PrintDebug("8259 PIC: Setting ICW3 = %x (wr_Master2)\n", cw); - state->master_icw3 = cw; + state->master_icw3 = cw; - if (cw1->ic4 == 1) { - state->master_state = ICW4; - } else { - state->master_state = READY; - } + if (cw1->ic4 == 1) { + state->master_state = ICW4; + } else { + state->master_state = READY; + } } else if (state->master_state == ICW4) { - PrintDebug("8259 PIC: Setting ICW4 = %x (wr_Master2)\n", cw); - state->master_icw4 = cw; - state->master_state = READY; + PrintDebug("8259 PIC: Setting ICW4 = %x (wr_Master2)\n", cw); + state->master_icw4 = cw; + state->master_state = READY; } else if (state->master_state == READY) { - PrintDebug("8259 PIC: Setting IMR = %x (wr_Master2)\n", cw); - state->master_imr = cw; + PrintDebug("8259 PIC: Setting IMR = %x (wr_Master2)\n", cw); + state->master_imr = cw; } else { - // error - PrintError("8259 PIC: Invalid master PIC State (wr_Master2)\n"); - return -1; + // error + PrintError("8259 PIC: Invalid master PIC State (wr_Master2)\n"); + return -1; } return 1; } static int write_slave_port1(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct pic_internal * state = (struct pic_internal*)dev->private_data; - uchar_t cw = *(uchar_t *)src; + struct pic_internal * state = (struct pic_internal*)dev->private_data; + uchar_t cw = *(uchar_t *)src; - PrintDebug("8259 PIC: Write slave port 1 with 0x%x\n",cw); + PrintDebug("8259 PIC: Write slave port 1 with 0x%x\n",cw); - if (length != 1) { - // error - PrintError("8259 PIC: Invalid Write length (wr_Slave1)\n"); - return -1; - } + if (length != 1) { + // error + PrintError("8259 PIC: Invalid Write length (wr_Slave1)\n"); + return -1; + } - if (IS_ICW1(cw)) { - PrintDebug("8259 PIC: Setting ICW1 = %x (wr_Slave1)\n", cw); - state->slave_icw1 = cw; - state->slave_state = ICW2; - } else if (state->slave_state == READY) { - if (IS_OCW2(cw)) { - // handle the EOI here - struct ocw2 * cw2 = (struct ocw2 *)&cw; + if (IS_ICW1(cw)) { + PrintDebug("8259 PIC: Setting ICW1 = %x (wr_Slave1)\n", cw); + state->slave_icw1 = cw; + state->slave_state = ICW2; + } else if (state->slave_state == READY) { + if (IS_OCW2(cw)) { + // handle the EOI here + struct ocw2 * cw2 = (struct ocw2 *)&cw; - PrintDebug("8259 PIC: Setting OCW2 = %x (wr_Slave1)\n", cw); + PrintDebug("8259 PIC: Setting OCW2 = %x (wr_Slave1)\n", cw); - if ((cw2->EOI) && (!cw2->R) && (cw2->SL)) { - // specific EOI; - state->slave_isr &= ~(0x01 << cw2->level); - } else if ((cw2->EOI) & (!cw2->R) && (!cw2->SL)) { - int i; - // Non-specific EOI - PrintDebug("8259 PIC: Pre ISR = %x (wr_Slave1)\n", state->slave_isr); - for (i = 0; i < 8; i++) { - if (state->slave_isr & (0x01 << i)) { - state->slave_isr &= ~(0x01 << i); - break; - } - } - PrintDebug("8259 PIC: Post ISR = %x (wr_Slave1)\n", state->slave_isr); - } else { - PrintError("8259 PIC: Command not handled or invalid (wr_Slave1)\n"); - return -1; - } - - state->slave_ocw2 = cw; - } else if (IS_OCW3(cw)) { - // Basically sets the IRR/ISR read flag - PrintDebug("8259 PIC: Setting OCW3 = %x (wr_Slave1)\n", cw); - state->slave_ocw3 = cw; + if ((cw2->EOI) && (!cw2->R) && (cw2->SL)) { + // specific EOI; + state->slave_isr &= ~(0x01 << cw2->level); + } else if ((cw2->EOI) & (!cw2->R) && (!cw2->SL)) { + int i; + // Non-specific EOI + PrintDebug("8259 PIC: Pre ISR = %x (wr_Slave1)\n", state->slave_isr); + for (i = 0; i < 8; i++) { + if (state->slave_isr & (0x01 << i)) { + state->slave_isr &= ~(0x01 << i); + break; + } + } + PrintDebug("8259 PIC: Post ISR = %x (wr_Slave1)\n", state->slave_isr); + } else { + PrintError("8259 PIC: Command not handled or invalid (wr_Slave1)\n"); + return -1; + } + + state->slave_ocw2 = cw; + } else if (IS_OCW3(cw)) { + // Basically sets the IRR/ISR read flag + PrintDebug("8259 PIC: Setting OCW3 = %x (wr_Slave1)\n", cw); + state->slave_ocw3 = cw; + } else { + PrintError("8259 PIC: Invalid command work (wr_Slave1)\n"); + return -1; + } } else { - PrintError("8259 PIC: Invalid command work (wr_Slave1)\n"); - return -1; + PrintError("8259 PIC: Invalid State writing (wr_Slave1)\n"); + return -1; } - } else { - PrintError("8259 PIC: Invalid State writing (wr_Slave1)\n"); - return -1; - } - return 1; + return 1; } static int write_slave_port2(ushort_t port, void * src, uint_t length, struct vm_device * dev) { @@ -575,48 +575,48 @@ static int write_slave_port2(ushort_t port, void * src, uint_t length, struct vm PrintDebug("8259 PIC: Write slave port 2 with 0x%x\n",cw); if (length != 1) { - PrintError("8259 PIC: Invalid write length (wr_Slave2)\n"); - return -1; + PrintError("8259 PIC: Invalid write length (wr_Slave2)\n"); + return -1; } if (state->slave_state == ICW2) { - struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1); + struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1); - PrintDebug("8259 PIC: Setting ICW2 = %x (wr_Slave2)\n", cw); + PrintDebug("8259 PIC: Setting ICW2 = %x (wr_Slave2)\n", cw); - state->slave_icw2 = cw; + state->slave_icw2 = cw; - if (cw1->sngl == 0) { - state->slave_state = ICW3; - } else if (cw1->ic4 == 1) { - state->slave_state = ICW4; - } else { - state->slave_state = READY; - } + if (cw1->sngl == 0) { + state->slave_state = ICW3; + } else if (cw1->ic4 == 1) { + state->slave_state = ICW4; + } else { + state->slave_state = READY; + } } else if (state->slave_state == ICW3) { - struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1); + struct icw1 * cw1 = (struct icw1 *)&(state->master_icw1); - PrintDebug("8259 PIC: Setting ICW3 = %x (wr_Slave2)\n", cw); + PrintDebug("8259 PIC: Setting ICW3 = %x (wr_Slave2)\n", cw); - state->slave_icw3 = cw; + state->slave_icw3 = cw; - if (cw1->ic4 == 1) { - state->slave_state = ICW4; - } else { - state->slave_state = READY; - } + if (cw1->ic4 == 1) { + state->slave_state = ICW4; + } else { + state->slave_state = READY; + } } else if (state->slave_state == ICW4) { - PrintDebug("8259 PIC: Setting ICW4 = %x (wr_Slave2)\n", cw); - state->slave_icw4 = cw; - state->slave_state = READY; + PrintDebug("8259 PIC: Setting ICW4 = %x (wr_Slave2)\n", cw); + state->slave_icw4 = cw; + state->slave_state = READY; } else if (state->slave_state == READY) { - PrintDebug("8259 PIC: Setting IMR = %x (wr_Slave2)\n", cw); - state->slave_imr = cw; + PrintDebug("8259 PIC: Setting IMR = %x (wr_Slave2)\n", cw); + state->slave_imr = cw; } else { - PrintError("8259 PIC: Invalid State at write (wr_Slave2)\n"); - return -1; + PrintError("8259 PIC: Invalid State at write (wr_Slave2)\n"); + return -1; } return 1; @@ -630,50 +630,50 @@ static int write_slave_port2(ushort_t port, void * src, uint_t length, struct vm static int pic_init(struct vm_device * dev) { - struct pic_internal * state = (struct pic_internal*)dev->private_data; - - v3_register_intr_controller(dev->vm, &intr_ops, state); - - state->master_irr = 0; - state->master_isr = 0; - state->master_icw1 = 0; - state->master_icw2 = 0; - state->master_icw3 = 0; - state->master_icw4 = 0; - state->master_imr = 0; - state->master_ocw2 = 0; - state->master_ocw3 = 0x02; - state->master_state = ICW1; - - - state->slave_irr = 0; - state->slave_isr = 0; - state->slave_icw1 = 0; - state->slave_icw2 = 0; - state->slave_icw3 = 0; - state->slave_icw4 = 0; - state->slave_imr = 0; - state->slave_ocw2 = 0; - state->slave_ocw3 = 0x02; - state->slave_state = ICW1; - - - v3_dev_hook_io(dev, MASTER_PORT1, &read_master_port1, &write_master_port1); - v3_dev_hook_io(dev, MASTER_PORT2, &read_master_port2, &write_master_port2); - v3_dev_hook_io(dev, SLAVE_PORT1, &read_slave_port1, &write_slave_port1); - v3_dev_hook_io(dev, SLAVE_PORT2, &read_slave_port2, &write_slave_port2); + struct pic_internal * state = (struct pic_internal*)dev->private_data; - return 0; + v3_register_intr_controller(dev->vm, &intr_ops, state); + + state->master_irr = 0; + state->master_isr = 0; + state->master_icw1 = 0; + state->master_icw2 = 0; + state->master_icw3 = 0; + state->master_icw4 = 0; + state->master_imr = 0; + state->master_ocw2 = 0; + state->master_ocw3 = 0x02; + state->master_state = ICW1; + + + state->slave_irr = 0; + state->slave_isr = 0; + state->slave_icw1 = 0; + state->slave_icw2 = 0; + state->slave_icw3 = 0; + state->slave_icw4 = 0; + state->slave_imr = 0; + state->slave_ocw2 = 0; + state->slave_ocw3 = 0x02; + state->slave_state = ICW1; + + + v3_dev_hook_io(dev, MASTER_PORT1, &read_master_port1, &write_master_port1); + v3_dev_hook_io(dev, MASTER_PORT2, &read_master_port2, &write_master_port2); + v3_dev_hook_io(dev, SLAVE_PORT1, &read_slave_port1, &write_slave_port1); + v3_dev_hook_io(dev, SLAVE_PORT2, &read_slave_port2, &write_slave_port2); + + return 0; } static int pic_deinit(struct vm_device * dev) { - v3_dev_unhook_io(dev, MASTER_PORT1); - v3_dev_unhook_io(dev, MASTER_PORT2); - v3_dev_unhook_io(dev, SLAVE_PORT1); - v3_dev_unhook_io(dev, SLAVE_PORT2); + v3_dev_unhook_io(dev, MASTER_PORT1); + v3_dev_unhook_io(dev, MASTER_PORT2); + v3_dev_unhook_io(dev, SLAVE_PORT1); + v3_dev_unhook_io(dev, SLAVE_PORT2); - return 0; + return 0; } @@ -683,24 +683,20 @@ static int pic_deinit(struct vm_device * dev) { static struct vm_device_ops dev_ops = { - .init = pic_init, - .deinit = pic_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, + .init = pic_init, + .deinit = pic_deinit, + .reset = NULL, + .start = NULL, + .stop = NULL, }; struct vm_device * v3_create_pic() { - struct pic_internal * state = NULL; - state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal)); - V3_ASSERT(state != NULL); + struct pic_internal * state = NULL; + state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal)); + V3_ASSERT(state != NULL); - struct vm_device *device = v3_create_device("8259A", &dev_ops, state); + struct vm_device *device = v3_create_device("8259A", &dev_ops, state); - return device; + return device; } - - - - diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index df9dd12..cb58823 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -116,653 +116,652 @@ typedef enum { APIC_TMR_INT, APIC_THERM_INT, APIC_PERF_INT, struct apic_msr { - union { - uint64_t val; - struct { - uchar_t rsvd; - uint_t bootstrap_cpu : 1; - uint_t rsvd2 : 2; - uint_t apic_enable : 1; - ullong_t base_addr : 40; - uint_t rsvd3 : 12; + union { + uint64_t val; + struct { + uchar_t rsvd; + uint_t bootstrap_cpu : 1; + uint_t rsvd2 : 2; + uint_t apic_enable : 1; + ullong_t base_addr : 40; + uint_t rsvd3 : 12; + } __attribute__((packed)); } __attribute__((packed)); - } __attribute__((packed)); } __attribute__((packed)); struct apic_state { - addr_t base_addr; - - /* MSRs */ - v3_msr_t base_addr_msr; - - - /* memory map registers */ - - struct lapic_id_reg lapic_id; - struct apic_ver_reg apic_ver; - struct ext_apic_ctrl_reg ext_apic_ctrl; - struct local_vec_tbl_reg local_vec_tbl; - struct tmr_vec_tbl_reg tmr_vec_tbl; - struct tmr_div_cfg_reg tmr_div_cfg; - struct lint_vec_tbl_reg lint0_vec_tbl; - struct lint_vec_tbl_reg lint1_vec_tbl; - struct perf_ctr_loc_vec_tbl_reg perf_ctr_loc_vec_tbl; - struct therm_loc_vec_tbl_reg therm_loc_vec_tbl; - struct err_vec_tbl_reg err_vec_tbl; - struct err_status_reg err_status; - struct spurious_int_reg spurious_int; - struct int_cmd_reg int_cmd; - struct log_dst_reg log_dst; - struct dst_fmt_reg dst_fmt; - struct arb_prio_reg arb_prio; - struct task_prio_reg task_prio; - struct proc_prio_reg proc_prio; - struct ext_apic_feature_reg ext_apic_feature; - struct spec_eoi_reg spec_eoi; + addr_t base_addr; + + /* MSRs */ + v3_msr_t base_addr_msr; + + + /* memory map registers */ + + struct lapic_id_reg lapic_id; + struct apic_ver_reg apic_ver; + struct ext_apic_ctrl_reg ext_apic_ctrl; + struct local_vec_tbl_reg local_vec_tbl; + struct tmr_vec_tbl_reg tmr_vec_tbl; + struct tmr_div_cfg_reg tmr_div_cfg; + struct lint_vec_tbl_reg lint0_vec_tbl; + struct lint_vec_tbl_reg lint1_vec_tbl; + struct perf_ctr_loc_vec_tbl_reg perf_ctr_loc_vec_tbl; + struct therm_loc_vec_tbl_reg therm_loc_vec_tbl; + struct err_vec_tbl_reg err_vec_tbl; + struct err_status_reg err_status; + struct spurious_int_reg spurious_int; + struct int_cmd_reg int_cmd; + struct log_dst_reg log_dst; + struct dst_fmt_reg dst_fmt; + struct arb_prio_reg arb_prio; + struct task_prio_reg task_prio; + struct proc_prio_reg proc_prio; + struct ext_apic_feature_reg ext_apic_feature; + struct spec_eoi_reg spec_eoi; - uint32_t tmr_cur_cnt; - uint32_t tmr_init_cnt; + uint32_t tmr_cur_cnt; + uint32_t tmr_init_cnt; - uint32_t rem_rd_data; + uint32_t rem_rd_data; - uchar_t int_req_reg[32]; - uchar_t int_svc_reg[32]; - uchar_t int_en_reg[32]; - uchar_t trig_mode_reg[32]; + uchar_t int_req_reg[32]; + uchar_t int_svc_reg[32]; + uchar_t int_en_reg[32]; + uchar_t trig_mode_reg[32]; - uint32_t eoi; + uint32_t eoi; }; static void init_apic_state(struct apic_state * apic) { - apic->base_addr = DEFAULT_BASE_ADDR; - apic->base_addr_msr.value = 0x0000000000000900LL; - apic->base_addr_msr.value |= ((uint64_t)DEFAULT_BASE_ADDR); - - PrintDebug("Sizeof Interrupt Request Register %d, should be 32\n", - (uint_t)sizeof(apic->int_req_reg)); - - memset(apic->int_req_reg, 0, sizeof(apic->int_req_reg)); - memset(apic->int_svc_reg, 0, sizeof(apic->int_svc_reg)); - memset(apic->int_en_reg, 0xff, sizeof(apic->int_en_reg)); - memset(apic->trig_mode_reg, 0, sizeof(apic->trig_mode_reg)); - - apic->eoi = 0x00000000; - apic->rem_rd_data = 0x00000000; - apic->tmr_init_cnt = 0x00000000; - apic->tmr_cur_cnt = 0x00000000; - - // TODO: - // We need to figure out what the APIC ID is.... - apic->lapic_id.val = 0x00000000; - - // The P6 has 6 LVT entries, so we set the value to (6-1)... - apic->apic_ver.val = 0x80050010; - - apic->task_prio.val = 0x00000000; - apic->arb_prio.val = 0x00000000; - apic->proc_prio.val = 0x00000000; - apic->log_dst.val = 0x00000000; - apic->dst_fmt.val = 0xffffffff; - apic->spurious_int.val = 0x000000ff; - apic->err_status.val = 0x00000000; - apic->int_cmd.val = 0x0000000000000000LL; - apic->tmr_vec_tbl.val = 0x00010000; - apic->therm_loc_vec_tbl.val = 0x00010000; - apic->perf_ctr_loc_vec_tbl.val = 0x00010000; - apic->lint0_vec_tbl.val = 0x00010000; - apic->lint1_vec_tbl.val = 0x00010000; - apic->err_vec_tbl.val = 0x00010000; - apic->tmr_div_cfg.val = 0x00000000; - apic->ext_apic_feature.val = 0x00040007; - apic->ext_apic_ctrl.val = 0x00000000; - apic->spec_eoi.val = 0x00000000; + apic->base_addr = DEFAULT_BASE_ADDR; + apic->base_addr_msr.value = 0x0000000000000900LL; + apic->base_addr_msr.value |= ((uint64_t)DEFAULT_BASE_ADDR); + + PrintDebug("Sizeof Interrupt Request Register %d, should be 32\n", + (uint_t)sizeof(apic->int_req_reg)); + + memset(apic->int_req_reg, 0, sizeof(apic->int_req_reg)); + memset(apic->int_svc_reg, 0, sizeof(apic->int_svc_reg)); + memset(apic->int_en_reg, 0xff, sizeof(apic->int_en_reg)); + memset(apic->trig_mode_reg, 0, sizeof(apic->trig_mode_reg)); + + apic->eoi = 0x00000000; + apic->rem_rd_data = 0x00000000; + apic->tmr_init_cnt = 0x00000000; + apic->tmr_cur_cnt = 0x00000000; + + // TODO: + // We need to figure out what the APIC ID is.... + apic->lapic_id.val = 0x00000000; + + // The P6 has 6 LVT entries, so we set the value to (6-1)... + apic->apic_ver.val = 0x80050010; + + apic->task_prio.val = 0x00000000; + apic->arb_prio.val = 0x00000000; + apic->proc_prio.val = 0x00000000; + apic->log_dst.val = 0x00000000; + apic->dst_fmt.val = 0xffffffff; + apic->spurious_int.val = 0x000000ff; + apic->err_status.val = 0x00000000; + apic->int_cmd.val = 0x0000000000000000LL; + apic->tmr_vec_tbl.val = 0x00010000; + apic->therm_loc_vec_tbl.val = 0x00010000; + apic->perf_ctr_loc_vec_tbl.val = 0x00010000; + apic->lint0_vec_tbl.val = 0x00010000; + apic->lint1_vec_tbl.val = 0x00010000; + apic->err_vec_tbl.val = 0x00010000; + apic->tmr_div_cfg.val = 0x00000000; + apic->ext_apic_feature.val = 0x00040007; + apic->ext_apic_ctrl.val = 0x00000000; + apic->spec_eoi.val = 0x00000000; } static int read_apic_msr(uint_t msr, v3_msr_t * dst, void * priv_data) { - struct vm_device * dev = (struct vm_device *)priv_data; - struct apic_state * apic = (struct apic_state *)dev->private_data; - PrintError("READING APIC BASE ADDR: HI=%x LO=%x\n", apic->base_addr_msr.hi, apic->base_addr_msr.lo); + struct vm_device * dev = (struct vm_device *)priv_data; + struct apic_state * apic = (struct apic_state *)dev->private_data; + PrintError("READING APIC BASE ADDR: HI=%x LO=%x\n", apic->base_addr_msr.hi, apic->base_addr_msr.lo); - return -1; + return -1; } static int write_apic_msr(uint_t msr, v3_msr_t src, void * priv_data) { - // struct vm_device * dev = (struct vm_device *)priv_data; - // struct apic_state * apic = (struct apic_state *)dev->private_data; + // struct vm_device * dev = (struct vm_device *)priv_data; + // struct apic_state * apic = (struct apic_state *)dev->private_data; - PrintError("WRITING APIC BASE ADDR: HI=%x LO=%x\n", src.hi, src.lo); + PrintError("WRITING APIC BASE ADDR: HI=%x LO=%x\n", src.hi, src.lo); - return -1; + return -1; } // irq_num is the bit offset into a 256 bit buffer... static int activate_apic_irq(struct apic_state * apic, uint32_t irq_num) { - int major_offset = (irq_num & ~0x00000007) >> 3; - int minor_offset = irq_num & 0x00000007; - uchar_t * req_location = apic->int_req_reg + major_offset; - uchar_t * en_location = apic->int_en_reg + major_offset; - uchar_t flag = 0x1 << minor_offset; - - if (irq_num <= 15) { - PrintError("Attempting to raise an invalid interrupt: %d\n", irq_num); - return -1; - } + int major_offset = (irq_num & ~0x00000007) >> 3; + int minor_offset = irq_num & 0x00000007; + uchar_t * req_location = apic->int_req_reg + major_offset; + uchar_t * en_location = apic->int_en_reg + major_offset; + uchar_t flag = 0x1 << minor_offset; + + if (irq_num <= 15) { + PrintError("Attempting to raise an invalid interrupt: %d\n", irq_num); + return -1; + } - PrintDebug("Raising APIC IRQ %d\n", irq_num); + PrintDebug("Raising APIC IRQ %d\n", irq_num); - if (*en_location & flag) { - *req_location |= flag; - } else { - PrintDebug("Interrupt not enabled... %.2x\n", *en_location); - return 0; - } + if (*en_location & flag) { + *req_location |= flag; + } else { + PrintDebug("Interrupt not enabled... %.2x\n", *en_location); + return 0; + } - return 0; + return 0; } static int apic_do_eoi(struct apic_state * apic) { - int i = 0, j = 0; + int i = 0, j = 0; - // We iterate backwards to find the highest priority - for (i = 31; i >= 0; i--) { - uchar_t * svc_major = apic->int_svc_reg + i; + // We iterate backwards to find the highest priority + for (i = 31; i >= 0; i--) { + uchar_t * svc_major = apic->int_svc_reg + i; - if ((*svc_major) & 0xff) { - for (j = 7; j >= 0; j--) { - uchar_t flag = 0x1 << j; - if ((*svc_major) & flag) { - *svc_major &= ~flag; - return 0; + if ((*svc_major) & 0xff) { + for (j = 7; j >= 0; j--) { + uchar_t flag = 0x1 << j; + if ((*svc_major) & flag) { + *svc_major &= ~flag; + return 0; + } + } } - } } - } - return 0; + return 0; } static int activate_internal_irq(struct apic_state * apic, apic_irq_type_t int_type) { - uint32_t vec_num = 0; - uint32_t del_mode = 0; - int masked = 0; - - - switch (int_type) { - case APIC_TMR_INT: - vec_num = apic->tmr_vec_tbl.vec; - del_mode = APIC_FIXED_DELIVERY; - masked = apic->tmr_vec_tbl.mask; - break; - case APIC_THERM_INT: - vec_num = apic->therm_loc_vec_tbl.vec; - del_mode = apic->therm_loc_vec_tbl.msg_type; - masked = apic->therm_loc_vec_tbl.mask; - break; - case APIC_PERF_INT: - vec_num = apic->perf_ctr_loc_vec_tbl.vec; - del_mode = apic->perf_ctr_loc_vec_tbl.msg_type; - masked = apic->perf_ctr_loc_vec_tbl.mask; - break; - case APIC_LINT0_INT: - vec_num = apic->lint0_vec_tbl.vec; - del_mode = apic->lint0_vec_tbl.msg_type; - masked = apic->lint0_vec_tbl.mask; - break; - case APIC_LINT1_INT: - vec_num = apic->lint1_vec_tbl.vec; - del_mode = apic->lint1_vec_tbl.msg_type; - masked = apic->lint1_vec_tbl.mask; - break; - case APIC_ERR_INT: - vec_num = apic->err_vec_tbl.vec; - del_mode = APIC_FIXED_DELIVERY; - masked = apic->err_vec_tbl.mask; - break; - default: - PrintError("Invalid APIC interrupt type\n"); - return -1; - } + uint32_t vec_num = 0; + uint32_t del_mode = 0; + int masked = 0; + + + switch (int_type) { + case APIC_TMR_INT: + vec_num = apic->tmr_vec_tbl.vec; + del_mode = APIC_FIXED_DELIVERY; + masked = apic->tmr_vec_tbl.mask; + break; + case APIC_THERM_INT: + vec_num = apic->therm_loc_vec_tbl.vec; + del_mode = apic->therm_loc_vec_tbl.msg_type; + masked = apic->therm_loc_vec_tbl.mask; + break; + case APIC_PERF_INT: + vec_num = apic->perf_ctr_loc_vec_tbl.vec; + del_mode = apic->perf_ctr_loc_vec_tbl.msg_type; + masked = apic->perf_ctr_loc_vec_tbl.mask; + break; + case APIC_LINT0_INT: + vec_num = apic->lint0_vec_tbl.vec; + del_mode = apic->lint0_vec_tbl.msg_type; + masked = apic->lint0_vec_tbl.mask; + break; + case APIC_LINT1_INT: + vec_num = apic->lint1_vec_tbl.vec; + del_mode = apic->lint1_vec_tbl.msg_type; + masked = apic->lint1_vec_tbl.mask; + break; + case APIC_ERR_INT: + vec_num = apic->err_vec_tbl.vec; + del_mode = APIC_FIXED_DELIVERY; + masked = apic->err_vec_tbl.mask; + break; + default: + PrintError("Invalid APIC interrupt type\n"); + return -1; + } - // interrupt is masked, don't send - if (masked == 1) { - PrintDebug("Inerrupt is masked\n"); - return 0; - } + // interrupt is masked, don't send + if (masked == 1) { + PrintDebug("Inerrupt is masked\n"); + return 0; + } - if (del_mode == APIC_FIXED_DELIVERY) { - //PrintDebug("Activating internal APIC IRQ %d\n", vec_num); - return activate_apic_irq(apic, vec_num); - } else { - PrintError("Unhandled Delivery Mode\n"); - return -1; - } + if (del_mode == APIC_FIXED_DELIVERY) { + //PrintDebug("Activating internal APIC IRQ %d\n", vec_num); + return activate_apic_irq(apic, vec_num); + } else { + PrintError("Unhandled Delivery Mode\n"); + return -1; + } } static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) { - struct vm_device * dev = (struct vm_device *)priv_data; - struct apic_state * apic = (struct apic_state *)dev->private_data; - addr_t reg_addr = guest_addr - apic->base_addr; - struct apic_msr * msr = (struct apic_msr *)&(apic->base_addr_msr.value); - uint32_t val = 0; + struct vm_device * dev = (struct vm_device *)priv_data; + struct apic_state * apic = (struct apic_state *)dev->private_data; + addr_t reg_addr = guest_addr - apic->base_addr; + struct apic_msr * msr = (struct apic_msr *)&(apic->base_addr_msr.value); + uint32_t val = 0; - PrintDebug("Read apic address space (%p)\n", - (void *)guest_addr); + PrintDebug("Read apic address space (%p)\n", + (void *)guest_addr); - if (msr->apic_enable == 0) { - PrintError("Write to APIC address space with disabled APIC\n"); - return -1; - } - - - /* Because "May not be supported" doesn't matter to Linux developers... */ - /* if (length != 4) { */ - /* PrintError("Invalid apic read length (%d)\n", length); */ - /* return -1; */ - /* } */ - - switch (reg_addr & ~0x3) { - case EOI_OFFSET: - // Well, only an idiot would read from a architectural write only register - // Oh, Hello Linux. - // PrintError("Attempting to read from write only register\n"); - // return -1; - break; - - // data registers - case APIC_ID_OFFSET: - val = apic->lapic_id.val; - break; - case APIC_VERSION_OFFSET: - val = apic->apic_ver.val; - break; - case TPR_OFFSET: - val = apic->task_prio.val; - break; - case APR_OFFSET: - val = apic->arb_prio.val; - break; - case PPR_OFFSET: - val = apic->proc_prio.val; - break; - case REMOTE_READ_OFFSET: - val = apic->rem_rd_data; - break; - case LDR_OFFSET: - val = apic->log_dst.val; - break; - case DFR_OFFSET: - val = apic->dst_fmt.val; - break; - case SPURIOUS_INT_VEC_OFFSET: - val = apic->spurious_int.val; - break; - case ESR_OFFSET: - val = apic->err_status.val; - break; - case TMR_LOC_VEC_TBL_OFFSET: - val = apic->tmr_vec_tbl.val; - break; - case LINT0_VEC_TBL_OFFSET: - val = apic->lint0_vec_tbl.val; - break; - case LINT1_VEC_TBL_OFFSET: - val = apic->lint1_vec_tbl.val; - break; - case ERR_VEC_TBL_OFFSET: - val = apic->err_vec_tbl.val; - break; - case TMR_INIT_CNT_OFFSET: - val = apic->tmr_init_cnt; - break; - case TMR_DIV_CFG_OFFSET: - val = apic->tmr_div_cfg.val; - break; - - case IER_OFFSET0: - val = *(uint32_t *)(apic->int_en_reg); - break; - case IER_OFFSET1: - val = *(uint32_t *)(apic->int_en_reg + 4); - break; - case IER_OFFSET2: - val = *(uint32_t *)(apic->int_en_reg + 8); - break; - case IER_OFFSET3: - val = *(uint32_t *)(apic->int_en_reg + 12); - break; - case IER_OFFSET4: - val = *(uint32_t *)(apic->int_en_reg + 16); - break; - case IER_OFFSET5: - val = *(uint32_t *)(apic->int_en_reg + 20); - break; - case IER_OFFSET6: - val = *(uint32_t *)(apic->int_en_reg + 24); - break; - case IER_OFFSET7: - val = *(uint32_t *)(apic->int_en_reg + 28); - break; - - case ISR_OFFSET0: - val = *(uint32_t *)(apic->int_svc_reg); - break; - case ISR_OFFSET1: - val = *(uint32_t *)(apic->int_svc_reg + 4); - break; - case ISR_OFFSET2: - val = *(uint32_t *)(apic->int_svc_reg + 8); - break; - case ISR_OFFSET3: - val = *(uint32_t *)(apic->int_svc_reg + 12); - break; - case ISR_OFFSET4: - val = *(uint32_t *)(apic->int_svc_reg + 16); - break; - case ISR_OFFSET5: - val = *(uint32_t *)(apic->int_svc_reg + 20); - break; - case ISR_OFFSET6: - val = *(uint32_t *)(apic->int_svc_reg + 24); - break; - case ISR_OFFSET7: - val = *(uint32_t *)(apic->int_svc_reg + 28); - break; + if (msr->apic_enable == 0) { + PrintError("Write to APIC address space with disabled APIC\n"); + return -1; + } + + + /* Because "May not be supported" doesn't matter to Linux developers... */ + /* if (length != 4) { */ + /* PrintError("Invalid apic read length (%d)\n", length); */ + /* return -1; */ + /* } */ + + switch (reg_addr & ~0x3) { + case EOI_OFFSET: + // Well, only an idiot would read from a architectural write only register + // Oh, Hello Linux. + // PrintError("Attempting to read from write only register\n"); + // return -1; + break; + + // data registers + case APIC_ID_OFFSET: + val = apic->lapic_id.val; + break; + case APIC_VERSION_OFFSET: + val = apic->apic_ver.val; + break; + case TPR_OFFSET: + val = apic->task_prio.val; + break; + case APR_OFFSET: + val = apic->arb_prio.val; + break; + case PPR_OFFSET: + val = apic->proc_prio.val; + break; + case REMOTE_READ_OFFSET: + val = apic->rem_rd_data; + break; + case LDR_OFFSET: + val = apic->log_dst.val; + break; + case DFR_OFFSET: + val = apic->dst_fmt.val; + break; + case SPURIOUS_INT_VEC_OFFSET: + val = apic->spurious_int.val; + break; + case ESR_OFFSET: + val = apic->err_status.val; + break; + case TMR_LOC_VEC_TBL_OFFSET: + val = apic->tmr_vec_tbl.val; + break; + case LINT0_VEC_TBL_OFFSET: + val = apic->lint0_vec_tbl.val; + break; + case LINT1_VEC_TBL_OFFSET: + val = apic->lint1_vec_tbl.val; + break; + case ERR_VEC_TBL_OFFSET: + val = apic->err_vec_tbl.val; + break; + case TMR_INIT_CNT_OFFSET: + val = apic->tmr_init_cnt; + break; + case TMR_DIV_CFG_OFFSET: + val = apic->tmr_div_cfg.val; + break; + + case IER_OFFSET0: + val = *(uint32_t *)(apic->int_en_reg); + break; + case IER_OFFSET1: + val = *(uint32_t *)(apic->int_en_reg + 4); + break; + case IER_OFFSET2: + val = *(uint32_t *)(apic->int_en_reg + 8); + break; + case IER_OFFSET3: + val = *(uint32_t *)(apic->int_en_reg + 12); + break; + case IER_OFFSET4: + val = *(uint32_t *)(apic->int_en_reg + 16); + break; + case IER_OFFSET5: + val = *(uint32_t *)(apic->int_en_reg + 20); + break; + case IER_OFFSET6: + val = *(uint32_t *)(apic->int_en_reg + 24); + break; + case IER_OFFSET7: + val = *(uint32_t *)(apic->int_en_reg + 28); + break; + + case ISR_OFFSET0: + val = *(uint32_t *)(apic->int_svc_reg); + break; + case ISR_OFFSET1: + val = *(uint32_t *)(apic->int_svc_reg + 4); + break; + case ISR_OFFSET2: + val = *(uint32_t *)(apic->int_svc_reg + 8); + break; + case ISR_OFFSET3: + val = *(uint32_t *)(apic->int_svc_reg + 12); + break; + case ISR_OFFSET4: + val = *(uint32_t *)(apic->int_svc_reg + 16); + break; + case ISR_OFFSET5: + val = *(uint32_t *)(apic->int_svc_reg + 20); + break; + case ISR_OFFSET6: + val = *(uint32_t *)(apic->int_svc_reg + 24); + break; + case ISR_OFFSET7: + val = *(uint32_t *)(apic->int_svc_reg + 28); + break; - case TRIG_OFFSET0: - val = *(uint32_t *)(apic->trig_mode_reg); - break; - case TRIG_OFFSET1: - val = *(uint32_t *)(apic->trig_mode_reg + 4); - break; - case TRIG_OFFSET2: - val = *(uint32_t *)(apic->trig_mode_reg + 8); - break; - case TRIG_OFFSET3: - val = *(uint32_t *)(apic->trig_mode_reg + 12); - break; - case TRIG_OFFSET4: - val = *(uint32_t *)(apic->trig_mode_reg + 16); - break; - case TRIG_OFFSET5: - val = *(uint32_t *)(apic->trig_mode_reg + 20); - break; - case TRIG_OFFSET6: - val = *(uint32_t *)(apic->trig_mode_reg + 24); - break; - case TRIG_OFFSET7: - val = *(uint32_t *)(apic->trig_mode_reg + 28); - break; - - case IRR_OFFSET0: - val = *(uint32_t *)(apic->int_req_reg); - break; - case IRR_OFFSET1: - val = *(uint32_t *)(apic->int_req_reg + 4); - break; - case IRR_OFFSET2: - val = *(uint32_t *)(apic->int_req_reg + 8); - break; - case IRR_OFFSET3: - val = *(uint32_t *)(apic->int_req_reg + 12); - break; - case IRR_OFFSET4: - val = *(uint32_t *)(apic->int_req_reg + 16); - break; - case IRR_OFFSET5: - val = *(uint32_t *)(apic->int_req_reg + 20); - break; - case IRR_OFFSET6: - val = *(uint32_t *)(apic->int_req_reg + 24); - break; - case IRR_OFFSET7: - val = *(uint32_t *)(apic->int_req_reg + 28); - break; - case TMR_CUR_CNT_OFFSET: - val = apic->tmr_cur_cnt; - break; - - // We are not going to implement these.... - case THERM_LOC_VEC_TBL_OFFSET: - val = apic->therm_loc_vec_tbl.val; - break; - case PERF_CTR_LOC_VEC_TBL_OFFSET: - val = apic->perf_ctr_loc_vec_tbl.val; - break; + case TRIG_OFFSET0: + val = *(uint32_t *)(apic->trig_mode_reg); + break; + case TRIG_OFFSET1: + val = *(uint32_t *)(apic->trig_mode_reg + 4); + break; + case TRIG_OFFSET2: + val = *(uint32_t *)(apic->trig_mode_reg + 8); + break; + case TRIG_OFFSET3: + val = *(uint32_t *)(apic->trig_mode_reg + 12); + break; + case TRIG_OFFSET4: + val = *(uint32_t *)(apic->trig_mode_reg + 16); + break; + case TRIG_OFFSET5: + val = *(uint32_t *)(apic->trig_mode_reg + 20); + break; + case TRIG_OFFSET6: + val = *(uint32_t *)(apic->trig_mode_reg + 24); + break; + case TRIG_OFFSET7: + val = *(uint32_t *)(apic->trig_mode_reg + 28); + break; + + case IRR_OFFSET0: + val = *(uint32_t *)(apic->int_req_reg); + break; + case IRR_OFFSET1: + val = *(uint32_t *)(apic->int_req_reg + 4); + break; + case IRR_OFFSET2: + val = *(uint32_t *)(apic->int_req_reg + 8); + break; + case IRR_OFFSET3: + val = *(uint32_t *)(apic->int_req_reg + 12); + break; + case IRR_OFFSET4: + val = *(uint32_t *)(apic->int_req_reg + 16); + break; + case IRR_OFFSET5: + val = *(uint32_t *)(apic->int_req_reg + 20); + break; + case IRR_OFFSET6: + val = *(uint32_t *)(apic->int_req_reg + 24); + break; + case IRR_OFFSET7: + val = *(uint32_t *)(apic->int_req_reg + 28); + break; + case TMR_CUR_CNT_OFFSET: + val = apic->tmr_cur_cnt; + break; + + // We are not going to implement these.... + case THERM_LOC_VEC_TBL_OFFSET: + val = apic->therm_loc_vec_tbl.val; + break; + case PERF_CTR_LOC_VEC_TBL_OFFSET: + val = apic->perf_ctr_loc_vec_tbl.val; + break; - // handled registers - case INT_CMD_LO_OFFSET: - val = apic->int_cmd.lo; - break; - case INT_CMD_HI_OFFSET: - val = apic->int_cmd.hi; - break; - - // handle current timer count - - // Unhandled Registers - case EXT_INT_LOC_VEC_TBL_OFFSET0: - case EXT_INT_LOC_VEC_TBL_OFFSET1: - case EXT_INT_LOC_VEC_TBL_OFFSET2: - case EXT_INT_LOC_VEC_TBL_OFFSET3: - case EXT_APIC_FEATURE_OFFSET: - case EXT_APIC_CMD_OFFSET: - case SEOI_OFFSET: - - default: - PrintError("Read from Unhandled APIC Register: %x\n", (uint32_t)reg_addr); - return -1; - } + // handled registers + case INT_CMD_LO_OFFSET: + val = apic->int_cmd.lo; + break; + case INT_CMD_HI_OFFSET: + val = apic->int_cmd.hi; + break; + + // handle current timer count + + // Unhandled Registers + case EXT_INT_LOC_VEC_TBL_OFFSET0: + case EXT_INT_LOC_VEC_TBL_OFFSET1: + case EXT_INT_LOC_VEC_TBL_OFFSET2: + case EXT_INT_LOC_VEC_TBL_OFFSET3: + case EXT_APIC_FEATURE_OFFSET: + case EXT_APIC_CMD_OFFSET: + case SEOI_OFFSET: + + default: + PrintError("Read from Unhandled APIC Register: %x\n", (uint32_t)reg_addr); + return -1; + } - if (length == 1) { - uint_t byte_addr = reg_addr & 0x3; - uint8_t * val_ptr = (uint8_t *)dst; + if (length == 1) { + uint_t byte_addr = reg_addr & 0x3; + uint8_t * val_ptr = (uint8_t *)dst; - *val_ptr = *(((uint8_t *)&val) + byte_addr); + *val_ptr = *(((uint8_t *)&val) + byte_addr); - } else if ((length == 2) && - ((reg_addr & 0x3) == 0x3)) { - uint_t byte_addr = reg_addr & 0x3; - uint16_t * val_ptr = (uint16_t *)dst; - *val_ptr = *(((uint16_t *)&val) + byte_addr); + } else if ((length == 2) && + ((reg_addr & 0x3) == 0x3)) { + uint_t byte_addr = reg_addr & 0x3; + uint16_t * val_ptr = (uint16_t *)dst; + *val_ptr = *(((uint16_t *)&val) + byte_addr); - } else if (length == 4) { - uint32_t * val_ptr = (uint32_t *)dst; - *val_ptr = val; + } else if (length == 4) { + uint32_t * val_ptr = (uint32_t *)dst; + *val_ptr = val; - } else { - PrintError("Invalid apic read length (%d)\n", length); - return -1; - } + } else { + PrintError("Invalid apic read length (%d)\n", length); + return -1; + } - PrintDebug("Read finished (val=%x)\n", *(uint32_t *)dst); + PrintDebug("Read finished (val=%x)\n", *(uint32_t *)dst); - return length; + return length; } static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) { - struct vm_device * dev = (struct vm_device *)priv_data; - struct apic_state * apic = (struct apic_state *)dev->private_data; - addr_t reg_addr = guest_addr - apic->base_addr; - struct apic_msr * msr = (struct apic_msr *)&(apic->base_addr_msr.value); - uint32_t op_val = *(uint32_t *)src; - - PrintDebug("Write to apic address space (%p) (val=%x)\n", - (void *)guest_addr, *(uint32_t *)src); + struct vm_device * dev = (struct vm_device *)priv_data; + struct apic_state * apic = (struct apic_state *)dev->private_data; + addr_t reg_addr = guest_addr - apic->base_addr; + struct apic_msr * msr = (struct apic_msr *)&(apic->base_addr_msr.value); + uint32_t op_val = *(uint32_t *)src; + + PrintDebug("Write to apic address space (%p) (val=%x)\n", + (void *)guest_addr, *(uint32_t *)src); + + if (msr->apic_enable == 0) { + PrintError("Write to APIC address space with disabled APIC\n"); + return -1; + } - if (msr->apic_enable == 0) { - PrintError("Write to APIC address space with disabled APIC\n"); - return -1; - } + if (length != 4) { + PrintError("Invalid apic write length (%d)\n", length); + return -1; + } - if (length != 4) { - PrintError("Invalid apic write length (%d)\n", length); - return -1; - } - - switch (reg_addr) { - case REMOTE_READ_OFFSET: - case APIC_VERSION_OFFSET: - case APR_OFFSET: - case IRR_OFFSET0: - case IRR_OFFSET1: - case IRR_OFFSET2: - case IRR_OFFSET3: - case IRR_OFFSET4: - case IRR_OFFSET5: - case IRR_OFFSET6: - case IRR_OFFSET7: - case ISR_OFFSET0: - case ISR_OFFSET1: - case ISR_OFFSET2: - case ISR_OFFSET3: - case ISR_OFFSET4: - case ISR_OFFSET5: - case ISR_OFFSET6: - case ISR_OFFSET7: - case TRIG_OFFSET0: - case TRIG_OFFSET1: - case TRIG_OFFSET2: - case TRIG_OFFSET3: - case TRIG_OFFSET4: - case TRIG_OFFSET5: - case TRIG_OFFSET6: - case TRIG_OFFSET7: - case PPR_OFFSET: - case EXT_APIC_FEATURE_OFFSET: + switch (reg_addr) { + case REMOTE_READ_OFFSET: + case APIC_VERSION_OFFSET: + case APR_OFFSET: + case IRR_OFFSET0: + case IRR_OFFSET1: + case IRR_OFFSET2: + case IRR_OFFSET3: + case IRR_OFFSET4: + case IRR_OFFSET5: + case IRR_OFFSET6: + case IRR_OFFSET7: + case ISR_OFFSET0: + case ISR_OFFSET1: + case ISR_OFFSET2: + case ISR_OFFSET3: + case ISR_OFFSET4: + case ISR_OFFSET5: + case ISR_OFFSET6: + case ISR_OFFSET7: + case TRIG_OFFSET0: + case TRIG_OFFSET1: + case TRIG_OFFSET2: + case TRIG_OFFSET3: + case TRIG_OFFSET4: + case TRIG_OFFSET5: + case TRIG_OFFSET6: + case TRIG_OFFSET7: + case PPR_OFFSET: + case EXT_APIC_FEATURE_OFFSET: #if 1 - PrintError("Attempting to write to read only register %p (ignored)\n", (void *)reg_addr); + PrintError("Attempting to write to read only register %p (ignored)\n", (void *)reg_addr); #else - PrintError("Attempting to write to read only register %p (error)\n", (void *)reg_addr); - return -1; + PrintError("Attempting to write to read only register %p (error)\n", (void *)reg_addr); + return -1; #endif - break; - - // Data registers - case APIC_ID_OFFSET: - apic->lapic_id.val = op_val; - break; - case TPR_OFFSET: - apic->task_prio.val = op_val; - break; - case LDR_OFFSET: - apic->log_dst.val = op_val; - break; - case DFR_OFFSET: - apic->dst_fmt.val = op_val; - break; - case SPURIOUS_INT_VEC_OFFSET: - apic->spurious_int.val = op_val; - break; - case ESR_OFFSET: - apic->err_status.val = op_val; - break; - case TMR_LOC_VEC_TBL_OFFSET: - apic->tmr_vec_tbl.val = op_val; - break; - case THERM_LOC_VEC_TBL_OFFSET: - apic->therm_loc_vec_tbl.val = op_val; - break; - case PERF_CTR_LOC_VEC_TBL_OFFSET: - apic->perf_ctr_loc_vec_tbl.val = op_val; - break; - case LINT0_VEC_TBL_OFFSET: - apic->lint0_vec_tbl.val = op_val; - break; - case LINT1_VEC_TBL_OFFSET: - apic->lint1_vec_tbl.val = op_val; - break; - case ERR_VEC_TBL_OFFSET: - apic->err_vec_tbl.val = op_val; - break; - case TMR_INIT_CNT_OFFSET: - apic->tmr_init_cnt = op_val; - apic->tmr_cur_cnt = op_val; - break; - case TMR_CUR_CNT_OFFSET: - apic->tmr_cur_cnt = op_val; - break; - case TMR_DIV_CFG_OFFSET: - apic->tmr_div_cfg.val = op_val; - break; - - - // Enable mask (256 bits) - case IER_OFFSET0: - *(uint32_t *)(apic->int_en_reg) = op_val; - break; - case IER_OFFSET1: - *(uint32_t *)(apic->int_en_reg + 4) = op_val; - break; - case IER_OFFSET2: - *(uint32_t *)(apic->int_en_reg + 8) = op_val; - break; - case IER_OFFSET3: - *(uint32_t *)(apic->int_en_reg + 12) = op_val; - break; - case IER_OFFSET4: - *(uint32_t *)(apic->int_en_reg + 16) = op_val; - break; - case IER_OFFSET5: - *(uint32_t *)(apic->int_en_reg + 20) = op_val; - break; - case IER_OFFSET6: - *(uint32_t *)(apic->int_en_reg + 24) = op_val; - break; - case IER_OFFSET7: - *(uint32_t *)(apic->int_en_reg + 28) = op_val; - break; + break; + + // Data registers + case APIC_ID_OFFSET: + apic->lapic_id.val = op_val; + break; + case TPR_OFFSET: + apic->task_prio.val = op_val; + break; + case LDR_OFFSET: + apic->log_dst.val = op_val; + break; + case DFR_OFFSET: + apic->dst_fmt.val = op_val; + break; + case SPURIOUS_INT_VEC_OFFSET: + apic->spurious_int.val = op_val; + break; + case ESR_OFFSET: + apic->err_status.val = op_val; + break; + case TMR_LOC_VEC_TBL_OFFSET: + apic->tmr_vec_tbl.val = op_val; + break; + case THERM_LOC_VEC_TBL_OFFSET: + apic->therm_loc_vec_tbl.val = op_val; + break; + case PERF_CTR_LOC_VEC_TBL_OFFSET: + apic->perf_ctr_loc_vec_tbl.val = op_val; + break; + case LINT0_VEC_TBL_OFFSET: + apic->lint0_vec_tbl.val = op_val; + break; + case LINT1_VEC_TBL_OFFSET: + apic->lint1_vec_tbl.val = op_val; + break; + case ERR_VEC_TBL_OFFSET: + apic->err_vec_tbl.val = op_val; + break; + case TMR_INIT_CNT_OFFSET: + apic->tmr_init_cnt = op_val; + apic->tmr_cur_cnt = op_val; + break; + case TMR_CUR_CNT_OFFSET: + apic->tmr_cur_cnt = op_val; + break; + case TMR_DIV_CFG_OFFSET: + apic->tmr_div_cfg.val = op_val; + break; + + + // Enable mask (256 bits) + case IER_OFFSET0: + *(uint32_t *)(apic->int_en_reg) = op_val; + break; + case IER_OFFSET1: + *(uint32_t *)(apic->int_en_reg + 4) = op_val; + break; + case IER_OFFSET2: + *(uint32_t *)(apic->int_en_reg + 8) = op_val; + break; + case IER_OFFSET3: + *(uint32_t *)(apic->int_en_reg + 12) = op_val; + break; + case IER_OFFSET4: + *(uint32_t *)(apic->int_en_reg + 16) = op_val; + break; + case IER_OFFSET5: + *(uint32_t *)(apic->int_en_reg + 20) = op_val; + break; + case IER_OFFSET6: + *(uint32_t *)(apic->int_en_reg + 24) = op_val; + break; + case IER_OFFSET7: + *(uint32_t *)(apic->int_en_reg + 28) = op_val; + break; - // Action Registers - case INT_CMD_LO_OFFSET: - case INT_CMD_HI_OFFSET: - case EOI_OFFSET: - { - // do eoi - apic_do_eoi(apic); - break; - + // Action Registers + case INT_CMD_LO_OFFSET: + case INT_CMD_HI_OFFSET: + case EOI_OFFSET: + { + // do eoi + apic_do_eoi(apic); + break; + } + // Unhandled Registers + case EXT_INT_LOC_VEC_TBL_OFFSET0: + case EXT_INT_LOC_VEC_TBL_OFFSET1: + case EXT_INT_LOC_VEC_TBL_OFFSET2: + case EXT_INT_LOC_VEC_TBL_OFFSET3: + case EXT_APIC_CMD_OFFSET: + case SEOI_OFFSET: + default: + PrintError("Write to Unhandled APIC Register: %x\n", (uint32_t)reg_addr); + return -1; } - // Unhandled Registers - case EXT_INT_LOC_VEC_TBL_OFFSET0: - case EXT_INT_LOC_VEC_TBL_OFFSET1: - case EXT_INT_LOC_VEC_TBL_OFFSET2: - case EXT_INT_LOC_VEC_TBL_OFFSET3: - case EXT_APIC_CMD_OFFSET: - case SEOI_OFFSET: - default: - PrintError("Write to Unhandled APIC Register: %x\n", (uint32_t)reg_addr); - return -1; - } - PrintDebug("Write finished\n"); + PrintDebug("Write finished\n"); - return length; + return length; } @@ -770,152 +769,152 @@ static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_ /* Interrupt Controller Functions */ static int apic_intr_pending(void * private_data) { - struct vm_device * dev = (struct vm_device *)private_data; - struct apic_state * apic = (struct apic_state *)dev->private_data; - int i = 0; + struct vm_device * dev = (struct vm_device *)private_data; + struct apic_state * apic = (struct apic_state *)dev->private_data; + int i = 0; - // just scan the request register looking for any set bit - // we should probably just do this with uint64 casts - for (i = 0; i < 32; i++) { - if (apic->int_req_reg[i] & 0xff) { - return 1; + // just scan the request register looking for any set bit + // we should probably just do this with uint64 casts + for (i = 0; i < 32; i++) { + if (apic->int_req_reg[i] & 0xff) { + return 1; + } } - } - return 0; + return 0; } static int apic_get_intr_number(void * private_data) { - struct vm_device * dev = (struct vm_device *)private_data; - struct apic_state * apic = (struct apic_state *)dev->private_data; - int i = 0, j = 0; + struct vm_device * dev = (struct vm_device *)private_data; + struct apic_state * apic = (struct apic_state *)dev->private_data; + int i = 0, j = 0; - // We iterate backwards to find the highest priority - for (i = 31; i >= 0; i--) { - uchar_t req_major = apic->int_req_reg[i]; + // We iterate backwards to find the highest priority + for (i = 31; i >= 0; i--) { + uchar_t req_major = apic->int_req_reg[i]; - if (req_major & 0xff) { - for (j = 7; j >= 0; j--) { - if ((req_major >> j) == 0x1) { - return (i * 8) + j; + if (req_major & 0xff) { + for (j = 7; j >= 0; j--) { + if ((req_major >> j) == 0x1) { + return (i * 8) + j; + } + } } - } } - } - return -1; + return -1; } static int apic_raise_intr(void * private_data, int irq) { - return 0; + return 0; } static int apic_lower_intr(void * private_data, int irq) { - return 0; + return 0; } static int apic_begin_irq(void * private_data, int irq) { - struct vm_device * dev = (struct vm_device *)private_data; - struct apic_state * apic = (struct apic_state *)dev->private_data; - int major_offset = (irq & ~0x00000007) >> 3; - int minor_offset = irq & 0x00000007; - uchar_t * req_location = apic->int_req_reg + major_offset; - uchar_t * svc_location = apic->int_svc_reg + major_offset; - uchar_t flag = 0x01 << minor_offset; - - *svc_location |= flag; - *req_location &= ~flag; - - return 0; + struct vm_device * dev = (struct vm_device *)private_data; + struct apic_state * apic = (struct apic_state *)dev->private_data; + int major_offset = (irq & ~0x00000007) >> 3; + int minor_offset = irq & 0x00000007; + uchar_t * req_location = apic->int_req_reg + major_offset; + uchar_t * svc_location = apic->int_svc_reg + major_offset; + uchar_t flag = 0x01 << minor_offset; + + *svc_location |= flag; + *req_location &= ~flag; + + return 0; } int v3_apic_raise_intr(struct vm_device * apic_dev, int intr_num) { - struct apic_state * apic = (struct apic_state *)apic_dev->private_data; - return activate_apic_irq(apic, intr_num); + struct apic_state * apic = (struct apic_state *)apic_dev->private_data; + return activate_apic_irq(apic, intr_num); } /* Timer Functions */ static void apic_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data) { - struct vm_device * dev = (struct vm_device *)priv_data; - struct apic_state * apic = (struct apic_state *)dev->private_data; - // The 32 bit GCC runtime is a pile of shit + struct vm_device * dev = (struct vm_device *)priv_data; + struct apic_state * apic = (struct apic_state *)dev->private_data; + // The 32 bit GCC runtime is a pile of shit #ifdef __V3_64BIT__ - uint64_t tmr_ticks = 0; + uint64_t tmr_ticks = 0; #else - uint32_t tmr_ticks = 0; + uint32_t tmr_ticks = 0; #endif - uchar_t tmr_div = *(uchar_t *)&(apic->tmr_div_cfg.val); - uint_t shift_num = 0; - - - // Check whether this is true: - // -> If the Init count is zero then the timer is disabled - // and doesn't just blitz interrupts to the CPU - if ((apic->tmr_init_cnt == 0) || - ( (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_ONESHOT) && - (apic->tmr_cur_cnt == 0))) { - //PrintDebug("APIC timer not yet initialized\n"); - return; - } - - - switch (tmr_div) { - case APIC_TMR_DIV1: - shift_num = 0; - break; - case APIC_TMR_DIV2: - shift_num = 1; - break; - case APIC_TMR_DIV4: - shift_num = 2; - break; - case APIC_TMR_DIV8: - shift_num = 3; - break; - case APIC_TMR_DIV16: - shift_num = 4; - break; - case APIC_TMR_DIV32: - shift_num = 5; - break; - case APIC_TMR_DIV64: - shift_num = 6; - break; - case APIC_TMR_DIV128: - shift_num = 7; - break; - default: - PrintError("Invalid Timer Divider configuration\n"); - return; - } - - tmr_ticks = cpu_cycles >> shift_num; - // PrintDebug("Timer Ticks: %p\n", (void *)tmr_ticks); - - if (tmr_ticks < apic->tmr_cur_cnt) { - apic->tmr_cur_cnt -= tmr_ticks; - } else { - tmr_ticks -= apic->tmr_cur_cnt; - apic->tmr_cur_cnt = 0; - - // raise irq - PrintDebug("Raising APIC Timer interrupt (periodic=%d) (icnt=%d) (div=%d)\n", - apic->tmr_vec_tbl.tmr_mode, apic->tmr_init_cnt, shift_num); - if (activate_internal_irq(apic, APIC_TMR_INT) == -1) { - PrintError("Could not raise Timer interrupt\n"); + uchar_t tmr_div = *(uchar_t *)&(apic->tmr_div_cfg.val); + uint_t shift_num = 0; + + + // Check whether this is true: + // -> If the Init count is zero then the timer is disabled + // and doesn't just blitz interrupts to the CPU + if ((apic->tmr_init_cnt == 0) || + ( (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_ONESHOT) && + (apic->tmr_cur_cnt == 0))) { + //PrintDebug("APIC timer not yet initialized\n"); + return; + } + + + switch (tmr_div) { + case APIC_TMR_DIV1: + shift_num = 0; + break; + case APIC_TMR_DIV2: + shift_num = 1; + break; + case APIC_TMR_DIV4: + shift_num = 2; + break; + case APIC_TMR_DIV8: + shift_num = 3; + break; + case APIC_TMR_DIV16: + shift_num = 4; + break; + case APIC_TMR_DIV32: + shift_num = 5; + break; + case APIC_TMR_DIV64: + shift_num = 6; + break; + case APIC_TMR_DIV128: + shift_num = 7; + break; + default: + PrintError("Invalid Timer Divider configuration\n"); + return; } + + tmr_ticks = cpu_cycles >> shift_num; + // PrintDebug("Timer Ticks: %p\n", (void *)tmr_ticks); + + if (tmr_ticks < apic->tmr_cur_cnt) { + apic->tmr_cur_cnt -= tmr_ticks; + } else { + tmr_ticks -= apic->tmr_cur_cnt; + apic->tmr_cur_cnt = 0; + + // raise irq + PrintDebug("Raising APIC Timer interrupt (periodic=%d) (icnt=%d) (div=%d)\n", + apic->tmr_vec_tbl.tmr_mode, apic->tmr_init_cnt, shift_num); + if (activate_internal_irq(apic, APIC_TMR_INT) == -1) { + PrintError("Could not raise Timer interrupt\n"); + } - if (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_PERIODIC) { - tmr_ticks = tmr_ticks % apic->tmr_init_cnt; - apic->tmr_cur_cnt = apic->tmr_init_cnt - tmr_ticks; + if (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_PERIODIC) { + tmr_ticks = tmr_ticks % apic->tmr_init_cnt; + apic->tmr_cur_cnt = apic->tmr_init_cnt - tmr_ticks; + } } - } } @@ -923,59 +922,59 @@ static void apic_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv static struct intr_ctrl_ops intr_ops = { - .intr_pending = apic_intr_pending, - .get_intr_number = apic_get_intr_number, - .raise_intr = apic_raise_intr, - .begin_irq = apic_begin_irq, - .lower_intr = apic_lower_intr, + .intr_pending = apic_intr_pending, + .get_intr_number = apic_get_intr_number, + .raise_intr = apic_raise_intr, + .begin_irq = apic_begin_irq, + .lower_intr = apic_lower_intr, }; static struct vm_timer_ops timer_ops = { - .update_time = apic_update_time, + .update_time = apic_update_time, }; static int apic_init(struct vm_device * dev) { - struct guest_info * info = dev->vm; - struct apic_state * apic = (struct apic_state *)(dev->private_data); + struct guest_info * info = dev->vm; + struct apic_state * apic = (struct apic_state *)(dev->private_data); - v3_register_intr_controller(dev->vm, &intr_ops, dev); - v3_add_timer(dev->vm, &timer_ops, dev); + v3_register_intr_controller(dev->vm, &intr_ops, dev); + v3_add_timer(dev->vm, &timer_ops, dev); - init_apic_state(apic); + init_apic_state(apic); - v3_hook_msr(info, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, dev); + v3_hook_msr(info, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, dev); - v3_hook_full_mem(info, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, dev); + v3_hook_full_mem(info, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, dev); - return 0; + return 0; } static int apic_deinit(struct vm_device * dev) { - struct guest_info * info = dev->vm; + struct guest_info * info = dev->vm; - v3_unhook_msr(info, BASE_ADDR_MSR); + v3_unhook_msr(info, BASE_ADDR_MSR); - return 0; + return 0; } static struct vm_device_ops dev_ops = { - .init = apic_init, - .deinit = apic_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, + .init = apic_init, + .deinit = apic_deinit, + .reset = NULL, + .start = NULL, + .stop = NULL, }; struct vm_device * v3_create_apic() { - PrintDebug("Creating APIC\n"); + PrintDebug("Creating APIC\n"); - struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state)); + struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state)); - struct vm_device * device = v3_create_device("APIC", &dev_ops, apic); + struct vm_device * device = v3_create_device("APIC", &dev_ops, apic); - return device; + return device; } diff --git a/palacios/src/devices/bochs_debug.c b/palacios/src/devices/bochs_debug.c index 45bc751..b834ba3 100644 --- a/palacios/src/devices/bochs_debug.c +++ b/palacios/src/devices/bochs_debug.c @@ -31,114 +31,114 @@ struct debug_state { - char debug_buf[BUF_SIZE]; - uint_t debug_offset; + char debug_buf[BUF_SIZE]; + uint_t debug_offset; - char info_buf[BUF_SIZE]; - uint_t info_offset; + char info_buf[BUF_SIZE]; + uint_t info_offset; }; static int handle_info_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct debug_state * state = (struct debug_state *)dev->private_data; + struct debug_state * state = (struct debug_state *)dev->private_data; - state->info_buf[state->info_offset++] = *(char*)src; + state->info_buf[state->info_offset++] = *(char*)src; - if ((*(char*)src == 0xa) || (state->info_offset == (BUF_SIZE - 1))) { - PrintDebug("BOCHSINFO>%s", state->info_buf); - memset(state->info_buf, 0, BUF_SIZE); - state->info_offset = 0; - } + if ((*(char*)src == 0xa) || (state->info_offset == (BUF_SIZE - 1))) { + PrintDebug("BOCHSINFO>%s", state->info_buf); + memset(state->info_buf, 0, BUF_SIZE); + state->info_offset = 0; + } - return length; + return length; } static int handle_debug_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct debug_state * state = (struct debug_state *)dev->private_data; + struct debug_state * state = (struct debug_state *)dev->private_data; - state->debug_buf[state->debug_offset++] = *(char*)src; + state->debug_buf[state->debug_offset++] = *(char*)src; - if ((*(char*)src == 0xa) || (state->debug_offset == (BUF_SIZE - 1))) { - PrintDebug("BOCHSDEBUG>%s", state->debug_buf); - memset(state->debug_buf, 0, BUF_SIZE); - state->debug_offset = 0; - } + if ((*(char*)src == 0xa) || (state->debug_offset == (BUF_SIZE - 1))) { + PrintDebug("BOCHSDEBUG>%s", state->debug_buf); + memset(state->debug_buf, 0, BUF_SIZE); + state->debug_offset = 0; + } - return length; + return length; } static int handle_gen_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - switch (length) { - case 1: - PrintDebug(">0x%.2x\n", *(uchar_t*)src); - break; - case 2: - PrintDebug(">0x%.4x\n", *(ushort_t*)src); - break; - case 4: - PrintDebug(">0x%.8x\n", *(uint_t*)src); - break; - default: - PrintError("Invalid length in handle_gen_write\n"); - return -1; - break; - } - - return length; + switch (length) { + case 1: + PrintDebug(">0x%.2x\n", *(uchar_t*)src); + break; + case 2: + PrintDebug(">0x%.4x\n", *(ushort_t*)src); + break; + case 4: + PrintDebug(">0x%.8x\n", *(uint_t*)src); + break; + default: + PrintError("Invalid length in handle_gen_write\n"); + return -1; + break; + } + + return length; } static int debug_init(struct vm_device * dev) { - struct debug_state * state = (struct debug_state *)dev->private_data; + struct debug_state * state = (struct debug_state *)dev->private_data; - state->debug_offset = 0; - state->info_offset = 0; - memset(state->debug_buf, 0, BUF_SIZE); - memset(state->info_buf, 0, BUF_SIZE); + state->debug_offset = 0; + state->info_offset = 0; + memset(state->debug_buf, 0, BUF_SIZE); + memset(state->info_buf, 0, BUF_SIZE); - v3_dev_hook_io(dev, BOCHS_PORT1, NULL, &handle_gen_write); - v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write); - v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write); - v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write); + v3_dev_hook_io(dev, BOCHS_PORT1, NULL, &handle_gen_write); + v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write); + v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write); + v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write); - return 0; + return 0; } static int debug_deinit(struct vm_device * dev) { - v3_dev_unhook_io(dev, BOCHS_PORT1); - v3_dev_unhook_io(dev, BOCHS_PORT2); - v3_dev_unhook_io(dev, BOCHS_INFO_PORT); - v3_dev_unhook_io(dev, BOCHS_DEBUG_PORT); + v3_dev_unhook_io(dev, BOCHS_PORT1); + v3_dev_unhook_io(dev, BOCHS_PORT2); + v3_dev_unhook_io(dev, BOCHS_INFO_PORT); + v3_dev_unhook_io(dev, BOCHS_DEBUG_PORT); - return 0; + return 0; }; static struct vm_device_ops dev_ops = { - .init = debug_init, - .deinit = debug_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, + .init = debug_init, + .deinit = debug_deinit, + .reset = NULL, + .start = NULL, + .stop = NULL, }; struct vm_device * v3_create_bochs_debug() { - struct debug_state * state = NULL; + struct debug_state * state = NULL; - state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state)); + state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state)); - V3_ASSERT(state != NULL); + V3_ASSERT(state != NULL); - PrintDebug("Creating Bochs Debug Device\n"); - struct vm_device * device = v3_create_device("BOCHS Debug", &dev_ops, state); + PrintDebug("Creating Bochs Debug Device\n"); + struct vm_device * device = v3_create_device("BOCHS Debug", &dev_ops, state); - return device; + return device; } diff --git a/palacios/src/devices/cdrom.c b/palacios/src/devices/cdrom.c index ff1c55c..b46a361 100644 --- a/palacios/src/devices/cdrom.c +++ b/palacios/src/devices/cdrom.c @@ -32,13 +32,13 @@ struct cdrom_state { - uchar_t * image_addr; //memory address - ulong_t capacity_in_bytes; - ulong_t head; //current position + uchar_t * image_addr; //memory address + ulong_t capacity_in_bytes; + ulong_t head; //current position - struct vm_device * ide_dev; + struct vm_device * ide_dev; - uchar_t lba; + uchar_t lba; }; @@ -49,16 +49,16 @@ struct cdrom_state { */ static rd_bool cdrom_insert(void * private_data) { - PrintDebug("[cdrom_insert]\n"); - return 1; + PrintDebug("[cdrom_insert]\n"); + return 1; } /* * Logically eject the CD. */ static void cdrom_eject(void * private_data) { - PrintDebug("[cdrom_eject]\n"); - return; + PrintDebug("[cdrom_eject]\n"); + return; } /* @@ -66,51 +66,51 @@ static void cdrom_eject(void * private_data) { */ static rd_bool cdrom_read_toc(void * private_data, uint8_t* buf, int* length, rd_bool msf, int start_track) { - *length = 4; - PrintDebug("[cdrom_read_toc]\n"); - return 1; + *length = 4; + PrintDebug("[cdrom_read_toc]\n"); + return 1; } /* * Return CD-ROM capacity (in 2048 byte frames) */ static uint32_t cdrom_capacity(void * private_data) { - struct cdrom_state * cdrom = (struct cdrom_state *)private_data; - - PrintDebug("[cdrom_capacity] s_ramdiskSize = %d\n", cdrom->capacity_in_bytes); - - if (cdrom->lba) { - if (cdrom->capacity_in_bytes % 2048) { - PrintDebug("\t\t capacity in LBA is %d\n", (cdrom->capacity_in_bytes / 2048) + 1); - return (cdrom->capacity_in_bytes / 2048) + 1; + struct cdrom_state * cdrom = (struct cdrom_state *)private_data; + + PrintDebug("[cdrom_capacity] s_ramdiskSize = %d\n", cdrom->capacity_in_bytes); + + if (cdrom->lba) { + if (cdrom->capacity_in_bytes % 2048) { + PrintDebug("\t\t capacity in LBA is %d\n", (cdrom->capacity_in_bytes / 2048) + 1); + return (cdrom->capacity_in_bytes / 2048) + 1; + } else { + PrintDebug("\t\t capacity in LBA is %d\n", cdrom->capacity_in_bytes / 2048); + return cdrom->capacity_in_bytes / 2048; + } } else { - PrintDebug("\t\t capacity in LBA is %d\n", cdrom->capacity_in_bytes / 2048); - return cdrom->capacity_in_bytes / 2048; + PrintError("Unsupported CDROM mode in capacity query\n"); + //FIXME CHS mode + return 0; } - } else { - PrintError("Unsupported CDROM mode in capacity query\n"); - //FIXME CHS mode - return 0; - } } /* * Read a single block from the CD */ static void cdrom_read_block(void * private_data, uint8_t * buf, int lba)/* __attribute__(regparm(2)); */ { - struct cdrom_state * cdrom = (struct cdrom_state *)private_data; + struct cdrom_state * cdrom = (struct cdrom_state *)private_data; - V3_ASSERT(lba != 0); + V3_ASSERT(lba != 0); - PrintDebug("[cdrom_read_block] lba = %d (cdrom_image_start=%x)\n", lba, cdrom->image_addr); - memcpy(buf, (uchar_t *)(cdrom->image_addr + lba * 2048), 2048); - //PrintDebug("Returning from read block\n"); - return; + PrintDebug("[cdrom_read_block] lba = %d (cdrom_image_start=%x)\n", lba, cdrom->image_addr); + memcpy(buf, (uchar_t *)(cdrom->image_addr + lba * 2048), 2048); + //PrintDebug("Returning from read block\n"); + return; } static void set_LBA(void * private_data, uchar_t lba) { - struct cdrom_state * cdrom = (struct cdrom_state *)private_data; - cdrom->lba = lba; + struct cdrom_state * cdrom = (struct cdrom_state *)private_data; + cdrom->lba = lba; } @@ -118,65 +118,63 @@ static void set_LBA(void * private_data, uchar_t lba) { * Start (spin up) the CD. */ static int cdrom_start(void * private_data) { - PrintDebug("[cdrom_start]\n"); - return 1; + PrintDebug("[cdrom_start]\n"); + return 1; } static struct cdrom_ops cd_ops = { - .insert_cdrom = cdrom_insert, - .eject_cdrom = cdrom_eject, - .read_toc = cdrom_read_toc, - .capacity = cdrom_capacity, - .read_block = cdrom_read_block, - .start_cdrom = cdrom_start, - .set_LBA = set_LBA, + .insert_cdrom = cdrom_insert, + .eject_cdrom = cdrom_eject, + .read_toc = cdrom_read_toc, + .capacity = cdrom_capacity, + .read_block = cdrom_read_block, + .start_cdrom = cdrom_start, + .set_LBA = set_LBA, }; static int cdrom_device_init(struct vm_device * dev) { - struct cdrom_state * cdrom = (struct cdrom_state *)dev->private_data; - PrintDebug("[cdrom_init]\n"); - PrintDebug("CDIMAGE located at: %x\n", cdrom->image_addr); + struct cdrom_state * cdrom = (struct cdrom_state *)dev->private_data; + PrintDebug("[cdrom_init]\n"); + PrintDebug("CDIMAGE located at: %x\n", cdrom->image_addr); - //FIXME:lba - cdrom->lba = 1; + //FIXME:lba + cdrom->lba = 1; - v3_ramdisk_register_cdrom(cdrom->ide_dev, 1, 0, &cd_ops, cdrom); + v3_ramdisk_register_cdrom(cdrom->ide_dev, 1, 0, &cd_ops, cdrom); - return 0; + return 0; } static int cdrom_device_deinit(struct vm_device * dev) { - return 0; + return 0; } static struct vm_device_ops dev_ops = { - .init = cdrom_device_init, - .deinit = cdrom_device_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, + .init = cdrom_device_init, + .deinit = cdrom_device_deinit, + .reset = NULL, + .start = NULL, + .stop = NULL, }; struct vm_device * v3_create_cdrom(struct vm_device * ramdisk_dev, void * ramdisk, uint_t ramdisk_size){ - struct cdrom_state * cd = (struct cdrom_state *)V3_Malloc(sizeof(struct cdrom_state)); - V3_ASSERT(cd != NULL); + struct cdrom_state * cd = (struct cdrom_state *)V3_Malloc(sizeof(struct cdrom_state)); + V3_ASSERT(cd != NULL); - memset(cd, 0, sizeof(struct cdrom_state)); + memset(cd, 0, sizeof(struct cdrom_state)); - cd->image_addr = (uchar_t *)V3_VAddr(ramdisk); - cd->capacity_in_bytes = ramdisk_size; - cd->ide_dev = ramdisk_dev; + cd->image_addr = (uchar_t *)V3_VAddr(ramdisk); + cd->capacity_in_bytes = ramdisk_size; + cd->ide_dev = ramdisk_dev; - PrintDebug("Creating RamDISK CDROM\n"); + PrintDebug("Creating RamDISK CDROM\n"); - struct vm_device * cd_dev = v3_create_device("Ram Based CD", &dev_ops, cd); + struct vm_device * cd_dev = v3_create_device("Ram Based CD", &dev_ops, cd); - return cd_dev; + return cd_dev; } - - diff --git a/palacios/src/devices/generic.c b/palacios/src/devices/generic.c index 130c708..cc26934 100644 --- a/palacios/src/devices/generic.c +++ b/palacios/src/devices/generic.c @@ -38,41 +38,41 @@ struct generic_internal { - struct list_head port_list; - uint_t num_port_ranges; - struct list_head mem_list; - uint_t num_mem_ranges; - struct list_head irq_list; - uint_t num_irq_ranges; + struct list_head port_list; + uint_t num_port_ranges; + struct list_head mem_list; + uint_t num_mem_ranges; + struct list_head irq_list; + uint_t num_irq_ranges; }; struct port_range { - uint_t start; - uint_t end; - uint_t type; - struct list_head range_link; + uint_t start; + uint_t end; + uint_t type; + struct list_head range_link; }; struct mem_range { - void * start; - void * end; - uint_t type; - struct list_head range_link; + void * start; + void * end; + uint_t type; + struct list_head range_link; }; struct irq_range { - uint_t start; - uint_t end; - uint_t type; - struct list_head range_link; + uint_t start; + uint_t end; + uint_t type; + struct list_head range_link; }; static int generic_reset_device(struct vm_device * dev) { - PrintDebug("generic: reset device\n"); - return 0; + PrintDebug("generic: reset device\n"); + return 0; } @@ -80,14 +80,14 @@ static int generic_reset_device(struct vm_device * dev) { static int generic_start_device(struct vm_device * dev) { - PrintDebug("generic: start device\n"); - return 0; + PrintDebug("generic: start device\n"); + return 0; } static int generic_stop_device(struct vm_device * dev) { - PrintDebug("generic: stop device\n"); - return 0; + PrintDebug("generic: stop device\n"); + return 0; } @@ -97,90 +97,90 @@ static int generic_write_port_passthrough(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - uint_t i; + uint_t i; - PrintDebug("generic: writing 0x"); + PrintDebug("generic: writing 0x"); - for (i = 0; i < length; i++) { - PrintDebug("%x", ((uchar_t*)src)[i]); - } - - PrintDebug(" to port 0x%x ... ", port); - - - switch (length) { - case 1: - v3_outb(port,((uchar_t*)src)[0]); - break; - case 2: - v3_outw(port,((ushort_t*)src)[0]); - break; - case 4: - v3_outdw(port,((uint_t*)src)[0]); - break; - default: for (i = 0; i < length; i++) { - v3_outb(port, ((uchar_t*)src)[i]); + PrintDebug("%x", ((uchar_t*)src)[i]); } - } //switch length + + PrintDebug(" to port 0x%x ... ", port); - PrintDebug(" done\n"); + switch (length) { + case 1: + v3_outb(port,((uchar_t*)src)[0]); + break; + case 2: + v3_outw(port,((ushort_t*)src)[0]); + break; + case 4: + v3_outdw(port,((uint_t*)src)[0]); + break; + default: + for (i = 0; i < length; i++) { + v3_outb(port, ((uchar_t*)src)[i]); + } + } //switch length + + + PrintDebug(" done\n"); - return length; + return length; } static int generic_read_port_passthrough(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - uint_t i; + uint_t i; - PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port); + PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port); switch (length) { - case 1: - ((uchar_t*)src)[0] = v3_inb(port); - break; - case 2: - ((ushort_t*)src)[0] = v3_inw(port); - break; - case 4: - ((uint_t*)src)[0] = v3_indw(port); - break; - default: - for (i = 0; i < length; i++) { - ((uchar_t*)src)[i] = v3_inb(port); - } + case 1: + ((uchar_t*)src)[0] = v3_inb(port); + break; + case 2: + ((ushort_t*)src)[0] = v3_inw(port); + break; + case 4: + ((uint_t*)src)[0] = v3_indw(port); + break; + default: + for (i = 0; i < length; i++) { + ((uchar_t*)src)[i] = v3_inb(port); + } }//switch length - PrintDebug(" done ... read 0x"); + PrintDebug(" done ... read 0x"); - for (i = 0; i < length; i++) { - PrintDebug("%x", ((uchar_t*)src)[i]); - } + for (i = 0; i < length; i++) { + PrintDebug("%x", ((uchar_t*)src)[i]); + } - PrintDebug("\n"); + PrintDebug("\n"); - return length; + return length; } static int generic_write_port_ignore(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - uint_t i; + uint_t i; - PrintDebug("generic: writing 0x"); + PrintDebug("generic: writing 0x"); - for (i = 0; i < length; i++) { - PrintDebug("%x", ((uchar_t*)src)[i]); - } + for (i = 0; i < length; i++) { + PrintDebug("%x", ((uchar_t*)src)[i]); + } - PrintDebug(" to port 0x%x ... ignored\n", port); + PrintDebug(" to port 0x%x ... ignored\n", port); - return length; + return length; } static int generic_read_port_ignore(ushort_t port, @@ -188,194 +188,194 @@ static int generic_read_port_ignore(ushort_t port, uint_t length, struct vm_device * dev) { - PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port); + PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port); - memset((char*)src, 0, length); - PrintDebug(" ignored (return zeroed buffer)\n"); + memset((char*)src, 0, length); + PrintDebug(" ignored (return zeroed buffer)\n"); - return length; + return length; } static int generic_interrupt(uint_t irq, struct vm_device * dev) { - PrintDebug("generic: interrupt 0x%x - injecting into VM\n", irq); + PrintDebug("generic: interrupt 0x%x - injecting into VM\n", irq); - v3_raise_irq(dev->vm, irq); + v3_raise_irq(dev->vm, irq); - return 0; + return 0; } static int generic_init_device(struct vm_device * dev) { - struct generic_internal * state = (struct generic_internal *)(dev->private_data); + struct generic_internal * state = (struct generic_internal *)(dev->private_data); - PrintDebug("generic: init_device\n"); - generic_reset_device(dev); + PrintDebug("generic: init_device\n"); + generic_reset_device(dev); - if (PORT_HOOKS) { // This is a runtime conditional on a #define - struct port_range * tmp = NULL; + if (PORT_HOOKS) { // This is a runtime conditional on a #define + struct port_range * tmp = NULL; - list_for_each_entry(tmp, &(state->port_list), range_link) { - uint_t i = 0; + list_for_each_entry(tmp, &(state->port_list), range_link) { + uint_t i = 0; - PrintDebug("generic: hooking ports 0x%x to 0x%x as %x\n", - tmp->start, tmp->end, - (tmp->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore"); + PrintDebug("generic: hooking ports 0x%x to 0x%x as %x\n", + tmp->start, tmp->end, + (tmp->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore"); - for (i = tmp->start; i <= tmp->end; i++) { - if (tmp->type == GENERIC_PRINT_AND_PASSTHROUGH) { + for (i = tmp->start; i <= tmp->end; i++) { + if (tmp->type == GENERIC_PRINT_AND_PASSTHROUGH) { - if (v3_dev_hook_io(dev, i, &generic_read_port_passthrough, &generic_write_port_passthrough)) { - PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", i); - } + if (v3_dev_hook_io(dev, i, &generic_read_port_passthrough, &generic_write_port_passthrough)) { + PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", i); + } - } else if (tmp->type == GENERIC_PRINT_AND_IGNORE) { + } else if (tmp->type == GENERIC_PRINT_AND_IGNORE) { - if (v3_dev_hook_io(dev, i, &generic_read_port_ignore, &generic_write_port_ignore)) { - PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", i); - } - } - } + if (v3_dev_hook_io(dev, i, &generic_read_port_ignore, &generic_write_port_ignore)) { + PrintDebug("generic: can't hook port 0x%x (already hooked?)\n", i); + } + } + } + } + } else { + PrintDebug("generic: hooking ports not supported\n"); } - } else { - PrintDebug("generic: hooking ports not supported\n"); - } - if (MEM_HOOKS) { // This is a runtime conditional on a #define - struct mem_range * tmp; + if (MEM_HOOKS) { // This is a runtime conditional on a #define + struct mem_range * tmp; - list_for_each_entry(tmp, &(state->mem_list), range_link) { + list_for_each_entry(tmp, &(state->mem_list), range_link) { - PrintDebug("generic: hooking addresses 0x%x to 0x%x\n", - tmp->start, tmp->end); + PrintDebug("generic: hooking addresses 0x%x to 0x%x\n", + tmp->start, tmp->end); - if (v3_dev_hook_mem(dev, tmp->start, tmp->end)) { - PrintDebug("generic: Can't hook addresses 0x%x to 0x%x (already hooked?)\n", - tmp->start, tmp->end); - } + if (v3_dev_hook_mem(dev, tmp->start, tmp->end)) { + PrintDebug("generic: Can't hook addresses 0x%x to 0x%x (already hooked?)\n", + tmp->start, tmp->end); + } + } + } else { + PrintDebug("generic: hooking addresses not supported\n"); } - } else { - PrintDebug("generic: hooking addresses not supported\n"); - } - if (IRQ_HOOKS) { // This is a runtime conditional on a #define - struct irq_range * tmp; + if (IRQ_HOOKS) { // This is a runtime conditional on a #define + struct irq_range * tmp; - list_for_each_entry(tmp, &(state->irq_list), range_link) { - uint_t i; + list_for_each_entry(tmp, &(state->irq_list), range_link) { + uint_t i; - PrintDebug("generic: hooking irqs 0x%x to 0x%x\n", - tmp->start, tmp->end); + PrintDebug("generic: hooking irqs 0x%x to 0x%x\n", + tmp->start, tmp->end); - for (i = tmp->start; i <= tmp->end; i++) { - if (v3_dev_hook_irq(dev, i, &generic_interrupt)) { - PrintDebug("generic: can't hook irq 0x%x (already hooked?)\n", i); - } - } + for (i = tmp->start; i <= tmp->end; i++) { + if (v3_dev_hook_irq(dev, i, &generic_interrupt)) { + PrintDebug("generic: can't hook irq 0x%x (already hooked?)\n", i); + } + } + } + } else { + PrintDebug("generic: hooking irqs not supported\n"); } - } else { - PrintDebug("generic: hooking irqs not supported\n"); - } - return 0; + return 0; } static int generic_deinit_device(struct vm_device * dev) { - struct generic_internal * state = (struct generic_internal *)(dev->private_data); + struct generic_internal * state = (struct generic_internal *)(dev->private_data); - PrintDebug("generic: deinit_device\n"); + PrintDebug("generic: deinit_device\n"); - if (IRQ_HOOKS) { // This is a runtime conditional on a #define - struct irq_range * tmp; - struct irq_range * cur; + if (IRQ_HOOKS) { // This is a runtime conditional on a #define + struct irq_range * tmp; + struct irq_range * cur; - list_for_each_entry_safe(cur, tmp, &(state->irq_list), range_link) { - uint_t i; + list_for_each_entry_safe(cur, tmp, &(state->irq_list), range_link) { + uint_t i; - PrintDebug("generic: unhooking irqs 0x%x to 0x%x\n", - cur->start, cur->end); + PrintDebug("generic: unhooking irqs 0x%x to 0x%x\n", + cur->start, cur->end); - for (i = cur->start; i <= cur->end; i++) { - if (v3_dev_unhook_irq(dev, i)) { - PrintDebug("generic: can't unhook irq 0x%x (already unhooked?)\n", i); - } - } + for (i = cur->start; i <= cur->end; i++) { + if (v3_dev_unhook_irq(dev, i)) { + PrintDebug("generic: can't unhook irq 0x%x (already unhooked?)\n", i); + } + } - list_del(&(cur->range_link)); - state->num_irq_ranges--; - V3_Free(cur); + list_del(&(cur->range_link)); + state->num_irq_ranges--; + V3_Free(cur); + } + } else { + PrintDebug("generic: unhooking irqs not supported\n"); } - } else { - PrintDebug("generic: unhooking irqs not supported\n"); - } - if (MEM_HOOKS) { - struct mem_range * tmp; - struct mem_range * cur; + if (MEM_HOOKS) { + struct mem_range * tmp; + struct mem_range * cur; - list_for_each_entry_safe(cur, tmp, &(state->mem_list), range_link) { + list_for_each_entry_safe(cur, tmp, &(state->mem_list), range_link) { - PrintDebug("generic: unhooking addresses 0x%x to 0x%x\n", - cur->start, cur->end); + PrintDebug("generic: unhooking addresses 0x%x to 0x%x\n", + cur->start, cur->end); - if (v3_dev_unhook_mem(dev, cur->start, cur->end)) { - PrintDebug("generic: Can't unhook addresses 0x%x to 0x%x (already unhooked?)\n", - cur->start, cur->end); - } + if (v3_dev_unhook_mem(dev, cur->start, cur->end)) { + PrintDebug("generic: Can't unhook addresses 0x%x to 0x%x (already unhooked?)\n", + cur->start, cur->end); + } - list_del(&(cur->range_link)); - state->num_mem_ranges--; - V3_Free(cur); + list_del(&(cur->range_link)); + state->num_mem_ranges--; + V3_Free(cur); + } + } else { + PrintDebug("generic: unhooking addresses not supported\n"); } - } else { - PrintDebug("generic: unhooking addresses not supported\n"); - } - if (PORT_HOOKS) { - struct port_range * tmp; - struct port_range * cur; + if (PORT_HOOKS) { + struct port_range * tmp; + struct port_range * cur; - list_for_each_entry_safe(cur, tmp, &(state->port_list), range_link) { - uint_t i; + list_for_each_entry_safe(cur, tmp, &(state->port_list), range_link) { + uint_t i; - PrintDebug("generic: unhooking ports 0x%x to 0x%x\n", - cur->start, cur->end); + PrintDebug("generic: unhooking ports 0x%x to 0x%x\n", + cur->start, cur->end); - for (i = cur->start; i <= cur->end; i++) { - if (v3_dev_unhook_io(dev, i)) { - PrintDebug("generic: can't unhook port 0x%x (already unhooked?)\n", i); + for (i = cur->start; i <= cur->end; i++) { + if (v3_dev_unhook_io(dev, i)) { + PrintDebug("generic: can't unhook port 0x%x (already unhooked?)\n", i); + } + } + + list_del(&(cur->range_link)); + state->num_port_ranges--; + V3_Free(cur); } - } - - list_del(&(cur->range_link)); - state->num_port_ranges--; - V3_Free(cur); + } else { + PrintDebug("generic: unhooking ports not supported\n"); } - } else { - PrintDebug("generic: unhooking ports not supported\n"); - } - generic_reset_device(dev); - return 0; + generic_reset_device(dev); + return 0; } @@ -383,11 +383,11 @@ static int generic_deinit_device(struct vm_device * dev) { static struct vm_device_ops dev_ops = { - .init = generic_init_device, - .deinit = generic_deinit_device, - .reset = generic_reset_device, - .start = generic_start_device, - .stop = generic_stop_device, + .init = generic_init_device, + .deinit = generic_deinit_device, + .reset = generic_reset_device, + .start = generic_start_device, + .stop = generic_stop_device, }; @@ -395,84 +395,84 @@ static struct vm_device_ops dev_ops = { int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type) { - if (PORT_HOOKS) { - struct generic_internal * state = (struct generic_internal *)(dev->private_data); + if (PORT_HOOKS) { + struct generic_internal * state = (struct generic_internal *)(dev->private_data); - struct port_range * range = (struct port_range *)V3_Malloc(sizeof(struct port_range)); - range->start = start; - range->end = end; - range->type = type; + struct port_range * range = (struct port_range *)V3_Malloc(sizeof(struct port_range)); + range->start = start; + range->end = end; + range->type = type; - PrintDebug("generic: Adding Port Range: 0x%x to 0x%x as %x\n", - range->start, range->end, - (range->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore"); + PrintDebug("generic: Adding Port Range: 0x%x to 0x%x as %x\n", + range->start, range->end, + (range->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore"); - list_add(&(range->range_link), &(state->port_list)); - state->num_port_ranges++; - } else { - PrintDebug("generic: hooking IO ports not supported\n"); - return -1; - } - - return 0; + list_add(&(range->range_link), &(state->port_list)); + state->num_port_ranges++; + } else { + PrintDebug("generic: hooking IO ports not supported\n"); + return -1; + } + + return 0; } int v3_generic_add_mem_range(struct vm_device * dev, void * start, void * end, uint_t type) { - if (MEM_HOOKS) { - struct generic_internal * state = (struct generic_internal *)(dev->private_data); + if (MEM_HOOKS) { + struct generic_internal * state = (struct generic_internal *)(dev->private_data); - struct mem_range * range = (struct mem_range *)V3_Malloc(sizeof(struct mem_range)); - range->start = start; - range->end = end; - range->type = type; + struct mem_range * range = (struct mem_range *)V3_Malloc(sizeof(struct mem_range)); + range->start = start; + range->end = end; + range->type = type; - list_add(&(range->range_link), &(state->port_list)); - state->num_mem_ranges++; - } else { - PrintDebug("generic: hooking memory not supported\n"); - return -1; - } - - return 0; + list_add(&(range->range_link), &(state->port_list)); + state->num_mem_ranges++; + } else { + PrintDebug("generic: hooking memory not supported\n"); + return -1; + } + + return 0; } int v3_generic_add_irq_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type) { - if (IRQ_HOOKS) { - struct generic_internal * state = (struct generic_internal *)(dev->private_data); + if (IRQ_HOOKS) { + struct generic_internal * state = (struct generic_internal *)(dev->private_data); - struct irq_range * range = (struct irq_range *)V3_Malloc(sizeof(struct irq_range)); - range->start = start; - range->end = end; - range->type = type; + struct irq_range * range = (struct irq_range *)V3_Malloc(sizeof(struct irq_range)); + range->start = start; + range->end = end; + range->type = type; - list_add(&(range->range_link), &(state->port_list)); - state->num_irq_ranges++; - } else { - PrintDebug("generic: hooking IRQs not supported\n"); - return -1; - } - - return 0; + list_add(&(range->range_link), &(state->port_list)); + state->num_irq_ranges++; + } else { + PrintDebug("generic: hooking IRQs not supported\n"); + return -1; + } + + return 0; } struct vm_device * v3_create_generic() { - struct generic_internal * generic_state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal)); + struct generic_internal * generic_state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal)); - generic_state->num_port_ranges = 0; - generic_state->num_mem_ranges = 0; - generic_state->num_irq_ranges = 0; + generic_state->num_port_ranges = 0; + generic_state->num_mem_ranges = 0; + generic_state->num_irq_ranges = 0; - INIT_LIST_HEAD(&(generic_state->port_list)); - INIT_LIST_HEAD(&(generic_state->mem_list)); - INIT_LIST_HEAD(&(generic_state->irq_list)); + INIT_LIST_HEAD(&(generic_state->port_list)); + INIT_LIST_HEAD(&(generic_state->mem_list)); + INIT_LIST_HEAD(&(generic_state->irq_list)); - struct vm_device * device = v3_create_device("GENERIC", &dev_ops, generic_state); + struct vm_device * device = v3_create_device("GENERIC", &dev_ops, generic_state); - return device; + return device; } diff --git a/palacios/src/devices/io_apic.c b/palacios/src/devices/io_apic.c index 7188f26..8eae20a 100644 --- a/palacios/src/devices/io_apic.c +++ b/palacios/src/devices/io_apic.c @@ -23,10 +23,10 @@ #include /* -#ifndef DEBUG_IO_APIC -#undef PrintDebug -#define PrintDebug(fmt, args...) -#endif + #ifndef DEBUG_IO_APIC + #undef PrintDebug + #define PrintDebug(fmt, args...) + #endif */ @@ -42,60 +42,60 @@ #define REDIR_LO_MASK ~0x00005000 struct ioapic_reg_sel { - union { - uint32_t val; - struct { - uint_t reg_addr : 8; - uint_t rsvd : 24; + union { + uint32_t val; + struct { + uint_t reg_addr : 8; + uint_t rsvd : 24; + } __attribute__((packed)); } __attribute__((packed)); - } __attribute__((packed)); } __attribute__((packed)); struct ioapic_id_reg { - union { - uint32_t val; - struct { - uint_t rsvd1 : 24; - uint_t id : 4; - uint_t rsvd2 : 4; + union { + uint32_t val; + struct { + uint_t rsvd1 : 24; + uint_t id : 4; + uint_t rsvd2 : 4; + } __attribute__((packed)); } __attribute__((packed)); - } __attribute__((packed)); } __attribute__((packed)); struct ioapic_ver_reg { - union { - uint32_t val; - struct { - uint_t version : 8; - uint_t rsvd1 : 8; - uint_t max_redir : 8; - uint_t rsvd2 : 8; + union { + uint32_t val; + struct { + uint_t version : 8; + uint_t rsvd1 : 8; + uint_t max_redir : 8; + uint_t rsvd2 : 8; + } __attribute__((packed)); } __attribute__((packed)); - } __attribute__((packed)); } __attribute__((packed)); struct ioapic_arb_reg { - union { - uint32_t val; - struct { - uint_t rsvd1 : 24; - uint_t max_redir : 4; - uint_t rsvd2 : 4; + union { + uint32_t val; + struct { + uint_t rsvd1 : 24; + uint_t max_redir : 4; + uint_t rsvd2 : 4; + } __attribute__((packed)); } __attribute__((packed)); - } __attribute__((packed)); } __attribute__((packed)); struct redir_tbl_entry { - union { - uint64_t val; - struct { - uint32_t lo; - uint32_t hi; - } __attribute__((packed)); - struct { - uint_t vec : 8; + union { + uint64_t val; + struct { + uint32_t lo; + uint32_t hi; + } __attribute__((packed)); + struct { + uint_t vec : 8; #define FIXED 0x0 #define LOWEST_PRIOR 0x1 @@ -103,242 +103,242 @@ struct redir_tbl_entry { #define NMI 0x4 #define INIT 0x5 #define EXTINT 0x7 - uint_t del_mode : 3; + uint_t del_mode : 3; #define PHSYICAL_DST_MODE 0 #define LOGICAL_DST_MODE 1 - uint_t dst_mode : 1; - uint_t del_status : 1; + uint_t dst_mode : 1; + uint_t del_status : 1; #define HIGH_ACTIVE 0 #define LOW_ACTIVE 1 - uint_t intr_pol : 1; - uint_t rem_irr : 1; - uint_t trig_mode : 1; - uint_t mask : 1; - uint64_t rsvd : 39; - uint_t dst_field : 8; + uint_t intr_pol : 1; + uint_t rem_irr : 1; + uint_t trig_mode : 1; + uint_t mask : 1; + uint64_t rsvd : 39; + uint_t dst_field : 8; + } __attribute__((packed)); } __attribute__((packed)); - } __attribute__((packed)); } __attribute__((packed)); struct io_apic_state { - addr_t base_addr; + addr_t base_addr; - uint32_t index_reg; + uint32_t index_reg; - struct ioapic_id_reg ioapic_id; - struct ioapic_ver_reg ioapic_ver; - struct ioapic_arb_reg ioapic_arb_id; + struct ioapic_id_reg ioapic_id; + struct ioapic_ver_reg ioapic_ver; + struct ioapic_arb_reg ioapic_arb_id; - struct redir_tbl_entry redir_tbl[24]; + struct redir_tbl_entry redir_tbl[24]; - // This is a temporary method of communication between the IOAPIC and the LAPIC - struct vm_device * apic; + // This is a temporary method of communication between the IOAPIC and the LAPIC + struct vm_device * apic; }; static void init_ioapic_state(struct io_apic_state * ioapic) { - int i = 0; - ioapic->base_addr = IO_APIC_BASE_ADDR; - ioapic->index_reg = 0; - - ioapic->ioapic_id.val = 0x00000000; - ioapic->ioapic_ver.val = 0x00170011; - ioapic->ioapic_arb_id.val = 0x00000000; - - for (i = 0; i < 24; i++) { - ioapic->redir_tbl[i].val = 0x0001000000000000LL; - // Mask all interrupts until they are enabled.... - ioapic->redir_tbl[i].mask = 1; - } + int i = 0; + ioapic->base_addr = IO_APIC_BASE_ADDR; + ioapic->index_reg = 0; + + ioapic->ioapic_id.val = 0x00000000; + ioapic->ioapic_ver.val = 0x00170011; + ioapic->ioapic_arb_id.val = 0x00000000; + + for (i = 0; i < 24; i++) { + ioapic->redir_tbl[i].val = 0x0001000000000000LL; + // Mask all interrupts until they are enabled.... + ioapic->redir_tbl[i].mask = 1; + } } static int ioapic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) { - struct vm_device * dev = (struct vm_device *)priv_data; - struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data); - uint32_t reg_tgt = guest_addr - ioapic->base_addr; - uint32_t * op_val = (uint32_t *)dst; - - PrintDebug("IOAPIC Read at %p\n", (void *)guest_addr); - - if (reg_tgt == 0x00) { - *op_val = ioapic->index_reg; - } else if (reg_tgt == 0x10) { - // IOWIN register - switch (ioapic->index_reg) { - case IOAPIC_ID_REG: - *op_val = ioapic->ioapic_id.val; - break; - case IOAPIC_VER_REG: - *op_val = ioapic->ioapic_ver.val; - break; - case IOAPIC_ARB_REG: - *op_val = ioapic->ioapic_arb_id.val; - break; - default: - { - uint_t redir_index = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) & 0xfffffffe; - uint_t hi_val = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) % 1; - - if (redir_index > 0x3f) { - PrintError("Invalid redirection table entry %x\n", (uint32_t)redir_index); - return -1; - } - if (hi_val) { - *op_val = ioapic->redir_tbl[redir_index].hi; - } else { - *op_val = ioapic->redir_tbl[redir_index].lo; + struct vm_device * dev = (struct vm_device *)priv_data; + struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data); + uint32_t reg_tgt = guest_addr - ioapic->base_addr; + uint32_t * op_val = (uint32_t *)dst; + + PrintDebug("IOAPIC Read at %p\n", (void *)guest_addr); + + if (reg_tgt == 0x00) { + *op_val = ioapic->index_reg; + } else if (reg_tgt == 0x10) { + // IOWIN register + switch (ioapic->index_reg) { + case IOAPIC_ID_REG: + *op_val = ioapic->ioapic_id.val; + break; + case IOAPIC_VER_REG: + *op_val = ioapic->ioapic_ver.val; + break; + case IOAPIC_ARB_REG: + *op_val = ioapic->ioapic_arb_id.val; + break; + default: + { + uint_t redir_index = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) & 0xfffffffe; + uint_t hi_val = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) % 1; + + if (redir_index > 0x3f) { + PrintError("Invalid redirection table entry %x\n", (uint32_t)redir_index); + return -1; + } + if (hi_val) { + *op_val = ioapic->redir_tbl[redir_index].hi; + } else { + *op_val = ioapic->redir_tbl[redir_index].lo; + } + } } - } } - } - return length; + return length; } static int ioapic_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) { - struct vm_device * dev = (struct vm_device *)priv_data; - struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data); - uint32_t reg_tgt = guest_addr - ioapic->base_addr; - uint32_t op_val = *(uint32_t *)src; - - PrintDebug("IOAPIC Write at %p (val = %d)\n", (void *)guest_addr, *(uint32_t *)src); - - if (reg_tgt == 0x00) { - ioapic->index_reg = op_val; - } else if (reg_tgt == 0x10) { - // IOWIN register - switch (ioapic->index_reg) { - case IOAPIC_ID_REG: - ioapic->ioapic_id.val = op_val; - break; - case IOAPIC_VER_REG: - // GPF/PageFault/Ignore? - PrintError("Writing to read only IOAPIC register\n"); - return -1; - case IOAPIC_ARB_REG: - ioapic->ioapic_arb_id.val = op_val; - break; - default: - { - uint_t redir_index = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) & 0xfffffffe; - uint_t hi_val = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) % 1; - - - - - if (redir_index > 0x3f) { - PrintError("Invalid redirection table entry %x\n", (uint32_t)redir_index); - return -1; + struct vm_device * dev = (struct vm_device *)priv_data; + struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data); + uint32_t reg_tgt = guest_addr - ioapic->base_addr; + uint32_t op_val = *(uint32_t *)src; + + PrintDebug("IOAPIC Write at %p (val = %d)\n", (void *)guest_addr, *(uint32_t *)src); + + if (reg_tgt == 0x00) { + ioapic->index_reg = op_val; + } else if (reg_tgt == 0x10) { + // IOWIN register + switch (ioapic->index_reg) { + case IOAPIC_ID_REG: + ioapic->ioapic_id.val = op_val; + break; + case IOAPIC_VER_REG: + // GPF/PageFault/Ignore? + PrintError("Writing to read only IOAPIC register\n"); + return -1; + case IOAPIC_ARB_REG: + ioapic->ioapic_arb_id.val = op_val; + break; + default: + { + uint_t redir_index = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) & 0xfffffffe; + uint_t hi_val = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) % 1; + + + + + if (redir_index > 0x3f) { + PrintError("Invalid redirection table entry %x\n", (uint32_t)redir_index); + return -1; + } + if (hi_val) { + PrintDebug("Writing to hi of pin %d\n", redir_index); + ioapic->redir_tbl[redir_index].hi = op_val; + } else { + PrintDebug("Writing to lo of pin %d\n", redir_index); + op_val &= REDIR_LO_MASK; + ioapic->redir_tbl[redir_index].lo &= ~REDIR_LO_MASK; + ioapic->redir_tbl[redir_index].lo |= op_val; + } + } } - if (hi_val) { - PrintDebug("Writing to hi of pin %d\n", redir_index); - ioapic->redir_tbl[redir_index].hi = op_val; - } else { - PrintDebug("Writing to lo of pin %d\n", redir_index); - op_val &= REDIR_LO_MASK; - ioapic->redir_tbl[redir_index].lo &= ~REDIR_LO_MASK; - ioapic->redir_tbl[redir_index].lo |= op_val; - } - } } - } - return length; + return length; } /* Interrupt controller functions */ static int ioapic_intr_pending(void * private_data) { - return 0; + return 0; } static int ioapic_get_intr_number(void * private_data) { - return 0; + return 0; } static int ioapic_begin_irq(void * private_data, int irq) { - return 0; + return 0; } static int ioapic_raise_irq(void * private_data, int irq) { - struct vm_device * dev = (struct vm_device *)private_data; - struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data); - struct redir_tbl_entry * irq_entry = NULL; + struct vm_device * dev = (struct vm_device *)private_data; + struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data); + struct redir_tbl_entry * irq_entry = NULL; - if (irq > 24) { - PrintError("IRQ out of range of IO APIC\n"); - return -1; - } + if (irq > 24) { + PrintError("IRQ out of range of IO APIC\n"); + return -1; + } - irq_entry = &(ioapic->redir_tbl[irq]); + irq_entry = &(ioapic->redir_tbl[irq]); - if (irq_entry->mask == 0) { - PrintDebug("IOAPIC Signalling APIC to raise INTR %d\n", irq_entry->vec); - v3_apic_raise_intr(ioapic->apic, irq_entry->vec); - } + if (irq_entry->mask == 0) { + PrintDebug("IOAPIC Signalling APIC to raise INTR %d\n", irq_entry->vec); + v3_apic_raise_intr(ioapic->apic, irq_entry->vec); + } - return 0; + return 0; } /* I don't know if we can do anything here.... */ static int ioapic_lower_irq(void * private_data, int irq) { - return 0; + return 0; } static struct intr_ctrl_ops intr_ops = { - .intr_pending = ioapic_intr_pending, - .get_intr_number = ioapic_get_intr_number, - .raise_intr = ioapic_raise_irq, - .begin_irq = ioapic_begin_irq, - .lower_intr = ioapic_lower_irq, + .intr_pending = ioapic_intr_pending, + .get_intr_number = ioapic_get_intr_number, + .raise_intr = ioapic_raise_irq, + .begin_irq = ioapic_begin_irq, + .lower_intr = ioapic_lower_irq, }; static int io_apic_init(struct vm_device * dev) { - struct guest_info * info = dev->vm; - struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data); + struct guest_info * info = dev->vm; + struct io_apic_state * ioapic = (struct io_apic_state *)(dev->private_data); - v3_register_intr_controller(dev->vm, &intr_ops, dev); - init_ioapic_state(ioapic); + v3_register_intr_controller(dev->vm, &intr_ops, dev); + init_ioapic_state(ioapic); - v3_hook_full_mem(info, ioapic->base_addr, ioapic->base_addr + PAGE_SIZE_4KB, - ioapic_read, ioapic_write, dev); + v3_hook_full_mem(info, ioapic->base_addr, ioapic->base_addr + PAGE_SIZE_4KB, + ioapic_read, ioapic_write, dev); - return 0; + return 0; } static int io_apic_deinit(struct vm_device * dev) { - // struct guest_info * info = dev->vm; + // struct guest_info * info = dev->vm; - return 0; + return 0; } static struct vm_device_ops dev_ops = { - .init = io_apic_init, - .deinit = io_apic_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, + .init = io_apic_init, + .deinit = io_apic_deinit, + .reset = NULL, + .start = NULL, + .stop = NULL, }; struct vm_device * v3_create_io_apic(struct vm_device * apic) { - PrintDebug("Creating IO APIC\n"); + PrintDebug("Creating IO APIC\n"); - struct io_apic_state * ioapic = (struct io_apic_state *)V3_Malloc(sizeof(struct io_apic_state)); - ioapic->apic = apic; + struct io_apic_state * ioapic = (struct io_apic_state *)V3_Malloc(sizeof(struct io_apic_state)); + ioapic->apic = apic; - struct vm_device * device = v3_create_device("IOAPIC", &dev_ops, ioapic); + struct vm_device * device = v3_create_device("IOAPIC", &dev_ops, ioapic); - return device; + return device; } diff --git a/palacios/src/devices/keyboard.c b/palacios/src/devices/keyboard.c index afcfc25..28442c7 100644 --- a/palacios/src/devices/keyboard.c +++ b/palacios/src/devices/keyboard.c @@ -103,22 +103,22 @@ struct keyboard_internal { - // - // 0x60 is the port for the keyboard microcontroller - // writes are commands - // reads from it usually return scancodes - // however, it can also return other data - // depending on the state of the onboard microcontroller - // - // 0x64 is the port for the onboard microcontroller - // writes are commands - // reads are status - // - - // state of the onboard microcontroller - // this is needed because sometimes 0x60 reads come - // from the onboard microcontroller - enum {// Normal mode measn we deliver keys + // + // 0x60 is the port for the keyboard microcontroller + // writes are commands + // reads from it usually return scancodes + // however, it can also return other data + // depending on the state of the onboard microcontroller + // + // 0x64 is the port for the onboard microcontroller + // writes are commands + // reads are status + // + + // state of the onboard microcontroller + // this is needed because sometimes 0x60 reads come + // from the onboard microcontroller + enum {// Normal mode measn we deliver keys // to the vm and accept commands from it NORMAL, // after receiving cmd 0x60 @@ -146,63 +146,63 @@ struct keyboard_internal { // we wait for a new output byte on 60 // then send it to the mouse IN_MOUSE, - } state; - - - enum { - // after receiving a mouse command 0f 0xff - // we return the ack and then the next thing will be the - // bat code (aa - success) - RESET1, - // followed by the device id (00 - mouse) - RESET2, - // Then it goes into stream mode - STREAM1, // - STREAM2, // - STREAM3, // for each of the following bytes in mouse_packet - // this is used for setting sample rate - SAMPLE1, - // this is used for getting device id - DEVICE1, - // just like the stream moes - REMOTE1, - REMOTE2, - REMOTE3, - // For getting status info - STATUS1, - STATUS2, - STATUS3, - // set resolution - SETRES1, - } mouse_state; - - - uchar_t wrap; - uchar_t mouse_packet[3]; // byte 1: y over, xover, y sign, x sign, 1, middle, right, left - // byte 2: x movement - // byte 3: y movement - - uchar_t mouse_needs_ack; // - uchar_t mouse_done_after_ack; - - uchar_t cmd_byte; // for keyboard uC - read/written - // via read/write cmd byte command - uchar_t status_byte; // for on-board uC - read via 64h - - uchar_t output_byte; // output port of onboard uC (e.g. A20) - - uchar_t input_byte; // input port of onboard uC - - // Data for 8042 - uchar_t input_queue; // - uint_t input_queue_len; // - //uint_t input_queue_read; - //uint_t input_queue_write; - // Data for system - uchar_t output_queue; // - uint_t output_queue_len; // - //uint_t output_queue_read; - //uint_t output_queue_write; + } state; + + + enum { + // after receiving a mouse command 0f 0xff + // we return the ack and then the next thing will be the + // bat code (aa - success) + RESET1, + // followed by the device id (00 - mouse) + RESET2, + // Then it goes into stream mode + STREAM1, // + STREAM2, // + STREAM3, // for each of the following bytes in mouse_packet + // this is used for setting sample rate + SAMPLE1, + // this is used for getting device id + DEVICE1, + // just like the stream moes + REMOTE1, + REMOTE2, + REMOTE3, + // For getting status info + STATUS1, + STATUS2, + STATUS3, + // set resolution + SETRES1, + } mouse_state; + + + uchar_t wrap; + uchar_t mouse_packet[3]; // byte 1: y over, xover, y sign, x sign, 1, middle, right, left + // byte 2: x movement + // byte 3: y movement + + uchar_t mouse_needs_ack; // + uchar_t mouse_done_after_ack; + + uchar_t cmd_byte; // for keyboard uC - read/written + // via read/write cmd byte command + uchar_t status_byte; // for on-board uC - read via 64h + + uchar_t output_byte; // output port of onboard uC (e.g. A20) + + uchar_t input_byte; // input port of onboard uC + + // Data for 8042 + uchar_t input_queue; // + uint_t input_queue_len; // + //uint_t input_queue_read; + //uint_t input_queue_write; + // Data for system + uchar_t output_queue; // + uint_t output_queue_len; // + //uint_t output_queue_read; + //uint_t output_queue_write; }; @@ -214,33 +214,33 @@ struct keyboard_internal { // static int PushToOutputQueue(struct vm_device * dev, uchar_t value, uchar_t overwrite, uchar_t cmd, uchar_t mouse) { - struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); + struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); - if ((state->output_queue_len == 0) || overwrite) { + if ((state->output_queue_len == 0) || overwrite) { - state->output_queue = value; - state->output_queue_len = 1; + state->output_queue = value; + state->output_queue_len = 1; - if (cmd) { - state->status_byte |= STATUS_COMMAND_DATA_AVAIL; - } else { - state->status_byte &= ~STATUS_COMMAND_DATA_AVAIL; - } + if (cmd) { + state->status_byte |= STATUS_COMMAND_DATA_AVAIL; + } else { + state->status_byte &= ~STATUS_COMMAND_DATA_AVAIL; + } - if (mouse) { - state->status_byte |= STATUS_MOUSE_BUFFER_FULL; - } + if (mouse) { + state->status_byte |= STATUS_MOUSE_BUFFER_FULL; + } - { - state->status_byte |= STATUS_OUTPUT_BUFFER_FULL; - } + { + state->status_byte |= STATUS_OUTPUT_BUFFER_FULL; + } - return 0; + return 0; - } else { - PrintError("keyboard: PushToOutputQueue Failed - Queue Full\n"); - return -1; - } + } else { + PrintError("keyboard: PushToOutputQueue Failed - Queue Full\n"); + return -1; + } } #if 1 @@ -250,31 +250,31 @@ static int PushToOutputQueue(struct vm_device * dev, uchar_t value, uchar_t over // static int PullFromOutputQueue(struct vm_device * dev, uchar_t * value) { - struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); + struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); - if (1 || (state->output_queue_len == 1)) { + if (1 || (state->output_queue_len == 1)) { - *value = state->output_queue; - state->output_queue_len = 0; + *value = state->output_queue; + state->output_queue_len = 0; - if (state->status_byte & STATUS_OUTPUT_BUFFER_FULL) { - state->status_byte &= ~STATUS_OUTPUT_BUFFER_FULL; - } + if (state->status_byte & STATUS_OUTPUT_BUFFER_FULL) { + state->status_byte &= ~STATUS_OUTPUT_BUFFER_FULL; + } - if (state->status_byte & STATUS_MOUSE_BUFFER_FULL) { - state->status_byte &= ~STATUS_MOUSE_BUFFER_FULL; - } + if (state->status_byte & STATUS_MOUSE_BUFFER_FULL) { + state->status_byte &= ~STATUS_MOUSE_BUFFER_FULL; + } - if (state->status_byte & STATUS_COMMAND_DATA_AVAIL) { - state->status_byte &= ~STATUS_COMMAND_DATA_AVAIL; - } // reset to data + if (state->status_byte & STATUS_COMMAND_DATA_AVAIL) { + state->status_byte &= ~STATUS_COMMAND_DATA_AVAIL; + } // reset to data - return 0; - } else { - PrintError("keyboard: PullFromOutputQueue Failed - Queue Empty\n"); - return -1; - } + return 0; + } else { + PrintError("keyboard: PullFromOutputQueue Failed - Queue Empty\n"); + return -1; + } } #endif @@ -285,19 +285,19 @@ static int PullFromOutputQueue(struct vm_device * dev, uchar_t * value) // static int PushToInputQueue(struct vm_device * dev, uchar_t value, uchar_t overwrite) { - struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); + struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); - if ((state->input_queue_len == 0) || overwrite) { + if ((state->input_queue_len == 0) || overwrite) { - state->input_queue = value; - state->input_queue_len = 1; - state->status_byte |= STATUS_INPUT_BUFFER_FULL; + state->input_queue = value; + state->input_queue_len = 1; + state->status_byte |= STATUS_INPUT_BUFFER_FULL; - return 0; - } else { - PrintError("keyboard: PushToOutputQueue Failed - Queue Full\n"); - return -1; - } + return 0; + } else { + PrintError("keyboard: PushToOutputQueue Failed - Queue Full\n"); + return -1; + } } // @@ -306,19 +306,19 @@ static int PushToInputQueue(struct vm_device * dev, uchar_t value, uchar_t overw // static int PullFromInputQueue(struct vm_device *dev, uchar_t *value) { - struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data); + struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data); - if (state->input_queue_len == 1) { + if (state->input_queue_len == 1) { - *value = state->input_queue; - state->input_queue_len = 0; - state->status_byte &= ~STATUS_INPUT_BUFFER_FULL; + *value = state->input_queue; + state->input_queue_len = 0; + state->status_byte &= ~STATUS_INPUT_BUFFER_FULL; - return 0; - } else { - PrintError("keyboard: PullFromInputQueue Failed - Queue Empty\n"); - return -1; - } + return 0; + } else { + PrintError("keyboard: PullFromInputQueue Failed - Queue Empty\n"); + return -1; + } } #endif @@ -327,11 +327,11 @@ static int PullFromInputQueue(struct vm_device *dev, uchar_t *value) static int keyboard_interrupt(struct vm_device * dev, uint_t irq) { - PrintDebug("keyboard: interrupt 0x%x\n", irq); + PrintDebug("keyboard: interrupt 0x%x\n", irq); - v3_raise_irq(dev->vm, irq); + v3_raise_irq(dev->vm, irq); - return 0; + return 0; } @@ -340,86 +340,86 @@ static int keyboard_interrupt(struct vm_device * dev, uint_t irq) { static int key_event_handler(struct guest_info * info, struct v3_keyboard_event * evt, void * private_data) { - struct vm_device * dev = (struct vm_device *)private_data; - struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); + struct vm_device * dev = (struct vm_device *)private_data; + struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); - PrintDebug("keyboard: injected status 0x%x, and scancode 0x%x\n", evt->status, evt->scan_code); + PrintDebug("keyboard: injected status 0x%x, and scancode 0x%x\n", evt->status, evt->scan_code); - if ( (state->status_byte & STATUS_ENABLED) // onboard is enabled - && (!(state->cmd_byte & CMD_DISABLE)) ) { // keyboard is enabled + if ( (state->status_byte & STATUS_ENABLED) // onboard is enabled + && (!(state->cmd_byte & CMD_DISABLE)) ) { // keyboard is enabled - PushToOutputQueue(dev, evt->scan_code, OVERWRITE, DATA, KEYBOARD); + PushToOutputQueue(dev, evt->scan_code, OVERWRITE, DATA, KEYBOARD); - if (state->cmd_byte & CMD_INTR) { - keyboard_interrupt(dev, KEYBOARD_IRQ); + if (state->cmd_byte & CMD_INTR) { + keyboard_interrupt(dev, KEYBOARD_IRQ); + } } - } - return 0; + return 0; } static int mouse_event_handler(struct guest_info * info, struct v3_mouse_event * evt, void * private_data) { - struct vm_device * dev = (struct vm_device *)private_data; - struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data); + struct vm_device * dev = (struct vm_device *)private_data; + struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data); - PrintDebug("keyboard: injected mouse packet 0x %x %x %x\n", - evt->data[0], evt->data[1], evt->data[2]); + PrintDebug("keyboard: injected mouse packet 0x %x %x %x\n", + evt->data[0], evt->data[1], evt->data[2]); - memcpy(state->mouse_packet, evt->data, 3); + memcpy(state->mouse_packet, evt->data, 3); - state->status_byte |= STATUS_MOUSE_BUFFER_FULL; + state->status_byte |= STATUS_MOUSE_BUFFER_FULL; - switch (state->mouse_state) { - case STREAM1: - case STREAM2: - case STREAM3: - if (!(state->cmd_byte & CMD_MOUSE_DISABLE)) { - keyboard_interrupt(dev, MOUSE_IRQ); + switch (state->mouse_state) { + case STREAM1: + case STREAM2: + case STREAM3: + if (!(state->cmd_byte & CMD_MOUSE_DISABLE)) { + keyboard_interrupt(dev, MOUSE_IRQ); + } + break; + default: + return -1; + break; } - break; - default: - return -1; - break; - } - return 0; + return 0; } static int keyboard_reset_device(struct vm_device * dev) { - struct keyboard_internal *data = (struct keyboard_internal *)(dev->private_data); + struct keyboard_internal *data = (struct keyboard_internal *)(dev->private_data); - memset(data, 0, sizeof(struct keyboard_internal)); + memset(data, 0, sizeof(struct keyboard_internal)); - data->state = NORMAL; - data->mouse_state = STREAM1; + data->state = NORMAL; + data->mouse_state = STREAM1; - data->cmd_byte = - CMD_INTR // interrupts on - | CMD_MOUSE_INTR // mouse interupts on - | CMD_SYSTEM ; // self test passed - // PS2, keyboard+mouse enabled, generic translation + data->cmd_byte = + CMD_INTR // interrupts on + | CMD_MOUSE_INTR // mouse interupts on + | CMD_SYSTEM ; // self test passed + // PS2, keyboard+mouse enabled, generic translation - data->status_byte = - STATUS_SYSTEM // self-tests passed - | STATUS_ENABLED ; // keyboard ready - // buffers empty, no errors + data->status_byte = + STATUS_SYSTEM // self-tests passed + | STATUS_ENABLED ; // keyboard ready + // buffers empty, no errors - data->output_byte = 0; // ? + data->output_byte = 0; // ? - data->input_byte = INPUT_RAM; // we have some - // also display=color, jumper 0, keyboard enabled + data->input_byte = INPUT_RAM; // we have some + // also display=color, jumper 0, keyboard enabled - PrintDebug("keyboard: reset device\n"); + PrintDebug("keyboard: reset device\n"); - return 0; + return 0; } @@ -427,358 +427,358 @@ static int keyboard_reset_device(struct vm_device * dev) static int keyboard_start_device(struct vm_device *dev) { - PrintDebug("keyboard: start device\n"); - return 0; + PrintDebug("keyboard: start device\n"); + return 0; } static int keyboard_stop_device(struct vm_device *dev) { - PrintDebug("keyboard: stop device\n"); - return 0; + PrintDebug("keyboard: stop device\n"); + return 0; } static int mouse_read_input(struct vm_device *dev) { - struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); + struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); - if (state->mouse_needs_ack) { - state->mouse_needs_ack = 0; + if (state->mouse_needs_ack) { + state->mouse_needs_ack = 0; - // the ack has been stuffed previously - if (state->mouse_done_after_ack) { - return 1; - } else { - return 0; + // the ack has been stuffed previously + if (state->mouse_done_after_ack) { + return 1; + } else { + return 0; + } } - } - switch (state->mouse_state) { + switch (state->mouse_state) { - case RESET1: // requesting the BAT code - PushToOutputQueue(dev, 0xaa, OVERWRITE, DATA, MOUSE) ; // BAT successful - PrintDebug(" mouse sent BAT code (sucesssful) "); - state->mouse_state = RESET2; + case RESET1: // requesting the BAT code + PushToOutputQueue(dev, 0xaa, OVERWRITE, DATA, MOUSE) ; // BAT successful + PrintDebug(" mouse sent BAT code (sucesssful) "); + state->mouse_state = RESET2; - return 0; // not done with mouse processing yet - break; + return 0; // not done with mouse processing yet + break; - case RESET2: // requesting the device id - PushToOutputQueue(dev, 0x00, OVERWRITE, DATA, MOUSE) ; // normal mouse type - PrintDebug(" mouse sent device id "); - state->mouse_state = STREAM1; + case RESET2: // requesting the device id + PushToOutputQueue(dev, 0x00, OVERWRITE, DATA, MOUSE) ; // normal mouse type + PrintDebug(" mouse sent device id "); + state->mouse_state = STREAM1; - return 1; // done with mouse processing - break; + return 1; // done with mouse processing + break; - case STREAM1: // send data - PushToOutputQueue(dev, state->mouse_packet[0], OVERWRITE, DATA, MOUSE); - PrintDebug(" mouse sent stream data1 "); - state->mouse_state = STREAM2; + case STREAM1: // send data + PushToOutputQueue(dev, state->mouse_packet[0], OVERWRITE, DATA, MOUSE); + PrintDebug(" mouse sent stream data1 "); + state->mouse_state = STREAM2; - return 0; - break; + return 0; + break; - case STREAM2: // send data - PushToOutputQueue(dev, state->mouse_packet[1], OVERWRITE, DATA, MOUSE); - PrintDebug(" mouse sent stream data2 "); - state->mouse_state = STREAM3; + case STREAM2: // send data + PushToOutputQueue(dev, state->mouse_packet[1], OVERWRITE, DATA, MOUSE); + PrintDebug(" mouse sent stream data2 "); + state->mouse_state = STREAM3; - return 0; - break; + return 0; + break; - case STREAM3: // send data - PushToOutputQueue(dev, state->mouse_packet[2], OVERWRITE, DATA, MOUSE); - PrintDebug(" mouse sent stream data3 "); - state->mouse_state = STREAM1; + case STREAM3: // send data + PushToOutputQueue(dev, state->mouse_packet[2], OVERWRITE, DATA, MOUSE); + PrintDebug(" mouse sent stream data3 "); + state->mouse_state = STREAM1; - return 1; // now done - break; + return 1; // now done + break; - case REMOTE1: // send data - PushToOutputQueue(dev, state->mouse_packet[0], OVERWRITE, DATA, MOUSE); - PrintDebug(" mouse sent remote data1 "); - state->mouse_state = REMOTE2; + case REMOTE1: // send data + PushToOutputQueue(dev, state->mouse_packet[0], OVERWRITE, DATA, MOUSE); + PrintDebug(" mouse sent remote data1 "); + state->mouse_state = REMOTE2; - return 0; - break; + return 0; + break; - case REMOTE2: // send data - PushToOutputQueue(dev, state->mouse_packet[1], OVERWRITE, DATA, MOUSE); - PrintDebug(" mouse sent remote data2 "); - state->mouse_state = REMOTE3; + case REMOTE2: // send data + PushToOutputQueue(dev, state->mouse_packet[1], OVERWRITE, DATA, MOUSE); + PrintDebug(" mouse sent remote data2 "); + state->mouse_state = REMOTE3; - return 0; - break; + return 0; + break; - case REMOTE3: // send data - PushToOutputQueue(dev, state->mouse_packet[2], OVERWRITE, DATA, MOUSE); - PrintDebug(" mouse sent remote data3 "); - state->mouse_state = REMOTE1; + case REMOTE3: // send data + PushToOutputQueue(dev, state->mouse_packet[2], OVERWRITE, DATA, MOUSE); + PrintDebug(" mouse sent remote data3 "); + state->mouse_state = REMOTE1; - return 1; // now done - break; + return 1; // now done + break; - case STATUS1: // send data - PushToOutputQueue(dev, 0x0, OVERWRITE, DATA, MOUSE); - PrintDebug(" mouse sent status data1 "); - state->mouse_state = STATUS2; + case STATUS1: // send data + PushToOutputQueue(dev, 0x0, OVERWRITE, DATA, MOUSE); + PrintDebug(" mouse sent status data1 "); + state->mouse_state = STATUS2; - return 0; - break; + return 0; + break; - case STATUS2: // send data - PushToOutputQueue(dev, 0x0, OVERWRITE, DATA, MOUSE); - PrintDebug(" mouse sent status data2 "); - state->mouse_state = STATUS3; + case STATUS2: // send data + PushToOutputQueue(dev, 0x0, OVERWRITE, DATA, MOUSE); + PrintDebug(" mouse sent status data2 "); + state->mouse_state = STATUS3; - return 0; - break; + return 0; + break; - case STATUS3: // send data - PushToOutputQueue(dev, 0x0, OVERWRITE, DATA, MOUSE); - PrintDebug(" mouse sent status data3 "); - state->mouse_state = STREAM1; + case STATUS3: // send data + PushToOutputQueue(dev, 0x0, OVERWRITE, DATA, MOUSE); + PrintDebug(" mouse sent status data3 "); + state->mouse_state = STREAM1; - return 1; // now done - break; + return 1; // now done + break; - case DEVICE1: // send device id - PushToOutputQueue(dev, 0x0, OVERWRITE, DATA, MOUSE); - PrintDebug(" mouse sent device id "); - state->mouse_state = STREAM1; + case DEVICE1: // send device id + PushToOutputQueue(dev, 0x0, OVERWRITE, DATA, MOUSE); + PrintDebug(" mouse sent device id "); + state->mouse_state = STREAM1; - return 1; // now done - break; + return 1; // now done + break; - default: - PrintDebug(" mouse has no data "); - return 1; // done - break; - } + default: + PrintDebug(" mouse has no data "); + return 1; // done + break; + } } static int mouse_write_output(struct vm_device * dev, uchar_t data) { - struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data); - - switch (state->mouse_state) { - case STREAM1: - case STREAM2: - case STREAM3: - case REMOTE1: - case REMOTE2: - case REMOTE3: - switch (data) { - - case 0xff: //reset - PushToOutputQueue(dev, 0xfe, OVERWRITE, DATA, MOUSE) ; // no mouse! - PrintDebug(" mouse reset begins (no mouse) "); - - return 1; // not done; - break; - - /* - case 0xff: //reset - PushToOutputQueue(dev,0xfa,OVERWRITE,DATA,MOUSE) ; - PrintDebug(" mouse reset begins "); - state->mouse_done_after_ack=0; - state->mouse_needs_ack=1; - state->mouse_state=RESET1; - return 0; // not done; - break; - */ - case 0xfe: //resend - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - PrintDebug(" mouse resend begins "); - state->mouse_done_after_ack = 0; - state->mouse_needs_ack = 0; - state->mouse_state = STREAM1; - return 0; // not done - break; + struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data); + + switch (state->mouse_state) { + case STREAM1: + case STREAM2: + case STREAM3: + case REMOTE1: + case REMOTE2: + case REMOTE3: + switch (data) { + + case 0xff: //reset + PushToOutputQueue(dev, 0xfe, OVERWRITE, DATA, MOUSE) ; // no mouse! + PrintDebug(" mouse reset begins (no mouse) "); + + return 1; // not done; + break; + + /* + case 0xff: //reset + PushToOutputQueue(dev,0xfa,OVERWRITE,DATA,MOUSE) ; + PrintDebug(" mouse reset begins "); + state->mouse_done_after_ack=0; + state->mouse_needs_ack=1; + state->mouse_state=RESET1; + return 0; // not done; + break; + */ + case 0xfe: //resend + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + PrintDebug(" mouse resend begins "); + state->mouse_done_after_ack = 0; + state->mouse_needs_ack = 0; + state->mouse_state = STREAM1; + return 0; // not done + break; - case 0xf6: // set defaults - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - PrintDebug(" mouse set defaults "); - state->mouse_done_after_ack = 1; - state->mouse_needs_ack = 1; - state->mouse_state = STREAM1; - return 0; // not done - break; + case 0xf6: // set defaults + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + PrintDebug(" mouse set defaults "); + state->mouse_done_after_ack = 1; + state->mouse_needs_ack = 1; + state->mouse_state = STREAM1; + return 0; // not done + break; - case 0xf5: // disable data reporting - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 1; - state->mouse_needs_ack = 1; - PrintDebug(" mouse disable data reporting "); - state->mouse_state = STREAM1; - return 0; // not done - break; + case 0xf5: // disable data reporting + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 1; + state->mouse_needs_ack = 1; + PrintDebug(" mouse disable data reporting "); + state->mouse_state = STREAM1; + return 0; // not done + break; - case 0xf4: // enable data reporting - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 1; - state->mouse_needs_ack = 1; - PrintDebug(" mouse enable data reporting "); - state->mouse_state = STREAM1; - return 0; // not done - break; + case 0xf4: // enable data reporting + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 1; + state->mouse_needs_ack = 1; + PrintDebug(" mouse enable data reporting "); + state->mouse_state = STREAM1; + return 0; // not done + break; - case 0xf3: // set sample rate - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 0; - state->mouse_needs_ack = 1; - PrintDebug(" mouse set sample rate begins "); - state->mouse_state = SAMPLE1; - return 0; // not done - break; + case 0xf3: // set sample rate + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 0; + state->mouse_needs_ack = 1; + PrintDebug(" mouse set sample rate begins "); + state->mouse_state = SAMPLE1; + return 0; // not done + break; - case 0xf2: // get device id - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 0; - state->mouse_needs_ack = 1; - PrintDebug(" mouse get device id begins "); - state->mouse_state = DEVICE1; - return 0; // not done - break; + case 0xf2: // get device id + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 0; + state->mouse_needs_ack = 1; + PrintDebug(" mouse get device id begins "); + state->mouse_state = DEVICE1; + return 0; // not done + break; - case 0xf0: // set remote mode - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 1; - state->mouse_needs_ack = 1; - PrintDebug(" mouse set remote mode "); - state->mouse_state = REMOTE1; - return 0; // not done - break; - - case 0xee: // set wrap mode - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 1; - state->mouse_needs_ack = 1; - PrintDebug(" mouse set wrap mode (ignored) "); - state->mouse_state = STREAM1; - return 0; // not done - break; - - case 0xec: // reset wrap mode - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 1; - state->mouse_needs_ack = 1; - PrintDebug(" mouse reset wrap mode (ignored) "); - state->mouse_state = STREAM1; - return 0; // done - break; - - case 0xeb: // read data - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 0; - state->mouse_needs_ack = 1; - PrintDebug(" mouse switch to wrap mode (ignored) "); - state->mouse_state = REMOTE1; - return 0; // not done - break; + case 0xf0: // set remote mode + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 1; + state->mouse_needs_ack = 1; + PrintDebug(" mouse set remote mode "); + state->mouse_state = REMOTE1; + return 0; // not done + break; + + case 0xee: // set wrap mode + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 1; + state->mouse_needs_ack = 1; + PrintDebug(" mouse set wrap mode (ignored) "); + state->mouse_state = STREAM1; + return 0; // not done + break; + + case 0xec: // reset wrap mode + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 1; + state->mouse_needs_ack = 1; + PrintDebug(" mouse reset wrap mode (ignored) "); + state->mouse_state = STREAM1; + return 0; // done + break; + + case 0xeb: // read data + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 0; + state->mouse_needs_ack = 1; + PrintDebug(" mouse switch to wrap mode (ignored) "); + state->mouse_state = REMOTE1; + return 0; // not done + break; - case 0xea: // set stream mode - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 1; - state->mouse_needs_ack = 1; - PrintDebug(" mouse set stream mode "); - state->mouse_state = STREAM1; - return 0; // not done - break; - - case 0xe9: // status request - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 0; - state->mouse_needs_ack = 1; - PrintDebug(" mouse status request begins "); - state->mouse_state = STATUS1; - return 0; // notdone - break; - - case 0xe8: // set resolution - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 0; - state->mouse_needs_ack = 1; - PrintDebug(" mouse set resolution begins "); - state->mouse_state = SETRES1; - return 0; // notdone - break; - - case 0xe7: // set scaling 2:1 - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 1; - state->mouse_needs_ack = 1; - PrintDebug(" mouse set scaling 2:1 "); - state->mouse_state = STREAM1; - return 0; // not done - break; - - case 0xe6: // set scaling 1:1 - PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; - state->mouse_done_after_ack = 1; - state->mouse_needs_ack = 1; - PrintDebug(" mouse set scaling 1:1 "); - state->mouse_state = STREAM1; - return 0; // done - break; + case 0xea: // set stream mode + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 1; + state->mouse_needs_ack = 1; + PrintDebug(" mouse set stream mode "); + state->mouse_state = STREAM1; + return 0; // not done + break; + + case 0xe9: // status request + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 0; + state->mouse_needs_ack = 1; + PrintDebug(" mouse status request begins "); + state->mouse_state = STATUS1; + return 0; // notdone + break; + + case 0xe8: // set resolution + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 0; + state->mouse_needs_ack = 1; + PrintDebug(" mouse set resolution begins "); + state->mouse_state = SETRES1; + return 0; // notdone + break; + + case 0xe7: // set scaling 2:1 + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 1; + state->mouse_needs_ack = 1; + PrintDebug(" mouse set scaling 2:1 "); + state->mouse_state = STREAM1; + return 0; // not done + break; + + case 0xe6: // set scaling 1:1 + PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; + state->mouse_done_after_ack = 1; + state->mouse_needs_ack = 1; + PrintDebug(" mouse set scaling 1:1 "); + state->mouse_state = STREAM1; + return 0; // done + break; - default: - PrintDebug(" receiving unknown mouse command (0x%x) in acceptable state ", data); - return 1; // done - break; + default: + PrintDebug(" receiving unknown mouse command (0x%x) in acceptable state ", data); + return 1; // done + break; - } + } - default: - PrintDebug(" receiving mouse output in unhandled state (0x%x) ", state->mouse_state); - break; - return 1; // done? - break; - } - - PrintDebug(" HUH? "); - return 1; // done + default: + PrintDebug(" receiving mouse output in unhandled state (0x%x) ", state->mouse_state); + break; + return 1; // done? + break; + } + + PrintDebug(" HUH? "); + return 1; // done } #if KEYBOARD_DEBUG_80H static int keyboard_write_delay(ushort_t port, - void * src, - uint_t length, - struct vm_device * dev) + void * src, + uint_t length, + struct vm_device * dev) { - if (length == 1) { - PrintDebug("keyboard: write of 0x%x to 80h\n", *((uchar_t*)src)); + if (length == 1) { + PrintDebug("keyboard: write of 0x%x to 80h\n", *((uchar_t*)src)); - return 1; - } else { - PrintDebug("keyboard: write of >1 byte to 80h\n", *((uchar_t*)src)); + return 1; + } else { + PrintDebug("keyboard: write of >1 byte to 80h\n", *((uchar_t*)src)); - return length; - } + return length; + } } static int keyboard_read_delay(ushort_t port, - void * dest, - uint_t length, - struct vm_device * dev) + void * dest, + uint_t length, + struct vm_device * dev) { - if (length == 1) { - *((uchar_t*)dest) = v3_inb(port); + if (length == 1) { + *((uchar_t*)dest) = v3_inb(port); - PrintDebug("keyboard: read of 0x%x from 80h\n", *((uchar_t*)dest)); + PrintDebug("keyboard: read of 0x%x from 80h\n", *((uchar_t*)dest)); - return 1; - } else { - PrintDebug("keyboard: read of >1 byte from 80h\n"); + return 1; + } else { + PrintDebug("keyboard: read of >1 byte from 80h\n"); - return length; - } + return length; + } } #endif @@ -791,196 +791,196 @@ static int keyboard_write_command(ushort_t port, uint_t length, struct vm_device * dev) { - struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); - uchar_t cmd; + struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); + uchar_t cmd; - // Should always be single byte write + // Should always be single byte write - if (length != 1) { - PrintError("keyboard: write of >1 bytes (%d) to 64h\n", length); - return -1; - } + if (length != 1) { + PrintError("keyboard: write of >1 bytes (%d) to 64h\n", length); + return -1; + } - cmd = *((uchar_t*)src); + cmd = *((uchar_t*)src); - if (state->state != NORMAL) { - PrintDebug("keyboard: warning - receiving command on 64h but state != NORMAL\n"); - } + if (state->state != NORMAL) { + PrintDebug("keyboard: warning - receiving command on 64h but state != NORMAL\n"); + } - PrintDebug("keyboard: command 0x%x on 64h\n", cmd); - - switch (cmd) { - - case 0x20: // READ COMMAND BYTE (returned in 60h) - PushToOutputQueue(dev, state->cmd_byte, OVERWRITE, COMMAND,KEYBOARD); - state->state = NORMAL; // the next read on 0x60 will get the right data - PrintDebug("keyboard: command byte 0x%x returned\n", state->cmd_byte); - break; - - case 0x60: // WRITE COMMAND BYTE (read from 60h) - state->state = WRITING_CMD_BYTE; // we need to make sure we send the next 0x60 byte appropriately - PrintDebug("keyboard: prepare to write command byte\n"); - break; - - // case 0x90-9f - write to output port (?) - - case 0xa1: // Get version number - PushToOutputQueue(dev, 0, OVERWRITE, COMMAND, KEYBOARD); - state->state = NORMAL; - PrintDebug("keyboard: version number 0x0 returned\n"); - break; - - case 0xa4: // is password installed? send result to 0x60 - // we don't support passwords - PushToOutputQueue(dev, 0xf1, OVERWRITE, COMMAND, KEYBOARD); - PrintDebug("keyboard: password not installed\n"); - state->state = NORMAL; - break; - - case 0xa5: // new password will arrive on 0x60 - state->state = TRANSMIT_PASSWD; - PrintDebug("keyboard: pepare to transmit password\n"); - break; - - case 0xa6: // check passwd; - // since we do not support passwords, we will simply ignore this - // the implication is that any password check immediately succeeds - // with a blank password - state->state = NORMAL; - PrintDebug("keyboard: password check succeeded\n"); - break; - - case 0xa7: // disable mouse - state->cmd_byte |= CMD_MOUSE_DISABLE; - state->state = NORMAL; - PrintDebug("keyboard: mouse disabled\n"); - break; - - case 0xa8: // enable mouse - state->cmd_byte &= ~CMD_MOUSE_DISABLE; - state->state = NORMAL; - PrintDebug("keyboard: mouse enabled\n"); - break; - - case 0xa9: // mouse interface test (always succeeds) - PushToOutputQueue(dev, 0, OVERWRITE, COMMAND, KEYBOARD); - PrintDebug("keyboard: mouse interface test succeeded\n"); - state->state = NORMAL; - break; - - case 0xaa: // controller self test (always succeeds) - PushToOutputQueue(dev, 0x55, OVERWRITE, COMMAND, KEYBOARD); - PrintDebug("keyboard: controller self test succeeded\n"); - state->state = NORMAL; - break; - - case 0xab: // keyboard interface test (always succeeds) - PushToOutputQueue(dev, 0, OVERWRITE, COMMAND, KEYBOARD); - state->state = NORMAL; - PrintDebug("keyboard: keyboard interface test succeeded\n"); - break; - - case 0xad: // disable keyboard - state->cmd_byte |= CMD_DISABLE; - state->state = NORMAL; - PrintDebug("keyboard: keyboard disabled\n"); - break; - - case 0xae: // enable keyboard - state->cmd_byte &= ~CMD_DISABLE; - state->state = NORMAL; - PrintDebug("keyboard: keyboard enabled\n"); - break; - - case 0xaf: // get version - PushToOutputQueue(dev, 0x00, OVERWRITE, COMMAND, KEYBOARD); - state->state = NORMAL; - PrintDebug("keyboard: version 0 returned \n"); - break; - - case 0xd0: // return microcontroller output on 60h - PushToOutputQueue(dev, state->output_byte, OVERWRITE, COMMAND, KEYBOARD); - state->state = NORMAL; - PrintDebug("keyboard: output byte 0x%x returned\n", state->output_byte); - break; - - case 0xd1: // request to write next byte on 60h to the microcontroller output port - state->state = WRITING_OUTPUT_PORT; - PrintDebug("keyboard: prepare to write output byte\n"); - break; - - case 0xd2: // write keyboard buffer (inject key) - state->state = INJECTING_KEY; - PrintDebug("keyboard: prepare to inject key\n"); - break; - - case 0xd3: // write mouse buffer (inject mouse) - state->state = INJECTING_MOUSE; - PrintDebug("keyboard: prepare to inject mouse\n"); - break; - - case 0xd4: // write mouse device (command to mouse?) - state->state = IN_MOUSE; - PrintDebug("keyboard: prepare to inject mouse command\n"); - break; - - case 0xc0: // read input port - PushToOutputQueue(dev, state->input_byte, OVERWRITE, COMMAND, KEYBOARD); - state->state = NORMAL; - PrintDebug("keyboard: input byte 0x%x returned\n", state->input_byte); - break; - - case 0xc1: //copy input port lsn to status msn - state->status_byte &= 0x0f; - state->status_byte |= (state->input_byte & 0xf) << 4; - state->state = NORMAL; - PrintDebug("keyboard: copied input byte lsn to status msn\n"); - break; - - case 0xc2: // copy input port msn to status msn - state->status_byte &= 0x0f; - state->status_byte |= (state->input_byte & 0xf0); - state->state = NORMAL; - PrintDebug("keyboard: copied input byte msn to status msn\n"); - break; + PrintDebug("keyboard: command 0x%x on 64h\n", cmd); + + switch (cmd) { + + case 0x20: // READ COMMAND BYTE (returned in 60h) + PushToOutputQueue(dev, state->cmd_byte, OVERWRITE, COMMAND,KEYBOARD); + state->state = NORMAL; // the next read on 0x60 will get the right data + PrintDebug("keyboard: command byte 0x%x returned\n", state->cmd_byte); + break; + + case 0x60: // WRITE COMMAND BYTE (read from 60h) + state->state = WRITING_CMD_BYTE; // we need to make sure we send the next 0x60 byte appropriately + PrintDebug("keyboard: prepare to write command byte\n"); + break; + + // case 0x90-9f - write to output port (?) + + case 0xa1: // Get version number + PushToOutputQueue(dev, 0, OVERWRITE, COMMAND, KEYBOARD); + state->state = NORMAL; + PrintDebug("keyboard: version number 0x0 returned\n"); + break; + + case 0xa4: // is password installed? send result to 0x60 + // we don't support passwords + PushToOutputQueue(dev, 0xf1, OVERWRITE, COMMAND, KEYBOARD); + PrintDebug("keyboard: password not installed\n"); + state->state = NORMAL; + break; + + case 0xa5: // new password will arrive on 0x60 + state->state = TRANSMIT_PASSWD; + PrintDebug("keyboard: pepare to transmit password\n"); + break; + + case 0xa6: // check passwd; + // since we do not support passwords, we will simply ignore this + // the implication is that any password check immediately succeeds + // with a blank password + state->state = NORMAL; + PrintDebug("keyboard: password check succeeded\n"); + break; + + case 0xa7: // disable mouse + state->cmd_byte |= CMD_MOUSE_DISABLE; + state->state = NORMAL; + PrintDebug("keyboard: mouse disabled\n"); + break; + + case 0xa8: // enable mouse + state->cmd_byte &= ~CMD_MOUSE_DISABLE; + state->state = NORMAL; + PrintDebug("keyboard: mouse enabled\n"); + break; + + case 0xa9: // mouse interface test (always succeeds) + PushToOutputQueue(dev, 0, OVERWRITE, COMMAND, KEYBOARD); + PrintDebug("keyboard: mouse interface test succeeded\n"); + state->state = NORMAL; + break; + + case 0xaa: // controller self test (always succeeds) + PushToOutputQueue(dev, 0x55, OVERWRITE, COMMAND, KEYBOARD); + PrintDebug("keyboard: controller self test succeeded\n"); + state->state = NORMAL; + break; + + case 0xab: // keyboard interface test (always succeeds) + PushToOutputQueue(dev, 0, OVERWRITE, COMMAND, KEYBOARD); + state->state = NORMAL; + PrintDebug("keyboard: keyboard interface test succeeded\n"); + break; + + case 0xad: // disable keyboard + state->cmd_byte |= CMD_DISABLE; + state->state = NORMAL; + PrintDebug("keyboard: keyboard disabled\n"); + break; + + case 0xae: // enable keyboard + state->cmd_byte &= ~CMD_DISABLE; + state->state = NORMAL; + PrintDebug("keyboard: keyboard enabled\n"); + break; + + case 0xaf: // get version + PushToOutputQueue(dev, 0x00, OVERWRITE, COMMAND, KEYBOARD); + state->state = NORMAL; + PrintDebug("keyboard: version 0 returned \n"); + break; + + case 0xd0: // return microcontroller output on 60h + PushToOutputQueue(dev, state->output_byte, OVERWRITE, COMMAND, KEYBOARD); + state->state = NORMAL; + PrintDebug("keyboard: output byte 0x%x returned\n", state->output_byte); + break; + + case 0xd1: // request to write next byte on 60h to the microcontroller output port + state->state = WRITING_OUTPUT_PORT; + PrintDebug("keyboard: prepare to write output byte\n"); + break; + + case 0xd2: // write keyboard buffer (inject key) + state->state = INJECTING_KEY; + PrintDebug("keyboard: prepare to inject key\n"); + break; + + case 0xd3: // write mouse buffer (inject mouse) + state->state = INJECTING_MOUSE; + PrintDebug("keyboard: prepare to inject mouse\n"); + break; + + case 0xd4: // write mouse device (command to mouse?) + state->state = IN_MOUSE; + PrintDebug("keyboard: prepare to inject mouse command\n"); + break; + + case 0xc0: // read input port + PushToOutputQueue(dev, state->input_byte, OVERWRITE, COMMAND, KEYBOARD); + state->state = NORMAL; + PrintDebug("keyboard: input byte 0x%x returned\n", state->input_byte); + break; + + case 0xc1: //copy input port lsn to status msn + state->status_byte &= 0x0f; + state->status_byte |= (state->input_byte & 0xf) << 4; + state->state = NORMAL; + PrintDebug("keyboard: copied input byte lsn to status msn\n"); + break; + + case 0xc2: // copy input port msn to status msn + state->status_byte &= 0x0f; + state->status_byte |= (state->input_byte & 0xf0); + state->state = NORMAL; + PrintDebug("keyboard: copied input byte msn to status msn\n"); + break; - case 0xe0: // read test port - PushToOutputQueue(dev, state->output_byte >> 6, OVERWRITE, COMMAND, KEYBOARD); - state->state = NORMAL; - PrintDebug("keyboard: read 0x%x from test port\n", state->output_byte >> 6); - break; + case 0xe0: // read test port + PushToOutputQueue(dev, state->output_byte >> 6, OVERWRITE, COMMAND, KEYBOARD); + state->state = NORMAL; + PrintDebug("keyboard: read 0x%x from test port\n", state->output_byte >> 6); + break; - case 0xf0: // pulse output port - case 0xf1: // this should pulse 0..3 of cmd_byte on output port - case 0xf2: // instead of what is currently in output_byte (I think) - case 0xf3: // main effect is taht if bit zero is zero - case 0xf4: // should cause reset - case 0xf5: // I doubt anything more recent than a 286 running - case 0xf6: // OS2 with the penalty box will care - case 0xf7: - case 0xf8: - case 0xf9: - case 0xfa: - case 0xfb: - case 0xfc: - case 0xfd: - case 0xfe: - case 0xff: + case 0xf0: // pulse output port + case 0xf1: // this should pulse 0..3 of cmd_byte on output port + case 0xf2: // instead of what is currently in output_byte (I think) + case 0xf3: // main effect is taht if bit zero is zero + case 0xf4: // should cause reset + case 0xf5: // I doubt anything more recent than a 286 running + case 0xf6: // OS2 with the penalty box will care + case 0xf7: + case 0xf8: + case 0xf9: + case 0xfa: + case 0xfb: + case 0xfc: + case 0xfd: + case 0xfe: + case 0xff: - PrintDebug("keyboard: ignoring pulse of 0x%x (low=pulsed) on output port\n", (cmd & 0xf)); - state->state = NORMAL; - break; + PrintDebug("keyboard: ignoring pulse of 0x%x (low=pulsed) on output port\n", (cmd & 0xf)); + state->state = NORMAL; + break; - // case ac diagonstic - returns 16 bytes from keyboard microcontroler on 60h - default: - PrintDebug("keyboard: ignoring command (unimplemented)\n"); - state->state = NORMAL; - break; - } + // case ac diagonstic - returns 16 bytes from keyboard microcontroler on 60h + default: + PrintDebug("keyboard: ignoring command (unimplemented)\n"); + state->state = NORMAL; + break; + } - return 1; + return 1; } @@ -989,21 +989,21 @@ static int keyboard_read_status(ushort_t port, uint_t length, struct vm_device * dev) { - struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); + struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); - if (length == 1) { + if (length == 1) { - PrintDebug("keyboard: read status (64h): "); + PrintDebug("keyboard: read status (64h): "); - *((uchar_t*)dest) = state->status_byte; + *((uchar_t*)dest) = state->status_byte; - PrintDebug("0x%x\n", *((uchar_t*)dest)); + PrintDebug("0x%x\n", *((uchar_t*)dest)); - return 1; - } else { - PrintError("keyboard: >1 byte read for status (64h)\n"); - return -1; - } + return 1; + } else { + PrintError("keyboard: >1 byte read for status (64h)\n"); + return -1; + } } static int keyboard_write_output(ushort_t port, @@ -1011,95 +1011,95 @@ static int keyboard_write_output(ushort_t port, uint_t length, struct vm_device * dev) { - struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); + struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); - if (length != 1) { - PrintError("keyboard: write of 60h with >1 byte\n"); - return -1; - } + if (length != 1) { + PrintError("keyboard: write of 60h with >1 byte\n"); + return -1; + } - uchar_t data = *((uchar_t*)src); + uchar_t data = *((uchar_t*)src); - PrintDebug("keyboard: output 0x%x on 60h\n", data); - - switch (state->state) { - case WRITING_CMD_BYTE: - state->cmd_byte = data; - state->state = NORMAL; - PrintDebug("keyboard: wrote new command byte 0x%x\n", state->cmd_byte); - break; - case WRITING_OUTPUT_PORT: - state->output_byte = data; - state->state = NORMAL; - PrintDebug("keyboard: wrote new output byte 0x%x\n", state->output_byte); - break; - case INJECTING_KEY: - PushToOutputQueue(dev, data, OVERWRITE, COMMAND, KEYBOARD); // probably should be a call to deliver_key_to_vmm() - state->state = NORMAL; - PrintDebug("keyboard: injected key 0x%x\n", data); - break; - case INJECTING_MOUSE: - PrintDebug("keyboard: ignoring injected mouse event 0x%x\n", data); - state->state = NORMAL; - break; - case IN_MOUSE: - PrintDebug("keyboard: mouse action: "); - if (mouse_write_output(dev, data)) { - state->state = NORMAL; - } - PrintDebug("\n"); - break; - case TRANSMIT_PASSWD: - if (data) { - //ignore passwd - PrintDebug("keyboard: ignoring password character 0x%x\n",data); - } else { - // end of password - state->state = NORMAL; - PrintDebug("keyboard: done with password\n"); + PrintDebug("keyboard: output 0x%x on 60h\n", data); + + switch (state->state) { + case WRITING_CMD_BYTE: + state->cmd_byte = data; + state->state = NORMAL; + PrintDebug("keyboard: wrote new command byte 0x%x\n", state->cmd_byte); + break; + case WRITING_OUTPUT_PORT: + state->output_byte = data; + state->state = NORMAL; + PrintDebug("keyboard: wrote new output byte 0x%x\n", state->output_byte); + break; + case INJECTING_KEY: + PushToOutputQueue(dev, data, OVERWRITE, COMMAND, KEYBOARD); // probably should be a call to deliver_key_to_vmm() + state->state = NORMAL; + PrintDebug("keyboard: injected key 0x%x\n", data); + break; + case INJECTING_MOUSE: + PrintDebug("keyboard: ignoring injected mouse event 0x%x\n", data); + state->state = NORMAL; + break; + case IN_MOUSE: + PrintDebug("keyboard: mouse action: "); + if (mouse_write_output(dev, data)) { + state->state = NORMAL; + } + PrintDebug("\n"); + break; + case TRANSMIT_PASSWD: + if (data) { + //ignore passwd + PrintDebug("keyboard: ignoring password character 0x%x\n",data); + } else { + // end of password + state->state = NORMAL; + PrintDebug("keyboard: done with password\n"); + } + break; + case NORMAL: + { + // command is being sent to keyboard controller + switch (data) { + case 0xff: // reset + PushToOutputQueue(dev, 0xfa, OVERWRITE, COMMAND, KEYBOARD); // ack + state->state = RESET; + PrintDebug("keyboard: reset complete and acked\n"); + break; + case 0xf5: // disable scanning + case 0xf4: // enable scanning + // ack + PushToOutputQueue(dev, 0xfa, OVERWRITE, COMMAND, KEYBOARD); + // should do something here... PAD + state->state = NORMAL; + PrintDebug("keyboard: %s scanning done and acked\n",data==0xf5 ? "disable" : "enable"); + break; + case 0xfe: // resend + case 0xfd: // set key type make + case 0xfc: // set key typ make/break + case 0xfb: // set key type typematic + case 0xfa: // set all typematic make/break/typematic + case 0xf9: // set all make + case 0xf8: // set all make/break + case 0xf7: // set all typemaktic + case 0xf6: // set defaults + case 0xf3: // set typematic delay/rate + PrintDebug("keyboard: unhandled known command 0x%x on output buffer (60h)\n", data); + break; + default: + PrintDebug("keyboard: unhandled unknown command 0x%x on output buffer (60h)\n", data); + state->status_byte |= 0x1; + break; + } + break; + } + default: + PrintDebug("keyboard: unknown state %x on command 0x%x on output buffer (60h)\n", state->state, data); } - break; - case NORMAL: - { - // command is being sent to keyboard controller - switch (data) { - case 0xff: // reset - PushToOutputQueue(dev, 0xfa, OVERWRITE, COMMAND, KEYBOARD); // ack - state->state = RESET; - PrintDebug("keyboard: reset complete and acked\n"); - break; - case 0xf5: // disable scanning - case 0xf4: // enable scanning - // ack - PushToOutputQueue(dev, 0xfa, OVERWRITE, COMMAND, KEYBOARD); - // should do something here... PAD - state->state = NORMAL; - PrintDebug("keyboard: %s scanning done and acked\n",data==0xf5 ? "disable" : "enable"); - break; - case 0xfe: // resend - case 0xfd: // set key type make - case 0xfc: // set key typ make/break - case 0xfb: // set key type typematic - case 0xfa: // set all typematic make/break/typematic - case 0xf9: // set all make - case 0xf8: // set all make/break - case 0xf7: // set all typemaktic - case 0xf6: // set defaults - case 0xf3: // set typematic delay/rate - PrintDebug("keyboard: unhandled known command 0x%x on output buffer (60h)\n", data); - break; - default: - PrintDebug("keyboard: unhandled unknown command 0x%x on output buffer (60h)\n", data); - state->status_byte |= 0x1; - break; - } - break; - } - default: - PrintDebug("keyboard: unknown state %x on command 0x%x on output buffer (60h)\n", state->state, data); - } - return 1; + return 1; } static int keyboard_read_input(ushort_t port, @@ -1107,40 +1107,40 @@ static int keyboard_read_input(ushort_t port, uint_t length, struct vm_device * dev) { - struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); + struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data); - if (length == 1) { - uchar_t data; - int done_mouse; + if (length == 1) { + uchar_t data; + int done_mouse; - PrintDebug("keyboard: read from input (60h): "); + PrintDebug("keyboard: read from input (60h): "); - if (state->state == IN_MOUSE) { - done_mouse = mouse_read_input(dev); - if (done_mouse) { - state->state = NORMAL; - } - } + if (state->state == IN_MOUSE) { + done_mouse = mouse_read_input(dev); + if (done_mouse) { + state->state = NORMAL; + } + } - PullFromOutputQueue(dev, &data); + PullFromOutputQueue(dev, &data); - if (state->state == RESET) { - // We just delivered the ack for the reset - // now we will ready ourselves to deliver the BAT code (success) - PushToOutputQueue(dev, 0xaa, OVERWRITE, COMMAND, KEYBOARD); - state->state = NORMAL; - PrintDebug(" (in reset, pushing BAT test code 0xaa) "); - } + if (state->state == RESET) { + // We just delivered the ack for the reset + // now we will ready ourselves to deliver the BAT code (success) + PushToOutputQueue(dev, 0xaa, OVERWRITE, COMMAND, KEYBOARD); + state->state = NORMAL; + PrintDebug(" (in reset, pushing BAT test code 0xaa) "); + } - PrintDebug("0x%x\n", data); + PrintDebug("0x%x\n", data); - *((uchar_t*)dest) = data; + *((uchar_t*)dest) = data; - return 1; - } else { - PrintError("keyboard: unknown size read from input (60h)\n"); - return -1; - } + return 1; + } else { + PrintError("keyboard: unknown size read from input (60h)\n"); + return -1; + } } @@ -1150,45 +1150,45 @@ static int keyboard_read_input(ushort_t port, static int keyboard_init_device(struct vm_device * dev) { - // struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data; + // struct keyboard_internal *data = (struct keyboard_internal *) dev->private_data; - PrintDebug("keyboard: init_device\n"); + PrintDebug("keyboard: init_device\n"); - // Would read state here + // Would read state here - keyboard_reset_device(dev); + keyboard_reset_device(dev); - // hook ports - v3_dev_hook_io(dev, KEYBOARD_64H, &keyboard_read_status, &keyboard_write_command); - v3_dev_hook_io(dev, KEYBOARD_60H, &keyboard_read_input, &keyboard_write_output); + // hook ports + v3_dev_hook_io(dev, KEYBOARD_64H, &keyboard_read_status, &keyboard_write_command); + v3_dev_hook_io(dev, KEYBOARD_60H, &keyboard_read_input, &keyboard_write_output); - v3_hook_host_event(dev->vm, HOST_KEYBOARD_EVT, V3_HOST_EVENT_HANDLER(key_event_handler), dev); - v3_hook_host_event(dev->vm, HOST_MOUSE_EVT, V3_HOST_EVENT_HANDLER(mouse_event_handler), dev); + v3_hook_host_event(dev->vm, HOST_KEYBOARD_EVT, V3_HOST_EVENT_HANDLER(key_event_handler), dev); + v3_hook_host_event(dev->vm, HOST_MOUSE_EVT, V3_HOST_EVENT_HANDLER(mouse_event_handler), dev); #if KEYBOARD_DEBUG_80H - v3_dev_hook_io(dev, KEYBOARD_DELAY_80H, &keyboard_read_delay, &keyboard_write_delay); + v3_dev_hook_io(dev, KEYBOARD_DELAY_80H, &keyboard_read_delay, &keyboard_write_delay); #endif - // - // We do not hook the IRQ here. Instead, the underlying device driver - // is responsible to call us back - // + // + // We do not hook the IRQ here. Instead, the underlying device driver + // is responsible to call us back + // - return 0; + return 0; } static int keyboard_deinit_device(struct vm_device *dev) { - v3_dev_unhook_io(dev, KEYBOARD_60H); - v3_dev_unhook_io(dev, KEYBOARD_64H); + v3_dev_unhook_io(dev, KEYBOARD_60H); + v3_dev_unhook_io(dev, KEYBOARD_64H); #if KEYBOARD_DEBUG_80H - v3_dev_unhook_io(dev, KEYBOARD_DELAY_80H); + v3_dev_unhook_io(dev, KEYBOARD_DELAY_80H); #endif - keyboard_reset_device(dev); - return 0; + keyboard_reset_device(dev); + return 0; } @@ -1196,23 +1196,23 @@ static int keyboard_deinit_device(struct vm_device *dev) static struct vm_device_ops dev_ops = { - .init = keyboard_init_device, - .deinit = keyboard_deinit_device, - .reset = keyboard_reset_device, - .start = keyboard_start_device, - .stop = keyboard_stop_device, + .init = keyboard_init_device, + .deinit = keyboard_deinit_device, + .reset = keyboard_reset_device, + .start = keyboard_start_device, + .stop = keyboard_stop_device, }; struct vm_device * v3_create_keyboard() { - struct keyboard_internal * keyboard_state = NULL; + struct keyboard_internal * keyboard_state = NULL; - keyboard_state = (struct keyboard_internal *)V3_Malloc(sizeof(struct keyboard_internal)); + keyboard_state = (struct keyboard_internal *)V3_Malloc(sizeof(struct keyboard_internal)); - struct vm_device *device = v3_create_device("KEYBOARD", &dev_ops, keyboard_state); + struct vm_device *device = v3_create_device("KEYBOARD", &dev_ops, keyboard_state); - return device; + return device; } diff --git a/palacios/src/devices/nvram.c b/palacios/src/devices/nvram.c index 10574e4..1244f90 100644 --- a/palacios/src/devices/nvram.c +++ b/palacios/src/devices/nvram.c @@ -89,464 +89,464 @@ typedef enum {NVRAM_READY, NVRAM_REG_POSTED} nvram_state_t; struct nvram_internal { - nvram_state_t dev_state; - uchar_t thereg; - uchar_t mem_state[NVRAM_REG_MAX]; + nvram_state_t dev_state; + uchar_t thereg; + uchar_t mem_state[NVRAM_REG_MAX]; - uint_t us; //microseconds - for clock update - zeroed every second - uint_t pus; //microseconds - for periodic interrupt - cleared every period + uint_t us; //microseconds - for clock update - zeroed every second + uint_t pus; //microseconds - for periodic interrupt - cleared every period }; struct rtc_stata { - uint_t rate: 4; // clock rate = 65536Hz / 2 rate (0110=1024 Hz) - uint_t basis: 3; // time base, 010 = 32,768 Hz - uint_t uip: 1; // 1=update in progress + uint_t rate: 4; // clock rate = 65536Hz / 2 rate (0110=1024 Hz) + uint_t basis: 3; // time base, 010 = 32,768 Hz + uint_t uip: 1; // 1=update in progress } __attribute__((__packed__)) __attribute__((__aligned__ (1))) ; struct rtc_statb { - uint_t sum: 1; // 1=summer (daylight savings) - uint_t h24: 1; // 1=24h clock - uint_t dm: 1; // 1=date/time is in bcd, 0=binary - uint_t rec: 1; // 1=rectangular signal - uint_t ui: 1; // 1=update interrupt - uint_t ai: 1; // 1=alarm interrupt - uint_t pi: 1; // 1=periodic interrupt - uint_t set: 1; // 1=blocked update + uint_t sum: 1; // 1=summer (daylight savings) + uint_t h24: 1; // 1=24h clock + uint_t dm: 1; // 1=date/time is in bcd, 0=binary + uint_t rec: 1; // 1=rectangular signal + uint_t ui: 1; // 1=update interrupt + uint_t ai: 1; // 1=alarm interrupt + uint_t pi: 1; // 1=periodic interrupt + uint_t set: 1; // 1=blocked update } __attribute__((__packed__)) __attribute__((__aligned__ (1))) ; struct rtc_statc { - uint_t res: 4; // reserved - uint_t uf: 1; // 1=source of interrupt is update - uint_t af: 1; // 1=source of interrupt is alarm interrupt - uint_t pf: 1; // 1=source of interrupt is periodic interrupt - uint_t irq: 1; // 1=interrupt requested + uint_t res: 4; // reserved + uint_t uf: 1; // 1=source of interrupt is update + uint_t af: 1; // 1=source of interrupt is alarm interrupt + uint_t pf: 1; // 1=source of interrupt is periodic interrupt + uint_t irq: 1; // 1=interrupt requested } __attribute__((__packed__)) __attribute__((__aligned__ (1))) ; struct rtc_statd { - uint_t res: 7; // reserved - uint_t val: 1; // 1=cmos ram data is OK + uint_t res: 7; // reserved + uint_t val: 1; // 1=cmos ram data is OK } __attribute__((__packed__)) __attribute__((__aligned__ (1))) ; struct bcd_num { - uchar_t bot : 4; - uchar_t top : 4; + uchar_t bot : 4; + uchar_t top : 4; }; static uchar_t add_to(uchar_t * left, uchar_t * right, uchar_t bcd) { - uchar_t temp; + uchar_t temp; - if (bcd) { - struct bcd_num * bl = (struct bcd_num *)left; - struct bcd_num * br = (struct bcd_num *)right; - uchar_t carry = 0; - - bl->bot += br->bot; - carry = bl->bot / 0xa; - bl->bot %= 0xa; + if (bcd) { + struct bcd_num * bl = (struct bcd_num *)left; + struct bcd_num * br = (struct bcd_num *)right; + uchar_t carry = 0; - bl->top += carry + br->top; - carry = bl->top / 0xa; - bl->top %= 0xa; + bl->bot += br->bot; + carry = bl->bot / 0xa; + bl->bot %= 0xa; - return carry; - } else { - temp = *left; - *left += *right; + bl->top += carry + br->top; + carry = bl->top / 0xa; + bl->top %= 0xa; - if (*left < temp) { - return 1; + return carry; } else { - return 0; + temp = *left; + *left += *right; + + if (*left < temp) { + return 1; + } else { + return 0; + } } - } } static uchar_t days_in_month(struct vm_device * dev, uchar_t month, uchar_t bcd) { - // This completely ignores Julian / Gregorian stuff right now - - if (bcd) { - - switch (month) - { - case 0x1: //jan - case 0x3: //march - case 0x5: //may - case 0x7: //july - case 0x8: //aug - case 0x10: //oct - case 0x12: //dec - return 0x31; - break; - case 0x4: //april - case 0x6: //june - case 0x9: //sept - case 0x11: //nov - return 0x30; - break; - case 0x2: //feb - return 0x28; - break; - default: - return 0x30; - } + // This completely ignores Julian / Gregorian stuff right now + + if (bcd) { + + switch (month) + { + case 0x1: //jan + case 0x3: //march + case 0x5: //may + case 0x7: //july + case 0x8: //aug + case 0x10: //oct + case 0x12: //dec + return 0x31; + break; + case 0x4: //april + case 0x6: //june + case 0x9: //sept + case 0x11: //nov + return 0x30; + break; + case 0x2: //feb + return 0x28; + break; + default: + return 0x30; + } - } else { - - switch (month) - { - case 1: //jan - case 3: //march - case 5: //may - case 7: //july - case 8: //aug - case 10: //oct - case 12: //dec - return 31; - break; - case 4: //april - case 6: //june - case 9: //sept - case 11: //nov - return 30; - break; - case 2: //feb - return 28; - break; - default: - return 30; - } - } -} - + } else { -static void update_time(struct vm_device * dev, uint_t period_us) { - struct nvram_internal * data = (struct nvram_internal *) (dev->private_data); - struct rtc_stata * stata = (struct rtc_stata *) &((data->mem_state[NVRAM_REG_STAT_A])); - struct rtc_statb * statb = (struct rtc_statb *) &((data->mem_state[NVRAM_REG_STAT_B])); - struct rtc_statc * statc = (struct rtc_statc *) &((data->mem_state[NVRAM_REG_STAT_C])); - //struct rtc_statd *statd = (struct rtc_statd *) &((data->mem_state[NVRAM_REG_STAT_D])); - uchar_t * sec = (uchar_t *) &(data->mem_state[NVRAM_REG_SEC]); - uchar_t * min = (uchar_t *) &(data->mem_state[NVRAM_REG_MIN]); - uchar_t * hour = (uchar_t *) &(data->mem_state[NVRAM_REG_HOUR]); - uchar_t * weekday = (uchar_t *) &(data->mem_state[NVRAM_REG_WEEK_DAY]); - uchar_t * monthday = (uchar_t *) &(data->mem_state[NVRAM_REG_MONTH_DAY]); - uchar_t * month = (uchar_t *) &(data->mem_state[NVRAM_REG_MONTH]); - uchar_t * year = (uchar_t *) &(data->mem_state[NVRAM_REG_YEAR]); - uchar_t * cent = (uchar_t *) &(data->mem_state[NVRAM_REG_IBM_CENTURY_BYTE]); - uchar_t * seca = (uchar_t *) &(data->mem_state[NVRAM_REG_SEC_ALARM]); - uchar_t * mina = (uchar_t *) &(data->mem_state[NVRAM_REG_MIN_ALARM]); - uchar_t * houra = (uchar_t *) &(data->mem_state[NVRAM_REG_HOUR_ALARM]); - uchar_t hour24; - - uchar_t bcd = (statb->dm == 1); - uchar_t carry = 0; - uchar_t nextday = 0; - uint_t periodic_period; - - //PrintDebug("nvram: sizeof(struct rtc_stata)=%d\n", sizeof(struct rtc_stata)); - - - //PrintDebug("nvram: update_time\n",statb->pi); - - // We will set these flags on exit - statc->irq = 0; - statc->pf = 0; - statc->af = 0; - statc->uf = 0; - - // We will reset us after one second - data->us += period_us; - // We will reset pus after one periodic_period - data->pus += period_us; - - if (data->us > 1000000) { - carry = 1; - carry = add_to(sec, &carry, bcd); - - if (carry) { - PrintDebug("nvram: somehow managed to get a carry in second update\n"); + switch (month) + { + case 1: //jan + case 3: //march + case 5: //may + case 7: //july + case 8: //aug + case 10: //oct + case 12: //dec + return 31; + break; + case 4: //april + case 6: //june + case 9: //sept + case 11: //nov + return 30; + break; + case 2: //feb + return 28; + break; + default: + return 30; + } } +} - if ( (bcd && (*sec == 0x60)) || - ((!bcd) && (*sec == 60))) { - - *sec = 0; - - carry = 1; - carry = add_to(min, &carry, bcd); - if (carry) { - PrintDebug("nvram: somehow managed to get a carry in minute update\n"); - } - - if ( (bcd && (*min == 0x60)) || - ((!bcd) && (*min == 60))) { - *min = 0; - hour24 = *hour; +static void update_time(struct vm_device * dev, uint_t period_us) { + struct nvram_internal * data = (struct nvram_internal *) (dev->private_data); + struct rtc_stata * stata = (struct rtc_stata *) &((data->mem_state[NVRAM_REG_STAT_A])); + struct rtc_statb * statb = (struct rtc_statb *) &((data->mem_state[NVRAM_REG_STAT_B])); + struct rtc_statc * statc = (struct rtc_statc *) &((data->mem_state[NVRAM_REG_STAT_C])); + //struct rtc_statd *statd = (struct rtc_statd *) &((data->mem_state[NVRAM_REG_STAT_D])); + uchar_t * sec = (uchar_t *) &(data->mem_state[NVRAM_REG_SEC]); + uchar_t * min = (uchar_t *) &(data->mem_state[NVRAM_REG_MIN]); + uchar_t * hour = (uchar_t *) &(data->mem_state[NVRAM_REG_HOUR]); + uchar_t * weekday = (uchar_t *) &(data->mem_state[NVRAM_REG_WEEK_DAY]); + uchar_t * monthday = (uchar_t *) &(data->mem_state[NVRAM_REG_MONTH_DAY]); + uchar_t * month = (uchar_t *) &(data->mem_state[NVRAM_REG_MONTH]); + uchar_t * year = (uchar_t *) &(data->mem_state[NVRAM_REG_YEAR]); + uchar_t * cent = (uchar_t *) &(data->mem_state[NVRAM_REG_IBM_CENTURY_BYTE]); + uchar_t * seca = (uchar_t *) &(data->mem_state[NVRAM_REG_SEC_ALARM]); + uchar_t * mina = (uchar_t *) &(data->mem_state[NVRAM_REG_MIN_ALARM]); + uchar_t * houra = (uchar_t *) &(data->mem_state[NVRAM_REG_HOUR_ALARM]); + uchar_t hour24; + + uchar_t bcd = (statb->dm == 1); + uchar_t carry = 0; + uchar_t nextday = 0; + uint_t periodic_period; - if (!(statb->h24)) { + //PrintDebug("nvram: sizeof(struct rtc_stata)=%d\n", sizeof(struct rtc_stata)); - if (hour24 & 0x80) { - hour24 &= 0x8f; - uchar_t temp = ((bcd) ? 0x12 : 12); - add_to(&hour24, &temp, bcd); - } - } + //PrintDebug("nvram: update_time\n",statb->pi); + + // We will set these flags on exit + statc->irq = 0; + statc->pf = 0; + statc->af = 0; + statc->uf = 0; + + // We will reset us after one second + data->us += period_us; + // We will reset pus after one periodic_period + data->pus += period_us; + + if (data->us > 1000000) { carry = 1; - carry = add_to(&hour24, &carry, bcd); + carry = add_to(sec, &carry, bcd); + if (carry) { - PrintDebug("nvram: somehow managed to get a carry in hour update\n"); + PrintDebug("nvram: somehow managed to get a carry in second update\n"); } - if ( (bcd && (hour24 == 0x24)) || - ((!bcd) && (hour24 == 24))) { - carry = 1; - nextday = 1; - hour24 = 0; - } else { - carry = 0; - } + if ( (bcd && (*sec == 0x60)) || + ((!bcd) && (*sec == 60))) { + + *sec = 0; + carry = 1; + carry = add_to(min, &carry, bcd); + if (carry) { + PrintDebug("nvram: somehow managed to get a carry in minute update\n"); + } - if (statb->h24) { - *hour = hour24; - } else { - if ( (bcd && (hour24 < 0x12)) || - ((!bcd) && (hour24 < 12))) { - *hour = hour24; + if ( (bcd && (*min == 0x60)) || + ((!bcd) && (*min == 60))) { - } else { + *min = 0; + hour24 = *hour; - if (!bcd) { - *hour = (hour24 - 12) | 0x80; - } else { - *hour = hour24; - struct bcd_num * n = (struct bcd_num *)hour; + if (!(statb->h24)) { - if (n->bot < 0x2) { - n->top--; - n->bot += 0xa; - } + if (hour24 & 0x80) { + hour24 &= 0x8f; + uchar_t temp = ((bcd) ? 0x12 : 12); + add_to(&hour24, &temp, bcd); + } + } - n->bot -= 0x2; - n->top -= 0x1; + carry = 1; + carry = add_to(&hour24, &carry, bcd); + if (carry) { + PrintDebug("nvram: somehow managed to get a carry in hour update\n"); + } + + if ( (bcd && (hour24 == 0x24)) || + ((!bcd) && (hour24 == 24))) { + carry = 1; + nextday = 1; + hour24 = 0; + } else { + carry = 0; + } + + + if (statb->h24) { + *hour = hour24; + } else { + if ( (bcd && (hour24 < 0x12)) || + ((!bcd) && (hour24 < 12))) { + *hour = hour24; + + } else { + + if (!bcd) { + *hour = (hour24 - 12) | 0x80; + } else { + *hour = hour24; + struct bcd_num * n = (struct bcd_num *)hour; + + if (n->bot < 0x2) { + n->top--; + n->bot += 0xa; + } + + n->bot -= 0x2; + n->top -= 0x1; + } + } + } + + // now see if we need to carry into the days and further + if (nextday) { + carry = 1; + add_to(weekday, &carry, bcd); + + *weekday %= 0x7; // same regardless of bcd + + if ((*monthday) != days_in_month(dev, *month, bcd)) { + add_to(monthday, &carry, bcd); + } else { + *monthday = 0x1; + + carry = 1; + add_to(month, &carry, bcd); + + if ( (bcd && (*month == 0x13)) || + ((!bcd) && (*month == 13))) { + *month = 1; // same for both + + carry = 1; + carry = add_to(year, &carry, bcd); + + if ( (bcd && carry) || + ((!bcd) && (*year == 100))) { + *year = 0; + carry = 1; + add_to(cent, &carry, bcd); + } + } + } + } } - } } - // now see if we need to carry into the days and further - if (nextday) { - carry = 1; - add_to(weekday, &carry, bcd); - - *weekday %= 0x7; // same regardless of bcd - - if ((*monthday) != days_in_month(dev, *month, bcd)) { - add_to(monthday, &carry, bcd); - } else { - *monthday = 0x1; - - carry = 1; - add_to(month, &carry, bcd); - - if ( (bcd && (*month == 0x13)) || - ((!bcd) && (*month == 13))) { - *month = 1; // same for both - carry = 1; - carry = add_to(year, &carry, bcd); - - if ( (bcd && carry) || - ((!bcd) && (*year == 100))) { - *year = 0; - carry = 1; - add_to(cent, &carry, bcd); - } + data->us -= 1000000; + // OK, now check for the alarm, if it is set to interrupt + if (statb->ai) { + if ((*sec == *seca) && (*min == *mina) && (*hour == *houra)) { + statc->af = 1; + PrintDebug("nvram: interrupt on alarm\n"); } - } } - } } - - data->us -= 1000000; - // OK, now check for the alarm, if it is set to interrupt - if (statb->ai) { - if ((*sec == *seca) && (*min == *mina) && (*hour == *houra)) { - statc->af = 1; - PrintDebug("nvram: interrupt on alarm\n"); - } - } - } - - if (statb->pi) { - periodic_period = 1000000 / (65536 / (0x1 << stata->rate)); - if (data->pus >= periodic_period) { - statc->pf = 1; - data->pus -= periodic_period; - PrintDebug("nvram: interrupt on periodic\n"); + if (statb->pi) { + periodic_period = 1000000 / (65536 / (0x1 << stata->rate)); + if (data->pus >= periodic_period) { + statc->pf = 1; + data->pus -= periodic_period; + PrintDebug("nvram: interrupt on periodic\n"); + } } - } - if (statb->ui) { - statc->uf = 1; - PrintDebug("nvram: interrupt on update\n"); - } + if (statb->ui) { + statc->uf = 1; + PrintDebug("nvram: interrupt on update\n"); + } - statc->irq = (statc->pf || statc->af || statc->uf); + statc->irq = (statc->pf || statc->af || statc->uf); - //PrintDebug("nvram: time is now: YMDHMS: 0x%x:0x%x:0x%x:0x%x:0x%x,0x%x bcd=%d\n", *year, *month, *monthday, *hour, *min, *sec,bcd); + //PrintDebug("nvram: time is now: YMDHMS: 0x%x:0x%x:0x%x:0x%x:0x%x,0x%x bcd=%d\n", *year, *month, *monthday, *hour, *min, *sec,bcd); - // Interrupt associated VM, if needed - if (statc->irq) { - PrintDebug("nvram: injecting interrupt\n"); - v3_raise_irq(dev->vm, NVRAM_RTC_IRQ); - } + // Interrupt associated VM, if needed + if (statc->irq) { + PrintDebug("nvram: injecting interrupt\n"); + v3_raise_irq(dev->vm, NVRAM_RTC_IRQ); + } } static int handle_timer_event(struct guest_info * info, - struct v3_timer_event * evt, - void * priv_data) { + struct v3_timer_event * evt, + void * priv_data) { - struct vm_device * dev = (struct vm_device *)priv_data; + struct vm_device * dev = (struct vm_device *)priv_data; - if (dev) { - update_time(dev, evt->period_us); - } + if (dev) { + update_time(dev, evt->period_us); + } - return 0; + return 0; } static void set_memory_size(struct nvram_internal * nvram, addr_t bytes) { - // 1. Conventional Mem: 0-640k in K - // 2. Extended Mem: 0-16MB in K - // 3. Big Mem: 0-4G in 64K - - if (bytes > 640 * 1024) { - nvram->mem_state[NVRAM_REG_BASE_MEMORY_HIGH] = 0x02; - nvram->mem_state[NVRAM_REG_BASE_MEMORY_LOW] = 0x80; - } else { - uint16_t memk = bytes * 1024; - nvram->mem_state[NVRAM_REG_BASE_MEMORY_HIGH] = (memk >> 8) & 0x00ff; - nvram->mem_state[NVRAM_REG_BASE_MEMORY_LOW] = memk & 0x00ff; + // 1. Conventional Mem: 0-640k in K + // 2. Extended Mem: 0-16MB in K + // 3. Big Mem: 0-4G in 64K - return; - } - - if (bytes > (16 * 1024 * 1024)) { - // Set extended memory to 15 MB - nvram->mem_state[NVRAM_REG_EXT_MEMORY_HIGH] = 0x3C; - nvram->mem_state[NVRAM_REG_EXT_MEMORY_LOW] = 0x00; - nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_HIGH]= 0x3C; - nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_LOW]= 0x00; - } else { - uint16_t memk = bytes * 1024; - nvram->mem_state[NVRAM_REG_EXT_MEMORY_HIGH] = (memk >> 8) & 0x00ff; - nvram->mem_state[NVRAM_REG_EXT_MEMORY_LOW] = memk & 0x00ff; - nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_HIGH]= (memk >> 8) & 0x00ff; - nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_LOW]= memk & 0x00ff; + if (bytes > 640 * 1024) { + nvram->mem_state[NVRAM_REG_BASE_MEMORY_HIGH] = 0x02; + nvram->mem_state[NVRAM_REG_BASE_MEMORY_LOW] = 0x80; + } else { + uint16_t memk = bytes * 1024; + nvram->mem_state[NVRAM_REG_BASE_MEMORY_HIGH] = (memk >> 8) & 0x00ff; + nvram->mem_state[NVRAM_REG_BASE_MEMORY_LOW] = memk & 0x00ff; - return; - } + return; + } - { - // Set the extended memory beyond 16 MB in 64k chunks - uint16_t mem_chunks = (bytes - (1024 * 1024 * 16)) / (1024 * 64); - nvram->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH] = (mem_chunks >> 8) & 0x00ff; - nvram->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW] = mem_chunks & 0x00ff; - } + if (bytes > (16 * 1024 * 1024)) { + // Set extended memory to 15 MB + nvram->mem_state[NVRAM_REG_EXT_MEMORY_HIGH] = 0x3C; + nvram->mem_state[NVRAM_REG_EXT_MEMORY_LOW] = 0x00; + nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_HIGH]= 0x3C; + nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_LOW]= 0x00; + } else { + uint16_t memk = bytes * 1024; + nvram->mem_state[NVRAM_REG_EXT_MEMORY_HIGH] = (memk >> 8) & 0x00ff; + nvram->mem_state[NVRAM_REG_EXT_MEMORY_LOW] = memk & 0x00ff; + nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_HIGH]= (memk >> 8) & 0x00ff; + nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_LOW]= memk & 0x00ff; - return; + return; + } + + { + // Set the extended memory beyond 16 MB in 64k chunks + uint16_t mem_chunks = (bytes - (1024 * 1024 * 16)) / (1024 * 64); + nvram->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH] = (mem_chunks >> 8) & 0x00ff; + nvram->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW] = mem_chunks & 0x00ff; + } + + return; } static int init_nvram_state(struct vm_device * dev) { - struct guest_info * info = dev->vm; - struct nvram_internal * nvram_state = (struct nvram_internal *)dev->private_data; + struct guest_info * info = dev->vm; + struct nvram_internal * nvram_state = (struct nvram_internal *)dev->private_data; - memset(nvram_state->mem_state, 0, NVRAM_REG_MAX); + memset(nvram_state->mem_state, 0, NVRAM_REG_MAX); - // - // 2 1.44 MB floppy drives - // + // + // 2 1.44 MB floppy drives + // #if 1 - nvram_state->mem_state[NVRAM_REG_FLOPPY_TYPE] = 0x44; + nvram_state->mem_state[NVRAM_REG_FLOPPY_TYPE] = 0x44; #else - nvram_state->mem_state[NVRAM_REG_FLOPPY_TYPE] = 0x00; + nvram_state->mem_state[NVRAM_REG_FLOPPY_TYPE] = 0x00; #endif - // - // For old boot sequence style, do floppy first - // - nvram_state->mem_state[NVRAM_REG_BOOTSEQ_OLD] = 0x10; + // + // For old boot sequence style, do floppy first + // + nvram_state->mem_state[NVRAM_REG_BOOTSEQ_OLD] = 0x10; #if 0 - // For new boot sequence style, do floppy, cd, then hd - nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_FIRST] = 0x31; - nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_SECOND] = 0x20; + // For new boot sequence style, do floppy, cd, then hd + nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_FIRST] = 0x31; + nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_SECOND] = 0x20; #endif - // For new boot sequence style, do cd, hd, floppy - nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_FIRST] = 0x23; - nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_SECOND] = 0x10; + // For new boot sequence style, do cd, hd, floppy + nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_FIRST] = 0x23; + nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_SECOND] = 0x10; - // Set equipment byte to note 2 floppies, vga display, keyboard,math,floppy - nvram_state->mem_state[NVRAM_REG_EQUIPMENT_BYTE] = 0x4f; - // nvram_state->mem_state[NVRAM_REG_EQUIPMENT_BYTE] = 0xf; + // Set equipment byte to note 2 floppies, vga display, keyboard,math,floppy + nvram_state->mem_state[NVRAM_REG_EQUIPMENT_BYTE] = 0x4f; + // nvram_state->mem_state[NVRAM_REG_EQUIPMENT_BYTE] = 0xf; - // This is the harddisk type.... Set accordingly... - nvram_state->mem_state[NVRAM_IBM_HD_DATA] = 0x20; + // This is the harddisk type.... Set accordingly... + nvram_state->mem_state[NVRAM_IBM_HD_DATA] = 0x20; - // Set the shutdown status gently - // soft reset - nvram_state->mem_state[NVRAM_REG_SHUTDOWN_STATUS] = 0x0; + // Set the shutdown status gently + // soft reset + nvram_state->mem_state[NVRAM_REG_SHUTDOWN_STATUS] = 0x0; - // RTC status A - // 00100110 = no update in progress, base=32768 Hz, rate = 1024 Hz - nvram_state->mem_state[NVRAM_REG_STAT_A] = 0x26; + // RTC status A + // 00100110 = no update in progress, base=32768 Hz, rate = 1024 Hz + nvram_state->mem_state[NVRAM_REG_STAT_A] = 0x26; - // RTC status B - // 00000100 = not setting, no interrupts, blocked rect signal, bcd mode, 24 hour, normal time - nvram_state->mem_state[NVRAM_REG_STAT_B] = 0x06; + // RTC status B + // 00000100 = not setting, no interrupts, blocked rect signal, bcd mode, 24 hour, normal time + nvram_state->mem_state[NVRAM_REG_STAT_B] = 0x06; - // RTC status C - // No IRQ requested, result not do to any source - nvram_state->mem_state[NVRAM_REG_STAT_C] = 0x00; + // RTC status C + // No IRQ requested, result not do to any source + nvram_state->mem_state[NVRAM_REG_STAT_C] = 0x00; - // RTC status D - // Battery is OK - nvram_state->mem_state[NVRAM_REG_STAT_D] = 0x80; + // RTC status D + // Battery is OK + nvram_state->mem_state[NVRAM_REG_STAT_D] = 0x80; - // january 1, 2008, 00:00:00 - nvram_state->mem_state[NVRAM_REG_MONTH] = 0x1; - nvram_state->mem_state[NVRAM_REG_MONTH_DAY] = 0x1; - nvram_state->mem_state[NVRAM_REG_WEEK_DAY] = 0x1; - nvram_state->mem_state[NVRAM_REG_YEAR] = 0x08; + // january 1, 2008, 00:00:00 + nvram_state->mem_state[NVRAM_REG_MONTH] = 0x1; + nvram_state->mem_state[NVRAM_REG_MONTH_DAY] = 0x1; + nvram_state->mem_state[NVRAM_REG_WEEK_DAY] = 0x1; + nvram_state->mem_state[NVRAM_REG_YEAR] = 0x08; - nvram_state->us = 0; - nvram_state->pus = 0; + nvram_state->us = 0; + nvram_state->pus = 0; - set_memory_size(nvram_state, info->mem_size); + set_memory_size(nvram_state, info->mem_size); - nvram_state->dev_state = NVRAM_READY; - nvram_state->thereg = 0; + nvram_state->dev_state = NVRAM_READY; + nvram_state->thereg = 0; - return 0; + return 0; } @@ -554,7 +554,7 @@ static int init_nvram_state(struct vm_device * dev) { static int nvram_reset_device(struct vm_device * dev) { - return 0; + return 0; } @@ -562,14 +562,14 @@ static int nvram_reset_device(struct vm_device * dev) { static int nvram_start_device(struct vm_device * dev) { - PrintDebug("nvram: start device\n"); - return 0; + PrintDebug("nvram: start device\n"); + return 0; } static int nvram_stop_device(struct vm_device * dev) { - PrintDebug("nvram: stop device\n"); - return 0; + PrintDebug("nvram: stop device\n"); + return 0; } @@ -579,69 +579,69 @@ static int nvram_write_reg_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct nvram_internal * data = (struct nvram_internal *)dev->private_data; + struct nvram_internal * data = (struct nvram_internal *)dev->private_data; - memcpy(&(data->thereg), src, 1); - PrintDebug("Writing To NVRAM reg: 0x%x\n", data->thereg); + memcpy(&(data->thereg), src, 1); + PrintDebug("Writing To NVRAM reg: 0x%x\n", data->thereg); - return 1; + return 1; } static int nvram_read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct nvram_internal * data = (struct nvram_internal *)dev->private_data; + struct nvram_internal * data = (struct nvram_internal *)dev->private_data; - memcpy(dst, &(data->mem_state[data->thereg]), 1); + memcpy(dst, &(data->mem_state[data->thereg]), 1); - PrintDebug("nvram_read_data_port(0x%x)=0x%x\n", data->thereg, data->mem_state[data->thereg]); + PrintDebug("nvram_read_data_port(0x%x)=0x%x\n", data->thereg, data->mem_state[data->thereg]); - // hack - if (data->thereg == NVRAM_REG_STAT_A) { - data->mem_state[data->thereg] ^= 0x80; // toggle Update in progess - } + // hack + if (data->thereg == NVRAM_REG_STAT_A) { + data->mem_state[data->thereg] ^= 0x80; // toggle Update in progess + } - return 1; + return 1; } static int nvram_write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct nvram_internal * data = (struct nvram_internal *)dev->private_data; + struct nvram_internal * data = (struct nvram_internal *)dev->private_data; - memcpy(&(data->mem_state[data->thereg]), src, 1); + memcpy(&(data->mem_state[data->thereg]), src, 1); - PrintDebug("nvram_write_data_port(0x%x)=0x%x\n", data->thereg, data->mem_state[data->thereg]); + PrintDebug("nvram_write_data_port(0x%x)=0x%x\n", data->thereg, data->mem_state[data->thereg]); - return 1; + return 1; } static int nvram_init_device(struct vm_device * dev) { - PrintDebug("nvram: init_device\n"); + PrintDebug("nvram: init_device\n"); - init_nvram_state(dev); + init_nvram_state(dev); - // hook ports - v3_dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port); - v3_dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port); + // hook ports + v3_dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port); + v3_dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port); - v3_hook_host_event(dev->vm, HOST_TIMER_EVT, V3_HOST_EVENT_HANDLER(handle_timer_event), dev); + v3_hook_host_event(dev->vm, HOST_TIMER_EVT, V3_HOST_EVENT_HANDLER(handle_timer_event), dev); - return 0; + return 0; } static int nvram_deinit_device(struct vm_device * dev) { - v3_dev_unhook_io(dev, NVRAM_REG_PORT); - v3_dev_unhook_io(dev, NVRAM_DATA_PORT); + v3_dev_unhook_io(dev, NVRAM_REG_PORT); + v3_dev_unhook_io(dev, NVRAM_DATA_PORT); - nvram_reset_device(dev); - return 0; + nvram_reset_device(dev); + return 0; } @@ -649,24 +649,24 @@ static int nvram_deinit_device(struct vm_device * dev) { static struct vm_device_ops dev_ops = { - .init = nvram_init_device, - .deinit = nvram_deinit_device, - .reset = nvram_reset_device, - .start = nvram_start_device, - .stop = nvram_stop_device, + .init = nvram_init_device, + .deinit = nvram_deinit_device, + .reset = nvram_reset_device, + .start = nvram_start_device, + .stop = nvram_stop_device, }; struct vm_device * v3_create_nvram() { - struct nvram_internal * nvram_state = NULL; + struct nvram_internal * nvram_state = NULL; - nvram_state = (struct nvram_internal *)V3_Malloc(sizeof(struct nvram_internal) + 1000); + nvram_state = (struct nvram_internal *)V3_Malloc(sizeof(struct nvram_internal) + 1000); - PrintDebug("nvram: internal at %p\n", (void *)nvram_state); + PrintDebug("nvram: internal at %p\n", (void *)nvram_state); - struct vm_device * device = v3_create_device("NVRAM", &dev_ops, nvram_state); + struct vm_device * device = v3_create_device("NVRAM", &dev_ops, nvram_state); - return device; + return device; } diff --git a/palacios/src/devices/os_debug.c b/palacios/src/devices/os_debug.c index 6bca537..adf9b06 100644 --- a/palacios/src/devices/os_debug.c +++ b/palacios/src/devices/os_debug.c @@ -27,66 +27,66 @@ struct debug_state { - char debug_buf[BUF_SIZE]; - uint_t debug_offset; + char debug_buf[BUF_SIZE]; + uint_t debug_offset; }; static int handle_gen_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct debug_state * state = (struct debug_state *)dev->private_data; + struct debug_state * state = (struct debug_state *)dev->private_data; - state->debug_buf[state->debug_offset++] = *(char*)src; + state->debug_buf[state->debug_offset++] = *(char*)src; - if ((*(char*)src == 0xa) || (state->debug_offset == (BUF_SIZE - 1))) { - PrintDebug("VM_CONSOLE>%s", state->debug_buf); - memset(state->debug_buf, 0, BUF_SIZE); - state->debug_offset = 0; - } + if ((*(char*)src == 0xa) || (state->debug_offset == (BUF_SIZE - 1))) { + PrintDebug("VM_CONSOLE>%s", state->debug_buf); + memset(state->debug_buf, 0, BUF_SIZE); + state->debug_offset = 0; + } - return length; + return length; } static int debug_init(struct vm_device * dev) { - struct debug_state * state = (struct debug_state *)dev->private_data; + struct debug_state * state = (struct debug_state *)dev->private_data; - v3_dev_hook_io(dev, DEBUG_PORT1, NULL, &handle_gen_write); + v3_dev_hook_io(dev, DEBUG_PORT1, NULL, &handle_gen_write); - state->debug_offset = 0; - memset(state->debug_buf, 0, BUF_SIZE); + state->debug_offset = 0; + memset(state->debug_buf, 0, BUF_SIZE); - return 0; + return 0; } static int debug_deinit(struct vm_device * dev) { - v3_dev_unhook_io(dev, DEBUG_PORT1); + v3_dev_unhook_io(dev, DEBUG_PORT1); - return 0; + return 0; }; static struct vm_device_ops dev_ops = { - .init = debug_init, - .deinit = debug_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, + .init = debug_init, + .deinit = debug_deinit, + .reset = NULL, + .start = NULL, + .stop = NULL, }; struct vm_device * v3_create_os_debug() { - struct debug_state * state = NULL; + struct debug_state * state = NULL; - state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state)); + state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state)); - PrintDebug("Creating OS Debug Device\n"); - struct vm_device * device = v3_create_device("OS Debug", &dev_ops, state); + PrintDebug("Creating OS Debug Device\n"); + struct vm_device * device = v3_create_device("OS Debug", &dev_ops, state); - return device; + return device; } diff --git a/palacios/src/devices/ramdisk.c b/palacios/src/devices/ramdisk.c index 10de469..53116d4 100644 --- a/palacios/src/devices/ramdisk.c +++ b/palacios/src/devices/ramdisk.c @@ -106,165 +106,165 @@ static const char none_str[] = "NONE"; static inline const char * device_type_to_str(device_type_t type) { - switch (type) { - case IDE_DISK: - return harddisk_str; - case IDE_CDROM: - return cdrom_str; - case IDE_NONE: - return none_str; - default: - return NULL; - } + switch (type) { + case IDE_DISK: + return harddisk_str; + case IDE_CDROM: + return cdrom_str; + case IDE_NONE: + return none_str; + default: + return NULL; + } } static inline void write_features(struct channel_t * channel, uchar_t value) { - channel->drives[0].controller.features = value; - channel->drives[1].controller.features = value; + channel->drives[0].controller.features = value; + channel->drives[1].controller.features = value; } static inline void write_sector_count(struct channel_t * channel, uchar_t value) { - channel->drives[0].controller.sector_count = value; - channel->drives[1].controller.sector_count = value; + channel->drives[0].controller.sector_count = value; + channel->drives[1].controller.sector_count = value; } static inline void write_sector_number(struct channel_t * channel, uchar_t value) { - channel->drives[0].controller.sector_no = value; - channel->drives[1].controller.sector_no = value; + channel->drives[0].controller.sector_no = value; + channel->drives[1].controller.sector_no = value; } static inline void write_cylinder_low(struct channel_t * channel, uchar_t value) { - channel->drives[0].controller.cylinder_no &= 0xff00; - channel->drives[0].controller.cylinder_no |= value; - channel->drives[1].controller.cylinder_no &= 0xff00; - channel->drives[1].controller.cylinder_no |= value; + channel->drives[0].controller.cylinder_no &= 0xff00; + channel->drives[0].controller.cylinder_no |= value; + channel->drives[1].controller.cylinder_no &= 0xff00; + channel->drives[1].controller.cylinder_no |= value; } static inline void write_cylinder_high(struct channel_t * channel, uchar_t value) { - ushort_t val2 = value; - val2 = val2 << 8; - channel->drives[0].controller.cylinder_no &= 0x00ff; - channel->drives[0].controller.cylinder_no |= (val2 & 0xff00); + ushort_t val2 = value; + val2 = val2 << 8; + channel->drives[0].controller.cylinder_no &= 0x00ff; + channel->drives[0].controller.cylinder_no |= (val2 & 0xff00); - channel->drives[1].controller.cylinder_no &= 0x00ff; - channel->drives[1].controller.cylinder_no |= (val2 & 0xff00); + channel->drives[1].controller.cylinder_no &= 0x00ff; + channel->drives[1].controller.cylinder_no |= (val2 & 0xff00); } static inline void write_head_no(struct channel_t * channel, uchar_t value) { - channel->drives[0].controller.head_no = value; - channel->drives[1].controller.head_no = value; + channel->drives[0].controller.head_no = value; + channel->drives[1].controller.head_no = value; } static inline void write_lba_mode(struct channel_t * channel, uchar_t value) { - channel->drives[0].controller.lba_mode = value; - channel->drives[1].controller.lba_mode = value; + channel->drives[0].controller.lba_mode = value; + channel->drives[1].controller.lba_mode = value; } static inline uint_t get_channel_no(struct ramdisk_t * ramdisk, struct channel_t * channel) { - return (((uchar_t *)channel - (uchar_t *)(ramdisk->channels)) / sizeof(struct channel_t)); + return (((uchar_t *)channel - (uchar_t *)(ramdisk->channels)) / sizeof(struct channel_t)); } static inline uint_t get_drive_no(struct channel_t * channel, struct drive_t * drive) { - return (((uchar_t *)drive - (uchar_t*)(channel->drives)) / sizeof(struct drive_t)); + return (((uchar_t *)drive - (uchar_t*)(channel->drives)) / sizeof(struct drive_t)); } static inline struct drive_t * get_selected_drive(struct channel_t * channel) { - return &(channel->drives[channel->drive_select]); + return &(channel->drives[channel->drive_select]); } static inline int is_primary_port(struct ramdisk_t * ramdisk, ushort_t port) { - switch(port) - { - case PRI_DATA_PORT: - case PRI_FEATURES_PORT: - case PRI_SECT_CNT_PORT: - case PRI_SECT_ADDR1_PORT: - case PRI_SECT_ADDR2_PORT: - case PRI_SECT_ADDR3_PORT: - case PRI_DRV_SEL_PORT: - case PRI_CMD_PORT: - case PRI_CTRL_PORT: - return 1; - default: - return 0; - } + switch(port) + { + case PRI_DATA_PORT: + case PRI_FEATURES_PORT: + case PRI_SECT_CNT_PORT: + case PRI_SECT_ADDR1_PORT: + case PRI_SECT_ADDR2_PORT: + case PRI_SECT_ADDR3_PORT: + case PRI_DRV_SEL_PORT: + case PRI_CMD_PORT: + case PRI_CTRL_PORT: + return 1; + default: + return 0; + } } static inline int is_secondary_port(struct ramdisk_t * ramdisk, ushort_t port) { - switch(port) - { - case SEC_DATA_PORT: - case SEC_FEATURES_PORT: - case SEC_SECT_CNT_PORT: - case SEC_SECT_ADDR1_PORT: - case SEC_SECT_ADDR2_PORT: - case SEC_SECT_ADDR3_PORT: - case SEC_DRV_SEL_PORT: - case SEC_CMD_PORT: - case SEC_CTRL_PORT: - return 1; - default: - return 0; - } + switch(port) + { + case SEC_DATA_PORT: + case SEC_FEATURES_PORT: + case SEC_SECT_CNT_PORT: + case SEC_SECT_ADDR1_PORT: + case SEC_SECT_ADDR2_PORT: + case SEC_SECT_ADDR3_PORT: + case SEC_DRV_SEL_PORT: + case SEC_CMD_PORT: + case SEC_CTRL_PORT: + return 1; + default: + return 0; + } } static inline int num_drives_on_channel(struct channel_t * channel) { - if ((channel->drives[0].device_type == IDE_NONE) && - (channel->drives[1].device_type == IDE_NONE)) { - return 0; - } else if ((channel->drives[0].device_type != IDE_NONE) && - (channel->drives[1].device_type != IDE_NONE)) { - return 2; - } else { - return 1; - } + if ((channel->drives[0].device_type == IDE_NONE) && + (channel->drives[1].device_type == IDE_NONE)) { + return 0; + } else if ((channel->drives[0].device_type != IDE_NONE) && + (channel->drives[1].device_type != IDE_NONE)) { + return 2; + } else { + return 1; + } } static inline uchar_t extract_bits(uchar_t * buf, uint_t buf_offset, uint_t bit_offset, uint_t num_bits) { - uchar_t val = buf[buf_offset]; - val = val >> bit_offset; - val &= ((1 << num_bits) -1); - return val; + uchar_t val = buf[buf_offset]; + val = val >> bit_offset; + val &= ((1 << num_bits) -1); + return val; } static inline uchar_t get_packet_field(struct channel_t * channel, uint_t packet_offset, uint_t bit_offset, uint_t num_bits) { - struct drive_t * drive = get_selected_drive(channel); - return extract_bits(drive->controller.buffer, packet_offset, bit_offset, num_bits); + struct drive_t * drive = get_selected_drive(channel); + return extract_bits(drive->controller.buffer, packet_offset, bit_offset, num_bits); } static inline uchar_t get_packet_byte(struct channel_t * channel, uint_t offset) { - struct drive_t * drive = get_selected_drive(channel); - return drive->controller.buffer[offset]; + struct drive_t * drive = get_selected_drive(channel); + return drive->controller.buffer[offset]; } static inline uint16_t get_packet_word(struct channel_t * channel, uint_t offset) { - struct drive_t * drive = get_selected_drive(channel); - uint16_t val = drive->controller.buffer[offset]; - val = val << 8; - val |= drive->controller.buffer[offset + 1]; - return val; + struct drive_t * drive = get_selected_drive(channel); + uint16_t val = drive->controller.buffer[offset]; + val = val << 8; + val |= drive->controller.buffer[offset + 1]; + return val; } static inline uint16_t rd_read_16bit(const uint8_t* buf) { - return (buf[0] << 8) | buf[1]; + return (buf[0] << 8) | buf[1]; } static inline uint32_t rd_read_32bit(const uint8_t* buf) { - return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; } //////////////////////////////////////////////////////////////////////////// @@ -330,134 +330,134 @@ static int check_bit_fields(struct controller_t * controller); int v3_ramdisk_register_cdrom(struct vm_device * dev, uint_t busID, uint_t driveID, struct cdrom_ops* cd, void * private_data) { - struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); - struct channel_t * channel = &(ramdisk->channels[busID]); - struct drive_t * drive = &(channel->drives[driveID]); - struct controller_t * controller = &(drive->controller); + struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); + struct channel_t * channel = &(ramdisk->channels[busID]); + struct drive_t * drive = &(channel->drives[driveID]); + struct controller_t * controller = &(drive->controller); - if (drive->device_type != IDE_NONE) { - PrintError("Device already registered at this location\n"); - return -1; - } + if (drive->device_type != IDE_NONE) { + PrintError("Device already registered at this location\n"); + return -1; + } - channel->irq = 15; + channel->irq = 15; - // Make model string - strncpy((char*)(drive->model_no), "V3VEE Ramdisk", 40); + // Make model string + strncpy((char*)(drive->model_no), "V3VEE Ramdisk", 40); - while (strlen((char *)(drive->model_no)) < 40) { - strcat ((char*)(drive->model_no), " "); - } + while (strlen((char *)(drive->model_no)) < 40) { + strcat ((char*)(drive->model_no), " "); + } - PrintDebug("CDROM on target %d/%d\n", busID, driveID); + PrintDebug("CDROM on target %d/%d\n", busID, driveID); - drive->device_type = IDE_CDROM; - drive->cdrom.locked = 0; - drive->sense.sense_key = SENSE_NONE; - drive->sense.asc = 0; - drive->sense.ascq = 0; + drive->device_type = IDE_CDROM; + drive->cdrom.locked = 0; + drive->sense.sense_key = SENSE_NONE; + drive->sense.asc = 0; + drive->sense.ascq = 0; - drive->private_data = private_data; + drive->private_data = private_data; #ifdef DEBUG_RAMDISK - if (check_bit_fields(controller) == INTR_REASON_BIT_ERR) { - PrintError("interrupt reason: bit field error\n"); - return INTR_REASON_BIT_ERR; - } + if (check_bit_fields(controller) == INTR_REASON_BIT_ERR) { + PrintError("interrupt reason: bit field error\n"); + return INTR_REASON_BIT_ERR; + } #endif - controller->sector_count = 0; + controller->sector_count = 0; - drive->cdrom.cd = cd; + drive->cdrom.cd = cd; - PrintDebug("\t\tCD on ata%d-%d: '%s'\n", - busID, - driveID, ""); + PrintDebug("\t\tCD on ata%d-%d: '%s'\n", + busID, + driveID, ""); - if(drive->cdrom.cd->insert_cdrom(drive->private_data)) { - PrintDebug("\t\tMedia present in CD-ROM drive\n"); - drive->cdrom.ready = 1; - drive->cdrom.capacity = drive->cdrom.cd->capacity(drive->private_data); - PrintDebug("\t\tCDROM capacity is %d\n", drive->cdrom.capacity); - } else { - PrintDebug("\t\tCould not locate CD-ROM, continuing with media not present\n"); - drive->cdrom.ready = 0; - } + if(drive->cdrom.cd->insert_cdrom(drive->private_data)) { + PrintDebug("\t\tMedia present in CD-ROM drive\n"); + drive->cdrom.ready = 1; + drive->cdrom.capacity = drive->cdrom.cd->capacity(drive->private_data); + PrintDebug("\t\tCDROM capacity is %d\n", drive->cdrom.capacity); + } else { + PrintDebug("\t\tCould not locate CD-ROM, continuing with media not present\n"); + drive->cdrom.ready = 0; + } - return 0; + return 0; } static Bit32u rd_init_hardware(struct ramdisk_t *ramdisk) { - uint_t channel_num; - uint_t device; - struct channel_t *channels = (struct channel_t *)(&(ramdisk->channels)); + uint_t channel_num; + uint_t device; + struct channel_t *channels = (struct channel_t *)(&(ramdisk->channels)); - PrintDebug("[rd_init_harddrive]\n"); + PrintDebug("[rd_init_harddrive]\n"); - for (channel_num = 0; channel_num < MAX_ATA_CHANNEL; channel_num++) { - memset((char *)(channels + channel_num), 0, sizeof(struct channel_t)); - } + for (channel_num = 0; channel_num < MAX_ATA_CHANNEL; channel_num++) { + memset((char *)(channels + channel_num), 0, sizeof(struct channel_t)); + } - for (channel_num = 0; channel_num < MAX_ATA_CHANNEL; channel_num++){ - struct channel_t * channel = &(channels[channel_num]); - - channel->ioaddr1 = 0x0; - channel->ioaddr2 = 0x0; - channel->irq = 0; - - for (device = 0; device < 2; device++){ - struct drive_t * drive = &(channel->drives[device]); - struct controller_t * controller = &(drive->controller); - - controller->status.busy = 0; - controller->status.drive_ready = 1; - controller->status.write_fault = 0; - controller->status.seek_complete = 1; - controller->status.drq = 0; - controller->status.corrected_data = 0; - controller->status.index_pulse = 0; - controller->status.index_pulse_count = 0; - controller->status.err = 0; - - controller->error_register = 0x01; // diagnostic code: no error - controller->head_no = 0; - controller->sector_count = 1; - controller->sector_no = 1; - controller->cylinder_no = 0; - controller->current_command = 0x00; - controller->buffer_index = 0; - - controller->control.reset = 0; - controller->control.disable_irq = 0; - controller->reset_in_progress = 0; - - controller->sectors_per_block = 0x80; - controller->lba_mode = 0; + for (channel_num = 0; channel_num < MAX_ATA_CHANNEL; channel_num++){ + struct channel_t * channel = &(channels[channel_num]); + + channel->ioaddr1 = 0x0; + channel->ioaddr2 = 0x0; + channel->irq = 0; + + for (device = 0; device < 2; device++){ + struct drive_t * drive = &(channel->drives[device]); + struct controller_t * controller = &(drive->controller); + + controller->status.busy = 0; + controller->status.drive_ready = 1; + controller->status.write_fault = 0; + controller->status.seek_complete = 1; + controller->status.drq = 0; + controller->status.corrected_data = 0; + controller->status.index_pulse = 0; + controller->status.index_pulse_count = 0; + controller->status.err = 0; + + controller->error_register = 0x01; // diagnostic code: no error + controller->head_no = 0; + controller->sector_count = 1; + controller->sector_no = 1; + controller->cylinder_no = 0; + controller->current_command = 0x00; + controller->buffer_index = 0; + + controller->control.reset = 0; + controller->control.disable_irq = 0; + controller->reset_in_progress = 0; + + controller->sectors_per_block = 0x80; + controller->lba_mode = 0; - controller->features = 0; + controller->features = 0; - // If not present - drive->device_type = IDE_NONE; + // If not present + drive->device_type = IDE_NONE; - // Make model string - strncpy((char*)(drive->model_no), "", 40); - while(strlen((char *)(drive->model_no)) < 40) { - strcat ((char*)(drive->model_no), " "); - } + // Make model string + strncpy((char*)(drive->model_no), "", 40); + while(strlen((char *)(drive->model_no)) < 40) { + strcat ((char*)(drive->model_no), " "); + } - }//for device - }//for channel + }//for device + }//for channel #ifdef DEBUG_RAMDISK - rd_print_state(ramdisk); + rd_print_state(ramdisk); #endif - return 0; + return 0; } @@ -468,7 +468,7 @@ static Bit32u rd_init_hardware(struct ramdisk_t *ramdisk) { */ static void rd_close_harddrive(struct ramdisk_t *ramdisk) { - return; + return; } @@ -477,253 +477,253 @@ static void rd_close_harddrive(struct ramdisk_t *ramdisk) { static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); - struct channel_t * channel = NULL; - struct drive_t * drive = NULL; - struct controller_t * controller = NULL; + struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); + struct channel_t * channel = NULL; + struct drive_t * drive = NULL; + struct controller_t * controller = NULL; - if (is_primary_port(ramdisk, port)) { - channel = &(ramdisk->channels[0]); - } else if (is_secondary_port(ramdisk, port)) { - channel = &(ramdisk->channels[1]); - } else { - PrintError("Invalid Port: %d\n", port); - return -1; - } + if (is_primary_port(ramdisk, port)) { + channel = &(ramdisk->channels[0]); + } else if (is_secondary_port(ramdisk, port)) { + channel = &(ramdisk->channels[1]); + } else { + PrintError("Invalid Port: %d\n", port); + return -1; + } - drive = get_selected_drive(channel); - controller = &(drive->controller); + drive = get_selected_drive(channel); + controller = &(drive->controller); - PrintTrace("[read_data_handler] IO Read at 0x%x, on drive %d/%d current cmd=0x%x\n", - port, - get_channel_no(ramdisk, channel), - get_drive_no(channel, drive), - controller->current_command); + PrintTrace("[read_data_handler] IO Read at 0x%x, on drive %d/%d current cmd=0x%x\n", + port, + get_channel_no(ramdisk, channel), + get_drive_no(channel, drive), + controller->current_command); - switch (controller->current_command) { - case 0xec: // IDENTIFY DEVICE - case 0xa1: - { + switch (controller->current_command) { + case 0xec: // IDENTIFY DEVICE + case 0xa1: + { - controller->status.busy = 0; - controller->status.drive_ready = 1; - controller->status.write_fault = 0; - controller->status.seek_complete = 1; - controller->status.corrected_data = 0; - controller->status.err = 0; + controller->status.busy = 0; + controller->status.drive_ready = 1; + controller->status.write_fault = 0; + controller->status.seek_complete = 1; + controller->status.corrected_data = 0; + controller->status.err = 0; - /* - value32 = controller->buffer[index]; - index++; + /* + value32 = controller->buffer[index]; + index++; - if (io_len >= 2) { - value32 |= (controller->buffer[index] << 8); - index++; - } + if (io_len >= 2) { + value32 |= (controller->buffer[index] << 8); + index++; + } - if (io_len == 4) { - value32 |= (controller->buffer[index] << 16); - value32 |= (controller->buffer[index+1] << 24); - index += 2; - } + if (io_len == 4) { + value32 |= (controller->buffer[index] << 16); + value32 |= (controller->buffer[index+1] << 24); + index += 2; + } - controller->buffer_index = index; - */ - /* JRL */ - memcpy(dst, controller->buffer + controller->buffer_index, length); - controller->buffer_index += length; + controller->buffer_index = index; + */ + /* JRL */ + memcpy(dst, controller->buffer + controller->buffer_index, length); + controller->buffer_index += length; - if (controller->buffer_index >= 512) { - controller->status.drq = 0; - } + if (controller->buffer_index >= 512) { + controller->status.drq = 0; + } - return length; - } - case 0xa0: //send packet cmd - { - uint_t index = controller->buffer_index; + return length; + } + case 0xa0: //send packet cmd + { + uint_t index = controller->buffer_index; - PrintTrace("\t\tatapi.command(%02x), index(%d), cdrom.remaining_blocks(%d)\n", - drive->atapi.command, - index, - drive->cdrom.remaining_blocks); + PrintTrace("\t\tatapi.command(%02x), index(%d), cdrom.remaining_blocks(%d)\n", + drive->atapi.command, + index, + drive->cdrom.remaining_blocks); - // Load block if necessary - if (index >= 2048) { + // Load block if necessary + if (index >= 2048) { - if (index > 2048) { - PrintError("\t\tindex > 2048 : 0x%x\n", index); - return -1; - } + if (index > 2048) { + PrintError("\t\tindex > 2048 : 0x%x\n", index); + return -1; + } - switch (drive->atapi.command) { - case 0x28: // read (10) - case 0xa8: // read (12) - { + switch (drive->atapi.command) { + case 0x28: // read (10) + case 0xa8: // read (12) + { - if (!(drive->cdrom.ready)) { - PrintError("\t\tRead with CDROM not ready\n"); - return -1; - } + if (!(drive->cdrom.ready)) { + PrintError("\t\tRead with CDROM not ready\n"); + return -1; + } - drive->cdrom.cd->read_block(drive->private_data, controller->buffer, - drive->cdrom.next_lba); - drive->cdrom.next_lba++; - drive->cdrom.remaining_blocks--; + drive->cdrom.cd->read_block(drive->private_data, controller->buffer, + drive->cdrom.next_lba); + drive->cdrom.next_lba++; + drive->cdrom.remaining_blocks--; - if (!(drive->cdrom.remaining_blocks)) { - PrintDebug("\t\tLast READ block loaded {CDROM}\n"); - } else { - PrintDebug("\t\tREAD block loaded (%d remaining) {CDROM}\n", - drive->cdrom.remaining_blocks); - } + if (!(drive->cdrom.remaining_blocks)) { + PrintDebug("\t\tLast READ block loaded {CDROM}\n"); + } else { + PrintDebug("\t\tREAD block loaded (%d remaining) {CDROM}\n", + drive->cdrom.remaining_blocks); + } - // one block transfered, start at beginning - index = 0; - break; - } - default: // no need to load a new block - break; - } - } + // one block transfered, start at beginning + index = 0; + break; + } + default: // no need to load a new block + break; + } + } - /* - increment = 0; - value32 = controller->buffer[index + increment]; - increment++; + /* + increment = 0; + value32 = controller->buffer[index + increment]; + increment++; - if (io_len >= 2) { - value32 |= (controller->buffer[index + increment] << 8); - increment++; - } + if (io_len >= 2) { + value32 |= (controller->buffer[index + increment] << 8); + increment++; + } - if (io_len == 4) { - value32 |= (controller->buffer[index + increment] << 16); - value32 |= (controller->buffer[index + increment + 1] << 24); - increment += 2; - } - - controller->buffer_index = index + increment; - controller->drq_index += increment; - - */ - /* JRL: CHECK THAT there is enough data in the buffer to copy.... */ - { - memcpy(dst, controller->buffer + index, length); + if (io_len == 4) { + value32 |= (controller->buffer[index + increment] << 16); + value32 |= (controller->buffer[index + increment + 1] << 24); + increment += 2; + } + + controller->buffer_index = index + increment; + controller->drq_index += increment; + + */ + /* JRL: CHECK THAT there is enough data in the buffer to copy.... */ + { + memcpy(dst, controller->buffer + index, length); - controller->buffer_index = index + length; - controller->drq_index += length; - } + controller->buffer_index = index + length; + controller->drq_index += length; + } - /* *** */ + /* *** */ - if (controller->drq_index >= (unsigned)drive->atapi.drq_bytes) { - controller->status.drq = 0; - controller->drq_index = 0; + if (controller->drq_index >= (unsigned)drive->atapi.drq_bytes) { + controller->status.drq = 0; + controller->drq_index = 0; - drive->atapi.total_bytes_remaining -= drive->atapi.drq_bytes; + drive->atapi.total_bytes_remaining -= drive->atapi.drq_bytes; - if (drive->atapi.total_bytes_remaining > 0) { - // one or more blocks remaining (works only for single block commands) + if (drive->atapi.total_bytes_remaining > 0) { + // one or more blocks remaining (works only for single block commands) - PrintDebug("\t\tPACKET drq bytes read\n"); - controller->interrupt_reason.i_o = 1; - controller->status.busy = 0; - controller->status.drq = 1; - controller->interrupt_reason.c_d = 0; + PrintDebug("\t\tPACKET drq bytes read\n"); + controller->interrupt_reason.i_o = 1; + controller->status.busy = 0; + controller->status.drq = 1; + controller->interrupt_reason.c_d = 0; - // set new byte count if last block - if (drive->atapi.total_bytes_remaining < controller->byte_count) { - controller->byte_count = drive->atapi.total_bytes_remaining; - } - drive->atapi.drq_bytes = controller->byte_count; + // set new byte count if last block + if (drive->atapi.total_bytes_remaining < controller->byte_count) { + controller->byte_count = drive->atapi.total_bytes_remaining; + } + drive->atapi.drq_bytes = controller->byte_count; - rd_raise_interrupt(dev, channel); - } else { - // all bytes read - PrintDebug("\t\tPACKET all bytes read\n"); + rd_raise_interrupt(dev, channel); + } else { + // all bytes read + PrintDebug("\t\tPACKET all bytes read\n"); - controller->interrupt_reason.i_o = 1; - controller->interrupt_reason.c_d = 1; - controller->status.drive_ready = 1; - controller->interrupt_reason.rel = 0; - controller->status.busy = 0; - controller->status.drq = 0; - controller->status.err = 0; + controller->interrupt_reason.i_o = 1; + controller->interrupt_reason.c_d = 1; + controller->status.drive_ready = 1; + controller->interrupt_reason.rel = 0; + controller->status.busy = 0; + controller->status.drq = 0; + controller->status.err = 0; - rd_raise_interrupt(dev, channel); - } - } - return length; - break; - } + rd_raise_interrupt(dev, channel); + } + } + return length; + break; + } - default: - PrintError("\t\tunsupported command: %02x\n", controller->current_command); - break; - } + default: + PrintError("\t\tunsupported command: %02x\n", controller->current_command); + break; + } - return -1; + return -1; } static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); - struct channel_t * channel = NULL; - struct drive_t * drive = NULL; - struct controller_t * controller = NULL; - - if (is_primary_port(ramdisk, port)) { - channel = &(ramdisk->channels[0]); - } else if (is_secondary_port(ramdisk, port)) { - channel = &(ramdisk->channels[1]); - } else { - PrintError("Invalid Port: %d\n", port); - return -1; - } + struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); + struct channel_t * channel = NULL; + struct drive_t * drive = NULL; + struct controller_t * controller = NULL; + + if (is_primary_port(ramdisk, port)) { + channel = &(ramdisk->channels[0]); + } else if (is_secondary_port(ramdisk, port)) { + channel = &(ramdisk->channels[1]); + } else { + PrintError("Invalid Port: %d\n", port); + return -1; + } - drive = get_selected_drive(channel); - controller = &(drive->controller); + drive = get_selected_drive(channel); + controller = &(drive->controller); - PrintDebug("[write_data_handler] IO write at 0x%x, current_cmd = 0x%02x\n", - port, controller->current_command); + PrintDebug("[write_data_handler] IO write at 0x%x, current_cmd = 0x%02x\n", + port, controller->current_command); - //PrintDebug("[write_data_handler]\n"); - switch (controller->current_command) { - case 0x30: // WRITE SECTORS - PrintError("\t\tneed to implement 0x30(write sector) to port 0x%x\n", port); - return -1; + //PrintDebug("[write_data_handler]\n"); + switch (controller->current_command) { + case 0x30: // WRITE SECTORS + PrintError("\t\tneed to implement 0x30(write sector) to port 0x%x\n", port); + return -1; - case 0xa0: // PACKET + case 0xa0: // PACKET - if (handle_atapi_packet_command(dev, channel, *(ushort_t *)src) == -1) { - PrintError("Error sending atapi packet command in PACKET write to data port\n"); - return -1; - } + if (handle_atapi_packet_command(dev, channel, *(ushort_t *)src) == -1) { + PrintError("Error sending atapi packet command in PACKET write to data port\n"); + return -1; + } - return length; + return length; - default: - PrintError("\t\tIO write(0x%x): current command is %02xh\n", - port, controller->current_command); + default: + PrintError("\t\tIO write(0x%x): current command is %02xh\n", + port, controller->current_command); - return -1; - } + return -1; + } - return -1; + return -1; } @@ -733,615 +733,615 @@ static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_d static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); - struct channel_t * channel = NULL; - struct drive_t * drive = NULL; - struct controller_t * controller = NULL; + struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); + struct channel_t * channel = NULL; + struct drive_t * drive = NULL; + struct controller_t * controller = NULL; - if (is_primary_port(ramdisk, port)) { - channel = &(ramdisk->channels[0]); - } else if (is_secondary_port(ramdisk, port)) { - channel = &(ramdisk->channels[1]); - } else { - PrintError("Invalid Port: %d\n", port); - return -1; - } + if (is_primary_port(ramdisk, port)) { + channel = &(ramdisk->channels[0]); + } else if (is_secondary_port(ramdisk, port)) { + channel = &(ramdisk->channels[1]); + } else { + PrintError("Invalid Port: %d\n", port); + return -1; + } - drive = get_selected_drive(channel); - controller = &(drive->controller); + drive = get_selected_drive(channel); + controller = &(drive->controller); - PrintDebug("[read_status_handler] IO read at 0x%x, on drive %d/%d\n", - port, get_channel_no(ramdisk, channel), - channel->drive_select); + PrintDebug("[read_status_handler] IO read at 0x%x, on drive %d/%d\n", + port, get_channel_no(ramdisk, channel), + channel->drive_select); - if (num_drives_on_channel(channel) == 0) { - PrintDebug("Setting value to zero because 0 devices on channel\n"); - // (mch) Just return zero for these registers - memset(dst, 0, length); + if (num_drives_on_channel(channel) == 0) { + PrintDebug("Setting value to zero because 0 devices on channel\n"); + // (mch) Just return zero for these registers + memset(dst, 0, length); - } else { - uchar_t val = ( - (controller->status.busy << 7) | - (controller->status.drive_ready << 6) | - (controller->status.write_fault << 5) | - (controller->status.seek_complete << 4) | - (controller->status.drq << 3) | - (controller->status.corrected_data << 2) | - (controller->status.index_pulse << 1) | - (controller->status.err) ); + } else { + uchar_t val = ( + (controller->status.busy << 7) | + (controller->status.drive_ready << 6) | + (controller->status.write_fault << 5) | + (controller->status.seek_complete << 4) | + (controller->status.drq << 3) | + (controller->status.corrected_data << 2) | + (controller->status.index_pulse << 1) | + (controller->status.err) ); - memcpy(dst, &val, length); + memcpy(dst, &val, length); - controller->status.index_pulse_count++; - controller->status.index_pulse = 0; + controller->status.index_pulse_count++; + controller->status.index_pulse = 0; - if (controller->status.index_pulse_count >= INDEX_PULSE_CYCLE) { - controller->status.index_pulse = 1; - controller->status.index_pulse_count = 0; + if (controller->status.index_pulse_count >= INDEX_PULSE_CYCLE) { + controller->status.index_pulse = 1; + controller->status.index_pulse_count = 0; + } } - } - if ((port == SEC_CMD_PORT) || (port == PRI_CMD_PORT)) { - rd_lower_irq(dev, channel); - } + if ((port == SEC_CMD_PORT) || (port == PRI_CMD_PORT)) { + rd_lower_irq(dev, channel); + } - PrintDebug("\t\tRead STATUS = 0x%x\n", *(uchar_t *)dst); + PrintDebug("\t\tRead STATUS = 0x%x\n", *(uchar_t *)dst); - return length; + return length; } static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); - struct channel_t * channel = NULL; - struct drive_t * drive = NULL; - struct controller_t * controller = NULL; - uchar_t value = *(uchar_t *)src; - - if (length != 1) { - PrintError("Invalid Command port write length: %d (port=%d)\n", length, port); - return -1; - } + struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); + struct channel_t * channel = NULL; + struct drive_t * drive = NULL; + struct controller_t * controller = NULL; + uchar_t value = *(uchar_t *)src; + + if (length != 1) { + PrintError("Invalid Command port write length: %d (port=%d)\n", length, port); + return -1; + } - if (is_primary_port(ramdisk, port)) { - channel = &(ramdisk->channels[0]); - } else if (is_secondary_port(ramdisk, port)) { - channel = &(ramdisk->channels[1]); - } else { - PrintError("Invalid Port: %d\n", port); - return -1; - } + if (is_primary_port(ramdisk, port)) { + channel = &(ramdisk->channels[0]); + } else if (is_secondary_port(ramdisk, port)) { + channel = &(ramdisk->channels[1]); + } else { + PrintError("Invalid Port: %d\n", port); + return -1; + } - drive = get_selected_drive(channel); - controller = &(drive->controller); + drive = get_selected_drive(channel); + controller = &(drive->controller); - PrintDebug("[write_command_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n", - port, get_channel_no(ramdisk, channel), - get_drive_no(channel, drive), - value); + PrintDebug("[write_command_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n", + port, get_channel_no(ramdisk, channel), + get_drive_no(channel, drive), + value); - switch (value) { + switch (value) { #if 0 - case 0xec: // IDENTIFY DEVICE - { - - if (drive->device_type == IDE_NONE) { - PrintError("\t\tError: disk ata%d-%d not present, aborting\n", - get_channel_no(ramdisk, channel), - get_drive_no(channel, drive)); - rd_command_aborted(dev, channel, value); - break; - } else if (drive->device_type == IDE_CDROM) { - PrintDebug("Identifying CDROM...Going to abort????\n"); - controller->head_no = 0; - controller->sector_count = 1; - controller->sector_no = 1; - controller->cylinder_no = 0xeb14; - rd_command_aborted(dev, channel, 0xec); - } else { - PrintError("\t\tError: Want to identify HDD!!\n"); - /* - SELECTED_CONTROLLER(channel).current_command = value; - SELECTED_CONTROLLER(channel).error_register = 0; + case 0xec: // IDENTIFY DEVICE + { + + if (drive->device_type == IDE_NONE) { + PrintError("\t\tError: disk ata%d-%d not present, aborting\n", + get_channel_no(ramdisk, channel), + get_drive_no(channel, drive)); + rd_command_aborted(dev, channel, value); + break; + } else if (drive->device_type == IDE_CDROM) { + PrintDebug("Identifying CDROM...Going to abort????\n"); + controller->head_no = 0; + controller->sector_count = 1; + controller->sector_no = 1; + controller->cylinder_no = 0xeb14; + rd_command_aborted(dev, channel, 0xec); + } else { + PrintError("\t\tError: Want to identify HDD!!\n"); + /* + SELECTED_CONTROLLER(channel).current_command = value; + SELECTED_CONTROLLER(channel).error_register = 0; - // See ATA/ATAPI-4, 8.12 - SELECTED_CONTROLLER(channel).status.busy = 0; - SELECTED_CONTROLLER(channel).status.drive_ready = 1; - SELECTED_CONTROLLER(channel).status.write_fault = 0; - SELECTED_CONTROLLER(channel).status.drq = 1; - SELECTED_CONTROLLER(channel).status.err = 0; + // See ATA/ATAPI-4, 8.12 + SELECTED_CONTROLLER(channel).status.busy = 0; + SELECTED_CONTROLLER(channel).status.drive_ready = 1; + SELECTED_CONTROLLER(channel).status.write_fault = 0; + SELECTED_CONTROLLER(channel).status.drq = 1; + SELECTED_CONTROLLER(channel).status.err = 0; - SELECTED_CONTROLLER(channel).status.seek_complete = 1; - SELECTED_CONTROLLER(channel).status.corrected_data = 0; + SELECTED_CONTROLLER(channel).status.seek_complete = 1; + SELECTED_CONTROLLER(channel).status.corrected_data = 0; - SELECTED_CONTROLLER(channel).buffer_index = 0; - raise_interrupt(channel); - identify_drive(channel); - */ - } + SELECTED_CONTROLLER(channel).buffer_index = 0; + raise_interrupt(channel); + identify_drive(channel); + */ + } - break; - } + break; + } #endif - // ATAPI commands - case 0xa1: // IDENTIFY PACKET DEVICE - { - if (drive->device_type == IDE_CDROM) { - controller->current_command = value; - controller->error_register = 0; + // ATAPI commands + case 0xa1: // IDENTIFY PACKET DEVICE + { + if (drive->device_type == IDE_CDROM) { + controller->current_command = value; + controller->error_register = 0; - controller->status.busy = 0; - controller->status.drive_ready = 1; - controller->status.write_fault = 0; - controller->status.drq = 1; - controller->status.err = 0; + controller->status.busy = 0; + controller->status.drive_ready = 1; + controller->status.write_fault = 0; + controller->status.drq = 1; + controller->status.err = 0; - controller->status.seek_complete = 1; - controller->status.corrected_data = 0; + controller->status.seek_complete = 1; + controller->status.corrected_data = 0; - controller->buffer_index = 0; - rd_raise_interrupt(dev, channel); - rd_identify_ATAPI_drive(dev, channel); - } else { - PrintError("Identifying non cdrom device not supported - ata %d/%d\n", - get_channel_no(ramdisk, channel), - get_drive_no(channel, drive)); - rd_command_aborted(dev, channel, 0xa1); - } - break; - } - case 0xa0: // SEND PACKET (atapi) - { - if (drive->device_type == IDE_CDROM) { - // PACKET + controller->buffer_index = 0; + rd_raise_interrupt(dev, channel); + rd_identify_ATAPI_drive(dev, channel); + } else { + PrintError("Identifying non cdrom device not supported - ata %d/%d\n", + get_channel_no(ramdisk, channel), + get_drive_no(channel, drive)); + rd_command_aborted(dev, channel, 0xa1); + } + break; + } + case 0xa0: // SEND PACKET (atapi) + { + if (drive->device_type == IDE_CDROM) { + // PACKET - if (controller->features & (1 << 0)) { - PrintError("\t\tPACKET-DMA not supported"); - return -1; - } + if (controller->features & (1 << 0)) { + PrintError("\t\tPACKET-DMA not supported"); + return -1; + } - if (controller->features & (1 << 1)) { - PrintError("\t\tPACKET-overlapped not supported"); - return -1; - } + if (controller->features & (1 << 1)) { + PrintError("\t\tPACKET-overlapped not supported"); + return -1; + } - // We're already ready! - controller->sector_count = 1; - controller->status.busy = 0; - controller->status.write_fault = 0; - - // serv bit?? - controller->status.drq = 1; - controller->status.err = 0; + // We're already ready! + controller->sector_count = 1; + controller->status.busy = 0; + controller->status.write_fault = 0; + + // serv bit?? + controller->status.drq = 1; + controller->status.err = 0; - // NOTE: no interrupt here - controller->current_command = value; - controller->buffer_index = 0; - } else { - PrintError("Sending packet to non cdrom device not supported\n"); - rd_command_aborted (dev, channel, 0xa0); - } - break; + // NOTE: no interrupt here + controller->current_command = value; + controller->buffer_index = 0; + } else { + PrintError("Sending packet to non cdrom device not supported\n"); + rd_command_aborted (dev, channel, 0xa0); + } + break; + } + default: + PrintError("\t\tneed translate command %2x - ata %d\%d\n", value, + get_channel_no(ramdisk, channel), + get_drive_no(channel, drive)); + //return -1; + /* JRL THIS NEEDS TO CHANGE */ + return length; + } - default: - PrintError("\t\tneed translate command %2x - ata %d\%d\n", value, - get_channel_no(ramdisk, channel), - get_drive_no(channel, drive)); - //return -1; - /* JRL THIS NEEDS TO CHANGE */ return length; - - } - return length; } static int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); - struct channel_t * channel = NULL; - struct drive_t * master_drive = NULL; - struct drive_t * slave_drive = NULL; - struct controller_t * controller = NULL; - uchar_t value = *(uchar_t *)src; - rd_bool prev_control_reset; - - if (length != 1) { - PrintError("Invalid Status port read length: %d (port=%d)\n", length, port); - return -1; - } + struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); + struct channel_t * channel = NULL; + struct drive_t * master_drive = NULL; + struct drive_t * slave_drive = NULL; + struct controller_t * controller = NULL; + uchar_t value = *(uchar_t *)src; + rd_bool prev_control_reset; + + if (length != 1) { + PrintError("Invalid Status port read length: %d (port=%d)\n", length, port); + return -1; + } - if (is_primary_port(ramdisk, port)) { - channel = &(ramdisk->channels[0]); - } else if (is_secondary_port(ramdisk, port)) { - channel = &(ramdisk->channels[1]); - } else { - PrintError("Invalid Port: %d\n", port); - return -1; - } + if (is_primary_port(ramdisk, port)) { + channel = &(ramdisk->channels[0]); + } else if (is_secondary_port(ramdisk, port)) { + channel = &(ramdisk->channels[1]); + } else { + PrintError("Invalid Port: %d\n", port); + return -1; + } - master_drive = &(channel->drives[0]); - slave_drive = &(channel->drives[1]); + master_drive = &(channel->drives[0]); + slave_drive = &(channel->drives[1]); - controller = &(get_selected_drive(channel)->controller); + controller = &(get_selected_drive(channel)->controller); - PrintDebug("[write_control_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n", - port, get_channel_no(ramdisk, channel), - channel->drive_select, - value); + PrintDebug("[write_control_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n", + port, get_channel_no(ramdisk, channel), + channel->drive_select, + value); - // (mch) Even if device 1 was selected, a write to this register - // goes to device 0 (if device 1 is absent) + // (mch) Even if device 1 was selected, a write to this register + // goes to device 0 (if device 1 is absent) - prev_control_reset = controller->control.reset; + prev_control_reset = controller->control.reset; - if (value & 0x04) { - PrintDebug("RESET Signaled\n"); - } + if (value & 0x04) { + PrintDebug("RESET Signaled\n"); + } - master_drive->controller.control.reset = value & 0x04; - slave_drive->controller.control.reset = value & 0x04; + master_drive->controller.control.reset = value & 0x04; + slave_drive->controller.control.reset = value & 0x04; - // CGS: was: SELECTED_CONTROLLER(channel).control.disable_irq = value & 0x02; - master_drive->controller.control.disable_irq = value & 0x02; - slave_drive->controller.control.disable_irq = value & 0x02; + // CGS: was: SELECTED_CONTROLLER(channel).control.disable_irq = value & 0x02; + master_drive->controller.control.disable_irq = value & 0x02; + slave_drive->controller.control.disable_irq = value & 0x02; - PrintDebug("\t\tadpater control reg: reset controller = %d\n", - (unsigned) (controller->control.reset) ? 1 : 0); - PrintDebug("\t\tadpater control reg: disable_irq(X) = %d\n", - (unsigned) (controller->control.disable_irq) ? 1 : 0); + PrintDebug("\t\tadpater control reg: reset controller = %d\n", + (unsigned) (controller->control.reset) ? 1 : 0); + PrintDebug("\t\tadpater control reg: disable_irq(X) = %d\n", + (unsigned) (controller->control.disable_irq) ? 1 : 0); - if ((!prev_control_reset) && (controller->control.reset)) { - uint_t id = 0; + if ((!prev_control_reset) && (controller->control.reset)) { + uint_t id = 0; - // transition from 0 to 1 causes all drives to reset - PrintDebug("\t\thard drive: RESET\n"); + // transition from 0 to 1 causes all drives to reset + PrintDebug("\t\thard drive: RESET\n"); - // (mch) Set BSY, drive not ready - for (id = 0; id < 2; id++) { - struct controller_t * ctrl = NULL; - - if (id == 0) { - ctrl = &(master_drive->controller); - } else if (id == 1) { - ctrl = &(slave_drive->controller); - } + // (mch) Set BSY, drive not ready + for (id = 0; id < 2; id++) { + struct controller_t * ctrl = NULL; + + if (id == 0) { + ctrl = &(master_drive->controller); + } else if (id == 1) { + ctrl = &(slave_drive->controller); + } - ctrl->status.busy = 1; - ctrl->status.drive_ready = 0; - ctrl->reset_in_progress = 1; + ctrl->status.busy = 1; + ctrl->status.drive_ready = 0; + ctrl->reset_in_progress = 1; - ctrl->status.write_fault = 0; - ctrl->status.seek_complete = 1; - ctrl->status.drq = 0; - ctrl->status.corrected_data = 0; - ctrl->status.err = 0; + ctrl->status.write_fault = 0; + ctrl->status.seek_complete = 1; + ctrl->status.drq = 0; + ctrl->status.corrected_data = 0; + ctrl->status.err = 0; - ctrl->error_register = 0x01; // diagnostic code: no error + ctrl->error_register = 0x01; // diagnostic code: no error - ctrl->current_command = 0x00; - ctrl->buffer_index = 0; + ctrl->current_command = 0x00; + ctrl->buffer_index = 0; - ctrl->sectors_per_block = 0x80; - ctrl->lba_mode = 0; + ctrl->sectors_per_block = 0x80; + ctrl->lba_mode = 0; - ctrl->control.disable_irq = 0; - } + ctrl->control.disable_irq = 0; + } - rd_lower_irq(dev, channel); + rd_lower_irq(dev, channel); - } else if ((controller->reset_in_progress) && - (!controller->control.reset)) { - uint_t id; - // Clear BSY and DRDY - PrintDebug("\t\tReset complete {%s}\n", device_type_to_str(get_selected_drive(channel)->device_type)); + } else if ((controller->reset_in_progress) && + (!controller->control.reset)) { + uint_t id; + // Clear BSY and DRDY + PrintDebug("\t\tReset complete {%s}\n", device_type_to_str(get_selected_drive(channel)->device_type)); - for (id = 0; id < 2; id++) { - struct controller_t * ctrl = NULL; - struct drive_t * drv = NULL; + for (id = 0; id < 2; id++) { + struct controller_t * ctrl = NULL; + struct drive_t * drv = NULL; - if (id == 0) { - ctrl = &(master_drive->controller); - drv = master_drive; - } else if (id == 1) { - ctrl = &(slave_drive->controller); - drv = slave_drive; - } + if (id == 0) { + ctrl = &(master_drive->controller); + drv = master_drive; + } else if (id == 1) { + ctrl = &(slave_drive->controller); + drv = slave_drive; + } - ctrl->status.busy = 0; - ctrl->status.drive_ready = 1; - ctrl->reset_in_progress = 0; + ctrl->status.busy = 0; + ctrl->status.drive_ready = 1; + ctrl->reset_in_progress = 0; - // Device signature - if (drv->device_type == IDE_DISK) { - PrintDebug("\t\tdrive %d/%d is harddrive\n", get_channel_no(ramdisk, channel), id); - ctrl->head_no = 0; - ctrl->sector_count = 1; - ctrl->sector_no = 1; - ctrl->cylinder_no = 0; - } else { - ctrl->head_no = 0; - ctrl->sector_count = 1; - ctrl->sector_no = 1; - ctrl->cylinder_no = 0xeb14; - } + // Device signature + if (drv->device_type == IDE_DISK) { + PrintDebug("\t\tdrive %d/%d is harddrive\n", get_channel_no(ramdisk, channel), id); + ctrl->head_no = 0; + ctrl->sector_count = 1; + ctrl->sector_no = 1; + ctrl->cylinder_no = 0; + } else { + ctrl->head_no = 0; + ctrl->sector_count = 1; + ctrl->sector_no = 1; + ctrl->cylinder_no = 0xeb14; + } + } } - } - PrintDebug("\t\ts[0].controller.control.disable_irq = %02x\n", - master_drive->controller.control.disable_irq); - PrintDebug("\t\ts[1].controller.control.disable_irq = %02x\n", - slave_drive->controller.control.disable_irq); - return length; + PrintDebug("\t\ts[0].controller.control.disable_irq = %02x\n", + master_drive->controller.control.disable_irq); + PrintDebug("\t\ts[1].controller.control.disable_irq = %02x\n", + slave_drive->controller.control.disable_irq); + return length; } static int read_general_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); - struct channel_t * channel = NULL; - struct drive_t * drive = NULL; - struct controller_t * controller = NULL; + struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); + struct channel_t * channel = NULL; + struct drive_t * drive = NULL; + struct controller_t * controller = NULL; - if (length != 1) { - PrintError("Invalid Status port read length: %d (port=%d)\n", length, port); - return -1; - } + if (length != 1) { + PrintError("Invalid Status port read length: %d (port=%d)\n", length, port); + return -1; + } - if (is_primary_port(ramdisk, port)) { - channel = &(ramdisk->channels[0]); - } else if (is_secondary_port(ramdisk, port)) { - channel = &(ramdisk->channels[1]); - } else { - PrintError("Invalid Port: %d\n", port); - return -1; - } + if (is_primary_port(ramdisk, port)) { + channel = &(ramdisk->channels[0]); + } else if (is_secondary_port(ramdisk, port)) { + channel = &(ramdisk->channels[1]); + } else { + PrintError("Invalid Port: %d\n", port); + return -1; + } - drive = get_selected_drive(channel); - controller = &(drive->controller); + drive = get_selected_drive(channel); + controller = &(drive->controller); - PrintDebug("[read_general_handler] IO read addr at %x, on drive %d/%d, curcmd = %02x\n", - port, get_channel_no(ramdisk, channel), - channel->drive_select, - controller->current_command); + PrintDebug("[read_general_handler] IO read addr at %x, on drive %d/%d, curcmd = %02x\n", + port, get_channel_no(ramdisk, channel), + channel->drive_select, + controller->current_command); - switch (port) { - case PRI_FEATURES_PORT: - case SEC_FEATURES_PORT: // hard disk error register 0x1f1 - { - uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->error_register; + switch (port) { + case PRI_FEATURES_PORT: + case SEC_FEATURES_PORT: // hard disk error register 0x1f1 + { + uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->error_register; - controller->status.err = 0; + controller->status.err = 0; - PrintDebug("\t\tRead FEATURES = 0x%x\n", val); + PrintDebug("\t\tRead FEATURES = 0x%x\n", val); - *(uchar_t *)dst = val; - return length; + *(uchar_t *)dst = val; + return length; - break; - } + break; + } - case PRI_SECT_CNT_PORT: - case SEC_SECT_CNT_PORT: // hard disk sector count / interrupt reason 0x1f2 - { - uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_count; - PrintDebug("\t\tRead SECTOR COUNT = 0x%x\n", val); - *(uchar_t *)dst = val; - return length; + case PRI_SECT_CNT_PORT: + case SEC_SECT_CNT_PORT: // hard disk sector count / interrupt reason 0x1f2 + { + uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_count; + PrintDebug("\t\tRead SECTOR COUNT = 0x%x\n", val); + *(uchar_t *)dst = val; + return length; - break; - } - case PRI_SECT_ADDR1_PORT: - case SEC_SECT_ADDR1_PORT: // sector number 0x1f3 - { - uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_no; + break; + } + case PRI_SECT_ADDR1_PORT: + case SEC_SECT_ADDR1_PORT: // sector number 0x1f3 + { + uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_no; - PrintDebug("\t\tRead SECTOR ADDR1 = 0x%x\n", val); + PrintDebug("\t\tRead SECTOR ADDR1 = 0x%x\n", val); - *(uchar_t *)dst = val; - return length; + *(uchar_t *)dst = val; + return length; - break; - } + break; + } - case PRI_SECT_ADDR2_PORT: - case SEC_SECT_ADDR2_PORT: // cylinder low 0x1f4 - { - // -- WARNING : On real hardware the controller registers are shared between drives. - // So we must respond even if the select device is not present. Some OS uses this fact - // to detect the disks.... minix2 for example - uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no & 0x00ff); + case PRI_SECT_ADDR2_PORT: + case SEC_SECT_ADDR2_PORT: // cylinder low 0x1f4 + { + // -- WARNING : On real hardware the controller registers are shared between drives. + // So we must respond even if the select device is not present. Some OS uses this fact + // to detect the disks.... minix2 for example + uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no & 0x00ff); - PrintDebug("\t\tRead SECTOR ADDR2 = 0x%x\n", val); + PrintDebug("\t\tRead SECTOR ADDR2 = 0x%x\n", val); - *(uchar_t *)dst = val; - return length; + *(uchar_t *)dst = val; + return length; - break; - } + break; + } - case PRI_SECT_ADDR3_PORT: - case SEC_SECT_ADDR3_PORT: // cylinder high 0x1f5 - { - // -- WARNING : On real hardware the controller registers are shared between drives. - // So we must respond even if the select device is not present. Some OS uses this fact - // to detect the disks.... minix2 for example - uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no >> 8); + case PRI_SECT_ADDR3_PORT: + case SEC_SECT_ADDR3_PORT: // cylinder high 0x1f5 + { + // -- WARNING : On real hardware the controller registers are shared between drives. + // So we must respond even if the select device is not present. Some OS uses this fact + // to detect the disks.... minix2 for example + uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no >> 8); - PrintDebug("\t\tRead SECTOR ADDR3 = 0x%x\n", val); + PrintDebug("\t\tRead SECTOR ADDR3 = 0x%x\n", val); - *(uchar_t *)dst = val; - return length; + *(uchar_t *)dst = val; + return length; - break; - } - case PRI_DRV_SEL_PORT: - case SEC_DRV_SEL_PORT: // hard disk drive and head register 0x1f6 - { - // b7 Extended data field for ECC - // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128 - // Since 512 was always used, bit 6 was taken to mean LBA mode: - // b6 1=LBA mode, 0=CHS mode - // b5 1 - // b4: DRV - // b3..0 HD3..HD0 - uchar_t val = ((1 << 7) | - ((controller->lba_mode > 0) << 6) | - (1 << 5) | // 01b = 512 sector size - (channel->drive_select << 4) | - (controller->head_no << 0)); + break; + } + case PRI_DRV_SEL_PORT: + case SEC_DRV_SEL_PORT: // hard disk drive and head register 0x1f6 + { + // b7 Extended data field for ECC + // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128 + // Since 512 was always used, bit 6 was taken to mean LBA mode: + // b6 1=LBA mode, 0=CHS mode + // b5 1 + // b4: DRV + // b3..0 HD3..HD0 + uchar_t val = ((1 << 7) | + ((controller->lba_mode > 0) << 6) | + (1 << 5) | // 01b = 512 sector size + (channel->drive_select << 4) | + (controller->head_no << 0)); - PrintDebug("\t\tRead DRIVE SELECT = 0x%x\n", val); - *(uchar_t *)dst = val; - return length; + PrintDebug("\t\tRead DRIVE SELECT = 0x%x\n", val); + *(uchar_t *)dst = val; + return length; - break; - } - case PRI_ADDR_REG_PORT: - case SEC_ADDR_REG_PORT: // Hard Disk Address Register 0x3f7 - { - // Obsolete and unsupported register. Not driven by hard - // disk controller. Report all 1's. If floppy controller - // is handling this address, it will call this function - // set/clear D7 (the only bit it handles), then return - // the combined value - *(uchar_t *)dst = 0xff; - return length; - } + break; + } + case PRI_ADDR_REG_PORT: + case SEC_ADDR_REG_PORT: // Hard Disk Address Register 0x3f7 + { + // Obsolete and unsupported register. Not driven by hard + // disk controller. Report all 1's. If floppy controller + // is handling this address, it will call this function + // set/clear D7 (the only bit it handles), then return + // the combined value + *(uchar_t *)dst = 0xff; + return length; + } - default: - PrintError("Invalid Port: %d\n", port); - return -1; - } + default: + PrintError("Invalid Port: %d\n", port); + return -1; + } } static int write_general_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); - struct channel_t * channel = NULL; - struct drive_t * drive = NULL; - struct controller_t * controller = NULL; - uchar_t value = *(uchar_t *)src; - - if (length != 1) { - PrintError("Invalid Status port read length: %d (port=%d)\n", length, port); - return -1; - } + struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); + struct channel_t * channel = NULL; + struct drive_t * drive = NULL; + struct controller_t * controller = NULL; + uchar_t value = *(uchar_t *)src; + + if (length != 1) { + PrintError("Invalid Status port read length: %d (port=%d)\n", length, port); + return -1; + } - if (is_primary_port(ramdisk, port)) { - channel = &(ramdisk->channels[0]); - } else if (is_secondary_port(ramdisk, port)) { - channel = &(ramdisk->channels[1]); - } else { - PrintError("Invalid Port: %d\n", port); - return -1; - } + if (is_primary_port(ramdisk, port)) { + channel = &(ramdisk->channels[0]); + } else if (is_secondary_port(ramdisk, port)) { + channel = &(ramdisk->channels[1]); + } else { + PrintError("Invalid Port: %d\n", port); + return -1; + } - drive = get_selected_drive(channel); - controller = &(drive->controller); + drive = get_selected_drive(channel); + controller = &(drive->controller); - PrintDebug("[write_general_handler] IO write to port %x (val=0x%02x), channel = %d\n", - port, value, get_channel_no(ramdisk, channel)); + PrintDebug("[write_general_handler] IO write to port %x (val=0x%02x), channel = %d\n", + port, value, get_channel_no(ramdisk, channel)); - switch (port) { + switch (port) { - case PRI_FEATURES_PORT: - case SEC_FEATURES_PORT: // hard disk write precompensation 0x1f1 - { - write_features(channel, value); - break; - } - case PRI_SECT_CNT_PORT: - case SEC_SECT_CNT_PORT: // hard disk sector count 0x1f2 - { - write_sector_count(channel, value); - break; - } - case PRI_SECT_ADDR1_PORT: - case SEC_SECT_ADDR1_PORT: // hard disk sector number 0x1f3 - { - write_sector_number(channel, value); - break; - } - case PRI_SECT_ADDR2_PORT: - case SEC_SECT_ADDR2_PORT: // hard disk cylinder low 0x1f4 - { - write_cylinder_low(channel, value); - break; - } - case PRI_SECT_ADDR3_PORT: - case SEC_SECT_ADDR3_PORT: // hard disk cylinder high 0x1f5 - { - write_cylinder_high(channel, value); - break; - } - case PRI_DRV_SEL_PORT: - case SEC_DRV_SEL_PORT: // hard disk drive and head register 0x1f6 - { - // b7 Extended data field for ECC - // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128 - // Since 512 was always used, bit 6 was taken to mean LBA mode: - // b6 1=LBA mode, 0=CHS mode - // b5 1 - // b4: DRV - // b3..0 HD3..HD0 - - // 1x1xxxxx - - PrintDebug("\tDrive Select value=%x\n", value); - - if ((value & 0xa0) != 0xa0) { - PrintDebug("\t\tIO write 0x%x (%02x): not 1x1xxxxxb\n", port, (unsigned) value); - } + case PRI_FEATURES_PORT: + case SEC_FEATURES_PORT: // hard disk write precompensation 0x1f1 + { + write_features(channel, value); + break; + } + case PRI_SECT_CNT_PORT: + case SEC_SECT_CNT_PORT: // hard disk sector count 0x1f2 + { + write_sector_count(channel, value); + break; + } + case PRI_SECT_ADDR1_PORT: + case SEC_SECT_ADDR1_PORT: // hard disk sector number 0x1f3 + { + write_sector_number(channel, value); + break; + } + case PRI_SECT_ADDR2_PORT: + case SEC_SECT_ADDR2_PORT: // hard disk cylinder low 0x1f4 + { + write_cylinder_low(channel, value); + break; + } + case PRI_SECT_ADDR3_PORT: + case SEC_SECT_ADDR3_PORT: // hard disk cylinder high 0x1f5 + { + write_cylinder_high(channel, value); + break; + } + case PRI_DRV_SEL_PORT: + case SEC_DRV_SEL_PORT: // hard disk drive and head register 0x1f6 + { + // b7 Extended data field for ECC + // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128 + // Since 512 was always used, bit 6 was taken to mean LBA mode: + // b6 1=LBA mode, 0=CHS mode + // b5 1 + // b4: DRV + // b3..0 HD3..HD0 + + // 1x1xxxxx + + PrintDebug("\tDrive Select value=%x\n", value); + + if ((value & 0xa0) != 0xa0) { + PrintDebug("\t\tIO write 0x%x (%02x): not 1x1xxxxxb\n", port, (unsigned) value); + } - write_head_no(channel, value & 0xf); - if ((controller->lba_mode == 0) && (((value >> 6) & 1) == 1)) { - PrintDebug("\t\tenabling LBA mode\n"); - } + write_head_no(channel, value & 0xf); + if ((controller->lba_mode == 0) && (((value >> 6) & 1) == 1)) { + PrintDebug("\t\tenabling LBA mode\n"); + } - write_lba_mode(channel, (value >> 6) & 1); + write_lba_mode(channel, (value >> 6) & 1); - if (drive->cdrom.cd) { - PrintDebug("\t\tSetting LBA on CDROM: %d\n", (value >> 6) & 1); - drive->cdrom.cd->set_LBA(drive->private_data, (value >> 6) & 1); - } + if (drive->cdrom.cd) { + PrintDebug("\t\tSetting LBA on CDROM: %d\n", (value >> 6) & 1); + drive->cdrom.cd->set_LBA(drive->private_data, (value >> 6) & 1); + } - channel->drive_select = (value >> 4) & 0x01; - drive = get_selected_drive(channel); + channel->drive_select = (value >> 4) & 0x01; + drive = get_selected_drive(channel); - if (drive->device_type == IDE_NONE) { - PrintError("\t\tError: device set to %d which does not exist! channel = 0x%x\n", - channel->drive_select, get_channel_no(ramdisk, channel)); + if (drive->device_type == IDE_NONE) { + PrintError("\t\tError: device set to %d which does not exist! channel = 0x%x\n", + channel->drive_select, get_channel_no(ramdisk, channel)); - controller->error_register = 0x04; // aborted - controller->status.err = 1; - } + controller->error_register = 0x04; // aborted + controller->status.err = 1; + } - break; + break; + } + default: + PrintError("\t\thard drive: io write to unhandled port 0x%x (value = %c)\n", port, value); + //return -1; } - default: - PrintError("\t\thard drive: io write to unhandled port 0x%x (value = %c)\n", port, value); - //return -1; - } - return length; + return length; } @@ -1349,27 +1349,27 @@ static int write_general_port(ushort_t port, void * src, uint_t length, struct v static void rd_raise_interrupt(struct vm_device * dev, struct channel_t * channel) { - // struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); - struct drive_t * drive = get_selected_drive(channel); - struct controller_t * controller = &(drive->controller); + // struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); + struct drive_t * drive = get_selected_drive(channel); + struct controller_t * controller = &(drive->controller); - PrintDebug("[raise_interrupt] disable_irq = 0x%02x\n", controller->control.disable_irq); + PrintDebug("[raise_interrupt] disable_irq = 0x%02x\n", controller->control.disable_irq); - if (!(controller->control.disable_irq)) { + if (!(controller->control.disable_irq)) { - PrintDebug("\t\tRaising interrupt %d {%s}\n\n", channel->irq, device_type_to_str(drive->device_type)); + PrintDebug("\t\tRaising interrupt %d {%s}\n\n", channel->irq, device_type_to_str(drive->device_type)); - v3_raise_irq(dev->vm, channel->irq); - } else { - PrintDebug("\t\tRaising irq but irq is disabled\n"); - } + v3_raise_irq(dev->vm, channel->irq); + } else { + PrintDebug("\t\tRaising irq but irq is disabled\n"); + } - return; + return; } static void rd_lower_irq(struct vm_device *dev, struct channel_t * channel) { - PrintDebug("[lower_irq] irq = %d\n", channel->irq); - v3_lower_irq(dev->vm, channel->irq); + PrintDebug("[lower_irq] irq = %d\n", channel->irq); + v3_lower_irq(dev->vm, channel->irq); } @@ -1387,630 +1387,629 @@ static void rd_lower_irq(struct vm_device *dev, struct channel_t * channel) { int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * channel, ushort_t value) { - struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); - struct drive_t * drive = get_selected_drive(channel); - struct controller_t * controller = &(drive->controller); - - if (controller->buffer_index >= PACKET_SIZE) { - PrintError("ATAPI packet exceeded maximum length: buffer_index (%d) >= PACKET_SIZE\n", - controller->buffer_index); - return -1; - } + struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data); + struct drive_t * drive = get_selected_drive(channel); + struct controller_t * controller = &(drive->controller); + + if (controller->buffer_index >= PACKET_SIZE) { + PrintError("ATAPI packet exceeded maximum length: buffer_index (%d) >= PACKET_SIZE\n", + controller->buffer_index); + return -1; + } - controller->buffer[controller->buffer_index] = value; - controller->buffer[controller->buffer_index + 1] = (value >> 8); - controller->buffer_index += 2; + controller->buffer[controller->buffer_index] = value; + controller->buffer[controller->buffer_index + 1] = (value >> 8); + controller->buffer_index += 2; - /* if packet completely writtten */ - if (controller->buffer_index >= PACKET_SIZE) { - // complete command received - Bit8u atapi_command = controller->buffer[0]; + /* if packet completely writtten */ + if (controller->buffer_index >= PACKET_SIZE) { + // complete command received + Bit8u atapi_command = controller->buffer[0]; - PrintDebug("\t\tcdrom: ATAPI command 0x%x started\n", atapi_command); + PrintDebug("\t\tcdrom: ATAPI command 0x%x started\n", atapi_command); - switch (atapi_command) { - case 0x00: // test unit ready - { - PrintDebug("Testing unit ready\n"); - if (drive->cdrom.ready) { - rd_atapi_cmd_nop(dev, channel); - } else { - PrintError("CDROM not ready in test unit ready\n"); - rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); - } + switch (atapi_command) { + case 0x00: // test unit ready + { + PrintDebug("Testing unit ready\n"); + if (drive->cdrom.ready) { + rd_atapi_cmd_nop(dev, channel); + } else { + PrintError("CDROM not ready in test unit ready\n"); + rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + } - rd_raise_interrupt(dev, channel); + rd_raise_interrupt(dev, channel); - break; - } - case 0x03: // request sense - { - int alloc_length = controller->buffer[4]; - - if (rd_init_send_atapi_command(dev, channel, atapi_command, 18, alloc_length, false) == -1) { - PrintError("Error sending atapi command in Request Sense\n"); - return -1; - } + break; + } + case 0x03: // request sense + { + int alloc_length = controller->buffer[4]; + + if (rd_init_send_atapi_command(dev, channel, atapi_command, 18, alloc_length, false) == -1) { + PrintError("Error sending atapi command in Request Sense\n"); + return -1; + } - // sense data - controller->buffer[0] = 0x70 | (1 << 7); - controller->buffer[1] = 0; - controller->buffer[2] = drive->sense.sense_key; - controller->buffer[3] = drive->sense.information.arr[0]; - controller->buffer[4] = drive->sense.information.arr[1]; - controller->buffer[5] = drive->sense.information.arr[2]; - controller->buffer[6] = drive->sense.information.arr[3]; - controller->buffer[7] = 17 - 7; - controller->buffer[8] = drive->sense.specific_inf.arr[0]; - controller->buffer[9] = drive->sense.specific_inf.arr[1]; - controller->buffer[10] = drive->sense.specific_inf.arr[2]; - controller->buffer[11] = drive->sense.specific_inf.arr[3]; - controller->buffer[12] = drive->sense.asc; - controller->buffer[13] = drive->sense.ascq; - controller->buffer[14] = drive->sense.fruc; - controller->buffer[15] = drive->sense.key_spec.arr[0]; - controller->buffer[16] = drive->sense.key_spec.arr[1]; - controller->buffer[17] = drive->sense.key_spec.arr[2]; + // sense data + controller->buffer[0] = 0x70 | (1 << 7); + controller->buffer[1] = 0; + controller->buffer[2] = drive->sense.sense_key; + controller->buffer[3] = drive->sense.information.arr[0]; + controller->buffer[4] = drive->sense.information.arr[1]; + controller->buffer[5] = drive->sense.information.arr[2]; + controller->buffer[6] = drive->sense.information.arr[3]; + controller->buffer[7] = 17 - 7; + controller->buffer[8] = drive->sense.specific_inf.arr[0]; + controller->buffer[9] = drive->sense.specific_inf.arr[1]; + controller->buffer[10] = drive->sense.specific_inf.arr[2]; + controller->buffer[11] = drive->sense.specific_inf.arr[3]; + controller->buffer[12] = drive->sense.asc; + controller->buffer[13] = drive->sense.ascq; + controller->buffer[14] = drive->sense.fruc; + controller->buffer[15] = drive->sense.key_spec.arr[0]; + controller->buffer[16] = drive->sense.key_spec.arr[1]; + controller->buffer[17] = drive->sense.key_spec.arr[2]; - rd_ready_to_send_atapi(dev, channel); - break; - } - case 0x1b: // start stop unit - { - //bx_bool Immed = (controller->buffer[1] >> 0) & 1; - rd_bool LoEj = (controller->buffer[4] >> 1) & 1; - rd_bool Start = (controller->buffer[4] >> 0) & 1; + rd_ready_to_send_atapi(dev, channel); + break; + } + case 0x1b: // start stop unit + { + //bx_bool Immed = (controller->buffer[1] >> 0) & 1; + rd_bool LoEj = (controller->buffer[4] >> 1) & 1; + rd_bool Start = (controller->buffer[4] >> 0) & 1; - // stop the disc - if ((!LoEj) && (!Start)) { - PrintError("FIXME: Stop disc not implemented\n"); + // stop the disc + if ((!LoEj) && (!Start)) { + PrintError("FIXME: Stop disc not implemented\n"); - rd_atapi_cmd_nop(dev, channel); - rd_raise_interrupt(dev, channel); + rd_atapi_cmd_nop(dev, channel); + rd_raise_interrupt(dev, channel); - } else if (!LoEj && Start) { // start (spin up) the disc + } else if (!LoEj && Start) { // start (spin up) the disc - drive->cdrom.cd->start_cdrom(drive->private_data); + drive->cdrom.cd->start_cdrom(drive->private_data); - PrintError("FIXME: ATAPI start disc not reading TOC\n"); - rd_atapi_cmd_nop(dev, channel); - rd_raise_interrupt(dev, channel); - - } else if (LoEj && !Start) { // Eject the disc - rd_atapi_cmd_nop(dev, channel); - PrintDebug("Ejecting Disk\n"); - if (drive->cdrom.ready) { + PrintError("FIXME: ATAPI start disc not reading TOC\n"); + rd_atapi_cmd_nop(dev, channel); + rd_raise_interrupt(dev, channel); + + } else if (LoEj && !Start) { // Eject the disc + rd_atapi_cmd_nop(dev, channel); + PrintDebug("Ejecting Disk\n"); + if (drive->cdrom.ready) { - drive->cdrom.cd->eject_cdrom(drive->private_data); + drive->cdrom.cd->eject_cdrom(drive->private_data); - drive->cdrom.ready = 0; - //bx_options.atadevice[channel][SLAVE_SELECTED(channel)].Ostatus->set(EJECTED); - //bx_gui->update_drive_status_buttons(); - } - rd_raise_interrupt(dev, channel); - - } else { // Load the disc - // My guess is that this command only closes the tray, that's a no-op for us - rd_atapi_cmd_nop(dev, channel); - rd_raise_interrupt(dev, channel); - } - break; - } - case 0xbd: // mechanism status - { - uint16_t alloc_length = rd_read_16bit(controller->buffer + 8); + drive->cdrom.ready = 0; + //bx_options.atadevice[channel][SLAVE_SELECTED(channel)].Ostatus->set(EJECTED); + //bx_gui->update_drive_status_buttons(); + } + rd_raise_interrupt(dev, channel); + + } else { // Load the disc + // My guess is that this command only closes the tray, that's a no-op for us + rd_atapi_cmd_nop(dev, channel); + rd_raise_interrupt(dev, channel); + } + break; + } + case 0xbd: // mechanism status + { + uint16_t alloc_length = rd_read_16bit(controller->buffer + 8); - if (alloc_length == 0) { - PrintError("Zero allocation length to MECHANISM STATUS not impl.\n"); - return -1; - } + if (alloc_length == 0) { + PrintError("Zero allocation length to MECHANISM STATUS not impl.\n"); + return -1; + } - if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, alloc_length, false) == -1) { - PrintError("Error sending atapi command in mechanism status\n"); - return -1; - } + if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, alloc_length, false) == -1) { + PrintError("Error sending atapi command in mechanism status\n"); + return -1; + } - controller->buffer[0] = 0; // reserved for non changers - controller->buffer[1] = 0; // reserved for non changers + controller->buffer[0] = 0; // reserved for non changers + controller->buffer[1] = 0; // reserved for non changers - controller->buffer[2] = 0; // Current LBA (TODO!) - controller->buffer[3] = 0; // Current LBA (TODO!) - controller->buffer[4] = 0; // Current LBA (TODO!) + controller->buffer[2] = 0; // Current LBA (TODO!) + controller->buffer[3] = 0; // Current LBA (TODO!) + controller->buffer[4] = 0; // Current LBA (TODO!) - controller->buffer[5] = 1; // one slot + controller->buffer[5] = 1; // one slot - controller->buffer[6] = 0; // slot table length - controller->buffer[7] = 0; // slot table length + controller->buffer[6] = 0; // slot table length + controller->buffer[7] = 0; // slot table length - rd_ready_to_send_atapi(dev, channel); - break; - } - case 0x5a: // mode sense - { - uint16_t alloc_length = rd_read_16bit(controller->buffer + 7); + rd_ready_to_send_atapi(dev, channel); + break; + } + case 0x5a: // mode sense + { + uint16_t alloc_length = rd_read_16bit(controller->buffer + 7); - Bit8u PC = controller->buffer[2] >> 6; - Bit8u PageCode = controller->buffer[2] & 0x3f; + Bit8u PC = controller->buffer[2] >> 6; + Bit8u PageCode = controller->buffer[2] & 0x3f; - switch (PC) { - case 0x0: // current values - { - switch (PageCode) { - case 0x01: // error recovery - { + switch (PC) { + case 0x0: // current values + { + switch (PageCode) { + case 0x01: // error recovery + { - if (rd_init_send_atapi_command(dev, channel, atapi_command, sizeof(struct error_recovery_t) + 8, alloc_length, false) == -1) { - PrintError("Error sending atapi command in mode sense error recovery\n"); - return -1; - } + if (rd_init_send_atapi_command(dev, channel, atapi_command, sizeof(struct error_recovery_t) + 8, alloc_length, false) == -1) { + PrintError("Error sending atapi command in mode sense error recovery\n"); + return -1; + } - rd_init_mode_sense_single(dev, channel, &(drive->cdrom.current.error_recovery), - sizeof(struct error_recovery_t)); - rd_ready_to_send_atapi(dev, channel); - break; - } - case 0x2a: // CD-ROM capabilities & mech. status - { - - if (rd_init_send_atapi_command(dev, channel, atapi_command, 28, alloc_length, false) == -1) { - PrintError("Error sending atapi command in CDROM caps/mech mode-sense\n"); - return -1; - } - - rd_init_mode_sense_single(dev, channel, &(controller->buffer[8]), 28); + rd_init_mode_sense_single(dev, channel, &(drive->cdrom.current.error_recovery), + sizeof(struct error_recovery_t)); + rd_ready_to_send_atapi(dev, channel); + break; + } + case 0x2a: // CD-ROM capabilities & mech. status + { + + if (rd_init_send_atapi_command(dev, channel, atapi_command, 28, alloc_length, false) == -1) { + PrintError("Error sending atapi command in CDROM caps/mech mode-sense\n"); + return -1; + } + + rd_init_mode_sense_single(dev, channel, &(controller->buffer[8]), 28); - controller->buffer[8] = 0x2a; - controller->buffer[9] = 0x12; - controller->buffer[10] = 0x00; - controller->buffer[11] = 0x00; - // Multisession, Mode 2 Form 2, Mode 2 Form 1 - controller->buffer[12] = 0x70; - controller->buffer[13] = (3 << 5); - controller->buffer[14] = (unsigned char) (1 | - (drive->cdrom.locked ? (1 << 1) : 0) | - (1 << 3) | - (1 << 5)); - controller->buffer[15] = 0x00; - controller->buffer[16] = (706 >> 8) & 0xff; - controller->buffer[17] = 706 & 0xff; - controller->buffer[18] = 0; - controller->buffer[19] = 2; - controller->buffer[20] = (512 >> 8) & 0xff; - controller->buffer[21] = 512 & 0xff; - controller->buffer[22] = (706 >> 8) & 0xff; - controller->buffer[23] = 706 & 0xff; - controller->buffer[24] = 0; - controller->buffer[25] = 0; - controller->buffer[26] = 0; - controller->buffer[27] = 0; - rd_ready_to_send_atapi(dev, channel); - break; - } - case 0x0d: // CD-ROM - case 0x0e: // CD-ROM audio control - case 0x3f: // all - { - PrintError("Ramdisk: cdrom: MODE SENSE (curr), code=%x not implemented yet\n", - PageCode); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - rd_raise_interrupt(dev, channel); - break; - } - default: - { - // not implemeted by this device - PrintError("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n", - PC, PageCode); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - rd_raise_interrupt(dev, channel); - break; - } - } - break; - } - case 0x1: // changeable values - { - switch (PageCode) { - case 0x01: // error recovery - case 0x0d: // CD-ROM - case 0x0e: // CD-ROM audio control - case 0x2a: // CD-ROM capabilities & mech. status - case 0x3f: // all - { - PrintError("cdrom: MODE SENSE (chg), code=%x not implemented yet\n", - PageCode); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - rd_raise_interrupt(dev, channel); - break; - } - default: - { - // not implemeted by this device - PrintError("Changeable values of mode sense not supported by cdrom\n"); - PrintDebug("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n", - PC, PageCode); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - rd_raise_interrupt(dev, channel); - break; - } - } - break; - } - case 0x2: // default values - { - switch (PageCode) { - case 0x01: // error recovery - case 0x0d: // CD-ROM - case 0x0e: // CD-ROM audio control - case 0x2a: // CD-ROM capabilities & mech. status - case 0x3f: // all - PrintError("Default values of mode sense not supported by cdrom\n"); - PrintDebug("cdrom: MODE SENSE (dflt), code=%x\n", - PageCode); - return -1; + controller->buffer[8] = 0x2a; + controller->buffer[9] = 0x12; + controller->buffer[10] = 0x00; + controller->buffer[11] = 0x00; + // Multisession, Mode 2 Form 2, Mode 2 Form 1 + controller->buffer[12] = 0x70; + controller->buffer[13] = (3 << 5); + controller->buffer[14] = (unsigned char) (1 | + (drive->cdrom.locked ? (1 << 1) : 0) | + (1 << 3) | + (1 << 5)); + controller->buffer[15] = 0x00; + controller->buffer[16] = (706 >> 8) & 0xff; + controller->buffer[17] = 706 & 0xff; + controller->buffer[18] = 0; + controller->buffer[19] = 2; + controller->buffer[20] = (512 >> 8) & 0xff; + controller->buffer[21] = 512 & 0xff; + controller->buffer[22] = (706 >> 8) & 0xff; + controller->buffer[23] = 706 & 0xff; + controller->buffer[24] = 0; + controller->buffer[25] = 0; + controller->buffer[26] = 0; + controller->buffer[27] = 0; + rd_ready_to_send_atapi(dev, channel); + break; + } + case 0x0d: // CD-ROM + case 0x0e: // CD-ROM audio control + case 0x3f: // all + { + PrintError("Ramdisk: cdrom: MODE SENSE (curr), code=%x not implemented yet\n", + PageCode); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, + ASC_INV_FIELD_IN_CMD_PACKET); + rd_raise_interrupt(dev, channel); + break; + } + default: + { + // not implemeted by this device + PrintError("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n", + PC, PageCode); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, + ASC_INV_FIELD_IN_CMD_PACKET); + rd_raise_interrupt(dev, channel); + break; + } + } + break; + } + case 0x1: // changeable values + { + switch (PageCode) { + case 0x01: // error recovery + case 0x0d: // CD-ROM + case 0x0e: // CD-ROM audio control + case 0x2a: // CD-ROM capabilities & mech. status + case 0x3f: // all + { + PrintError("cdrom: MODE SENSE (chg), code=%x not implemented yet\n", + PageCode); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, + ASC_INV_FIELD_IN_CMD_PACKET); + rd_raise_interrupt(dev, channel); + break; + } + default: + { + // not implemeted by this device + PrintError("Changeable values of mode sense not supported by cdrom\n"); + PrintDebug("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n", + PC, PageCode); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, + ASC_INV_FIELD_IN_CMD_PACKET); + rd_raise_interrupt(dev, channel); + break; + } + } + break; + } + case 0x2: // default values + { + switch (PageCode) { + case 0x01: // error recovery + case 0x0d: // CD-ROM + case 0x0e: // CD-ROM audio control + case 0x2a: // CD-ROM capabilities & mech. status + case 0x3f: // all + PrintError("Default values of mode sense not supported by cdrom\n"); + PrintDebug("cdrom: MODE SENSE (dflt), code=%x\n", + PageCode); + return -1; - default: - { - PrintError("Default values of mode sense not implemented in cdrom\n"); - // not implemeted by this device - PrintDebug("cdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n", - PC, PageCode); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - rd_raise_interrupt(dev, channel); - break; - } - } - break; - } - case 0x3: // saved values not implemented - { - PrintError("\t\tSaved values not implemented in mode sense\n"); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED); - rd_raise_interrupt(dev, channel); - break; - } - default: - { - PrintError("Unsupported Mode sense value\n"); - return -1; - break; - } - } - break; - } - case 0x12: // inquiry - { - uint8_t alloc_length = controller->buffer[4]; + default: + { + PrintError("Default values of mode sense not implemented in cdrom\n"); + // not implemeted by this device + PrintDebug("cdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n", + PC, PageCode); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, + ASC_INV_FIELD_IN_CMD_PACKET); + rd_raise_interrupt(dev, channel); + break; + } + } + break; + } + case 0x3: // saved values not implemented + { + PrintError("\t\tSaved values not implemented in mode sense\n"); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED); + rd_raise_interrupt(dev, channel); + break; + } + default: + { + PrintError("Unsupported Mode sense value\n"); + return -1; + break; + } + } + break; + } + case 0x12: // inquiry + { + uint8_t alloc_length = controller->buffer[4]; - if (rd_init_send_atapi_command(dev, channel, atapi_command, 36, alloc_length, false) == -1) { - PrintError("Error sending atapi command in inquiry\n"); - return -1; - } + if (rd_init_send_atapi_command(dev, channel, atapi_command, 36, alloc_length, false) == -1) { + PrintError("Error sending atapi command in inquiry\n"); + return -1; + } - controller->buffer[0] = 0x05; // CD-ROM - controller->buffer[1] = 0x80; // Removable - controller->buffer[2] = 0x00; // ISO, ECMA, ANSI version - controller->buffer[3] = 0x21; // ATAPI-2, as specified - controller->buffer[4] = 31; // additional length (total 36) - controller->buffer[5] = 0x00; // reserved - controller->buffer[6] = 0x00; // reserved - controller->buffer[7] = 0x00; // reserved + controller->buffer[0] = 0x05; // CD-ROM + controller->buffer[1] = 0x80; // Removable + controller->buffer[2] = 0x00; // ISO, ECMA, ANSI version + controller->buffer[3] = 0x21; // ATAPI-2, as specified + controller->buffer[4] = 31; // additional length (total 36) + controller->buffer[5] = 0x00; // reserved + controller->buffer[6] = 0x00; // reserved + controller->buffer[7] = 0x00; // reserved - // Vendor ID - const char* vendor_id = "VTAB "; - int i; - for (i = 0; i < 8; i++) { - controller->buffer[8+i] = vendor_id[i]; - } - - // Product ID - const char* product_id = "Turbo CD-ROM "; - for (i = 0; i < 16; i++) { - controller->buffer[16+i] = product_id[i]; - } - - // Product Revision level - const char* rev_level = "1.0 "; - for (i = 0; i < 4; i++) { - controller->buffer[32 + i] = rev_level[i]; - } - - rd_ready_to_send_atapi(dev, channel); - break; - } - case 0x25: // read cd-rom capacity - { - // no allocation length??? - if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, 8, false) == -1) { - PrintError("Error sending atapi command in read cdrom capacity\n"); - return -1; - } + // Vendor ID + const char* vendor_id = "VTAB "; + int i; + for (i = 0; i < 8; i++) { + controller->buffer[8+i] = vendor_id[i]; + } + + // Product ID + const char* product_id = "Turbo CD-ROM "; + for (i = 0; i < 16; i++) { + controller->buffer[16+i] = product_id[i]; + } + + // Product Revision level + const char* rev_level = "1.0 "; + for (i = 0; i < 4; i++) { + controller->buffer[32 + i] = rev_level[i]; + } + + rd_ready_to_send_atapi(dev, channel); + break; + } + case 0x25: // read cd-rom capacity + { + // no allocation length??? + if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, 8, false) == -1) { + PrintError("Error sending atapi command in read cdrom capacity\n"); + return -1; + } - if (drive->cdrom.ready) { - uint32_t capacity = drive->cdrom.capacity; - - PrintDebug("\t\tCapacity is %d sectors (%d bytes)\n", capacity, capacity * 2048); - - controller->buffer[0] = (capacity >> 24) & 0xff; - controller->buffer[1] = (capacity >> 16) & 0xff; - controller->buffer[2] = (capacity >> 8) & 0xff; - controller->buffer[3] = (capacity >> 0) & 0xff; - controller->buffer[4] = (2048 >> 24) & 0xff; - controller->buffer[5] = (2048 >> 16) & 0xff; - controller->buffer[6] = (2048 >> 8) & 0xff; - controller->buffer[7] = (2048 >> 0) & 0xff; - - rd_ready_to_send_atapi(dev, channel); - } else { - PrintError("CDROM not ready in read cdrom capacity\n"); - rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); - rd_raise_interrupt(dev, channel); - } - break; - } + if (drive->cdrom.ready) { + uint32_t capacity = drive->cdrom.capacity; + + PrintDebug("\t\tCapacity is %d sectors (%d bytes)\n", capacity, capacity * 2048); + + controller->buffer[0] = (capacity >> 24) & 0xff; + controller->buffer[1] = (capacity >> 16) & 0xff; + controller->buffer[2] = (capacity >> 8) & 0xff; + controller->buffer[3] = (capacity >> 0) & 0xff; + controller->buffer[4] = (2048 >> 24) & 0xff; + controller->buffer[5] = (2048 >> 16) & 0xff; + controller->buffer[6] = (2048 >> 8) & 0xff; + controller->buffer[7] = (2048 >> 0) & 0xff; + + rd_ready_to_send_atapi(dev, channel); + } else { + PrintError("CDROM not ready in read cdrom capacity\n"); + rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + rd_raise_interrupt(dev, channel); + } + break; + } - case 0xbe: // read cd - { - if (drive->cdrom.ready) { - PrintError("Read CD with CD present not implemented\n"); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); - rd_raise_interrupt(dev, channel); - } else { - PrintError("Drive not ready in read cd with CD present\n"); - rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); - rd_raise_interrupt(dev, channel); - } - break; - } - case 0x43: // read toc - { - if (drive->cdrom.ready) { - int toc_length = 0; - bool msf = (controller->buffer[1] >> 1) & 1; - uint8_t starting_track = controller->buffer[6]; + case 0xbe: // read cd + { + if (drive->cdrom.ready) { + PrintError("Read CD with CD present not implemented\n"); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); + rd_raise_interrupt(dev, channel); + } else { + PrintError("Drive not ready in read cd with CD present\n"); + rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + rd_raise_interrupt(dev, channel); + } + break; + } + case 0x43: // read toc + { + if (drive->cdrom.ready) { + int toc_length = 0; + bool msf = (controller->buffer[1] >> 1) & 1; + uint8_t starting_track = controller->buffer[6]; - uint16_t alloc_length = rd_read_16bit(controller->buffer + 7); + uint16_t alloc_length = rd_read_16bit(controller->buffer + 7); - uint8_t format = (controller->buffer[9] >> 6); - int i; - - PrintDebug("Reading CDROM TOC: Format=%d (byte count=%d) (toc length:%d)\n", - format, controller->byte_count, toc_length); - - switch (format) { - case 0: - { - if (!(drive->cdrom.cd->read_toc(drive->private_data, controller->buffer, - &toc_length, msf, starting_track))) { - PrintError("CDROM: Reading Table of Contents Failed\n"); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - rd_raise_interrupt(dev, channel); - break; - } + uint8_t format = (controller->buffer[9] >> 6); + int i; + + PrintDebug("Reading CDROM TOC: Format=%d (byte count=%d) (toc length:%d)\n", + format, controller->byte_count, toc_length); + + switch (format) { + case 0: + if (!(drive->cdrom.cd->read_toc(drive->private_data, controller->buffer, + &toc_length, msf, starting_track))) { + PrintError("CDROM: Reading Table of Contents Failed\n"); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, + ASC_INV_FIELD_IN_CMD_PACKET); + rd_raise_interrupt(dev, channel); + break; + } - if (rd_init_send_atapi_command(dev, channel, atapi_command, toc_length, alloc_length, false) == -1) { - PrintError("Failed to init send atapi command in read toc (fmt=%d)\n", format); - return -1; - } + if (rd_init_send_atapi_command(dev, channel, atapi_command, toc_length, alloc_length, false) == -1) { + PrintError("Failed to init send atapi command in read toc (fmt=%d)\n", format); + return -1; + } - rd_ready_to_send_atapi(dev, channel); + rd_ready_to_send_atapi(dev, channel); - break; - } - case 1: - // multi session stuff. we ignore this and emulate a single session only + break; - if (rd_init_send_atapi_command(dev, channel, atapi_command, 12, alloc_length, false) == -1) { - PrintError("Failed to init send atapi command in read toc (fmt=%d)\n", format); - return -1; - } + case 1: + // multi session stuff. we ignore this and emulate a single session only + + if (rd_init_send_atapi_command(dev, channel, atapi_command, 12, alloc_length, false) == -1) { + PrintError("Failed to init send atapi command in read toc (fmt=%d)\n", format); + return -1; + } - controller->buffer[0] = 0; - controller->buffer[1] = 0x0a; - controller->buffer[2] = 1; - controller->buffer[3] = 1; + controller->buffer[0] = 0; + controller->buffer[1] = 0x0a; + controller->buffer[2] = 1; + controller->buffer[3] = 1; - for (i = 0; i < 8; i++) { - controller->buffer[4 + i] = 0; - } + for (i = 0; i < 8; i++) { + controller->buffer[4 + i] = 0; + } - rd_ready_to_send_atapi(dev, channel); - break; + rd_ready_to_send_atapi(dev, channel); + break; - case 2: - default: - PrintError("(READ TOC) Format %d not supported\n", format); - return -1; - } - } else { - PrintError("CDROM not ready in read toc\n"); - rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); - rd_raise_interrupt(dev, channel); - } - break; - } - case 0x28: // read (10) - case 0xa8: // read (12) - { + case 2: + default: + PrintError("(READ TOC) Format %d not supported\n", format); + return -1; + } + } else { + PrintError("CDROM not ready in read toc\n"); + rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + rd_raise_interrupt(dev, channel); + } + break; + } + case 0x28: // read (10) + case 0xa8: // read (12) + { - uint32_t transfer_length; - if (atapi_command == 0x28) { - transfer_length = rd_read_16bit(controller->buffer + 7); - } else { - transfer_length = rd_read_32bit(controller->buffer + 6); - } - - uint32_t lba = rd_read_32bit(controller->buffer + 2); + uint32_t transfer_length; + if (atapi_command == 0x28) { + transfer_length = rd_read_16bit(controller->buffer + 7); + } else { + transfer_length = rd_read_32bit(controller->buffer + 6); + } + + uint32_t lba = rd_read_32bit(controller->buffer + 2); - if (!(drive->cdrom.ready)) { - PrintError("CDROM Error: Not Ready (ATA%d/%d)\n", - get_channel_no(ramdisk, channel), get_drive_no(channel, drive)); - rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); - rd_raise_interrupt(dev, channel); - break; - } + if (!(drive->cdrom.ready)) { + PrintError("CDROM Error: Not Ready (ATA%d/%d)\n", + get_channel_no(ramdisk, channel), get_drive_no(channel, drive)); + rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + rd_raise_interrupt(dev, channel); + break; + } - if (transfer_length == 0) { - PrintError("READ(%d) with transfer length 0, ok\n", - (atapi_command == 0x28) ? 10 : 12); - rd_atapi_cmd_nop(dev, channel); - rd_raise_interrupt(dev, channel); - break; - } + if (transfer_length == 0) { + PrintError("READ(%d) with transfer length 0, ok\n", + (atapi_command == 0x28) ? 10 : 12); + rd_atapi_cmd_nop(dev, channel); + rd_raise_interrupt(dev, channel); + break; + } - if (lba + transfer_length > drive->cdrom.capacity) { - PrintError("CDROM Error: Capacity exceeded [capacity=%d] (ATA%d/%d)\n", - drive->cdrom.capacity, - get_channel_no(ramdisk, channel), get_drive_no(channel, drive)); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR); - rd_raise_interrupt(dev, channel); - break; - } + if (lba + transfer_length > drive->cdrom.capacity) { + PrintError("CDROM Error: Capacity exceeded [capacity=%d] (ATA%d/%d)\n", + drive->cdrom.capacity, + get_channel_no(ramdisk, channel), get_drive_no(channel, drive)); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR); + rd_raise_interrupt(dev, channel); + break; + } - PrintDebug("\t\tcdrom: READ (%d) LBA=%d LEN=%d\n", - (atapi_command == 0x28) ? 10 : 12, - lba, transfer_length); + PrintDebug("\t\tcdrom: READ (%d) LBA=%d LEN=%d\n", + (atapi_command == 0x28) ? 10 : 12, + lba, transfer_length); - // handle command - if (rd_init_send_atapi_command(dev, channel, atapi_command, transfer_length * 2048, - transfer_length * 2048, true) == -1) { - PrintError("CDROM Error: Atapi command send error\n"); - return -1; - } - - drive->cdrom.remaining_blocks = transfer_length; - drive->cdrom.next_lba = lba; - rd_ready_to_send_atapi(dev, channel); - break; - } - case 0x2b: // seek - { - uint32_t lba = rd_read_32bit(controller->buffer + 2); - - if (!(drive->cdrom.ready)) { - PrintError("CDROM not ready in seek\n"); - rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); - rd_raise_interrupt(dev, channel); - break; - } + // handle command + if (rd_init_send_atapi_command(dev, channel, atapi_command, transfer_length * 2048, + transfer_length * 2048, true) == -1) { + PrintError("CDROM Error: Atapi command send error\n"); + return -1; + } + + drive->cdrom.remaining_blocks = transfer_length; + drive->cdrom.next_lba = lba; + rd_ready_to_send_atapi(dev, channel); + break; + } + case 0x2b: // seek + { + uint32_t lba = rd_read_32bit(controller->buffer + 2); + + if (!(drive->cdrom.ready)) { + PrintError("CDROM not ready in seek\n"); + rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + rd_raise_interrupt(dev, channel); + break; + } - if (lba > drive->cdrom.capacity) { - PrintError("LBA is greater than CDROM capacity in seek\n"); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR); - rd_raise_interrupt(dev, channel); - break; - } + if (lba > drive->cdrom.capacity) { + PrintError("LBA is greater than CDROM capacity in seek\n"); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR); + rd_raise_interrupt(dev, channel); + break; + } - PrintError("\t\tcdrom: SEEK (ignored)\n"); + PrintError("\t\tcdrom: SEEK (ignored)\n"); - rd_atapi_cmd_nop(dev, channel); - rd_raise_interrupt(dev, channel); + rd_atapi_cmd_nop(dev, channel); + rd_raise_interrupt(dev, channel); - break; - } - case 0x1e: // prevent/allow medium removal - { - - if (drive->cdrom.ready) { - drive->cdrom.locked = controller->buffer[4] & 1; - rd_atapi_cmd_nop(dev, channel); - } else { - PrintError("CD not ready in prevent/allow medium removal\n"); - rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); - } + break; + } + case 0x1e: // prevent/allow medium removal + { - rd_raise_interrupt(dev, channel); + if (drive->cdrom.ready) { + drive->cdrom.locked = controller->buffer[4] & 1; + rd_atapi_cmd_nop(dev, channel); + } else { + PrintError("CD not ready in prevent/allow medium removal\n"); + rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + } - break; - } - case 0x42: // read sub-channel - { - //bool msf = get_packet_field(channel,1, 1, 1); - bool sub_q = get_packet_field(channel,2, 6, 1); - //uint8_t data_format = get_packet_byte(channel,3); - //uint8_t track_number = get_packet_byte(channel,6); - uint16_t alloc_length = get_packet_word(channel,7); + rd_raise_interrupt(dev, channel); + + break; + } + case 0x42: // read sub-channel + { + //bool msf = get_packet_field(channel,1, 1, 1); + bool sub_q = get_packet_field(channel,2, 6, 1); + //uint8_t data_format = get_packet_byte(channel,3); + //uint8_t track_number = get_packet_byte(channel,6); + uint16_t alloc_length = get_packet_word(channel,7); - /* - UNUSED(msf); - UNUSED(data_format); - UNUSED(track_number); - */ - if (!(drive->cdrom.ready)) { - PrintError("CDROM not ready in read sub-channel\n"); - rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); - rd_raise_interrupt(dev, channel); - } else { - controller->buffer[0] = 0; - controller->buffer[1] = 0; // audio not supported - controller->buffer[2] = 0; - controller->buffer[3] = 0; + /* + UNUSED(msf); + UNUSED(data_format); + UNUSED(track_number); + */ + if (!(drive->cdrom.ready)) { + PrintError("CDROM not ready in read sub-channel\n"); + rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + rd_raise_interrupt(dev, channel); + } else { + controller->buffer[0] = 0; + controller->buffer[1] = 0; // audio not supported + controller->buffer[2] = 0; + controller->buffer[3] = 0; - int ret_len = 4; // header size + int ret_len = 4; // header size - if (sub_q) { // !sub_q == header only - PrintError("Read sub-channel with SubQ not implemented\n"); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - rd_raise_interrupt(dev, channel); - } + if (sub_q) { // !sub_q == header only + PrintError("Read sub-channel with SubQ not implemented\n"); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, + ASC_INV_FIELD_IN_CMD_PACKET); + rd_raise_interrupt(dev, channel); + } - if (rd_init_send_atapi_command(dev, channel, atapi_command, ret_len, alloc_length, false) == -1) { - PrintError("Error sending atapi command in read sub-channel\n"); - return -1; - } - rd_ready_to_send_atapi(dev, channel); + if (rd_init_send_atapi_command(dev, channel, atapi_command, ret_len, alloc_length, false) == -1) { + PrintError("Error sending atapi command in read sub-channel\n"); + return -1; + } + rd_ready_to_send_atapi(dev, channel); + } + break; + } + case 0x51: // read disc info + { + // no-op to keep the Linux CD-ROM driver happy + PrintError("Error: Read disk info no-op to keep the Linux CD-ROM driver happy\n"); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); + rd_raise_interrupt(dev, channel); + break; + } + case 0x55: // mode select + case 0xa6: // load/unload cd + case 0x4b: // pause/resume + case 0x45: // play audio + case 0x47: // play audio msf + case 0xbc: // play cd + case 0xb9: // read cd msf + case 0x44: // read header + case 0xba: // scan + case 0xbb: // set cd speed + case 0x4e: // stop play/scan + case 0x46: // ??? + case 0x4a: // ??? + PrintError("ATAPI command 0x%x not implemented yet\n", + atapi_command); + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); + rd_raise_interrupt(dev, channel); + break; + default: + PrintError("Unknown ATAPI command 0x%x (%d)\n", + atapi_command, atapi_command); + // We'd better signal the error if the user chose to continue + rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); + rd_raise_interrupt(dev, channel); + break; } - break; - } - case 0x51: // read disc info - { - // no-op to keep the Linux CD-ROM driver happy - PrintError("Error: Read disk info no-op to keep the Linux CD-ROM driver happy\n"); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); - rd_raise_interrupt(dev, channel); - break; - } - case 0x55: // mode select - case 0xa6: // load/unload cd - case 0x4b: // pause/resume - case 0x45: // play audio - case 0x47: // play audio msf - case 0xbc: // play cd - case 0xb9: // read cd msf - case 0x44: // read header - case 0xba: // scan - case 0xbb: // set cd speed - case 0x4e: // stop play/scan - case 0x46: // ??? - case 0x4a: // ??? - PrintError("ATAPI command 0x%x not implemented yet\n", - atapi_command); - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); - rd_raise_interrupt(dev, channel); - break; - default: - PrintError("Unknown ATAPI command 0x%x (%d)\n", - atapi_command, atapi_command); - // We'd better signal the error if the user chose to continue - rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); - rd_raise_interrupt(dev, channel); - break; } - } - return 0; + return 0; } @@ -2018,85 +2017,85 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann int rd_init_send_atapi_command(struct vm_device * dev, struct channel_t * channel, Bit8u command, int req_length, int alloc_length, bool lazy) { - struct drive_t * drive = &(channel->drives[channel->drive_select]); - struct controller_t * controller = &(drive->controller); + struct drive_t * drive = &(channel->drives[channel->drive_select]); + struct controller_t * controller = &(drive->controller); - // controller->byte_count is a union of controller->cylinder_no; - // lazy is used to force a data read in the buffer at the next read. + // controller->byte_count is a union of controller->cylinder_no; + // lazy is used to force a data read in the buffer at the next read. - PrintDebug("[rd_init_send_atapi_cmd]\n"); + PrintDebug("[rd_init_send_atapi_cmd]\n"); - if (controller->byte_count == 0xffff) { - controller->byte_count = 0xfffe; - } + if (controller->byte_count == 0xffff) { + controller->byte_count = 0xfffe; + } - if ((controller->byte_count & 1) && - !(alloc_length <= controller->byte_count)) { + if ((controller->byte_count & 1) && + !(alloc_length <= controller->byte_count)) { - PrintDebug("\t\tOdd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%x\n", - controller->byte_count, - command, - controller->byte_count - 1); + PrintDebug("\t\tOdd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%x\n", + controller->byte_count, + command, + controller->byte_count - 1); - controller->byte_count -= 1; - } + controller->byte_count -= 1; + } - if (controller->byte_count == 0) { - PrintError("\t\tATAPI command with zero byte count\n"); - return -1; - } + if (controller->byte_count == 0) { + PrintError("\t\tATAPI command with zero byte count\n"); + return -1; + } - if (alloc_length < 0) { - PrintError("\t\tAllocation length < 0\n"); - return -1; - } + if (alloc_length < 0) { + PrintError("\t\tAllocation length < 0\n"); + return -1; + } - if (alloc_length == 0) { - alloc_length = controller->byte_count; - } + if (alloc_length == 0) { + alloc_length = controller->byte_count; + } - controller->interrupt_reason.i_o = 1; - controller->interrupt_reason.c_d = 0; - controller->status.busy = 0; - controller->status.drq = 1; - controller->status.err = 0; + controller->interrupt_reason.i_o = 1; + controller->interrupt_reason.c_d = 0; + controller->status.busy = 0; + controller->status.drq = 1; + controller->status.err = 0; - // no bytes transfered yet - if (lazy) { - controller->buffer_index = 2048; - } else { - controller->buffer_index = 0; - } + // no bytes transfered yet + if (lazy) { + controller->buffer_index = 2048; + } else { + controller->buffer_index = 0; + } - controller->drq_index = 0; + controller->drq_index = 0; - if (controller->byte_count > req_length) { - controller->byte_count = req_length; - } + if (controller->byte_count > req_length) { + controller->byte_count = req_length; + } - if (controller->byte_count > alloc_length) { - controller->byte_count = alloc_length; - } + if (controller->byte_count > alloc_length) { + controller->byte_count = alloc_length; + } - drive->atapi.command = command; - drive->atapi.drq_bytes = controller->byte_count; - drive->atapi.total_bytes_remaining = (req_length < alloc_length) ? req_length : alloc_length; + drive->atapi.command = command; + drive->atapi.drq_bytes = controller->byte_count; + drive->atapi.total_bytes_remaining = (req_length < alloc_length) ? req_length : alloc_length; - // if (lazy) { - // // bias drq_bytes and total_bytes_remaining - // SELECTED_DRIVE(channel).atapi.drq_bytes += 2048; - // SELECTED_DRIVE(channel).atapi.total_bytes_remaining += 2048; - // } + // if (lazy) { + // // bias drq_bytes and total_bytes_remaining + // SELECTED_DRIVE(channel).atapi.drq_bytes += 2048; + // SELECTED_DRIVE(channel).atapi.total_bytes_remaining += 2048; + // } - return 0; + return 0; } void rd_ready_to_send_atapi(struct vm_device * dev, struct channel_t * channel) { - PrintDebug("[rd_ready_to_send_atapi]\n"); + PrintDebug("[rd_ready_to_send_atapi]\n"); - rd_raise_interrupt(dev, channel); + rd_raise_interrupt(dev, channel); } @@ -2105,46 +2104,46 @@ void rd_ready_to_send_atapi(struct vm_device * dev, struct channel_t * channel) void rd_atapi_cmd_error(struct vm_device * dev, struct channel_t * channel, sense_t sense_key, asc_t asc) { - struct drive_t * drive = &(channel->drives[channel->drive_select]); - struct controller_t * controller = &(drive->controller); + struct drive_t * drive = &(channel->drives[channel->drive_select]); + struct controller_t * controller = &(drive->controller); - struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data); - PrintError("[rd_atapi_cmd_error]\n"); - PrintError("Error: atapi_cmd_error channel=%02x key=%02x asc=%02x\n", - get_channel_no(ramdisk, channel), sense_key, asc); + struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data); + PrintError("[rd_atapi_cmd_error]\n"); + PrintError("Error: atapi_cmd_error channel=%02x key=%02x asc=%02x\n", + get_channel_no(ramdisk, channel), sense_key, asc); - controller->error_register = sense_key << 4; - controller->interrupt_reason.i_o = 1; - controller->interrupt_reason.c_d = 1; - controller->interrupt_reason.rel = 0; - controller->status.busy = 0; - controller->status.drive_ready = 1; - controller->status.write_fault = 0; - controller->status.drq = 0; - controller->status.err = 1; + controller->error_register = sense_key << 4; + controller->interrupt_reason.i_o = 1; + controller->interrupt_reason.c_d = 1; + controller->interrupt_reason.rel = 0; + controller->status.busy = 0; + controller->status.drive_ready = 1; + controller->status.write_fault = 0; + controller->status.drq = 0; + controller->status.err = 1; - drive->sense.sense_key = sense_key; - drive->sense.asc = asc; - drive->sense.ascq = 0; + drive->sense.sense_key = sense_key; + drive->sense.asc = asc; + drive->sense.ascq = 0; } void rd_atapi_cmd_nop(struct vm_device * dev, struct channel_t * channel) { - struct drive_t * drive = &(channel->drives[channel->drive_select]); - struct controller_t * controller = &(drive->controller); - - PrintDebug("[rd_atapi_cmd_nop]\n"); - controller->interrupt_reason.i_o = 1; - controller->interrupt_reason.c_d = 1; - controller->interrupt_reason.rel = 0; - controller->status.busy = 0; - controller->status.drive_ready = 1; - controller->status.drq = 0; - controller->status.err = 0; + struct drive_t * drive = &(channel->drives[channel->drive_select]); + struct controller_t * controller = &(drive->controller); + + PrintDebug("[rd_atapi_cmd_nop]\n"); + controller->interrupt_reason.i_o = 1; + controller->interrupt_reason.c_d = 1; + controller->interrupt_reason.rel = 0; + controller->status.busy = 0; + controller->status.drive_ready = 1; + controller->status.drq = 0; + controller->status.err = 0; } @@ -2152,112 +2151,112 @@ void rd_atapi_cmd_nop(struct vm_device * dev, struct channel_t * channel) void rd_identify_ATAPI_drive(struct vm_device * dev, struct channel_t * channel) { - struct drive_t * drive = &(channel->drives[channel->drive_select]); - struct controller_t * controller = &(drive->controller); + struct drive_t * drive = &(channel->drives[channel->drive_select]); + struct controller_t * controller = &(drive->controller); - uint_t i; - const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0"; - const char* firmware = "ALPHA1 "; + uint_t i; + const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0"; + const char* firmware = "ALPHA1 "; - drive->id_drive[0] = (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0); // Removable CDROM, 50us response, 12 byte packets + drive->id_drive[0] = (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0); // Removable CDROM, 50us response, 12 byte packets - for (i = 1; i <= 9; i++) { - drive->id_drive[i] = 0; - } + for (i = 1; i <= 9; i++) { + drive->id_drive[i] = 0; + } - for (i = 0; i < 10; i++) { - drive->id_drive[10 + i] = ((serial_number[i * 2] << 8) | - (serial_number[(i * 2) + 1])); - } + for (i = 0; i < 10; i++) { + drive->id_drive[10 + i] = ((serial_number[i * 2] << 8) | + (serial_number[(i * 2) + 1])); + } - for (i = 20; i <= 22; i++) { - drive->id_drive[i] = 0; - } + for (i = 20; i <= 22; i++) { + drive->id_drive[i] = 0; + } - for (i = 0; i < strlen(firmware)/2; i++) { - drive->id_drive[23 + i] = ((firmware[i * 2] << 8) | - (firmware[(i * 2) + 1])); - } - V3_ASSERT((23 + i) == 27); + for (i = 0; i < strlen(firmware)/2; i++) { + drive->id_drive[23 + i] = ((firmware[i * 2] << 8) | + (firmware[(i * 2) + 1])); + } + V3_ASSERT((23 + i) == 27); - for (i = 0; i < strlen((char *)(drive->model_no)) / 2; i++) { - drive->id_drive[27 + i] = ((drive->model_no[i * 2] << 8) | - (drive->model_no[(i * 2) + 1])); - } - V3_ASSERT((27 + i) == 47); + for (i = 0; i < strlen((char *)(drive->model_no)) / 2; i++) { + drive->id_drive[27 + i] = ((drive->model_no[i * 2] << 8) | + (drive->model_no[(i * 2) + 1])); + } + V3_ASSERT((27 + i) == 47); - drive->id_drive[47] = 0; - drive->id_drive[48] = 1; // 32 bits access + drive->id_drive[47] = 0; + drive->id_drive[48] = 1; // 32 bits access - drive->id_drive[49] = (1 << 9); // LBA supported + drive->id_drive[49] = (1 << 9); // LBA supported - drive->id_drive[50] = 0; - drive->id_drive[51] = 0; - drive->id_drive[52] = 0; + drive->id_drive[50] = 0; + drive->id_drive[51] = 0; + drive->id_drive[52] = 0; - drive->id_drive[53] = 3; // words 64-70, 54-58 valid + drive->id_drive[53] = 3; // words 64-70, 54-58 valid - for (i = 54; i <= 62; i++) { - drive->id_drive[i] = 0; - } + for (i = 54; i <= 62; i++) { + drive->id_drive[i] = 0; + } - // copied from CFA540A - drive->id_drive[63] = 0x0103; // variable (DMA stuff) - drive->id_drive[64] = 0x0001; // PIO - drive->id_drive[65] = 0x00b4; - drive->id_drive[66] = 0x00b4; - drive->id_drive[67] = 0x012c; - drive->id_drive[68] = 0x00b4; - - drive->id_drive[69] = 0; - drive->id_drive[70] = 0; - drive->id_drive[71] = 30; // faked - drive->id_drive[72] = 30; // faked - drive->id_drive[73] = 0; - drive->id_drive[74] = 0; - - drive->id_drive[75] = 0; - - for (i = 76; i <= 79; i++) { - drive->id_drive[i] = 0; - } + // copied from CFA540A + drive->id_drive[63] = 0x0103; // variable (DMA stuff) + drive->id_drive[64] = 0x0001; // PIO + drive->id_drive[65] = 0x00b4; + drive->id_drive[66] = 0x00b4; + drive->id_drive[67] = 0x012c; + drive->id_drive[68] = 0x00b4; + + drive->id_drive[69] = 0; + drive->id_drive[70] = 0; + drive->id_drive[71] = 30; // faked + drive->id_drive[72] = 30; // faked + drive->id_drive[73] = 0; + drive->id_drive[74] = 0; + + drive->id_drive[75] = 0; + + for (i = 76; i <= 79; i++) { + drive->id_drive[i] = 0; + } - drive->id_drive[80] = 0x1e; // supports up to ATA/ATAPI-4 - drive->id_drive[81] = 0; - drive->id_drive[82] = 0; - drive->id_drive[83] = 0; - drive->id_drive[84] = 0; - drive->id_drive[85] = 0; - drive->id_drive[86] = 0; - drive->id_drive[87] = 0; - drive->id_drive[88] = 0; - - for (i = 89; i <= 126; i++) { - drive->id_drive[i] = 0; - } + drive->id_drive[80] = 0x1e; // supports up to ATA/ATAPI-4 + drive->id_drive[81] = 0; + drive->id_drive[82] = 0; + drive->id_drive[83] = 0; + drive->id_drive[84] = 0; + drive->id_drive[85] = 0; + drive->id_drive[86] = 0; + drive->id_drive[87] = 0; + drive->id_drive[88] = 0; + + for (i = 89; i <= 126; i++) { + drive->id_drive[i] = 0; + } - drive->id_drive[127] = 0; - drive->id_drive[128] = 0; + drive->id_drive[127] = 0; + drive->id_drive[128] = 0; - for (i = 129; i <= 159; i++) { - drive->id_drive[i] = 0; - } + for (i = 129; i <= 159; i++) { + drive->id_drive[i] = 0; + } - for (i = 160; i <= 255; i++) { - drive->id_drive[i] = 0; - } + for (i = 160; i <= 255; i++) { + drive->id_drive[i] = 0; + } - // now convert the id_drive array (native 256 word format) to - // the controller buffer (512 bytes) - Bit16u temp16; - for (i = 0; i <= 255; i++) { - temp16 = drive->id_drive[i]; - controller->buffer[i * 2] = temp16 & 0x00ff; - controller->buffer[i * 2 + 1] = temp16 >> 8; - } + // now convert the id_drive array (native 256 word format) to + // the controller buffer (512 bytes) + Bit16u temp16; + for (i = 0; i <= 255; i++) { + temp16 = drive->id_drive[i]; + controller->buffer[i * 2] = temp16 & 0x00ff; + controller->buffer[i * 2 + 1] = temp16 >> 8; + } - return; + return; } @@ -2270,126 +2269,126 @@ static void rd_init_mode_sense_single(struct vm_device * dev, struct channel_t * channel, const void* src, int size) { - struct drive_t * drive = &(channel->drives[channel->drive_select]); - struct controller_t * controller = &(drive->controller); - - PrintDebug("[rd_init_mode_sense_single]\n"); - - // Header - controller->buffer[0] = (size + 6) >> 8; - controller->buffer[1] = (size + 6) & 0xff; - controller->buffer[2] = 0x70; // no media present - controller->buffer[3] = 0; // reserved - controller->buffer[4] = 0; // reserved - controller->buffer[5] = 0; // reserved - controller->buffer[6] = 0; // reserved - controller->buffer[7] = 0; // reserved + struct drive_t * drive = &(channel->drives[channel->drive_select]); + struct controller_t * controller = &(drive->controller); + + PrintDebug("[rd_init_mode_sense_single]\n"); + + // Header + controller->buffer[0] = (size + 6) >> 8; + controller->buffer[1] = (size + 6) & 0xff; + controller->buffer[2] = 0x70; // no media present + controller->buffer[3] = 0; // reserved + controller->buffer[4] = 0; // reserved + controller->buffer[5] = 0; // reserved + controller->buffer[6] = 0; // reserved + controller->buffer[7] = 0; // reserved - // Data - memcpy(controller->buffer + 8, src, size); + // Data + memcpy(controller->buffer + 8, src, size); } static void rd_command_aborted(struct vm_device * dev, struct channel_t * channel, unsigned value) { - struct drive_t * drive = &(channel->drives[channel->drive_select]); - struct controller_t * controller = &(drive->controller); - - PrintError("[rd_command_aborted]\n"); - PrintError("\t\taborting on command 0x%02x {%s}\n", value, device_type_to_str(drive->device_type)); - - controller->current_command = 0; - controller->status.busy = 0; - controller->status.drive_ready = 1; - controller->status.err = 1; - controller->error_register = 0x04; // command ABORTED - controller->status.drq = 0; - controller->status.seek_complete = 0; - controller->status.corrected_data = 0; - controller->buffer_index = 0; - - rd_raise_interrupt(dev, channel); + struct drive_t * drive = &(channel->drives[channel->drive_select]); + struct controller_t * controller = &(drive->controller); + + PrintError("[rd_command_aborted]\n"); + PrintError("\t\taborting on command 0x%02x {%s}\n", value, device_type_to_str(drive->device_type)); + + controller->current_command = 0; + controller->status.busy = 0; + controller->status.drive_ready = 1; + controller->status.err = 1; + controller->error_register = 0x04; // command ABORTED + controller->status.drq = 0; + controller->status.seek_complete = 0; + controller->status.corrected_data = 0; + controller->buffer_index = 0; + + rd_raise_interrupt(dev, channel); } static int ramdisk_init_device(struct vm_device *dev) { - struct ramdisk_t *ramdisk= (struct ramdisk_t *)dev->private_data; - - PrintDebug("Initializing Ramdisk\n"); - - - rd_init_hardware(ramdisk); - - - v3_dev_hook_io(dev, PRI_CTRL_PORT, - &read_status_port, &write_ctrl_port); - - v3_dev_hook_io(dev, PRI_DATA_PORT, - &read_data_port, &write_data_port); - v3_dev_hook_io(dev, PRI_FEATURES_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, PRI_SECT_ADDR1_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, PRI_SECT_ADDR2_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, PRI_SECT_ADDR3_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, PRI_CMD_PORT, - &read_status_port, &write_cmd_port); - - - v3_dev_hook_io(dev, SEC_CTRL_PORT, - &read_status_port, &write_ctrl_port); - - v3_dev_hook_io(dev, SEC_DATA_PORT, - &read_data_port, &write_data_port); - v3_dev_hook_io(dev, SEC_FEATURES_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, SEC_SECT_ADDR1_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, SEC_SECT_ADDR2_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, SEC_SECT_ADDR3_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, - &read_general_port, &write_general_port); - v3_dev_hook_io(dev, SEC_CMD_PORT, - &read_status_port, &write_cmd_port); + struct ramdisk_t *ramdisk= (struct ramdisk_t *)dev->private_data; + + PrintDebug("Initializing Ramdisk\n"); + + + rd_init_hardware(ramdisk); + + + v3_dev_hook_io(dev, PRI_CTRL_PORT, + &read_status_port, &write_ctrl_port); + + v3_dev_hook_io(dev, PRI_DATA_PORT, + &read_data_port, &write_data_port); + v3_dev_hook_io(dev, PRI_FEATURES_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, PRI_SECT_ADDR1_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, PRI_SECT_ADDR2_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, PRI_SECT_ADDR3_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, PRI_CMD_PORT, + &read_status_port, &write_cmd_port); + + + v3_dev_hook_io(dev, SEC_CTRL_PORT, + &read_status_port, &write_ctrl_port); + + v3_dev_hook_io(dev, SEC_DATA_PORT, + &read_data_port, &write_data_port); + v3_dev_hook_io(dev, SEC_FEATURES_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, SEC_SECT_ADDR1_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, SEC_SECT_ADDR2_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, SEC_SECT_ADDR3_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, + &read_general_port, &write_general_port); + v3_dev_hook_io(dev, SEC_CMD_PORT, + &read_status_port, &write_cmd_port); - v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, - &read_general_port, &write_general_port); + v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, + &read_general_port, &write_general_port); - v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, - &read_general_port, &write_general_port); + v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, + &read_general_port, &write_general_port); - return 0; + return 0; } static int ramdisk_deinit_device(struct vm_device *dev) { - struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data); - rd_close_harddrive(ramdisk); - return 0; + struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data); + rd_close_harddrive(ramdisk); + return 0; } static struct vm_device_ops dev_ops = { - .init = ramdisk_init_device, - .deinit = ramdisk_deinit_device, - .reset = NULL, - .start = NULL, - .stop = NULL, + .init = ramdisk_init_device, + .deinit = ramdisk_deinit_device, + .reset = NULL, + .start = NULL, + .stop = NULL, }; @@ -2398,15 +2397,15 @@ static struct vm_device_ops dev_ops = { struct vm_device * v3_create_ramdisk() { - struct ramdisk_t *ramdisk; - ramdisk = (struct ramdisk_t *)V3_Malloc(sizeof(struct ramdisk_t)); - V3_ASSERT(ramdisk != NULL); + struct ramdisk_t *ramdisk; + ramdisk = (struct ramdisk_t *)V3_Malloc(sizeof(struct ramdisk_t)); + V3_ASSERT(ramdisk != NULL); - PrintDebug("[create_ramdisk]\n"); + PrintDebug("[create_ramdisk]\n"); - struct vm_device * device = v3_create_device("RAMDISK", &dev_ops, ramdisk); + struct vm_device * device = v3_create_device("RAMDISK", &dev_ops, ramdisk); - return device; + return device; } @@ -2415,195 +2414,195 @@ struct vm_device * v3_create_ramdisk() #ifdef DEBUG_RAMDISK static void rd_print_state(struct ramdisk_t * ramdisk) { - uchar_t channel; - uchar_t device; - struct channel_t * channels = (struct channel_t *)(&(ramdisk->channels)); + uchar_t channel; + uchar_t device; + struct channel_t * channels = (struct channel_t *)(&(ramdisk->channels)); - /* - for (channel = 0; channel < MAX_ATA_CHANNEL; channel++) { - memset((char *)(channels + channel), 0, sizeof(struct channel_t)); - } - */ - PrintDebug("sizeof(*channels) = %d\n", sizeof(*channels)); - PrintDebug("sizeof(channles->drives[0].controller) = %d\n", sizeof((channels->drives[0].controller))); - PrintDebug("sizeof(channles->drives[0].cdrom) = %d\n", sizeof((channels->drives[0].cdrom))); - PrintDebug("sizeof(channles->drives[0].sense) = %d\n", sizeof((channels->drives[0].sense))); - PrintDebug("sizeof(channles->drives[0].atapi) = %d\n", sizeof((channels->drives[0].atapi))); + /* + for (channel = 0; channel < MAX_ATA_CHANNEL; channel++) { + memset((char *)(channels + channel), 0, sizeof(struct channel_t)); + } + */ + PrintDebug("sizeof(*channels) = %d\n", sizeof(*channels)); + PrintDebug("sizeof(channles->drives[0].controller) = %d\n", sizeof((channels->drives[0].controller))); + PrintDebug("sizeof(channles->drives[0].cdrom) = %d\n", sizeof((channels->drives[0].cdrom))); + PrintDebug("sizeof(channles->drives[0].sense) = %d\n", sizeof((channels->drives[0].sense))); + PrintDebug("sizeof(channles->drives[0].atapi) = %d\n", sizeof((channels->drives[0].atapi))); - PrintDebug("sizeof(channles->drives[0].controller.status) = %d\n", - sizeof((channels->drives[0].controller.status))); - PrintDebug("sizeof(channles->drives[0].controller.sector_count) = %d\n", - sizeof((channels->drives[0].controller.sector_count))); - PrintDebug("sizeof(channles->drives[0].controller.interrupt_reason) = %d\n", - sizeof((channels->drives[0].controller.interrupt_reason))); + PrintDebug("sizeof(channles->drives[0].controller.status) = %d\n", + sizeof((channels->drives[0].controller.status))); + PrintDebug("sizeof(channles->drives[0].controller.sector_count) = %d\n", + sizeof((channels->drives[0].controller.sector_count))); + PrintDebug("sizeof(channles->drives[0].controller.interrupt_reason) = %d\n", + sizeof((channels->drives[0].controller.interrupt_reason))); - PrintDebug("sizeof(channles->drives[0].controller.cylinder_no) = %d\n", - sizeof((channels->drives[0].controller.cylinder_no))); - PrintDebug("sizeof(channles->drives[0].controller.byte_count) = %d\n", - sizeof((channels->drives[0].controller.byte_count))); + PrintDebug("sizeof(channles->drives[0].controller.cylinder_no) = %d\n", + sizeof((channels->drives[0].controller.cylinder_no))); + PrintDebug("sizeof(channles->drives[0].controller.byte_count) = %d\n", + sizeof((channels->drives[0].controller.byte_count))); - PrintDebug("sizeof(channles->drives[0].controller.control) = %d\n", - sizeof((channels->drives[0].controller.control))); + PrintDebug("sizeof(channles->drives[0].controller.control) = %d\n", + sizeof((channels->drives[0].controller.control))); - for (channel = 0; channel < MAX_ATA_CHANNEL; channel++){ + for (channel = 0; channel < MAX_ATA_CHANNEL; channel++){ - for (device = 0; device < 2; device++){ + for (device = 0; device < 2; device++){ - // Initialize controller state, even if device is not present - PrintDebug("channels[%d].drives[%d].controller.status.busy = %d\n", - channel, device, - channels[channel].drives[device].controller.status.busy); - PrintDebug("channels[%d].drives[%d].controller.status.drive_ready = %d\n", - channel, device, - channels[channel].drives[device].controller.status.drive_ready); - PrintDebug("channels[%d].drives[%d].controller.status.write_fault = %d\n", - channel, device, - channels[channel].drives[device].controller.status.write_fault); - PrintDebug("channels[%d].drives[%d].controller.status.seek_complete = %d\n", - channel, device, - channels[channel].drives[device].controller.status.seek_complete); - PrintDebug("channels[%d].drives[%d].controller.status.drq = %d\n", - channel, device, - channels[channel].drives[device].controller.status.drq); - PrintDebug("channels[%d].drives[%d].controller.status.corrected_data = %d\n", - channel, device, - channels[channel].drives[device].controller.status.corrected_data); - PrintDebug("channels[%d].drives[%d].controller.status.index_pulse = %d\n", - channel, device, - channels[channel].drives[device].controller.status.index_pulse); - PrintDebug("channels[%d].drives[%d].controller.status.index_pulse_count = %d\n", - channel, device, - channels[channel].drives[device].controller.status.index_pulse_count); - PrintDebug("channels[%d].drives[%d].controller.status.err = %d\n", - channel, device, - channels[channel].drives[device].controller.status.err); - - - PrintDebug("channels[%d].drives[%d].controller.error_register = %d\n", - channel, device, - channels[channel].drives[device].controller.error_register); - PrintDebug("channels[%d].drives[%d].controller.head_no = %d\n", - channel, device, - channels[channel].drives[device].controller.head_no); - PrintDebug("channels[%d].drives[%d].controller.sector_count = %d\n", - channel, device, - channels[channel].drives[device].controller.sector_count); - PrintDebug("channels[%d].drives[%d].controller.sector_no = %d\n", - channel, device, - channels[channel].drives[device].controller.sector_no); - PrintDebug("channels[%d].drives[%d].controller.cylinder_no = %d\n", - channel, device, - channels[channel].drives[device].controller.cylinder_no); - PrintDebug("channels[%d].drives[%d].controller.current_command = %02x\n", - channel, device, - channels[channel].drives[device].controller.current_command); - PrintDebug("channels[%d].drives[%d].controller.buffer_index = %d\n", - channel, device, - channels[channel].drives[device].controller.buffer_index); - - - PrintDebug("channels[%d].drives[%d].controller.control.reset = %d\n", - channel, device, - channels[channel].drives[device].controller.control.reset); - PrintDebug("channels[%d].drives[%d].controller.control.disable_irq = %d\n", - channel, device, - channels[channel].drives[device].controller.control.disable_irq); - - - PrintDebug("channels[%d].drives[%d].controller.reset_in_progress = %d\n", - channel, device, - channels[channel].drives[device].controller.reset_in_progress); - PrintDebug("channels[%d].drives[%d].controller.sectors_per_block = %02x\n", - channel, device, - channels[channel].drives[device].controller.sectors_per_block); - PrintDebug("channels[%d].drives[%d].controller.lba_mode = %d\n", - channel, device, - channels[channel].drives[device].controller.lba_mode); - PrintDebug("channels[%d].drives[%d].controller.features = %d\n", - channel, device, - channels[channel].drives[device].controller.features); - - - PrintDebug("channels[%d].drives[%d].model_no = %s\n", - channel, device, - channels[channel].drives[device].model_no); - PrintDebug("channels[%d].drives[%d].device_type = %d\n", - channel, device, - channels[channel].drives[device].device_type); - PrintDebug("channels[%d].drives[%d].cdrom.locked = %d\n", - channel, device, - channels[channel].drives[device].cdrom.locked); - PrintDebug("channels[%d].drives[%d].sense.sense_key = %d\n", - channel, device, - channels[channel].drives[device].sense.sense_key); - PrintDebug("channels[%d].drives[%d].sense.asc = %d\n", - channel, device, - channels[channel].drives[device].sense.asc); - PrintDebug("channels[%d].drives[%d].sense.ascq = %d\n", - channel, device, - channels[channel].drives[device].sense.ascq); - - - - PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n", - channel, device, - channels[channel].drives[device].controller.interrupt_reason.c_d); - - PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n", - channel, device, - channels[channel].drives[device].controller.interrupt_reason.i_o); - - PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n", - channel, device, - channels[channel].drives[device].controller.interrupt_reason.rel); - - PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n", - channel, device, - channels[channel].drives[device].controller.interrupt_reason.tag); - - PrintDebug("channels[%d].drives[%d].cdrom.ready = %d\n", - channel, device, - channels[channel].drives[device].cdrom.ready); + // Initialize controller state, even if device is not present + PrintDebug("channels[%d].drives[%d].controller.status.busy = %d\n", + channel, device, + channels[channel].drives[device].controller.status.busy); + PrintDebug("channels[%d].drives[%d].controller.status.drive_ready = %d\n", + channel, device, + channels[channel].drives[device].controller.status.drive_ready); + PrintDebug("channels[%d].drives[%d].controller.status.write_fault = %d\n", + channel, device, + channels[channel].drives[device].controller.status.write_fault); + PrintDebug("channels[%d].drives[%d].controller.status.seek_complete = %d\n", + channel, device, + channels[channel].drives[device].controller.status.seek_complete); + PrintDebug("channels[%d].drives[%d].controller.status.drq = %d\n", + channel, device, + channels[channel].drives[device].controller.status.drq); + PrintDebug("channels[%d].drives[%d].controller.status.corrected_data = %d\n", + channel, device, + channels[channel].drives[device].controller.status.corrected_data); + PrintDebug("channels[%d].drives[%d].controller.status.index_pulse = %d\n", + channel, device, + channels[channel].drives[device].controller.status.index_pulse); + PrintDebug("channels[%d].drives[%d].controller.status.index_pulse_count = %d\n", + channel, device, + channels[channel].drives[device].controller.status.index_pulse_count); + PrintDebug("channels[%d].drives[%d].controller.status.err = %d\n", + channel, device, + channels[channel].drives[device].controller.status.err); + + + PrintDebug("channels[%d].drives[%d].controller.error_register = %d\n", + channel, device, + channels[channel].drives[device].controller.error_register); + PrintDebug("channels[%d].drives[%d].controller.head_no = %d\n", + channel, device, + channels[channel].drives[device].controller.head_no); + PrintDebug("channels[%d].drives[%d].controller.sector_count = %d\n", + channel, device, + channels[channel].drives[device].controller.sector_count); + PrintDebug("channels[%d].drives[%d].controller.sector_no = %d\n", + channel, device, + channels[channel].drives[device].controller.sector_no); + PrintDebug("channels[%d].drives[%d].controller.cylinder_no = %d\n", + channel, device, + channels[channel].drives[device].controller.cylinder_no); + PrintDebug("channels[%d].drives[%d].controller.current_command = %02x\n", + channel, device, + channels[channel].drives[device].controller.current_command); + PrintDebug("channels[%d].drives[%d].controller.buffer_index = %d\n", + channel, device, + channels[channel].drives[device].controller.buffer_index); + + + PrintDebug("channels[%d].drives[%d].controller.control.reset = %d\n", + channel, device, + channels[channel].drives[device].controller.control.reset); + PrintDebug("channels[%d].drives[%d].controller.control.disable_irq = %d\n", + channel, device, + channels[channel].drives[device].controller.control.disable_irq); + + + PrintDebug("channels[%d].drives[%d].controller.reset_in_progress = %d\n", + channel, device, + channels[channel].drives[device].controller.reset_in_progress); + PrintDebug("channels[%d].drives[%d].controller.sectors_per_block = %02x\n", + channel, device, + channels[channel].drives[device].controller.sectors_per_block); + PrintDebug("channels[%d].drives[%d].controller.lba_mode = %d\n", + channel, device, + channels[channel].drives[device].controller.lba_mode); + PrintDebug("channels[%d].drives[%d].controller.features = %d\n", + channel, device, + channels[channel].drives[device].controller.features); + + + PrintDebug("channels[%d].drives[%d].model_no = %s\n", + channel, device, + channels[channel].drives[device].model_no); + PrintDebug("channels[%d].drives[%d].device_type = %d\n", + channel, device, + channels[channel].drives[device].device_type); + PrintDebug("channels[%d].drives[%d].cdrom.locked = %d\n", + channel, device, + channels[channel].drives[device].cdrom.locked); + PrintDebug("channels[%d].drives[%d].sense.sense_key = %d\n", + channel, device, + channels[channel].drives[device].sense.sense_key); + PrintDebug("channels[%d].drives[%d].sense.asc = %d\n", + channel, device, + channels[channel].drives[device].sense.asc); + PrintDebug("channels[%d].drives[%d].sense.ascq = %d\n", + channel, device, + channels[channel].drives[device].sense.ascq); + + + + PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n", + channel, device, + channels[channel].drives[device].controller.interrupt_reason.c_d); + + PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n", + channel, device, + channels[channel].drives[device].controller.interrupt_reason.i_o); + + PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n", + channel, device, + channels[channel].drives[device].controller.interrupt_reason.rel); + + PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n", + channel, device, + channels[channel].drives[device].controller.interrupt_reason.tag); + + PrintDebug("channels[%d].drives[%d].cdrom.ready = %d\n", + channel, device, + channels[channel].drives[device].cdrom.ready); - } //for device - } //for channel + } //for device + } //for channel - return; + return; } static int check_bit_fields(struct controller_t * controller) { - //Check bit fields - controller->sector_count = 0; - controller->interrupt_reason.c_d = 1; - if (controller->sector_count != 0x01) { - return INTR_REASON_BIT_ERR; - } + //Check bit fields + controller->sector_count = 0; + controller->interrupt_reason.c_d = 1; + if (controller->sector_count != 0x01) { + return INTR_REASON_BIT_ERR; + } - controller->sector_count = 0; - controller->interrupt_reason.i_o = 1; - if (controller->sector_count != 0x02) { - return INTR_REASON_BIT_ERR; - } + controller->sector_count = 0; + controller->interrupt_reason.i_o = 1; + if (controller->sector_count != 0x02) { + return INTR_REASON_BIT_ERR; + } - controller->sector_count = 0; - controller->interrupt_reason.rel = 1; - if (controller->sector_count != 0x04) { - return INTR_REASON_BIT_ERR; - } + controller->sector_count = 0; + controller->interrupt_reason.rel = 1; + if (controller->sector_count != 0x04) { + return INTR_REASON_BIT_ERR; + } - controller->sector_count = 0; - controller->interrupt_reason.tag = 3; - if (controller->sector_count != 0x18) { - return INTR_REASON_BIT_ERR; - } + controller->sector_count = 0; + controller->interrupt_reason.tag = 3; + if (controller->sector_count != 0x18) { + return INTR_REASON_BIT_ERR; + } - return 0; + return 0; } #endif diff --git a/palacios/src/devices/serial.c b/palacios/src/devices/serial.c index 7468493..49982fb 100644 --- a/palacios/src/devices/serial.c +++ b/palacios/src/devices/serial.c @@ -72,11 +72,11 @@ struct irq_enable_reg { - uint_t erbfi : 1; // Enable Receiver Buffer full interrupt - uint_t etbei : 1; // Enable Transmit buffer empty interrupt - uint_t elsi : 1; // Enable Line Status Interrupt - uint_t edssi : 1; // Enable Delta Status signals interrupt - uint_t rsvd : 4; // MBZ + uint_t erbfi : 1; // Enable Receiver Buffer full interrupt + uint_t etbei : 1; // Enable Transmit buffer empty interrupt + uint_t elsi : 1; // Enable Line Status Interrupt + uint_t edssi : 1; // Enable Delta Status signals interrupt + uint_t rsvd : 4; // MBZ }; @@ -93,185 +93,185 @@ struct irq_enable_reg { #define MODEL_IRQ_DELTA_SET 0x0 struct irq_id_reg { - uint_t pending : 1; // Interrupt pending (0=interrupt pending) - uint_t iid : 3; // Interrupt Identification - uint_t rsvd : 2; // MBZ - uint_t fifo_en : 2; // FIFO enable + uint_t pending : 1; // Interrupt pending (0=interrupt pending) + uint_t iid : 3; // Interrupt Identification + uint_t rsvd : 2; // MBZ + uint_t fifo_en : 2; // FIFO enable }; struct fifo_ctrl_reg { - uint_t enable : 1; // enable fifo - uint_t rfres : 1; // RX FIFO reset - uint_t xfres : 1; // TX FIFO reset - uint_t dma_sel : 1; // DMA mode select - uint_t rsvd : 2; // MBZ - uint_t rx_trigger: 2; // RX FIFO trigger level select + uint_t enable : 1; // enable fifo + uint_t rfres : 1; // RX FIFO reset + uint_t xfres : 1; // TX FIFO reset + uint_t dma_sel : 1; // DMA mode select + uint_t rsvd : 2; // MBZ + uint_t rx_trigger: 2; // RX FIFO trigger level select }; struct line_ctrl_reg { - uint_t word_len : 2; // word length select - uint_t stop_bits : 1; // Stop Bit select - uint_t parity_enable : 1; // Enable parity - uint_t even_sel : 1; // Even Parity Select - uint_t stick_parity : 1; // Stick Parity Select - uint_t sbr : 1; // Set Break - uint_t dlab : 1; // Divisor latch access bit + uint_t word_len : 2; // word length select + uint_t stop_bits : 1; // Stop Bit select + uint_t parity_enable : 1; // Enable parity + uint_t even_sel : 1; // Even Parity Select + uint_t stick_parity : 1; // Stick Parity Select + uint_t sbr : 1; // Set Break + uint_t dlab : 1; // Divisor latch access bit }; struct modem_ctrl_reg { - uint_t dtr : 1; - uint_t rts : 1; - uint_t out1 : 1; - uint_t out2 : 1; - uint_t loop : 1; // loopback mode - uint_t rsvd : 3; // MBZ + uint_t dtr : 1; + uint_t rts : 1; + uint_t out1 : 1; + uint_t out2 : 1; + uint_t loop : 1; // loopback mode + uint_t rsvd : 3; // MBZ }; struct line_status_reg { - uint_t rbf : 1; // Receiver Buffer Full - uint_t oe : 1; // Overrun error - uint_t pe : 1; // Parity Error - uint_t fe : 1; // Framing Error - uint_t brk : 1; // broken line detected - uint_t thre : 1; // Transmitter holding register empty - uint_t temt : 1; // Transmitter Empty - uint_t fifo_err : 1; // at least one error is pending in the RX FIFO chain + uint_t rbf : 1; // Receiver Buffer Full + uint_t oe : 1; // Overrun error + uint_t pe : 1; // Parity Error + uint_t fe : 1; // Framing Error + uint_t brk : 1; // broken line detected + uint_t thre : 1; // Transmitter holding register empty + uint_t temt : 1; // Transmitter Empty + uint_t fifo_err : 1; // at least one error is pending in the RX FIFO chain }; struct modem_status_reg { - uint_t dcts : 1; // Delta Clear To Send - uint_t ddsr : 1; // Delta Data Set Ready - uint_t teri : 1; // Trailing Edge Ring Indicator - uint_t ddcd : 1; // Delta Data Carrier Detect - uint_t cts : 1; // Clear to Send - uint_t dsr : 1; // Data Set Ready - uint_t ri : 1; // Ring Indicator - uint_t dcd : 1; // Data Carrier Detect + uint_t dcts : 1; // Delta Clear To Send + uint_t ddsr : 1; // Delta Data Set Ready + uint_t teri : 1; // Trailing Edge Ring Indicator + uint_t ddcd : 1; // Delta Data Carrier Detect + uint_t cts : 1; // Clear to Send + uint_t dsr : 1; // Data Set Ready + uint_t ri : 1; // Ring Indicator + uint_t dcd : 1; // Data Carrier Detect }; #define SERIAL_BUF_LEN 256 struct serial_buffer { - uint_t head; // most recent data - uint_t tail; // oldest char - char buffer[SERIAL_BUF_LEN]; + uint_t head; // most recent data + uint_t tail; // oldest char + char buffer[SERIAL_BUF_LEN]; }; static int queue_data(struct serial_buffer * buf, char data) { - uint_t next_loc = (buf->head + 1) % SERIAL_BUF_LEN; + uint_t next_loc = (buf->head + 1) % SERIAL_BUF_LEN; - if (next_loc == buf->tail) { - return -1; - } + if (next_loc == buf->tail) { + return -1; + } - buf->buffer[next_loc] = data; - buf->head = next_loc; + buf->buffer[next_loc] = data; + buf->head = next_loc; - return 0; + return 0; } static int dequeue_data(struct serial_buffer * buf, char * data) { - uint_t next_tail = (buf->tail + 1) % SERIAL_BUF_LEN; + uint_t next_tail = (buf->tail + 1) % SERIAL_BUF_LEN; - if (buf->head == buf->tail) { - return -1; - } + if (buf->head == buf->tail) { + return -1; + } - *data = buf->buffer[buf->tail]; - buf->tail = next_tail; + *data = buf->buffer[buf->tail]; + buf->tail = next_tail; - return 0; + return 0; } struct serial_port { - char ier; - char iir; - char fcr; - char lcr; - char mcr; - char lsr; - char msr; - - struct serial_buffer tx_buffer; - struct serial_buffer rx_buffer; + char ier; + char iir; + char fcr; + char lcr; + char mcr; + char lsr; + char msr; + + struct serial_buffer tx_buffer; + struct serial_buffer rx_buffer; }; struct serial_state { - struct serial_port com1; - struct serial_port com2; - struct serial_port com3; - struct serial_port com4; + struct serial_port com1; + struct serial_port com2; + struct serial_port com3; + struct serial_port com4; }; static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct serial_state * state = (struct serial_state *)dev->private_data; - char * val = (char *)src; - PrintDebug("Write to Data Port 0x%x (val=%x)\n", port, *(char*)src); + struct serial_state * state = (struct serial_state *)dev->private_data; + char * val = (char *)src; + PrintDebug("Write to Data Port 0x%x (val=%x)\n", port, *(char*)src); - if (length != 1) { - PrintDebug("Invalid length(%d) in write to 0x%x\n", length, port); - return -1; - } - - switch (port) { - case COM1_DATA_PORT: - queue_data(&(state->com1.tx_buffer), *val); - break; - case COM2_DATA_PORT: - queue_data(&(state->com2.tx_buffer), *val); - break; - case COM3_DATA_PORT: - queue_data(&(state->com3.tx_buffer), *val); - break; - case COM4_DATA_PORT: - queue_data(&(state->com4.tx_buffer), *val); - break; - default: - return -1; - } + if (length != 1) { + PrintDebug("Invalid length(%d) in write to 0x%x\n", length, port); + return -1; + } + + switch (port) { + case COM1_DATA_PORT: + queue_data(&(state->com1.tx_buffer), *val); + break; + case COM2_DATA_PORT: + queue_data(&(state->com2.tx_buffer), *val); + break; + case COM3_DATA_PORT: + queue_data(&(state->com3.tx_buffer), *val); + break; + case COM4_DATA_PORT: + queue_data(&(state->com4.tx_buffer), *val); + break; + default: + return -1; + } - return length; + return length; } static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct serial_state * state = (struct serial_state *)dev->private_data; - char * val = (char *)dst; - PrintDebug("Read from Data Port 0x%x\n", port); + struct serial_state * state = (struct serial_state *)dev->private_data; + char * val = (char *)dst; + PrintDebug("Read from Data Port 0x%x\n", port); - if (length != 1) { - PrintDebug("Invalid length(%d) in write to 0x%x\n", length, port); - return -1; - } - - switch (port) { - case COM1_DATA_PORT: - dequeue_data(&(state->com1.tx_buffer), val); - break; - case COM2_DATA_PORT: - dequeue_data(&(state->com2.tx_buffer), val); - break; - case COM3_DATA_PORT: - dequeue_data(&(state->com3.tx_buffer), val); - break; - case COM4_DATA_PORT: - dequeue_data(&(state->com4.tx_buffer), val); - break; - default: - return -1; - } + if (length != 1) { + PrintDebug("Invalid length(%d) in write to 0x%x\n", length, port); + return -1; + } + + switch (port) { + case COM1_DATA_PORT: + dequeue_data(&(state->com1.tx_buffer), val); + break; + case COM2_DATA_PORT: + dequeue_data(&(state->com2.tx_buffer), val); + break; + case COM3_DATA_PORT: + dequeue_data(&(state->com3.tx_buffer), val); + break; + case COM4_DATA_PORT: + dequeue_data(&(state->com4.tx_buffer), val); + break; + default: + return -1; + } - return length; + return length; } @@ -279,191 +279,191 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de static int handle_ier_write(struct serial_port * com, struct irq_enable_reg * ier) { - return -1; + return -1; } static int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - struct serial_state * state = (struct serial_state *)dev->private_data; - char * val = (char *)src; - PrintDebug("Write to Control Port (val=%x)\n", *(char *)src); - - if (length != 1) { - PrintDebug("Invalid Write length to control port %d\n", port); - return -1; - } + struct serial_state * state = (struct serial_state *)dev->private_data; + char * val = (char *)src; + PrintDebug("Write to Control Port (val=%x)\n", *(char *)src); - switch (port) { - case COM1_IRQ_ENABLE_PORT: - if (handle_ier_write(&(state->com1), (struct irq_enable_reg *)val) == -1) { - return -1; + if (length != 1) { + PrintDebug("Invalid Write length to control port %d\n", port); + return -1; } - break; - case COM2_IRQ_ENABLE_PORT: - if (handle_ier_write(&(state->com2), (struct irq_enable_reg *)val) == -1) { - return -1; - } - break; - case COM3_IRQ_ENABLE_PORT: - if (handle_ier_write(&(state->com3), (struct irq_enable_reg *)val) == -1) { - return -1; - } - break; - case COM4_IRQ_ENABLE_PORT: - if (handle_ier_write(&(state->com4), (struct irq_enable_reg *)val) == -1) { - return -1; - } - break; - - case COM1_FIFO_CTRL_PORT: - case COM2_FIFO_CTRL_PORT: - case COM3_FIFO_CTRL_PORT: - case COM4_FIFO_CTRL_PORT: - - case COM1_LINE_CTRL_PORT: - case COM2_LINE_CTRL_PORT: - case COM3_LINE_CTRL_PORT: - case COM4_LINE_CTRL_PORT: - - case COM1_MODEM_CTRL_PORT: - case COM2_MODEM_CTRL_PORT: - case COM3_MODEM_CTRL_PORT: - case COM4_MODEM_CTRL_PORT: + + switch (port) { + case COM1_IRQ_ENABLE_PORT: + if (handle_ier_write(&(state->com1), (struct irq_enable_reg *)val) == -1) { + return -1; + } + break; + case COM2_IRQ_ENABLE_PORT: + if (handle_ier_write(&(state->com2), (struct irq_enable_reg *)val) == -1) { + return -1; + } + break; + case COM3_IRQ_ENABLE_PORT: + if (handle_ier_write(&(state->com3), (struct irq_enable_reg *)val) == -1) { + return -1; + } + break; + case COM4_IRQ_ENABLE_PORT: + if (handle_ier_write(&(state->com4), (struct irq_enable_reg *)val) == -1) { + return -1; + } + break; + + case COM1_FIFO_CTRL_PORT: + case COM2_FIFO_CTRL_PORT: + case COM3_FIFO_CTRL_PORT: + case COM4_FIFO_CTRL_PORT: + + case COM1_LINE_CTRL_PORT: + case COM2_LINE_CTRL_PORT: + case COM3_LINE_CTRL_PORT: + case COM4_LINE_CTRL_PORT: + + case COM1_MODEM_CTRL_PORT: + case COM2_MODEM_CTRL_PORT: + case COM3_MODEM_CTRL_PORT: + case COM4_MODEM_CTRL_PORT: - default: - return -1; - } + default: + return -1; + } - return -1; + return -1; } static int read_ctrl_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct serial_state * state = (struct serial_state *)dev->private_data; - char * val = (char *)dst; - PrintDebug("Read from Control Port\n"); + struct serial_state * state = (struct serial_state *)dev->private_data; + char * val = (char *)dst; + PrintDebug("Read from Control Port\n"); - if (length != 1) { - PrintDebug("Invalid Read length to control port\n"); - return -1; - } - - switch (port) { - case COM1_IRQ_ENABLE_PORT: - *val = state->com1.ier; - break; - case COM2_IRQ_ENABLE_PORT: - *val = state->com2.ier; - break; - case COM3_IRQ_ENABLE_PORT: - *val = state->com3.ier; - break; - case COM4_IRQ_ENABLE_PORT: - *val = state->com4.ier; - break; - - case COM1_FIFO_CTRL_PORT: - *val = state->com1.fcr; - break; - case COM2_FIFO_CTRL_PORT: - *val = state->com2.fcr; - break; - case COM3_FIFO_CTRL_PORT: - *val = state->com3.fcr; - break; - case COM4_FIFO_CTRL_PORT: - *val = state->com4.fcr; - break; - - case COM1_LINE_CTRL_PORT: - *val = state->com1.lcr; - break; - case COM2_LINE_CTRL_PORT: - *val = state->com2.lcr; - break; - case COM3_LINE_CTRL_PORT: - *val = state->com3.lcr; - break; - case COM4_LINE_CTRL_PORT: - *val = state->com4.lcr; - break; - - case COM1_MODEM_CTRL_PORT: - *val = state->com1.mcr; - break; - case COM2_MODEM_CTRL_PORT: - *val = state->com2.mcr; - break; - case COM3_MODEM_CTRL_PORT: - *val = state->com3.mcr; - break; - case COM4_MODEM_CTRL_PORT: - *val = state->com4.mcr; - break; - - default: - return -1; - } + if (length != 1) { + PrintDebug("Invalid Read length to control port\n"); + return -1; + } + + switch (port) { + case COM1_IRQ_ENABLE_PORT: + *val = state->com1.ier; + break; + case COM2_IRQ_ENABLE_PORT: + *val = state->com2.ier; + break; + case COM3_IRQ_ENABLE_PORT: + *val = state->com3.ier; + break; + case COM4_IRQ_ENABLE_PORT: + *val = state->com4.ier; + break; + + case COM1_FIFO_CTRL_PORT: + *val = state->com1.fcr; + break; + case COM2_FIFO_CTRL_PORT: + *val = state->com2.fcr; + break; + case COM3_FIFO_CTRL_PORT: + *val = state->com3.fcr; + break; + case COM4_FIFO_CTRL_PORT: + *val = state->com4.fcr; + break; + + case COM1_LINE_CTRL_PORT: + *val = state->com1.lcr; + break; + case COM2_LINE_CTRL_PORT: + *val = state->com2.lcr; + break; + case COM3_LINE_CTRL_PORT: + *val = state->com3.lcr; + break; + case COM4_LINE_CTRL_PORT: + *val = state->com4.lcr; + break; + + case COM1_MODEM_CTRL_PORT: + *val = state->com1.mcr; + break; + case COM2_MODEM_CTRL_PORT: + *val = state->com2.mcr; + break; + case COM3_MODEM_CTRL_PORT: + *val = state->com3.mcr; + break; + case COM4_MODEM_CTRL_PORT: + *val = state->com4.mcr; + break; + + default: + return -1; + } - return length; + return length; } static int write_status_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) { - PrintDebug("Write to Status Port 0x%x (val=%x)\n", port, *(char *)src); + PrintDebug("Write to Status Port 0x%x (val=%x)\n", port, *(char *)src); - return -1; + return -1; } static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - struct serial_state * state = (struct serial_state *)dev->private_data; - char * val = (char *)dst; - PrintDebug("Read from Status Port 0x%x\n", port); + struct serial_state * state = (struct serial_state *)dev->private_data; + char * val = (char *)dst; + PrintDebug("Read from Status Port 0x%x\n", port); - if (length != 1) { - PrintDebug("Invalid Read length to control port\n"); - return -1; - } + if (length != 1) { + PrintDebug("Invalid Read length to control port\n"); + return -1; + } - switch (port) { - case COM1_LINE_STATUS_PORT: - *val = state->com1.lsr; - break; - case COM2_LINE_STATUS_PORT: - *val = state->com2.lsr; - break; - case COM3_LINE_STATUS_PORT: - *val = state->com3.lsr; - break; - case COM4_LINE_STATUS_PORT: - *val = state->com4.lsr; - break; + switch (port) { + case COM1_LINE_STATUS_PORT: + *val = state->com1.lsr; + break; + case COM2_LINE_STATUS_PORT: + *val = state->com2.lsr; + break; + case COM3_LINE_STATUS_PORT: + *val = state->com3.lsr; + break; + case COM4_LINE_STATUS_PORT: + *val = state->com4.lsr; + break; - case COM1_MODEM_STATUS_PORT: - *val = state->com1.msr; - break; - case COM2_MODEM_STATUS_PORT: - *val = state->com2.msr; - break; - case COM3_MODEM_STATUS_PORT: - *val = state->com3.msr; - break; - case COM4_MODEM_STATUS_PORT: - *val = state->com4.msr; - break; - - default: - return -1; - } + case COM1_MODEM_STATUS_PORT: + *val = state->com1.msr; + break; + case COM2_MODEM_STATUS_PORT: + *val = state->com2.msr; + break; + case COM3_MODEM_STATUS_PORT: + *val = state->com3.msr; + break; + case COM4_MODEM_STATUS_PORT: + *val = state->com4.msr; + break; + + default: + return -1; + } - return length; + return length; } @@ -471,133 +471,133 @@ static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_ static int init_serial_port(struct serial_port * com) { - //struct irq_enable_reg * ier = (struct irq_enable_reg *)&(com->ier); - //struct irq_id_reg * iir = (struct irq_id_reg *)&(com->iir); - //struct fifo_ctrl_reg * fcr = (struct fifo_ctrl_reg *)&(com->fcr); - //struct line_ctrl_reg * lcr = (struct line_ctrl_reg *)&(com->lcr); - //struct modem_ctrl_reg * mcr = (struct modem_ctrl_reg *)&(com->mcr); - //struct line_status_reg * lsr = (struct line_status_reg *)&(com->lsr); - //struct modem_status_reg * msr = (struct modem_status_reg *)&(com->msr); - - com->ier = 0x00; - com->iir = 0x01; - com->fcr = 0x00; - com->lcr = 0x00; - com->mcr = 0x00; - com->lsr = 0x60; - com->msr = 0x00; - - return 0; + //struct irq_enable_reg * ier = (struct irq_enable_reg *)&(com->ier); + //struct irq_id_reg * iir = (struct irq_id_reg *)&(com->iir); + //struct fifo_ctrl_reg * fcr = (struct fifo_ctrl_reg *)&(com->fcr); + //struct line_ctrl_reg * lcr = (struct line_ctrl_reg *)&(com->lcr); + //struct modem_ctrl_reg * mcr = (struct modem_ctrl_reg *)&(com->mcr); + //struct line_status_reg * lsr = (struct line_status_reg *)&(com->lsr); + //struct modem_status_reg * msr = (struct modem_status_reg *)&(com->msr); + + com->ier = 0x00; + com->iir = 0x01; + com->fcr = 0x00; + com->lcr = 0x00; + com->mcr = 0x00; + com->lsr = 0x60; + com->msr = 0x00; + + return 0; } static int serial_init(struct vm_device * dev) { - struct serial_state * state = (struct serial_state *)dev->private_data; - - - init_serial_port(&(state->com1)); - init_serial_port(&(state->com2)); - init_serial_port(&(state->com3)); - init_serial_port(&(state->com4)); - - v3_dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM1_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - - v3_dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM2_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - - v3_dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM3_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - - v3_dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - - return 0; + struct serial_state * state = (struct serial_state *)dev->private_data; + + + init_serial_port(&(state->com1)); + init_serial_port(&(state->com2)); + init_serial_port(&(state->com3)); + init_serial_port(&(state->com4)); + + v3_dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port); + v3_dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM1_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM1_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + + v3_dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port); + v3_dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM2_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM2_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + + v3_dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port); + v3_dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM3_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM3_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + + v3_dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port); + v3_dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM4_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + v3_dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + v3_dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + + return 0; } static int serial_deinit(struct vm_device * dev) { - v3_dev_unhook_io(dev, COM1_DATA_PORT); - v3_dev_unhook_io(dev, COM1_IRQ_ENABLE_PORT); - v3_dev_unhook_io(dev, COM1_FIFO_CTRL_PORT); - v3_dev_unhook_io(dev, COM1_LINE_CTRL_PORT); - v3_dev_unhook_io(dev, COM1_MODEM_CTRL_PORT); - v3_dev_unhook_io(dev, COM1_LINE_STATUS_PORT); - v3_dev_unhook_io(dev, COM1_MODEM_STATUS_PORT); - v3_dev_unhook_io(dev, COM1_SCRATCH_PORT); - - v3_dev_unhook_io(dev, COM2_DATA_PORT); - v3_dev_unhook_io(dev, COM2_IRQ_ENABLE_PORT); - v3_dev_unhook_io(dev, COM2_FIFO_CTRL_PORT); - v3_dev_unhook_io(dev, COM2_LINE_CTRL_PORT); - v3_dev_unhook_io(dev, COM2_MODEM_CTRL_PORT); - v3_dev_unhook_io(dev, COM2_LINE_STATUS_PORT); - v3_dev_unhook_io(dev, COM2_MODEM_STATUS_PORT); - v3_dev_unhook_io(dev, COM2_SCRATCH_PORT); - - v3_dev_unhook_io(dev, COM3_DATA_PORT); - v3_dev_unhook_io(dev, COM3_IRQ_ENABLE_PORT); - v3_dev_unhook_io(dev, COM3_FIFO_CTRL_PORT); - v3_dev_unhook_io(dev, COM3_LINE_CTRL_PORT); - v3_dev_unhook_io(dev, COM3_MODEM_CTRL_PORT); - v3_dev_unhook_io(dev, COM3_LINE_STATUS_PORT); - v3_dev_unhook_io(dev, COM3_MODEM_STATUS_PORT); - v3_dev_unhook_io(dev, COM3_SCRATCH_PORT); - - v3_dev_unhook_io(dev, COM4_DATA_PORT); - v3_dev_unhook_io(dev, COM4_IRQ_ENABLE_PORT); - v3_dev_unhook_io(dev, COM4_FIFO_CTRL_PORT); - v3_dev_unhook_io(dev, COM4_LINE_CTRL_PORT); - v3_dev_unhook_io(dev, COM4_MODEM_CTRL_PORT); - v3_dev_unhook_io(dev, COM4_LINE_STATUS_PORT); - v3_dev_unhook_io(dev, COM4_MODEM_STATUS_PORT); - v3_dev_unhook_io(dev, COM4_SCRATCH_PORT); - - return 0; + v3_dev_unhook_io(dev, COM1_DATA_PORT); + v3_dev_unhook_io(dev, COM1_IRQ_ENABLE_PORT); + v3_dev_unhook_io(dev, COM1_FIFO_CTRL_PORT); + v3_dev_unhook_io(dev, COM1_LINE_CTRL_PORT); + v3_dev_unhook_io(dev, COM1_MODEM_CTRL_PORT); + v3_dev_unhook_io(dev, COM1_LINE_STATUS_PORT); + v3_dev_unhook_io(dev, COM1_MODEM_STATUS_PORT); + v3_dev_unhook_io(dev, COM1_SCRATCH_PORT); + + v3_dev_unhook_io(dev, COM2_DATA_PORT); + v3_dev_unhook_io(dev, COM2_IRQ_ENABLE_PORT); + v3_dev_unhook_io(dev, COM2_FIFO_CTRL_PORT); + v3_dev_unhook_io(dev, COM2_LINE_CTRL_PORT); + v3_dev_unhook_io(dev, COM2_MODEM_CTRL_PORT); + v3_dev_unhook_io(dev, COM2_LINE_STATUS_PORT); + v3_dev_unhook_io(dev, COM2_MODEM_STATUS_PORT); + v3_dev_unhook_io(dev, COM2_SCRATCH_PORT); + + v3_dev_unhook_io(dev, COM3_DATA_PORT); + v3_dev_unhook_io(dev, COM3_IRQ_ENABLE_PORT); + v3_dev_unhook_io(dev, COM3_FIFO_CTRL_PORT); + v3_dev_unhook_io(dev, COM3_LINE_CTRL_PORT); + v3_dev_unhook_io(dev, COM3_MODEM_CTRL_PORT); + v3_dev_unhook_io(dev, COM3_LINE_STATUS_PORT); + v3_dev_unhook_io(dev, COM3_MODEM_STATUS_PORT); + v3_dev_unhook_io(dev, COM3_SCRATCH_PORT); + + v3_dev_unhook_io(dev, COM4_DATA_PORT); + v3_dev_unhook_io(dev, COM4_IRQ_ENABLE_PORT); + v3_dev_unhook_io(dev, COM4_FIFO_CTRL_PORT); + v3_dev_unhook_io(dev, COM4_LINE_CTRL_PORT); + v3_dev_unhook_io(dev, COM4_MODEM_CTRL_PORT); + v3_dev_unhook_io(dev, COM4_LINE_STATUS_PORT); + v3_dev_unhook_io(dev, COM4_MODEM_STATUS_PORT); + v3_dev_unhook_io(dev, COM4_SCRATCH_PORT); + + return 0; } static struct vm_device_ops dev_ops = { - .init = serial_init, - .deinit = serial_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, + .init = serial_init, + .deinit = serial_deinit, + .reset = NULL, + .start = NULL, + .stop = NULL, }; struct vm_device * v3_create_serial(int num_ports) { - struct serial_state * state = NULL; - state = (struct serial_state *)V3_Malloc(sizeof(struct serial_state)); - V3_ASSERT(state != NULL); + struct serial_state * state = NULL; + state = (struct serial_state *)V3_Malloc(sizeof(struct serial_state)); + V3_ASSERT(state != NULL); - struct vm_device * device = v3_create_device("Serial UART", &dev_ops, state); + struct vm_device * device = v3_create_device("Serial UART", &dev_ops, state); - return device; + return device; } diff --git a/palacios/src/devices/simple_pic.c b/palacios/src/devices/simple_pic.c index 11848e0..828b588 100644 --- a/palacios/src/devices/simple_pic.c +++ b/palacios/src/devices/simple_pic.c @@ -23,54 +23,54 @@ #include struct pic_internal { - int pending_irq; + int pending_irq; }; static int pic_intr_pending(void * private_data) { - struct pic_internal * data = (struct pic_internal *)private_data; + struct pic_internal * data = (struct pic_internal *)private_data; - return (data->pending_irq > 0); + return (data->pending_irq > 0); } static int pic_raise_intr(void * private_data, int irq) { - struct pic_internal * data = (struct pic_internal *)private_data; + struct pic_internal * data = (struct pic_internal *)private_data; - data->pending_irq = irq; + data->pending_irq = irq; - return 0; + return 0; } static int pic_get_intr_number(void * private_data) { - struct pic_internal * data = (struct pic_internal *)private_data; + struct pic_internal * data = (struct pic_internal *)private_data; - return data->pending_irq; + return data->pending_irq; } static struct intr_ctrl_ops intr_ops = { - .intr_pending = pic_intr_pending, - .get_intr_number = pic_get_intr_number, - .raise_intr = pic_raise_intr + .intr_pending = pic_intr_pending, + .get_intr_number = pic_get_intr_number, + .raise_intr = pic_raise_intr }; static int pic_init_device(struct vm_device * dev) { - struct pic_internal * data = (struct pic_internal *)dev->private_data; - v3_register_intr_controller(dev->vm, &intr_ops, data); - data->pending_irq = 0; + struct pic_internal * data = (struct pic_internal *)dev->private_data; + v3_register_intr_controller(dev->vm, &intr_ops, data); + data->pending_irq = 0; - return 0; + return 0; } static int pic_deinit_device(struct vm_device * dev) { - return 0; + return 0; } @@ -78,21 +78,21 @@ static int pic_deinit_device(struct vm_device * dev) { static struct vm_device_ops dev_ops = { - .init = pic_init_device, - .deinit = pic_deinit_device, - .reset = NULL, - .start = NULL, - .stop = NULL + .init = pic_init_device, + .deinit = pic_deinit_device, + .reset = NULL, + .start = NULL, + .stop = NULL }; struct vm_device * v3_create_simple_pic() { - struct pic_internal * state = NULL; - state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal)); - V3_ASSERT(state != NULL); + struct pic_internal * state = NULL; + state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal)); + V3_ASSERT(state != NULL); - struct vm_device * pic_dev = v3_create_device("Simple Pic", &dev_ops, state); + struct vm_device * pic_dev = v3_create_device("Simple Pic", &dev_ops, state); - return pic_dev; + return pic_dev; } diff --git a/palacios/src/devices/timer.c b/palacios/src/devices/timer.c index 5ed434b..e0a8d70 100644 --- a/palacios/src/devices/timer.c +++ b/palacios/src/devices/timer.c @@ -24,47 +24,47 @@ #define TIMER_IRQ 32 struct timer_state { - int foo; + int foo; }; /* -static int irq_handler(uint_t irq, struct vm_device * dev) { + static int irq_handler(uint_t irq, struct vm_device * dev) { PrintDebug("Timer interrupt\n"); return 0; -} + } */ static int timer_init(struct vm_device * dev) { - //dev_hook_irq(dev, TIMER_IRQ, &irq_handler); + //dev_hook_irq(dev, TIMER_IRQ, &irq_handler); - return 0; + return 0; } static int timer_deinit(struct vm_device * dev) { - return 0; + return 0; } static struct vm_device_ops dev_ops = { - .init = timer_init, - .deinit = timer_deinit, - .reset = NULL, - .start = NULL, - .stop = NULL, + .init = timer_init, + .deinit = timer_deinit, + .reset = NULL, + .start = NULL, + .stop = NULL, }; struct vm_device * v3_create_timer() { - struct timer_state * timer = NULL; - timer = (struct timer_state *)V3_Malloc( sizeof(struct timer_state)); - V3_ASSERT(timer != NULL); + struct timer_state * timer = NULL; + timer = (struct timer_state *)V3_Malloc( sizeof(struct timer_state)); + V3_ASSERT(timer != NULL); - struct vm_device * dev = v3_create_device("Timer", &dev_ops, timer); + struct vm_device * dev = v3_create_device("Timer", &dev_ops, timer); - return dev; + return dev; }