#include <palacios/vmm_types.h>
+//
+// MUST DO APIC SCAN FOR PHYSICAL DELIVERY
+//
+
+
+
#ifndef CONFIG_DEBUG_APIC
#undef PrintDebug
#define PrintDebug(fmt, args...)
#endif
-#ifdef CONFIG_DEBUG_APIC
static char * shorthand_str[] = {
"(no shorthand)",
"(self)",
"(Start Up)",
"(ExtInt)",
};
+#ifdef CONFIG_DEBUG_APIC
#endif
+
+#define v3_lock(p) p=p
+#define v3_unlock(p) p=p
+
+
typedef enum { APIC_TMR_INT, APIC_THERM_INT, APIC_PERF_INT,
APIC_LINT0_INT, APIC_LINT1_INT, APIC_ERR_INT } apic_irq_type_t;
#define APIC_FIXED_DELIVERY 0x0
+#define APIC_LOWEST_DELIVERY 0x1
#define APIC_SMI_DELIVERY 0x2
+#define APIC_RES1_DELIVERY 0x3
#define APIC_NMI_DELIVERY 0x4
#define APIC_INIT_DELIVERY 0x5
+#define APIC_SIPI_DELIVERY 0x6
#define APIC_EXTINT_DELIVERY 0x7
+#define APIC_SHORTHAND_NONE 0x0
+#define APIC_SHORTHAND_SELF 0x1
+#define APIC_SHORTHAND_ALL 0x2
+#define APIC_SHORTHAND_ALL_BUT_ME 0x3
+
+#define APIC_DEST_PHYSICAL 0x0
+#define APIC_DEST_LOGICAL 0x1
+
#define BASE_ADDR_MSR 0x0000001B
#define DEFAULT_BASE_ADDR 0xfee00000
struct apic_dev_state {
int num_apics;
- v3_lock_t ipi_lock; // acquired by route_ipi - only one IPI active at a time
+ // v3_lock_t ipi_lock; // acquired by route_ipi - only one IPI active at a time
struct apic_state apics[0];
} __attribute__((packed));
v3_lock_init(&(apic->lock));
- apic->in_ipi=0;
-
+ //debug
apic->in_icr=0;
}
}
}
-// Caller is expected to have locked the source apic (if any) and destination apic
+// Caller is expected to have locked the destination apic
+// Only the src_apic pointer is used
static int deliver_ipi(struct apic_state * src_apic,
struct apic_state * dst_apic,
uint32_t vector, uint8_t del_mode) {
switch (del_mode) {
- case 0: //fixed
- case 1: // lowest priority - caller needs to have decided which apic to deliver to!
+ case APIC_FIXED_DELIVERY:
+ case APIC_LOWEST_DELIVERY:
+ // lowest priority -
+ // caller needs to have decided which apic to deliver to!
+
PrintDebug("delivering IRQ %d to core %u\n", vector, dst_core->cpu_id);
do_xcall=activate_apic_irq_nolock(dst_apic, vector);
}
break;
- case 5: { //INIT
+
+ case APIC_INIT_DELIVERY: {
PrintDebug(" INIT delivery to core %u\n", dst_core->cpu_id);
break;
}
- case 6: { //SIPI
+ case APIC_SIPI_DELIVERY: {
// Sanity check
if (dst_apic->ipi_state != SIPI) {
break;
}
- case 2: // SMI
- case 3: // reserved
- case 4: // NMI
- case 7: // ExtInt
+ case APIC_SMI_DELIVERY:
+ case APIC_RES1_DELIVERY: // reserved
+ case APIC_NMI_DELIVERY:
+ case APIC_EXTINT_DELIVERY: // ExtInt
default:
PrintError("IPI %d delivery is unsupported\n", del_mode);
return -1;
}
-// Caller is expected to have locked the source apic, if any
-// route_ipi will lock the destination apics
-/*
-
- Note that this model introduces a potential deadlock:
-
- APIC A-> APIC B while APIC B -> APIC A
-
- lock(A) lock(B)
- lock(B) lock(A)
-
- This deadlock condition is not currently handled.
- A good way of handling it might be to check to see if the
- destination apic is currently sending an IPI, and,
- if so, back out and ask the caller to drop the sender lock
- reacquire it, and then try route_ipi again. However,
- logical delivery complicates this considerably since
- we can hit the above situation in the middle of sending
- the ipi to a group of destination apics.
-
-
-*/
+// route_ipi is responsible for all locking
+// the assumption is that you enter with no locks
+// there is a global lock for the icc bus, so only
+// one route_ipi progresses at any time
+// destination apics are locked as needed
+// if multiple apic locks are acquired at any point,
+// this is done in the order of the array, so no
+// deadlock should be possible
static int route_ipi(struct apic_dev_state * apic_dev,
struct apic_state * src_apic,
struct int_cmd_reg * icr) {
struct apic_state * dest_apic = NULL;
- v3_lock(apic_dev->ipi_lock);
+ //v3_lock(apic_dev->ipi_lock); // this may not be needed
// now I know only one IPI is being routed, this one
// also, I do not have any apic locks
// I need to acquire locks on pairs of src/dest apics
icr->val);
#if 1
- if (icr->vec!=48) {
- V3_Print("apic: IPI %u from apic %p to %s %u (icr=0x%llx)\n",
- icr->vec,
- src_apic,
- (icr->dst_mode == 0) ? "(physical)" : "(logical)",
- icr->dst,
- icr->val);
- }
+ if (icr->vec!=48) {
+ V3_Print("apic: IPI %s %u from apic %p to %s %s %u (icr=0x%llx)\n",
+ deliverymode_str[icr->del_mode],
+ icr->vec,
+ src_apic,
+ (icr->dst_mode == 0) ? "(physical)" : "(logical)",
+ shorthand_str[icr->dst_shorthand],
+ icr->dst,
+ icr->val);
+ }
#endif
- /* Locking issue: we hold src_apic already. We will acquire dest_apic if needed */
- /* But this could lead to deadlock - we really need to have a total ordering */
-
+
switch (icr->dst_shorthand) {
- case 0: // no shorthand
- if (icr->dst_mode == 0) {
- // physical delivery
+ case APIC_SHORTHAND_NONE: // no shorthand
+ if (icr->dst_mode == APIC_DEST_PHYSICAL) {
if (icr->dst >= apic_dev->num_apics) {
PrintError("apic: Attempted send to unregistered apic id=%u\n", icr->dst);
- return -1;
+ goto route_ipi_out_bad;
}
dest_apic = &(apic_dev->apics[icr->dst]);
+
+ V3_Print("apic: phsyical destination of %u (apic %u at 0x%p)\n", icr->dst,dest_apic->lapic_id.val,dest_apic);
v3_lock(dest_apic->lock);
icr->vec, icr->del_mode) == -1) {
PrintError("apic: Could not deliver IPI\n");
v3_unlock(dest_apic->lock);
- return -1;
+ goto route_ipi_out_bad;
}
v3_unlock(dest_apic->lock);
- } else {
- // logical delivery
- if (icr->del_mode!=1) {
+ V3_Print("apic: done\n");
+
+ } else if (icr->dst_mode == APIC_DEST_LOGICAL) {
+
+ if (icr->del_mode!=APIC_LOWEST_DELIVERY ) {
// logical, but not lowest priority
// we immediately trigger
// fixed, smi, reserved, nmi, init, sipi, etc
int i;
- int have_lock;
uint8_t mda = icr->dst;
dest_apic = &(apic_dev->apics[i]);
-
- if (src_apic==0 || dest_apic!=src_apic) {
- v3_lock(dest_apic->lock);
- have_lock=1;
- } else {
- have_lock=0;
- }
+ v3_lock(dest_apic->lock);
int del_flag = should_deliver_ipi(dest_apic->core, dest_apic, mda);
if (del_flag == -1) {
PrintError("apic: Error checking delivery mode\n");
- if (have_lock) {
- v3_unlock(dest_apic->lock);
- }
- return -1;
+ v3_unlock(dest_apic->lock);
+ goto route_ipi_out_bad;
} else if (del_flag == 1) {
if (deliver_ipi(src_apic, dest_apic,
icr->vec, icr->del_mode) == -1) {
PrintError("apic: Error: Could not deliver IPI\n");
- if (have_lock) {
- v3_unlock(dest_apic->lock);
- }
- return -1;
+ v3_unlock(dest_apic->lock);
+ goto route_ipi_out_bad;
}
}
- if (have_lock) {
- v3_unlock(dest_apic->lock);
- }
+ v3_unlock(dest_apic->lock);
}
- } else {
+ } else { //APIC_LOWEST_DELIVERY
// logical, lowest priority
- // scan, then trigger
+ // scan, keeping a lock on the current best, then trigger
int i;
- int have_cur_lock; // do we have a lock on the one we are now considering?
+ int have_cur_lock;
struct apic_state * cur_best_apic = NULL;
uint8_t mda = icr->dst;
+
+ have_cur_lock=0;
+
+
+ // Note that even if there are multiple concurrent
+ // copies of this loop executing, they are all
+ // locking in the same order
for (i = 0; i < apic_dev->num_apics; i++) {
dest_apic = &(apic_dev->apics[i]);
-
- if (src_apic==0 || dest_apic!=src_apic) {
- v3_lock(dest_apic->lock);
- have_cur_lock=1;
- } else {
- have_cur_lock=0;
- }
+ v3_lock(dest_apic->lock);
+ have_cur_lock=1;
int del_flag = should_deliver_ipi(dest_apic->core, dest_apic, mda);
if (del_flag == -1) {
PrintError("apic: Error checking delivery mode\n");
- if (have_cur_lock) {
- v3_unlock(dest_apic->lock);
- }
- if (cur_best_apic && cur_best_apic!=src_apic) {
+ v3_unlock(dest_apic->lock);
+ if (cur_best_apic && cur_best_apic!=dest_apic) {
v3_unlock(cur_best_apic->lock);
}
-
- return -1;
+ goto route_ipi_out_bad;
} else if (del_flag == 1) {
// update priority for lowest priority scan
if (!cur_best_apic) {
- cur_best_apic=dest_apic;
- have_cur_lock=0; // will unlock as cur_best_apic
+ cur_best_apic=dest_apic; // note we leave it locked
+ have_cur_lock=0; // we will unlock as cur_best_apic
} else if (dest_apic->task_prio.val < cur_best_apic->task_prio.val) {
// we now unlock the current best one and then switch
// so in the end we have a lock on the new cur_best_apic
- if (cur_best_apic!=src_apic) {
- v3_unlock(cur_best_apic->lock);
- }
+ v3_unlock(cur_best_apic->lock);
cur_best_apic=dest_apic;
- have_cur_lock=0;
+ have_cur_lock=0; // will unlock as cur_best_apic
}
}
if (have_cur_lock) {
}
// now we will deliver to the best one if it exists
+ // and it is locked
if (!cur_best_apic) {
PrintDebug("apic: lowest priority deliver, but no destinations!\n");
} else {
if (deliver_ipi(src_apic, cur_best_apic,
icr->vec, icr->del_mode) == -1) {
PrintError("apic: Error: Could not deliver IPI\n");
- if (cur_best_apic!=src_apic) {
- v3_unlock(cur_best_apic->lock);
- }
- return -1;
+ v3_unlock(cur_best_apic->lock);
+ goto route_ipi_out_bad;
} else {
- if (cur_best_apic!=src_apic) {
- v3_unlock(cur_best_apic->lock);
- }
- //V3_Print("apic: logical, lowest priority delivery to apic %u\n",cur_best_apic->lapic_id.val);
+ v3_unlock(cur_best_apic->lock);
}
+ //V3_Print("apic: logical, lowest priority delivery to apic %u\n",cur_best_apic->lapic_id.val);
}
}
}
break;
- case 1: // self
+ case APIC_SHORTHAND_SELF: // self
/* I assume I am already locked! */
break;
}
- if (icr->dst_mode == 0) { /* physical delivery */
+ v3_lock(src_apic->lock);
+
+ if (icr->dst_mode == APIC_DEST_PHYSICAL) { /* physical delivery */
if (deliver_ipi(src_apic, src_apic, icr->vec, icr->del_mode) == -1) {
PrintError("apic: Could not deliver IPI to self (physical)\n");
- return -1;
+ v3_unlock(src_apic->lock);
+ goto route_ipi_out_bad;
}
- } else { /* logical delivery */
+ } else if (icr->dst_mode == APIC_DEST_LOGICAL) { /* logical delivery */
PrintError("apic: use of logical delivery in self (untested)\n");
if (deliver_ipi(src_apic, src_apic, icr->vec, icr->del_mode) == -1) {
PrintError("apic: Could not deliver IPI to self (logical)\n");
- return -1;
+ v3_unlock(src_apic->lock);
+ goto route_ipi_out_bad;
}
}
+ v3_unlock(src_apic->lock);
break;
- case 2:
- case 3: { /* all and all-but-me */
+ case APIC_SHORTHAND_ALL:
+ case APIC_SHORTHAND_ALL_BUT_ME: { /* all and all-but-me */
/* assuming that logical verus physical doesn't matter
although it is odd that both are used */
- int have_lock;
int i;
for (i = 0; i < apic_dev->num_apics; i++) {
dest_apic = &(apic_dev->apics[i]);
-
- if ((dest_apic != src_apic) || (icr->dst_shorthand == 2)) {
- if (src_apic==0 || dest_apic!=src_apic) {
- v3_lock(dest_apic->lock);
- have_lock=1;
- } else {
- have_lock=0;
- }
+
+ if ((dest_apic != src_apic) || (icr->dst_shorthand == APIC_SHORTHAND_ALL)) {
+ v3_lock(dest_apic->lock);
if (deliver_ipi(src_apic, dest_apic, icr->vec, icr->del_mode) == -1) {
PrintError("apic: Error: Could not deliver IPI\n");
- if (have_lock) {
- v3_unlock(dest_apic->lock);
- }
- return -1;
- }
- if (have_lock) {
v3_unlock(dest_apic->lock);
+ goto route_ipi_out_bad;
}
+ v3_unlock(dest_apic->lock);
}
- }
-
- break;
+
+ }
}
+ break;
default:
PrintError("apic: Error routing IPI, invalid Mode (%d)\n", icr->dst_shorthand);
- return -1;
+ goto route_ipi_out_bad;
}
-
+
+ // route_ipi_out_good:
+ //v3_unlock(apic_dev->ipi_lock);
return 0;
+
+ route_ipi_out_bad:
+ //v3_unlock(apic_dev->ipi_lock);
+ return -1;
}
// apic->int_cmd.val, apic->int_cmd.dst);
apic->in_icr=0;
- apic->in_ipi=1;
v3_unlock(apic->lock);
- // route_ipi is responsible for locking both source and destiation(s)
+ // route_ipi is responsible for locking apics, so we go in unlocked)
if (route_ipi(apic_dev, apic, &tmp_icr) == -1) {
PrintError("IPI Routing failure\n");
goto apic_write_out_bad;
}
- v3_lock(apic->lock);
- apic->in_ipi=0;
+
+ // v3_lock(apic->lock); // expected for leaving this function
}
break;
return -1;
}
- if (do_xcall && (V3_Get_CPU() != dst)) {
+ if (do_xcall>0 && (V3_Get_CPU() != dst)) {
#ifdef CONFIG_MULTITHREAD_OS
v3_interrupt_cpu(vm, dst, 0);
#else
apic_dev->num_apics = vm->num_cores;
- v3_lock_init(&(apic_dev->ipi_lock));
+ //v3_lock_init(&(apic_dev->ipi_lock));
struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, apic_dev);
* redistribute, and modify it as specified in the file "V3VEE_LICENSE".
*/
-
#include <devices/cirrus_gfx_card.h>
#include <palacios/vmm.h>
#include <palacios/vmm_emulator.h>
#include <devices/pci.h>
#include <devices/pci_types.h>
-#include "network_console.h"
+//#include "network_console.h"
#endif
}
-static int video_write_mem(addr_t guest_addr, void * dest, uint_t length, void * priv_data) {
+static int video_write_mem(struct guest_info * core, addr_t guest_addr, void * dest, uint_t length, void * priv_data) {
struct vm_device * dev = (struct vm_device *)priv_data;
struct video_internal * data = (struct video_internal *)dev->private_data;
addr_t write_offset = guest_addr - START_ADDR;
- uint_t difference = 0x18000;
- int i = 0;
-
+// uint_t difference = 0x18000;
+// int i = 0;
+ /*
PrintDebug("\n\nInside Video Write Memory.\n\n");
PrintDebug("Guest address: %p length = %d\n", (void *)guest_addr, length);
for (i = 0; i < length; i += 2) {
PrintDebug("%c", ((char *)(V3_VAddr((void *)guest_addr)))[i]);
}
-
+ */
#if PASSTHROUGH
memcpy(data->video_memory + write_offset, V3_VAddr((void*)guest_addr), length);
#endif
-
- if (send_update(data->client_fd, data->video_memory + difference, write_offset-difference, data->start_addr_offset, length) == -1) {
+/* if (send_update(data->client_fd, data->video_memory + difference, write_offset-difference, data->start_addr_offset, length) == -1) {
PrintError("Error sending update to client\n");
return -1;
}
-
- PrintDebug(" Done.\n");
+*/
+ // PrintDebug(" Done.\n");
return length;
}
-static int video_read_port(uint16_t port, void * dest, uint_t length, struct vm_device * dev) {
- //PrintDebug("Video: Read port 0x%x\n",port);
+static int video_read_port(struct guest_info * dev, uint16_t port, void * dest, uint_t length, void * priv_data ) {
+ PrintDebug("Video: Read port 0x%x\n",port);
video_do_in(port, dest, length);
return length;
}
-static int video_read_port_generic(uint16_t port, void * dest, uint_t length, struct vm_device * dev) {
+static int video_read_port_generic(struct guest_info * dev, uint16_t port, void * dest, uint_t length, void * priv_data) {
memset(dest, 0, length);
video_do_in(port, dest, length);
return length;
}
-static int video_write_port(uint16_t port, void * src, uint_t length, struct vm_device * dev) {
- /*
+static int video_write_port(struct guest_info * dev, uint16_t port, void * dest, uint_t length, void * priv_data) {
+
PrintDebug("Video: write port 0x%x...Wrote: ", port);
uint_t i;
for(i = 0; i < length; i++){
- PrintDebug("%x", ((uint8_t*)src)[i]);
+ PrintDebug("%x", ((uint8_t*)dest)[i]);
}
- PrintDebug("...Done\n"); */
- video_do_out(port, src, length);
+ PrintDebug("...Done\n");
+ video_do_out(port, dest, length);
return length;
}
-static int video_write_port_store(uint16_t port, void * src, uint_t length, struct vm_device * dev) {
- /*
+static int video_write_port_store(struct guest_info * dev, uint16_t port, void * dest, uint_t length, void * priv_data) {
+
PrintDebug("Entering video_write_port_store...port 0x%x\n", port);
uint_t i;
for(i = 0; i < length; i++){
- PrintDebug("%x", ((uint8_t*)src)[i]);
+ PrintDebug("%x", ((uint8_t*)dest)[i]);
}
PrintDebug("...Done\n");
- */
- struct video_internal * video_state = (struct video_internal *)dev->private_data;
+
+ struct video_internal * video_state = (struct video_internal *)priv_data;
video_state->ports[port - PORT_OFFSET] = 0;
- memcpy(video_state->ports + (port - PORT_OFFSET), src, length);
- video_do_out(port, src, length);
+ memcpy(video_state->ports + (port - PORT_OFFSET), dest, length);
+ video_do_out(port, dest, length);
return length;
}
-static int video_write_port_3D5(uint16_t port, void * src, uint_t length, struct vm_device * dev) {
- struct video_internal * video_state = (struct video_internal *)dev->private_data;
+static int video_write_port_3D5(struct guest_info * dev, uint16_t port, void * dest, uint_t length, void * priv_data) {
+ struct video_internal * video_state = (struct video_internal *)priv_data;
uint8_t new_start = 0;
uint_t index = 0;
{
uint_t i = 0;
for (i = 0; i < length; i++){
- PrintDebug("%x", ((uint8_t*)src)[i]);
+ PrintDebug("%x", ((uint8_t*)dest)[i]);
}
PrintDebug("...Done\n");
}
video_state->ports[port - PORT_OFFSET] = 0;
- memcpy(video_state->ports + (port - PORT_OFFSET), src, length);
+ memcpy(video_state->ports + (port - PORT_OFFSET), dest, length);
- memcpy(&(video_state->reg_3D5[index]), src, length);
+ memcpy(&(video_state->reg_3D5[index]), dest, length);
index = video_state->ports[port - 1 - PORT_OFFSET];
// JRL: Add length check
- new_start = *((uint8_t *)src);
+ new_start = *((uint8_t *)dest);
switch (index) {
PrintDebug("Scroll lines = %d\n", diff);
- send_scroll(video_state->client_fd, diff, video_state->video_memory);
+// send_scroll(video_state->client_fd, diff, video_state->video_memory);
break;
}
PrintDebug("New Cursor Location; X=%d Y=%d\n", x, y);
- send_cursor_update(video_state->client_fd, x, y);
+// send_cursor_update(video_state->client_fd, x, y);
break;
}
default:
break;
}
- video_do_out(port, src, length);
+ video_do_out(port, dest, length);
return length;
}
-static int video_write_port_3C5(uint16_t port, void * src, uint_t length, struct vm_device * dev) {
- struct video_internal * video_state = (struct video_internal *)dev->private_data;
+static int video_write_port_3C5(struct guest_info * dev, uint16_t port, void * dest, uint_t length, void * priv_data ) {
+ struct video_internal * video_state = (struct video_internal *)priv_data;
uint_t index = 0;
{
uint_t i = 0;
for(i = 0; i < length; i++){
- PrintDebug("%x", ((uint8_t*)src)[i]);
+ PrintDebug("%x", ((uint8_t*)dest)[i]);
}
PrintDebug("...Done\n");
}
video_state->ports[port - PORT_OFFSET] = 0;
- memcpy(video_state->ports + (port - PORT_OFFSET), src, length);
+ memcpy(video_state->ports + (port - PORT_OFFSET), dest, length);
index = video_state->ports[port - 1 - PORT_OFFSET];
- memcpy(&(video_state->reg_3C4[index]), src, length);
- video_do_out(port, src, length);
+ memcpy(&(video_state->reg_3C4[index]), dest, length);
+ video_do_out(port, dest, length);
return length;
}
-static int video_write_port_3CF(uint16_t port, void * src, uint_t length, struct vm_device * dev) {
- struct video_internal * video_state = (struct video_internal *)dev->private_data;
+static int video_write_port_3CF(struct guest_info * dev, uint16_t port, void * dest, uint_t length, void * priv_data) {
+ struct video_internal * video_state = (struct video_internal *)priv_data;
PrintDebug("Entering write_port_3CF....port 0x%x\n", port);
{
uint_t i = 0;
for(i = 0; i < length; i++){
- PrintDebug("%x", ((uint8_t*)src)[i]);
+ PrintDebug("%x", ((uint8_t*)dest)[i]);
}
PrintDebug("...Done\n");
}
video_state->ports[port - PORT_OFFSET] = 0;
- memcpy(video_state->ports + (port - PORT_OFFSET), src, length);
+ memcpy(video_state->ports + (port - PORT_OFFSET), dest, length);
uint_t index = video_state->ports[port - 1 - PORT_OFFSET];
- memcpy(&(video_state->reg_3CE[index]), src, length);
- video_do_out(port, src, length);
+ memcpy(&(video_state->reg_3CE[index]), dest, length);
+ video_do_out(port, dest, length);
return length;
}
-static int video_write_port_3D4(uint16_t port, void * src, uint_t length, struct vm_device * dev){
- struct video_internal * video_state = (struct video_internal *) dev -> private_data;
+static int video_write_port_3D4(struct guest_info * dev, uint16_t port, void * dest, uint_t length, void * priv_data){
+ struct video_internal * video_state = (struct video_internal *)priv_data;
#if 1
if (length == 1) {
video_state->ports[port - PORT_OFFSET] = 0;
- memcpy(video_state->ports + (port - PORT_OFFSET), src, length);
+ memcpy(video_state->ports + (port - PORT_OFFSET), dest, length);
} else if (length == 2) {
- uint16_t new_start = *((uint16_t *)src);
- uint16_t cursor_start = *((uint16_t *)src);;
+ uint16_t new_start = *((uint16_t *)dest);
+ uint16_t cursor_start = *((uint16_t *)dest);;
//Updating the cursor
if ((cursor_start & 0x00FF) == 0x000E) {
PrintDebug("New Cursor Location; X=%d Y=%d\n", x, y);
- send_cursor_update(video_state->client_fd, x, y);
+// send_cursor_update(video_state->client_fd, x, y);
}
//Checking to see if scrolling is needed
PrintDebug("Scroll lines = %d\n", diff);
- send_scroll(video_state->client_fd, diff, video_state->video_memory+0x18000);
+// send_scroll(video_state->client_fd, diff, video_state->video_memory+0x18000);
}
} else {
// JRL ??
return -1;
}
#endif
- video_do_out(port, src, length);
+ video_do_out(port, dest, length);
return length;
}
-static int video_write_mem_region(addr_t guest_addr, void * src, uint_t length, void * priv_data) {;
- PrintDebug("Video write mem region guest_addr: 0x%p, src: 0x%p, length: %d, Value?= %x\n", (void *)guest_addr, src, length, *((uint32_t *)V3_VAddr((void *)guest_addr)));
+static int video_write_mem_region(struct guest_info * core, addr_t guest_addr, void * dest, uint_t length, void * priv_data) {;
+ PrintDebug("Video write mem region guest_addr: 0x%p, src: 0x%p, length: %d, Value?= %x\n", (void *)guest_addr, dest, length, *((uint32_t *)V3_VAddr((void *)guest_addr)));
return length;
}
-static int video_read_mem_region(addr_t guest_addr, void * dest, uint_t length, void * priv_data){
+static int video_read_mem_region(struct guest_info * core, addr_t guest_addr, void * dest, uint_t length, void * priv_data){
PrintDebug("Video: Within video_read_mem_region\n");
return length;
}
-static int video_write_io_region(addr_t guest_addr, void * src, uint_t length, void * priv_data){
+static int video_write_io_region(struct guest_info * core, addr_t guest_addr, void * dest, uint_t length, void * priv_data){
PrintDebug("Video: Within video_write_io_region\n");
return length;
}
-static int video_read_io_region(addr_t guest_addr, void * dest, uint_t length, void * priv_data){
+static int video_read_io_region(struct guest_info * core, addr_t guest_addr, void * dest, uint_t length, void * priv_data){
PrintDebug("Video: Within video_read_io_region\n");
return length;
}
static int cirrus_gfx_card_free(struct vm_device * dev) {
- v3_unhook_mem(dev->vm, START_ADDR);
+ v3_unhook_mem(dev->vm, V3_MEM_CORE_ANY, START_ADDR);
return 0;
}
+/*
static int cirrus_gfx_card_reset_device(struct vm_device * dev) {
PrintDebug("Video: reset device\n");
return 0;
PrintDebug("Video: stop device\n");
return 0;
}
-
+*/
static struct v3_device_ops dev_ops = {
- .free = cirrus_gfx_card_free,
- .reset = cirrus_gfx_card_reset_device,
- .start = cirrus_gfx_card_start_device,
- .stop = cirrus_gfx_card_stop_device,
+ .free = (int (*)(void *))cirrus_gfx_card_free,
+// .reset = cirrus_gfx_card_reset_device,
+// .start = cirrus_gfx_card_start_device,
+// .stop = cirrus_gfx_card_stop_device,
};
-static int cirrus_gfx_card_init(struct guest_info * vm, v3_cfg_tree_t * cfg){
+static int cirrus_gfx_card_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg){
struct video_internal * video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal));
- struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data);
+// struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data);
+ struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
char * dev_id = v3_cfg_val(cfg, "ID");
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, video_state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, video_state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
return -1;
}
#if PASSTHROUGH
- if (v3_hook_write_mem(vm, START_ADDR, END_ADDR, START_ADDR, &video_write_mem, dev) == -1){
+ if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, START_ADDR, &video_write_mem, dev) == -1){
PrintDebug("\n\nVideo Hook failed.\n\n");
}
#else
- if (v3_hook_write_mem(vm, START_ADDR, END_ADDR, video_memory_pa, &video_write_mem, dev) == -1){
+ if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, video_memory_pa, &video_write_mem, dev) == -1){
PrintDebug("\n\nVideo Hook failed.\n\n");
}
#endif
PrintDebug("Video: Getting client connection\n");
- video_state->client_fd = get_client_connection(vm);
+ //video_state->client_fd = get_client_connection(vm);
PrintDebug("Video: Client connection established\n");