diff options
-rw-r--r-- | hw/goldfish_pipe.c | 48 | ||||
-rw-r--r-- | hw/goldfish_pipe.h | 15 |
2 files changed, 61 insertions, 2 deletions
diff --git a/hw/goldfish_pipe.c b/hw/goldfish_pipe.c index 97daefb..276ac9a 100644 --- a/hw/goldfish_pipe.c +++ b/hw/goldfish_pipe.c @@ -55,7 +55,7 @@ /* Maximum length of pipe service name, in characters (excluding final 0) */ #define MAX_PIPE_SERVICE_NAME_SIZE 255 -#define GOLDFISH_PIPE_SAVE_VERSION 1 +#define GOLDFISH_PIPE_SAVE_VERSION 2 /*********************************************************************** *********************************************************************** @@ -960,9 +960,9 @@ struct PipeDevice { uint32_t status; uint32_t channel; uint32_t wakes; + uint64_t params_addr; }; - static void pipeDevice_doCommand( PipeDevice* dev, uint32_t command ) { @@ -1097,6 +1097,42 @@ static void pipe_dev_write(void *opaque, target_phys_addr_t offset, uint32_t val s->channel = value; break; + case PIPE_REG_PARAMS_ADDR_HIGH: + s->params_addr = (s->params_addr & ~(0xFFFFFFFFULL << 32) ) | + ((uint64_t)value << 32); + break; + + case PIPE_REG_PARAMS_ADDR_LOW: + s->params_addr = (s->params_addr & ~(0xFFFFFFFFULL) ) | value; + break; + + case PIPE_REG_ACCESS_PARAMS: + { + struct access_params aps; + uint32_t cmd; + + /* Don't touch aps.result if anything wrong */ + if (s->params_addr == 0) + break; + + cpu_physical_memory_read(s->params_addr, (void*)&aps, + sizeof(struct access_params)); + + /* sync pipe device state from batch buffer */ + s->channel = aps.channel; + s->size = aps.size; + s->address = aps.address; + cmd = aps.cmd; + if ((cmd != PIPE_CMD_READ_BUFFER) && (cmd != PIPE_CMD_WRITE_BUFFER)) + break; + + pipeDevice_doCommand(s, cmd); + aps.result = s->status; + cpu_physical_memory_write(s->params_addr, (void*)&aps, + sizeof(struct access_params)); + } + break; + default: D("%s: offset=%d (0x%x) value=%d (0x%x)\n", __FUNCTION__, offset, offset, value, value); @@ -1136,6 +1172,12 @@ static uint32_t pipe_dev_read(void *opaque, target_phys_addr_t offset) DR("%s: wakes %d", __FUNCTION__, dev->wakes); return dev->wakes; + case PIPE_REG_PARAMS_ADDR_HIGH: + return dev->params_addr >> 32; + + case PIPE_REG_PARAMS_ADDR_LOW: + return dev->params_addr & 0xFFFFFFFFUL; + default: D("%s: offset=%d (0x%x)\n", __FUNCTION__, offset, offset); } @@ -1165,6 +1207,7 @@ goldfish_pipe_save( QEMUFile* file, void* opaque ) qemu_put_be32(file, dev->status); qemu_put_be32(file, dev->channel); qemu_put_be32(file, dev->wakes); + qemu_put_be64(file, dev->params_addr); /* Count the number of pipe connections */ int count = 0; @@ -1193,6 +1236,7 @@ goldfish_pipe_load( QEMUFile* file, void* opaque, int version_id ) dev->status = qemu_get_be32(file); dev->channel = qemu_get_be32(file); dev->wakes = qemu_get_be32(file); + dev->params_addr = qemu_get_be64(file); /* Count the number of pipe connections */ int count = qemu_get_sbe32(file); diff --git a/hw/goldfish_pipe.h b/hw/goldfish_pipe.h index f08cef8..10efa96 100644 --- a/hw/goldfish_pipe.h +++ b/hw/goldfish_pipe.h @@ -153,6 +153,11 @@ extern void goldfish_pipe_wake( void* hwpipe, unsigned flags ); #define PIPE_REG_SIZE 0x0c /* read/write: buffer size */ #define PIPE_REG_ADDRESS 0x10 /* write: physical address */ #define PIPE_REG_WAKES 0x14 /* read: wake flags */ +/* read/write: parameter buffer address */ +#define PIPE_REG_PARAMS_ADDR_LOW 0x18 +#define PIPE_REG_PARAMS_ADDR_HIGH 0x1c +/* write: access with paremeter buffer */ +#define PIPE_REG_ACCESS_PARAMS 0x20 /* list of commands for PIPE_REG_COMMAND */ #define PIPE_CMD_OPEN 1 /* open new channel */ @@ -189,4 +194,14 @@ extern void goldfish_pipe_wake( void* hwpipe, unsigned flags ); void pipe_dev_init(void); +struct access_params{ + uint32_t channel; + uint32_t size; + uint32_t address; + uint32_t cmd; + uint32_t result; + /* reserved for future extension */ + uint32_t flags; +}; + #endif /* _HW_GOLDFISH_PIPE_H */ |