Compare commits
38 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
34aee2552f | ||
|
9fd0e57dc9 | ||
|
2fd0f93286 | ||
|
8bd8199f70 | ||
|
2da1e39864 | ||
|
b468f27acd | ||
|
8bc2ad6a6a | ||
|
f24f1e2a85 | ||
|
5d00b89b12 | ||
|
a2b8ec7d7d | ||
|
a95ad7bcbb | ||
|
3d2d1e3960 | ||
|
3382d425bc | ||
|
2031cfc4ea | ||
|
260437cba3 | ||
|
233e01e475 | ||
|
544995e22e | ||
|
57ba0792ca | ||
|
a2daabc49a | ||
|
530a491fc3 | ||
|
2fcc1d5b69 | ||
|
cb2768eb3c | ||
|
202e9d440e | ||
|
3c398c0f86 | ||
|
4df8f71ee5 | ||
|
84eba9b8f1 | ||
|
a34b6eb776 | ||
|
1ed3d07a22 | ||
|
00f56b3dcf | ||
|
71dc1b6fcb | ||
|
eb5951f333 | ||
|
8cacc9ad14 | ||
|
76dcd4921c | ||
|
0ee50993ce | ||
|
7020c09209 | ||
|
8bb66d8601 | ||
|
bcb8c5535d | ||
|
da95f49a9d |
26
Changelog
26
Changelog
@@ -1,3 +1,29 @@
|
|||||||
|
version 0.10.4:
|
||||||
|
- Improve block range checks to remove integer overflow (Kevin Wolf)
|
||||||
|
- e1000: do not re-init PCI config space 0 (Amit Shah)
|
||||||
|
- fix AIO deletion race (Alex Graf)
|
||||||
|
- reset option roms on reboot (Glauber Costa)
|
||||||
|
- fix qcow2 corruption in cluster freeing (Gleb Natapov)
|
||||||
|
- Enable power button event generation (Gleb Natapov)
|
||||||
|
|
||||||
|
version 0.10.3:
|
||||||
|
- fix AIO cancellations (Avi Kivity)
|
||||||
|
- fix live migration error path on incoming
|
||||||
|
- avoid SEGV on pci hotplug failure (Chris Wright)
|
||||||
|
- fix serial option in -drive
|
||||||
|
- support DDIM for option roms (Glauber Costa)
|
||||||
|
- avoid fork/exec on pre-2.6.27 kernels with KVM (Jan Kiszka)
|
||||||
|
- block-vpc: don't silently create smaller images than requested (Kevin Wolf)
|
||||||
|
- Fix non-ACPI timer interrupt routing (Beth Kon)
|
||||||
|
- hpet: fix emulation of HPET_TN_SETVAL (Jan Kiszka)
|
||||||
|
- kvm: fix cpuid initialization (Jan Kiszka)
|
||||||
|
- qcow2: fix corruption on little endian hosts (Kevin Wolf)
|
||||||
|
- avoid leaing memory on hot unplug (Mark McLoughlin)
|
||||||
|
- fix savevm/migration after hot unplug (Mark McLoughlin)
|
||||||
|
- Fix keyboard mapping on newer Xords with non-default keymaps (balrog)
|
||||||
|
- Make PCI config status register read-only (Anthony Liguori)
|
||||||
|
- Fix crash on resolution change -> screen dump -> vga redraw (Avi Kivity)
|
||||||
|
|
||||||
version 0.10.2:
|
version 0.10.2:
|
||||||
|
|
||||||
- fix savevm/loadvm (Anthony Liguori)
|
- fix savevm/loadvm (Anthony Liguori)
|
||||||
|
3
aio.c
3
aio.c
@@ -44,7 +44,8 @@ static AioHandler *find_aio_handler(int fd)
|
|||||||
|
|
||||||
LIST_FOREACH(node, &aio_handlers, node) {
|
LIST_FOREACH(node, &aio_handlers, node) {
|
||||||
if (node->fd == fd)
|
if (node->fd == fd)
|
||||||
return node;
|
if (!node->deleted)
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -903,6 +903,12 @@ static int alloc_cluster_link_l2(BlockDriverState *bs, uint64_t cluster_offset,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
for (i = 0; i < m->nb_clusters; i++) {
|
for (i = 0; i < m->nb_clusters; i++) {
|
||||||
|
/* if two concurrent writes happen to the same unallocated cluster
|
||||||
|
* each write allocates separate cluster and writes data concurrently.
|
||||||
|
* The first one to complete updates l2 table with pointer to its
|
||||||
|
* cluster the second one has to do RMW (which is done above by
|
||||||
|
* copy_sectors()), update l2 table with its cluster pointer and free
|
||||||
|
* old cluster. This is what this loop does */
|
||||||
if(l2_table[l2_index + i] != 0)
|
if(l2_table[l2_index + i] != 0)
|
||||||
old_cluster[j++] = l2_table[l2_index + i];
|
old_cluster[j++] = l2_table[l2_index + i];
|
||||||
|
|
||||||
@@ -916,7 +922,8 @@ static int alloc_cluster_link_l2(BlockDriverState *bs, uint64_t cluster_offset,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
for (i = 0; i < j; i++)
|
for (i = 0; i < j; i++)
|
||||||
free_any_clusters(bs, old_cluster[i], 1);
|
free_any_clusters(bs, be64_to_cpu(old_cluster[i]) & ~QCOW_OFLAG_COPIED,
|
||||||
|
1);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
err:
|
err:
|
||||||
|
11
block-vpc.c
11
block-vpc.c
@@ -433,14 +433,16 @@ static int vpc_write(BlockDriverState *bs, int64_t sector_num,
|
|||||||
*
|
*
|
||||||
* Note that the geometry doesn't always exactly match total_sectors but
|
* Note that the geometry doesn't always exactly match total_sectors but
|
||||||
* may round it down.
|
* may round it down.
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -EFBIG if the size is larger than 127 GB
|
||||||
*/
|
*/
|
||||||
static void calculate_geometry(int64_t total_sectors, uint16_t* cyls,
|
static int calculate_geometry(int64_t total_sectors, uint16_t* cyls,
|
||||||
uint8_t* heads, uint8_t* secs_per_cyl)
|
uint8_t* heads, uint8_t* secs_per_cyl)
|
||||||
{
|
{
|
||||||
uint32_t cyls_times_heads;
|
uint32_t cyls_times_heads;
|
||||||
|
|
||||||
if (total_sectors > 65535 * 16 * 255)
|
if (total_sectors > 65535 * 16 * 255)
|
||||||
total_sectors = 65535 * 16 * 255;
|
return -EFBIG;
|
||||||
|
|
||||||
if (total_sectors > 65535 * 16 * 63) {
|
if (total_sectors > 65535 * 16 * 63) {
|
||||||
*secs_per_cyl = 255;
|
*secs_per_cyl = 255;
|
||||||
@@ -470,6 +472,8 @@ static void calculate_geometry(int64_t total_sectors, uint16_t* cyls,
|
|||||||
// Note: Rounding up deviates from the Virtual PC behaviour
|
// Note: Rounding up deviates from the Virtual PC behaviour
|
||||||
// However, we need this to avoid truncating images in qemu-img convert
|
// However, we need this to avoid truncating images in qemu-img convert
|
||||||
*cyls = (cyls_times_heads + *heads - 1) / *heads;
|
*cyls = (cyls_times_heads + *heads - 1) / *heads;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vpc_create(const char *filename, int64_t total_sectors,
|
static int vpc_create(const char *filename, int64_t total_sectors,
|
||||||
@@ -493,7 +497,8 @@ static int vpc_create(const char *filename, int64_t total_sectors,
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
// Calculate matching total_size and geometry
|
// Calculate matching total_size and geometry
|
||||||
calculate_geometry(total_sectors, &cyls, &heads, &secs_per_cyl);
|
if (calculate_geometry(total_sectors, &cyls, &heads, &secs_per_cyl))
|
||||||
|
return -EFBIG;
|
||||||
total_sectors = (int64_t) cyls * heads * secs_per_cyl;
|
total_sectors = (int64_t) cyls * heads * secs_per_cyl;
|
||||||
|
|
||||||
// Prepare the Hard Disk Footer
|
// Prepare the Hard Disk Footer
|
||||||
|
69
block.c
69
block.c
@@ -41,6 +41,8 @@
|
|||||||
#define SECTOR_BITS 9
|
#define SECTOR_BITS 9
|
||||||
#define SECTOR_SIZE (1 << SECTOR_BITS)
|
#define SECTOR_SIZE (1 << SECTOR_BITS)
|
||||||
|
|
||||||
|
static AIOPool vectored_aio_pool;
|
||||||
|
|
||||||
typedef struct BlockDriverAIOCBSync {
|
typedef struct BlockDriverAIOCBSync {
|
||||||
BlockDriverAIOCB common;
|
BlockDriverAIOCB common;
|
||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
@@ -141,6 +143,7 @@ static void bdrv_register(BlockDriver *bdrv)
|
|||||||
bdrv->bdrv_read = bdrv_read_em;
|
bdrv->bdrv_read = bdrv_read_em;
|
||||||
bdrv->bdrv_write = bdrv_write_em;
|
bdrv->bdrv_write = bdrv_write_em;
|
||||||
}
|
}
|
||||||
|
aio_pool_init(&bdrv->aio_pool, bdrv->aiocb_size, bdrv->bdrv_aio_cancel);
|
||||||
bdrv->next = first_drv;
|
bdrv->next = first_drv;
|
||||||
first_drv = bdrv;
|
first_drv = bdrv;
|
||||||
}
|
}
|
||||||
@@ -530,7 +533,10 @@ static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
|
|||||||
|
|
||||||
len = bdrv_getlength(bs);
|
len = bdrv_getlength(bs);
|
||||||
|
|
||||||
if ((offset + size) > len)
|
if (offset < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
if ((offset > len) || (len - offset < size))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1167,6 +1173,8 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
|
|||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
if (!drv->bdrv_write_compressed)
|
if (!drv->bdrv_write_compressed)
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
if (bdrv_check_request(bs, sector_num, nb_sectors))
|
||||||
|
return -EIO;
|
||||||
return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
|
return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1332,6 +1340,13 @@ typedef struct VectorTranslationState {
|
|||||||
BlockDriverAIOCB *this_aiocb;
|
BlockDriverAIOCB *this_aiocb;
|
||||||
} VectorTranslationState;
|
} VectorTranslationState;
|
||||||
|
|
||||||
|
static void bdrv_aio_cancel_vector(BlockDriverAIOCB *acb)
|
||||||
|
{
|
||||||
|
VectorTranslationState *s = acb->opaque;
|
||||||
|
|
||||||
|
bdrv_aio_cancel(s->aiocb);
|
||||||
|
}
|
||||||
|
|
||||||
static void bdrv_aio_rw_vector_cb(void *opaque, int ret)
|
static void bdrv_aio_rw_vector_cb(void *opaque, int ret)
|
||||||
{
|
{
|
||||||
VectorTranslationState *s = opaque;
|
VectorTranslationState *s = opaque;
|
||||||
@@ -1354,7 +1369,8 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
|
|||||||
|
|
||||||
{
|
{
|
||||||
VectorTranslationState *s = qemu_mallocz(sizeof(*s));
|
VectorTranslationState *s = qemu_mallocz(sizeof(*s));
|
||||||
BlockDriverAIOCB *aiocb = qemu_aio_get(bs, cb, opaque);
|
BlockDriverAIOCB *aiocb = qemu_aio_get_pool(&vectored_aio_pool, bs,
|
||||||
|
cb, opaque);
|
||||||
|
|
||||||
s->this_aiocb = aiocb;
|
s->this_aiocb = aiocb;
|
||||||
s->iov = iov;
|
s->iov = iov;
|
||||||
@@ -1443,14 +1459,7 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
|
|||||||
|
|
||||||
void bdrv_aio_cancel(BlockDriverAIOCB *acb)
|
void bdrv_aio_cancel(BlockDriverAIOCB *acb)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = acb->bs->drv;
|
acb->pool->cancel(acb);
|
||||||
|
|
||||||
if (acb->cb == bdrv_aio_rw_vector_cb) {
|
|
||||||
VectorTranslationState *s = acb->opaque;
|
|
||||||
acb = s->aiocb;
|
|
||||||
}
|
|
||||||
|
|
||||||
drv->bdrv_aio_cancel(acb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1551,6 +1560,9 @@ static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
|
|||||||
|
|
||||||
void bdrv_init(void)
|
void bdrv_init(void)
|
||||||
{
|
{
|
||||||
|
aio_pool_init(&vectored_aio_pool, sizeof(BlockDriverAIOCB),
|
||||||
|
bdrv_aio_cancel_vector);
|
||||||
|
|
||||||
bdrv_register(&bdrv_raw);
|
bdrv_register(&bdrv_raw);
|
||||||
bdrv_register(&bdrv_host_device);
|
bdrv_register(&bdrv_host_device);
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
@@ -1568,18 +1580,25 @@ void bdrv_init(void)
|
|||||||
bdrv_register(&bdrv_nbd);
|
bdrv_register(&bdrv_nbd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
|
void aio_pool_init(AIOPool *pool, int aiocb_size,
|
||||||
void *opaque)
|
void (*cancel)(BlockDriverAIOCB *acb))
|
||||||
|
{
|
||||||
|
pool->aiocb_size = aiocb_size;
|
||||||
|
pool->cancel = cancel;
|
||||||
|
pool->free_aiocb = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *qemu_aio_get_pool(AIOPool *pool, BlockDriverState *bs,
|
||||||
|
BlockDriverCompletionFunc *cb, void *opaque)
|
||||||
{
|
{
|
||||||
BlockDriver *drv;
|
|
||||||
BlockDriverAIOCB *acb;
|
BlockDriverAIOCB *acb;
|
||||||
|
|
||||||
drv = bs->drv;
|
if (pool->free_aiocb) {
|
||||||
if (drv->free_aiocb) {
|
acb = pool->free_aiocb;
|
||||||
acb = drv->free_aiocb;
|
pool->free_aiocb = acb->next;
|
||||||
drv->free_aiocb = acb->next;
|
|
||||||
} else {
|
} else {
|
||||||
acb = qemu_mallocz(drv->aiocb_size);
|
acb = qemu_mallocz(pool->aiocb_size);
|
||||||
|
acb->pool = pool;
|
||||||
}
|
}
|
||||||
acb->bs = bs;
|
acb->bs = bs;
|
||||||
acb->cb = cb;
|
acb->cb = cb;
|
||||||
@@ -1587,12 +1606,18 @@ void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
|
|||||||
return acb;
|
return acb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
return qemu_aio_get_pool(&bs->drv->aio_pool, bs, cb, opaque);
|
||||||
|
}
|
||||||
|
|
||||||
void qemu_aio_release(void *p)
|
void qemu_aio_release(void *p)
|
||||||
{
|
{
|
||||||
BlockDriverAIOCB *acb = p;
|
BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
|
||||||
BlockDriver *drv = acb->bs->drv;
|
AIOPool *pool = acb->pool;
|
||||||
acb->next = drv->free_aiocb;
|
acb->next = pool->free_aiocb;
|
||||||
drv->free_aiocb = acb;
|
pool->free_aiocb = acb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
|
14
block_int.h
14
block_int.h
@@ -30,6 +30,12 @@
|
|||||||
#define BLOCK_FLAG_COMPRESS 2
|
#define BLOCK_FLAG_COMPRESS 2
|
||||||
#define BLOCK_FLAG_COMPAT6 4
|
#define BLOCK_FLAG_COMPAT6 4
|
||||||
|
|
||||||
|
typedef struct AIOPool {
|
||||||
|
void (*cancel)(BlockDriverAIOCB *acb);
|
||||||
|
int aiocb_size;
|
||||||
|
BlockDriverAIOCB *free_aiocb;
|
||||||
|
} AIOPool;
|
||||||
|
|
||||||
struct BlockDriver {
|
struct BlockDriver {
|
||||||
const char *format_name;
|
const char *format_name;
|
||||||
int instance_size;
|
int instance_size;
|
||||||
@@ -90,7 +96,7 @@ struct BlockDriver {
|
|||||||
/* to control generic scsi devices */
|
/* to control generic scsi devices */
|
||||||
int (*bdrv_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf);
|
int (*bdrv_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf);
|
||||||
|
|
||||||
BlockDriverAIOCB *free_aiocb;
|
AIOPool aio_pool;
|
||||||
struct BlockDriver *next;
|
struct BlockDriver *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -140,6 +146,7 @@ struct BlockDriverState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct BlockDriverAIOCB {
|
struct BlockDriverAIOCB {
|
||||||
|
AIOPool *pool;
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
BlockDriverCompletionFunc *cb;
|
BlockDriverCompletionFunc *cb;
|
||||||
void *opaque;
|
void *opaque;
|
||||||
@@ -148,8 +155,13 @@ struct BlockDriverAIOCB {
|
|||||||
|
|
||||||
void get_tmp_filename(char *filename, int size);
|
void get_tmp_filename(char *filename, int size);
|
||||||
|
|
||||||
|
void aio_pool_init(AIOPool *pool, int aiocb_size,
|
||||||
|
void (*cancel)(BlockDriverAIOCB *acb));
|
||||||
|
|
||||||
void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
|
void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
|
void *qemu_aio_get_pool(AIOPool *pool, BlockDriverState *bs,
|
||||||
|
BlockDriverCompletionFunc *cb, void *opaque);
|
||||||
void qemu_aio_release(void *p);
|
void qemu_aio_release(void *p);
|
||||||
|
|
||||||
extern BlockDriverState *bdrv_first;
|
extern BlockDriverState *bdrv_first;
|
||||||
|
@@ -10,6 +10,8 @@
|
|||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
#include "block_int.h"
|
#include "block_int.h"
|
||||||
|
|
||||||
|
static AIOPool dma_aio_pool;
|
||||||
|
|
||||||
void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint)
|
void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint)
|
||||||
{
|
{
|
||||||
qsg->sg = qemu_malloc(alloc_hint * sizeof(ScatterGatherEntry));
|
qsg->sg = qemu_malloc(alloc_hint * sizeof(ScatterGatherEntry));
|
||||||
@@ -126,7 +128,7 @@ static BlockDriverAIOCB *dma_bdrv_io(
|
|||||||
DMABlockState *dbs = qemu_malloc(sizeof(*dbs));
|
DMABlockState *dbs = qemu_malloc(sizeof(*dbs));
|
||||||
|
|
||||||
dbs->bs = bs;
|
dbs->bs = bs;
|
||||||
dbs->acb = qemu_aio_get(bs, cb, opaque);
|
dbs->acb = qemu_aio_get_pool(&dma_aio_pool, bs, cb, opaque);
|
||||||
dbs->sg = sg;
|
dbs->sg = sg;
|
||||||
dbs->sector_num = sector_num;
|
dbs->sector_num = sector_num;
|
||||||
dbs->sg_cur_index = 0;
|
dbs->sg_cur_index = 0;
|
||||||
@@ -153,3 +155,14 @@ BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
|
|||||||
return dma_bdrv_io(bs, sg, sector, cb, opaque, 1);
|
return dma_bdrv_io(bs, sg, sector, cb, opaque, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dma_aio_cancel(BlockDriverAIOCB *acb)
|
||||||
|
{
|
||||||
|
DMABlockState *dbs = (DMABlockState *)acb->opaque;
|
||||||
|
|
||||||
|
bdrv_aio_cancel(dbs->acb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dma_helper_init(void)
|
||||||
|
{
|
||||||
|
aio_pool_init(&dma_aio_pool, sizeof(BlockDriverAIOCB), dma_aio_cancel);
|
||||||
|
}
|
||||||
|
1
dma.h
1
dma.h
@@ -37,5 +37,6 @@ BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs,
|
|||||||
BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
|
BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
|
||||||
QEMUSGList *sg, uint64_t sector,
|
QEMUSGList *sg, uint64_t sector,
|
||||||
BlockDriverCompletionFunc *cb, void *opaque);
|
BlockDriverCompletionFunc *cb, void *opaque);
|
||||||
|
void dma_helper_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
4
exec.c
4
exec.c
@@ -2386,6 +2386,10 @@ ram_addr_t qemu_ram_alloc(ram_addr_t size)
|
|||||||
}
|
}
|
||||||
addr = phys_ram_alloc_offset;
|
addr = phys_ram_alloc_offset;
|
||||||
phys_ram_alloc_offset = TARGET_PAGE_ALIGN(phys_ram_alloc_offset + size);
|
phys_ram_alloc_offset = TARGET_PAGE_ALIGN(phys_ram_alloc_offset + size);
|
||||||
|
|
||||||
|
if (kvm_enabled())
|
||||||
|
kvm_setup_guest_memory(phys_ram_base + addr, size);
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
hw/acpi.c
12
hw/acpi.c
@@ -604,7 +604,7 @@ static uint32_t gpe_readb(void *opaque, uint32_t addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("gpe read %lx == %lx\n", addr, val);
|
printf("gpe read %x == %x\n", addr, val);
|
||||||
#endif
|
#endif
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -646,7 +646,7 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("gpe write %lx <== %d\n", addr, val);
|
printf("gpe write %x <== %d\n", addr, val);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -666,7 +666,7 @@ static uint32_t pcihotplug_read(void *opaque, uint32_t addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("pcihotplug read %lx == %lx\n", addr, val);
|
printf("pcihotplug read %x == %x\n", addr, val);
|
||||||
#endif
|
#endif
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -684,14 +684,14 @@ static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("pcihotplug write %lx <== %d\n", addr, val);
|
printf("pcihotplug write %x <== %d\n", addr, val);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t pciej_read(void *opaque, uint32_t addr)
|
static uint32_t pciej_read(void *opaque, uint32_t addr)
|
||||||
{
|
{
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("pciej read %lx == %lx\n", addr, val);
|
printf("pciej read %x\n", addr);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -705,7 +705,7 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("pciej write %lx <== %d\n", addr, val);
|
printf("pciej write %x <== %d\n", addr, val);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
hw/e1000.c
19
hw/e1000.c
@@ -75,7 +75,6 @@ enum {
|
|||||||
typedef struct E1000State_st {
|
typedef struct E1000State_st {
|
||||||
PCIDevice dev;
|
PCIDevice dev;
|
||||||
VLANClientState *vc;
|
VLANClientState *vc;
|
||||||
NICInfo *nd;
|
|
||||||
int mmio_index;
|
int mmio_index;
|
||||||
|
|
||||||
uint32_t mac_reg[0x8000];
|
uint32_t mac_reg[0x8000];
|
||||||
@@ -1034,6 +1033,14 @@ e1000_mmio_map(PCIDevice *pci_dev, int region_num,
|
|||||||
excluded_regs[i] - 4);
|
excluded_regs[i] - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
e1000_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
E1000State *d = vc->opaque;
|
||||||
|
|
||||||
|
unregister_savevm("e1000", d);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pci_e1000_uninit(PCIDevice *dev)
|
pci_e1000_uninit(PCIDevice *dev)
|
||||||
{
|
{
|
||||||
@@ -1056,8 +1063,10 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
|
|||||||
d = (E1000State *)pci_register_device(bus, "e1000",
|
d = (E1000State *)pci_register_device(bus, "e1000",
|
||||||
sizeof(E1000State), devfn, NULL, NULL);
|
sizeof(E1000State), devfn, NULL, NULL);
|
||||||
|
|
||||||
|
if (!d)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
pci_conf = d->dev.config;
|
pci_conf = d->dev.config;
|
||||||
memset(pci_conf, 0, 256);
|
|
||||||
|
|
||||||
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
|
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
|
||||||
pci_config_set_device_id(pci_conf, E1000_DEVID);
|
pci_config_set_device_id(pci_conf, E1000_DEVID);
|
||||||
@@ -1078,7 +1087,6 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
|
|||||||
pci_register_io_region((PCIDevice *)d, 1, IOPORT_SIZE,
|
pci_register_io_region((PCIDevice *)d, 1, IOPORT_SIZE,
|
||||||
PCI_ADDRESS_SPACE_IO, ioport_map);
|
PCI_ADDRESS_SPACE_IO, ioport_map);
|
||||||
|
|
||||||
d->nd = nd;
|
|
||||||
memmove(d->eeprom_data, e1000_eeprom_template,
|
memmove(d->eeprom_data, e1000_eeprom_template,
|
||||||
sizeof e1000_eeprom_template);
|
sizeof e1000_eeprom_template);
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
@@ -1096,10 +1104,11 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
|
|||||||
memset(&d->tx, 0, sizeof d->tx);
|
memset(&d->tx, 0, sizeof d->tx);
|
||||||
|
|
||||||
d->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
d->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
e1000_receive, e1000_can_receive, d);
|
e1000_receive, e1000_can_receive,
|
||||||
|
e1000_cleanup, d);
|
||||||
d->vc->link_status_changed = e1000_set_link_status;
|
d->vc->link_status_changed = e1000_set_link_status;
|
||||||
|
|
||||||
qemu_format_nic_info_str(d->vc, d->nd->macaddr);
|
qemu_format_nic_info_str(d->vc, nd->macaddr);
|
||||||
|
|
||||||
register_savevm(info_str, -1, 2, nic_save, nic_load, d);
|
register_savevm(info_str, -1, 2, nic_save, nic_load, d);
|
||||||
d->dev.unregister = pci_e1000_uninit;
|
d->dev.unregister = pci_e1000_uninit;
|
||||||
|
@@ -1735,17 +1735,39 @@ static void nic_save(QEMUFile * f, void *opaque)
|
|||||||
qemu_put_buffer(f, s->configuration, sizeof(s->configuration));
|
qemu_put_buffer(f, s->configuration, sizeof(s->configuration));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd,
|
static void nic_cleanup(VLANClientState *vc)
|
||||||
const char *name, uint32_t device)
|
{
|
||||||
|
EEPRO100State *s = vc->opaque;
|
||||||
|
|
||||||
|
unregister_savevm(vc->model, s);
|
||||||
|
|
||||||
|
eeprom93xx_free(s->eeprom);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pci_nic_uninit(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
PCIEEPRO100State *d = (PCIEEPRO100State *) dev;
|
||||||
|
EEPRO100State *s = &d->eepro100;
|
||||||
|
|
||||||
|
cpu_unregister_io_memory(s->mmio_index);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd, uint32_t device)
|
||||||
{
|
{
|
||||||
PCIEEPRO100State *d;
|
PCIEEPRO100State *d;
|
||||||
EEPRO100State *s;
|
EEPRO100State *s;
|
||||||
|
|
||||||
logout("\n");
|
logout("\n");
|
||||||
|
|
||||||
d = (PCIEEPRO100State *) pci_register_device(bus, name,
|
d = (PCIEEPRO100State *) pci_register_device(bus, nd->model,
|
||||||
sizeof(PCIEEPRO100State), -1,
|
sizeof(PCIEEPRO100State), -1,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
if (!d)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
d->dev.unregister = pci_nic_uninit;
|
||||||
|
|
||||||
s = &d->eepro100;
|
s = &d->eepro100;
|
||||||
s->device = device;
|
s->device = device;
|
||||||
@@ -1776,30 +1798,30 @@ static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd,
|
|||||||
nic_reset(s);
|
nic_reset(s);
|
||||||
|
|
||||||
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
nic_receive, nic_can_receive, s);
|
nic_receive, nic_can_receive,
|
||||||
|
nic_cleanup, s);
|
||||||
|
|
||||||
qemu_format_nic_info_str(s->vc, s->macaddr);
|
qemu_format_nic_info_str(s->vc, s->macaddr);
|
||||||
|
|
||||||
qemu_register_reset(nic_reset, s);
|
qemu_register_reset(nic_reset, s);
|
||||||
|
|
||||||
register_savevm(name, -1, 3, nic_save, nic_load, s);
|
register_savevm(s->vc->model, -1, 3, nic_save, nic_load, s);
|
||||||
return (PCIDevice *)d;
|
return (PCIDevice *)d;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCIDevice *pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn)
|
PCIDevice *pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn)
|
||||||
{
|
{
|
||||||
return nic_init(bus, nd, "i82551", i82551);
|
return nic_init(bus, nd, i82551);
|
||||||
//~ uint8_t *pci_conf = d->dev.config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PCIDevice *pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn)
|
PCIDevice *pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn)
|
||||||
{
|
{
|
||||||
return nic_init(bus, nd, "i82557b", i82557B);
|
return nic_init(bus, nd, i82557B);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCIDevice *pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn)
|
PCIDevice *pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn)
|
||||||
{
|
{
|
||||||
return nic_init(bus, nd, "i82559er", i82559ER);
|
return nic_init(bus, nd, i82559ER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eof */
|
/* eof */
|
||||||
|
@@ -554,6 +554,16 @@ static CPUWriteMemoryFunc *eth_write[] = {
|
|||||||
ð_writel,
|
ð_writel,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void eth_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
struct fs_eth *eth = vc->opaque;
|
||||||
|
|
||||||
|
cpu_unregister_io_memory(eth->ethregs);
|
||||||
|
|
||||||
|
qemu_free(eth->dma_out);
|
||||||
|
qemu_free(eth);
|
||||||
|
}
|
||||||
|
|
||||||
void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
|
void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
|
||||||
qemu_irq *irq, target_phys_addr_t base, int phyaddr)
|
qemu_irq *irq, target_phys_addr_t base, int phyaddr)
|
||||||
{
|
{
|
||||||
@@ -585,7 +595,8 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
|
|||||||
cpu_register_physical_memory (base, 0x5c, eth->ethregs);
|
cpu_register_physical_memory (base, 0x5c, eth->ethregs);
|
||||||
|
|
||||||
eth->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
eth->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
eth_receive, eth_can_receive, eth);
|
eth_receive, eth_can_receive,
|
||||||
|
eth_cleanup, eth);
|
||||||
eth->vc->opaque = eth;
|
eth->vc->opaque = eth;
|
||||||
eth->vc->link_status_changed = eth_set_link;
|
eth->vc->link_status_changed = eth_set_link;
|
||||||
|
|
||||||
|
@@ -411,7 +411,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
|
|||||||
(timer->config & HPET_TN_SETVAL))
|
(timer->config & HPET_TN_SETVAL))
|
||||||
timer->cmp = (timer->cmp & 0xffffffff00000000ULL)
|
timer->cmp = (timer->cmp & 0xffffffff00000000ULL)
|
||||||
| new_val;
|
| new_val;
|
||||||
else {
|
if (timer_is_periodic(timer)) {
|
||||||
/*
|
/*
|
||||||
* FIXME: Clamp period to reasonable min value?
|
* FIXME: Clamp period to reasonable min value?
|
||||||
* Clamp period to reasonable max value
|
* Clamp period to reasonable max value
|
||||||
|
2
hw/hw.h
2
hw/hw.h
@@ -239,6 +239,8 @@ int register_savevm_live(const char *idstr,
|
|||||||
LoadStateHandler *load_state,
|
LoadStateHandler *load_state,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
|
|
||||||
|
void unregister_savevm(const char *idstr, void *opaque);
|
||||||
|
|
||||||
typedef void QEMUResetHandler(void *opaque);
|
typedef void QEMUResetHandler(void *opaque);
|
||||||
|
|
||||||
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
|
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
|
||||||
|
20
hw/mcf_fec.c
20
hw/mcf_fec.c
@@ -24,6 +24,7 @@ do { printf("mcf_fec: " fmt , ##args); } while (0)
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
qemu_irq *irq;
|
qemu_irq *irq;
|
||||||
|
int mmio_index;
|
||||||
VLANClientState *vc;
|
VLANClientState *vc;
|
||||||
uint32_t irq_state;
|
uint32_t irq_state;
|
||||||
uint32_t eir;
|
uint32_t eir;
|
||||||
@@ -441,21 +442,30 @@ static CPUWriteMemoryFunc *mcf_fec_writefn[] = {
|
|||||||
mcf_fec_write
|
mcf_fec_write
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void mcf_fec_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
mcf_fec_state *s = vc->opaque;
|
||||||
|
|
||||||
|
cpu_unregister_io_memory(s->mmio_index);
|
||||||
|
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq)
|
void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq)
|
||||||
{
|
{
|
||||||
mcf_fec_state *s;
|
mcf_fec_state *s;
|
||||||
int iomemtype;
|
|
||||||
|
|
||||||
qemu_check_nic_model(nd, "mcf_fec");
|
qemu_check_nic_model(nd, "mcf_fec");
|
||||||
|
|
||||||
s = (mcf_fec_state *)qemu_mallocz(sizeof(mcf_fec_state));
|
s = (mcf_fec_state *)qemu_mallocz(sizeof(mcf_fec_state));
|
||||||
s->irq = irq;
|
s->irq = irq;
|
||||||
iomemtype = cpu_register_io_memory(0, mcf_fec_readfn,
|
s->mmio_index = cpu_register_io_memory(0, mcf_fec_readfn,
|
||||||
mcf_fec_writefn, s);
|
mcf_fec_writefn, s);
|
||||||
cpu_register_physical_memory(base, 0x400, iomemtype);
|
cpu_register_physical_memory(base, 0x400, s->mmio_index);
|
||||||
|
|
||||||
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
mcf_fec_receive, mcf_fec_can_receive, s);
|
mcf_fec_receive, mcf_fec_can_receive,
|
||||||
|
mcf_fec_cleanup, s);
|
||||||
memcpy(s->macaddr, nd->macaddr, 6);
|
memcpy(s->macaddr, nd->macaddr, 6);
|
||||||
qemu_format_nic_info_str(s->vc, s->macaddr);
|
qemu_format_nic_info_str(s->vc, s->macaddr);
|
||||||
}
|
}
|
||||||
|
20
hw/mipsnet.c
20
hw/mipsnet.c
@@ -33,9 +33,9 @@ typedef struct MIPSnetState {
|
|||||||
uint32_t intctl;
|
uint32_t intctl;
|
||||||
uint8_t rx_buffer[MAX_ETH_FRAME_SIZE];
|
uint8_t rx_buffer[MAX_ETH_FRAME_SIZE];
|
||||||
uint8_t tx_buffer[MAX_ETH_FRAME_SIZE];
|
uint8_t tx_buffer[MAX_ETH_FRAME_SIZE];
|
||||||
|
int io_base;
|
||||||
qemu_irq irq;
|
qemu_irq irq;
|
||||||
VLANClientState *vc;
|
VLANClientState *vc;
|
||||||
NICInfo *nd;
|
|
||||||
} MIPSnetState;
|
} MIPSnetState;
|
||||||
|
|
||||||
static void mipsnet_reset(MIPSnetState *s)
|
static void mipsnet_reset(MIPSnetState *s)
|
||||||
@@ -232,6 +232,17 @@ static int mipsnet_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mipsnet_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
MIPSnetState *s = vc->opaque;
|
||||||
|
|
||||||
|
unregister_savevm("mipsnet", s);
|
||||||
|
|
||||||
|
isa_unassign_ioport(s->io_base, 36);
|
||||||
|
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
|
void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
|
||||||
{
|
{
|
||||||
MIPSnetState *s;
|
MIPSnetState *s;
|
||||||
@@ -247,16 +258,17 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
|
|||||||
register_ioport_write(base, 36, 4, mipsnet_ioport_write, s);
|
register_ioport_write(base, 36, 4, mipsnet_ioport_write, s);
|
||||||
register_ioport_read(base, 36, 4, mipsnet_ioport_read, s);
|
register_ioport_read(base, 36, 4, mipsnet_ioport_read, s);
|
||||||
|
|
||||||
|
s->io_base = base;
|
||||||
s->irq = irq;
|
s->irq = irq;
|
||||||
s->nd = nd;
|
|
||||||
if (nd && nd->vlan) {
|
if (nd && nd->vlan) {
|
||||||
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
mipsnet_receive, mipsnet_can_receive, s);
|
mipsnet_receive, mipsnet_can_receive,
|
||||||
|
mipsnet_cleanup, s);
|
||||||
} else {
|
} else {
|
||||||
s->vc = NULL;
|
s->vc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_format_nic_info_str(s->vc, s->nd->macaddr);
|
qemu_format_nic_info_str(s->vc, nd->macaddr);
|
||||||
|
|
||||||
mipsnet_reset(s);
|
mipsnet_reset(s);
|
||||||
register_savevm("mipsnet", 0, 0, mipsnet_save, mipsnet_load, s);
|
register_savevm("mipsnet", 0, 0, mipsnet_save, mipsnet_load, s);
|
||||||
|
@@ -545,6 +545,7 @@ typedef struct mv88w8618_eth_state {
|
|||||||
uint32_t smir;
|
uint32_t smir;
|
||||||
uint32_t icr;
|
uint32_t icr;
|
||||||
uint32_t imr;
|
uint32_t imr;
|
||||||
|
int mmio_index;
|
||||||
int vlan_header;
|
int vlan_header;
|
||||||
mv88w8618_tx_desc *tx_queue[2];
|
mv88w8618_tx_desc *tx_queue[2];
|
||||||
mv88w8618_rx_desc *rx_queue[4];
|
mv88w8618_rx_desc *rx_queue[4];
|
||||||
@@ -705,20 +706,29 @@ static CPUWriteMemoryFunc *mv88w8618_eth_writefn[] = {
|
|||||||
mv88w8618_eth_write
|
mv88w8618_eth_write
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void eth_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
mv88w8618_eth_state *s = vc->opaque;
|
||||||
|
|
||||||
|
cpu_unregister_io_memory(s->mmio_index);
|
||||||
|
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
static void mv88w8618_eth_init(NICInfo *nd, uint32_t base, qemu_irq irq)
|
static void mv88w8618_eth_init(NICInfo *nd, uint32_t base, qemu_irq irq)
|
||||||
{
|
{
|
||||||
mv88w8618_eth_state *s;
|
mv88w8618_eth_state *s;
|
||||||
int iomemtype;
|
|
||||||
|
|
||||||
qemu_check_nic_model(nd, "mv88w8618");
|
qemu_check_nic_model(nd, "mv88w8618");
|
||||||
|
|
||||||
s = qemu_mallocz(sizeof(mv88w8618_eth_state));
|
s = qemu_mallocz(sizeof(mv88w8618_eth_state));
|
||||||
s->irq = irq;
|
s->irq = irq;
|
||||||
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
eth_receive, eth_can_receive, s);
|
eth_receive, eth_can_receive,
|
||||||
iomemtype = cpu_register_io_memory(0, mv88w8618_eth_readfn,
|
eth_cleanup, s);
|
||||||
mv88w8618_eth_writefn, s);
|
s->mmio_index = cpu_register_io_memory(0, mv88w8618_eth_readfn,
|
||||||
cpu_register_physical_memory(base, MP_ETH_SIZE, iomemtype);
|
mv88w8618_eth_writefn, s);
|
||||||
|
cpu_register_physical_memory(base, MP_ETH_SIZE, s->mmio_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LCD register offsets */
|
/* LCD register offsets */
|
||||||
|
31
hw/ne2000.c
31
hw/ne2000.c
@@ -140,6 +140,7 @@ typedef struct NE2000State {
|
|||||||
uint8_t curpag;
|
uint8_t curpag;
|
||||||
uint8_t mult[8]; /* multicast mask array */
|
uint8_t mult[8]; /* multicast mask array */
|
||||||
qemu_irq irq;
|
qemu_irq irq;
|
||||||
|
int isa_io_base;
|
||||||
PCIDevice *pci_dev;
|
PCIDevice *pci_dev;
|
||||||
VLANClientState *vc;
|
VLANClientState *vc;
|
||||||
uint8_t macaddr[6];
|
uint8_t macaddr[6];
|
||||||
@@ -718,6 +719,19 @@ static int ne2000_load(QEMUFile* f,void* opaque,int version_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void isa_ne2000_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
NE2000State *s = vc->opaque;
|
||||||
|
|
||||||
|
unregister_savevm("ne2000", s);
|
||||||
|
|
||||||
|
isa_unassign_ioport(s->isa_io_base, 16);
|
||||||
|
isa_unassign_ioport(s->isa_io_base + 0x10, 2);
|
||||||
|
isa_unassign_ioport(s->isa_io_base + 0x1f, 1);
|
||||||
|
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd)
|
void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd)
|
||||||
{
|
{
|
||||||
NE2000State *s;
|
NE2000State *s;
|
||||||
@@ -736,13 +750,15 @@ void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd)
|
|||||||
|
|
||||||
register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
|
register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
|
||||||
register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
|
register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
|
||||||
|
s->isa_io_base = base;
|
||||||
s->irq = irq;
|
s->irq = irq;
|
||||||
memcpy(s->macaddr, nd->macaddr, 6);
|
memcpy(s->macaddr, nd->macaddr, 6);
|
||||||
|
|
||||||
ne2000_reset(s);
|
ne2000_reset(s);
|
||||||
|
|
||||||
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
ne2000_receive, ne2000_can_receive, s);
|
ne2000_receive, ne2000_can_receive,
|
||||||
|
isa_ne2000_cleanup, s);
|
||||||
|
|
||||||
qemu_format_nic_info_str(s->vc, s->macaddr);
|
qemu_format_nic_info_str(s->vc, s->macaddr);
|
||||||
|
|
||||||
@@ -777,6 +793,13 @@ static void ne2000_map(PCIDevice *pci_dev, int region_num,
|
|||||||
register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
|
register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ne2000_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
NE2000State *s = vc->opaque;
|
||||||
|
|
||||||
|
unregister_savevm("ne2000", s);
|
||||||
|
}
|
||||||
|
|
||||||
PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
|
PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
|
||||||
{
|
{
|
||||||
PCINE2000State *d;
|
PCINE2000State *d;
|
||||||
@@ -787,6 +810,9 @@ PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
|
|||||||
"NE2000", sizeof(PCINE2000State),
|
"NE2000", sizeof(PCINE2000State),
|
||||||
devfn,
|
devfn,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
if (!d)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
pci_conf = d->dev.config;
|
pci_conf = d->dev.config;
|
||||||
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
|
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
|
||||||
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_RTL8029);
|
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_RTL8029);
|
||||||
@@ -802,7 +828,8 @@ PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
|
|||||||
memcpy(s->macaddr, nd->macaddr, 6);
|
memcpy(s->macaddr, nd->macaddr, 6);
|
||||||
ne2000_reset(s);
|
ne2000_reset(s);
|
||||||
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
ne2000_receive, ne2000_can_receive, s);
|
ne2000_receive, ne2000_can_receive,
|
||||||
|
ne2000_cleanup, s);
|
||||||
|
|
||||||
qemu_format_nic_info_str(s->vc, s->macaddr);
|
qemu_format_nic_info_str(s->vc, s->macaddr);
|
||||||
|
|
||||||
|
41
hw/pc.c
41
hw/pc.c
@@ -63,6 +63,30 @@ static PITState *pit;
|
|||||||
static IOAPICState *ioapic;
|
static IOAPICState *ioapic;
|
||||||
static PCIDevice *i440fx_state;
|
static PCIDevice *i440fx_state;
|
||||||
|
|
||||||
|
typedef struct rom_reset_data {
|
||||||
|
uint8_t *data;
|
||||||
|
target_phys_addr_t addr;
|
||||||
|
unsigned size;
|
||||||
|
} RomResetData;
|
||||||
|
|
||||||
|
static void option_rom_reset(void *_rrd)
|
||||||
|
{
|
||||||
|
RomResetData *rrd = _rrd;
|
||||||
|
|
||||||
|
cpu_physical_memory_write_rom(rrd->addr, rrd->data, rrd->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void option_rom_setup_reset(target_phys_addr_t addr, unsigned size)
|
||||||
|
{
|
||||||
|
RomResetData *rrd = qemu_malloc(sizeof *rrd);
|
||||||
|
|
||||||
|
rrd->data = qemu_malloc(size);
|
||||||
|
cpu_physical_memory_read(addr, rrd->data, size);
|
||||||
|
rrd->addr = addr;
|
||||||
|
rrd->size = size;
|
||||||
|
qemu_register_reset(option_rom_reset, rrd);
|
||||||
|
}
|
||||||
|
|
||||||
static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
|
static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -447,7 +471,7 @@ static void bochs_bios_init(void)
|
|||||||
|
|
||||||
/* Generate an initial boot sector which sets state and jump to
|
/* Generate an initial boot sector which sets state and jump to
|
||||||
a specified vector */
|
a specified vector */
|
||||||
static void generate_bootsect(uint8_t *option_rom,
|
static void generate_bootsect(target_phys_addr_t option_rom,
|
||||||
uint32_t gpr[8], uint16_t segs[6], uint16_t ip)
|
uint32_t gpr[8], uint16_t segs[6], uint16_t ip)
|
||||||
{
|
{
|
||||||
uint8_t rom[512], *p, *reloc;
|
uint8_t rom[512], *p, *reloc;
|
||||||
@@ -521,7 +545,8 @@ static void generate_bootsect(uint8_t *option_rom,
|
|||||||
sum += rom[i];
|
sum += rom[i];
|
||||||
rom[sizeof(rom) - 1] = -sum;
|
rom[sizeof(rom) - 1] = -sum;
|
||||||
|
|
||||||
memcpy(option_rom, rom, sizeof(rom));
|
cpu_physical_memory_write_rom(option_rom, rom, sizeof(rom));
|
||||||
|
option_rom_setup_reset(option_rom, sizeof (rom));
|
||||||
}
|
}
|
||||||
|
|
||||||
static long get_file_size(FILE *f)
|
static long get_file_size(FILE *f)
|
||||||
@@ -538,7 +563,7 @@ static long get_file_size(FILE *f)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_linux(uint8_t *option_rom,
|
static void load_linux(target_phys_addr_t option_rom,
|
||||||
const char *kernel_filename,
|
const char *kernel_filename,
|
||||||
const char *initrd_filename,
|
const char *initrd_filename,
|
||||||
const char *kernel_cmdline)
|
const char *kernel_cmdline)
|
||||||
@@ -689,6 +714,12 @@ static void load_linux(uint8_t *option_rom,
|
|||||||
memset(gpr, 0, sizeof gpr);
|
memset(gpr, 0, sizeof gpr);
|
||||||
gpr[4] = cmdline_addr-real_addr-16; /* SP (-16 is paranoia) */
|
gpr[4] = cmdline_addr-real_addr-16; /* SP (-16 is paranoia) */
|
||||||
|
|
||||||
|
option_rom_setup_reset(real_addr, setup_size);
|
||||||
|
option_rom_setup_reset(prot_addr, kernel_size);
|
||||||
|
option_rom_setup_reset(cmdline_addr, cmdline_size);
|
||||||
|
if (initrd_filename)
|
||||||
|
option_rom_setup_reset(initrd_addr, initrd_size);
|
||||||
|
|
||||||
generate_bootsect(option_rom, gpr, seg, 0);
|
generate_bootsect(option_rom, gpr, seg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -896,10 +927,10 @@ vga_bios_error:
|
|||||||
offset = 0;
|
offset = 0;
|
||||||
if (linux_boot) {
|
if (linux_boot) {
|
||||||
option_rom_offset = qemu_ram_alloc(TARGET_PAGE_SIZE);
|
option_rom_offset = qemu_ram_alloc(TARGET_PAGE_SIZE);
|
||||||
load_linux(phys_ram_base + option_rom_offset,
|
load_linux(option_rom_offset,
|
||||||
kernel_filename, initrd_filename, kernel_cmdline);
|
kernel_filename, initrd_filename, kernel_cmdline);
|
||||||
cpu_register_physical_memory(0xd0000, TARGET_PAGE_SIZE,
|
cpu_register_physical_memory(0xd0000, TARGET_PAGE_SIZE,
|
||||||
option_rom_offset | IO_MEM_ROM);
|
option_rom_offset);
|
||||||
offset = TARGET_PAGE_SIZE;
|
offset = TARGET_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -37,10 +37,10 @@ static PCIDevice *qemu_pci_hot_add_nic(PCIBus *pci_bus, const char *opts)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = net_client_init ("nic", opts);
|
ret = net_client_init("nic", opts);
|
||||||
if (ret < 0 || !nd_table[ret].model)
|
if (ret < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
return pci_nic_init (pci_bus, &nd_table[ret], -1, "rtl8139");
|
return pci_nic_init(pci_bus, &nd_table[ret], -1, "rtl8139");
|
||||||
}
|
}
|
||||||
|
|
||||||
void drive_hot_add(const char *pci_addr, const char *opts)
|
void drive_hot_add(const char *pci_addr, const char *opts)
|
||||||
|
4
hw/pci.c
4
hw/pci.c
@@ -494,6 +494,8 @@ void pci_default_write_config(PCIDevice *d,
|
|||||||
case 0x01:
|
case 0x01:
|
||||||
case 0x02:
|
case 0x02:
|
||||||
case 0x03:
|
case 0x03:
|
||||||
|
case 0x06:
|
||||||
|
case 0x07:
|
||||||
case 0x08:
|
case 0x08:
|
||||||
case 0x09:
|
case 0x09:
|
||||||
case 0x0a:
|
case 0x0a:
|
||||||
@@ -517,6 +519,8 @@ void pci_default_write_config(PCIDevice *d,
|
|||||||
case 0x01:
|
case 0x01:
|
||||||
case 0x02:
|
case 0x02:
|
||||||
case 0x03:
|
case 0x03:
|
||||||
|
case 0x06:
|
||||||
|
case 0x07:
|
||||||
case 0x08:
|
case 0x08:
|
||||||
case 0x09:
|
case 0x09:
|
||||||
case 0x0a:
|
case 0x0a:
|
||||||
|
60
hw/pcnet.c
60
hw/pcnet.c
@@ -75,6 +75,7 @@ struct PCNetState_st {
|
|||||||
uint8_t buffer[4096];
|
uint8_t buffer[4096];
|
||||||
int tx_busy;
|
int tx_busy;
|
||||||
qemu_irq irq;
|
qemu_irq irq;
|
||||||
|
qemu_irq *reset_irq;
|
||||||
void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr,
|
void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr,
|
||||||
uint8_t *buf, int len, int do_bswap);
|
uint8_t *buf, int len, int do_bswap);
|
||||||
void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr,
|
void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr,
|
||||||
@@ -1929,7 +1930,15 @@ static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcnet_common_init(PCNetState *d, NICInfo *nd)
|
static void pcnet_common_cleanup(PCNetState *d)
|
||||||
|
{
|
||||||
|
unregister_savevm("pcnet", d);
|
||||||
|
|
||||||
|
qemu_del_timer(d->poll_timer);
|
||||||
|
qemu_free_timer(d->poll_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pcnet_common_init(PCNetState *d, NICInfo *nd, NetCleanup *cleanup)
|
||||||
{
|
{
|
||||||
d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
|
d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
|
||||||
|
|
||||||
@@ -1937,7 +1946,8 @@ static void pcnet_common_init(PCNetState *d, NICInfo *nd)
|
|||||||
|
|
||||||
if (nd && nd->vlan) {
|
if (nd && nd->vlan) {
|
||||||
d->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
d->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
pcnet_receive, pcnet_can_receive, d);
|
pcnet_receive, pcnet_can_receive,
|
||||||
|
cleanup, d);
|
||||||
|
|
||||||
qemu_format_nic_info_str(d->vc, d->nd->macaddr);
|
qemu_format_nic_info_str(d->vc, d->nd->macaddr);
|
||||||
} else {
|
} else {
|
||||||
@@ -1985,6 +1995,22 @@ static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
|
|||||||
cpu_physical_memory_read(addr, buf, len);
|
cpu_physical_memory_read(addr, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pci_pcnet_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
PCNetState *d = vc->opaque;
|
||||||
|
|
||||||
|
pcnet_common_cleanup(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pci_pcnet_uninit(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
PCNetState *d = (PCNetState *)dev;
|
||||||
|
|
||||||
|
cpu_unregister_io_memory(d->mmio_index);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
|
PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
|
||||||
{
|
{
|
||||||
PCNetState *d;
|
PCNetState *d;
|
||||||
@@ -1997,6 +2023,10 @@ PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
|
|||||||
|
|
||||||
d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
|
d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
|
||||||
devfn, NULL, NULL);
|
devfn, NULL, NULL);
|
||||||
|
if (!d)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
d->dev.unregister = pci_pcnet_uninit;
|
||||||
|
|
||||||
pci_conf = d->dev.config;
|
pci_conf = d->dev.config;
|
||||||
|
|
||||||
@@ -2031,7 +2061,8 @@ PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
|
|||||||
d->phys_mem_write = pci_physical_memory_write;
|
d->phys_mem_write = pci_physical_memory_write;
|
||||||
d->pci_dev = &d->dev;
|
d->pci_dev = &d->dev;
|
||||||
|
|
||||||
pcnet_common_init(d, nd);
|
pcnet_common_init(d, nd, pci_pcnet_cleanup);
|
||||||
|
|
||||||
return (PCIDevice *)d;
|
return (PCIDevice *)d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2081,29 +2112,42 @@ static CPUWriteMemoryFunc *lance_mem_write[3] = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void lance_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
PCNetState *d = vc->opaque;
|
||||||
|
|
||||||
|
pcnet_common_cleanup(d);
|
||||||
|
|
||||||
|
qemu_free_irqs(d->reset_irq);
|
||||||
|
|
||||||
|
cpu_unregister_io_memory(d->mmio_index);
|
||||||
|
|
||||||
|
qemu_free(d);
|
||||||
|
}
|
||||||
|
|
||||||
void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
|
void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
|
||||||
qemu_irq irq, qemu_irq *reset)
|
qemu_irq irq, qemu_irq *reset)
|
||||||
{
|
{
|
||||||
PCNetState *d;
|
PCNetState *d;
|
||||||
int lance_io_memory;
|
|
||||||
|
|
||||||
qemu_check_nic_model(nd, "lance");
|
qemu_check_nic_model(nd, "lance");
|
||||||
|
|
||||||
d = qemu_mallocz(sizeof(PCNetState));
|
d = qemu_mallocz(sizeof(PCNetState));
|
||||||
|
|
||||||
lance_io_memory =
|
d->mmio_index =
|
||||||
cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
|
cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
|
||||||
|
|
||||||
d->dma_opaque = dma_opaque;
|
d->dma_opaque = dma_opaque;
|
||||||
|
|
||||||
*reset = *qemu_allocate_irqs(parent_lance_reset, d, 1);
|
d->reset_irq = qemu_allocate_irqs(parent_lance_reset, d, 1);
|
||||||
|
*reset = *d->reset_irq;
|
||||||
|
|
||||||
cpu_register_physical_memory(leaddr, 4, lance_io_memory);
|
cpu_register_physical_memory(leaddr, 4, d->mmio_index);
|
||||||
|
|
||||||
d->irq = irq;
|
d->irq = irq;
|
||||||
d->phys_mem_read = ledma_memory_read;
|
d->phys_mem_read = ledma_memory_read;
|
||||||
d->phys_mem_write = ledma_memory_write;
|
d->phys_mem_write = ledma_memory_write;
|
||||||
|
|
||||||
pcnet_common_init(d, nd);
|
pcnet_common_init(d, nd, lance_cleanup);
|
||||||
}
|
}
|
||||||
#endif /* TARGET_SPARC */
|
#endif /* TARGET_SPARC */
|
||||||
|
35
hw/rtl8139.c
35
hw/rtl8139.c
@@ -3414,6 +3414,33 @@ static void rtl8139_timer(void *opaque)
|
|||||||
}
|
}
|
||||||
#endif /* RTL8139_ONBOARD_TIMER */
|
#endif /* RTL8139_ONBOARD_TIMER */
|
||||||
|
|
||||||
|
static void rtl8139_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
RTL8139State *s = vc->opaque;
|
||||||
|
|
||||||
|
if (s->cplus_txbuffer) {
|
||||||
|
qemu_free(s->cplus_txbuffer);
|
||||||
|
s->cplus_txbuffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RTL8139_ONBOARD_TIMER
|
||||||
|
qemu_del_timer(s->timer);
|
||||||
|
qemu_free_timer(s->timer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unregister_savevm("rtl8139", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pci_rtl8139_uninit(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
PCIRTL8139State *d = (PCIRTL8139State *)dev;
|
||||||
|
RTL8139State *s = &d->rtl8139;
|
||||||
|
|
||||||
|
cpu_unregister_io_memory(s->rtl8139_mmio_io_addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
|
PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
|
||||||
{
|
{
|
||||||
PCIRTL8139State *d;
|
PCIRTL8139State *d;
|
||||||
@@ -3424,6 +3451,11 @@ PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
|
|||||||
"RTL8139", sizeof(PCIRTL8139State),
|
"RTL8139", sizeof(PCIRTL8139State),
|
||||||
devfn,
|
devfn,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
if (!d)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
d->dev.unregister = pci_rtl8139_uninit;
|
||||||
|
|
||||||
pci_conf = d->dev.config;
|
pci_conf = d->dev.config;
|
||||||
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
|
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
|
||||||
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8139);
|
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8139);
|
||||||
@@ -3450,7 +3482,8 @@ PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
|
|||||||
memcpy(s->macaddr, nd->macaddr, 6);
|
memcpy(s->macaddr, nd->macaddr, 6);
|
||||||
rtl8139_reset(s);
|
rtl8139_reset(s);
|
||||||
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
rtl8139_receive, rtl8139_can_receive, s);
|
rtl8139_receive, rtl8139_can_receive,
|
||||||
|
rtl8139_cleanup, s);
|
||||||
|
|
||||||
qemu_format_nic_info_str(s->vc, s->macaddr);
|
qemu_format_nic_info_str(s->vc, s->macaddr);
|
||||||
|
|
||||||
|
@@ -42,6 +42,7 @@ typedef struct {
|
|||||||
uint8_t int_level;
|
uint8_t int_level;
|
||||||
uint8_t int_mask;
|
uint8_t int_mask;
|
||||||
uint8_t macaddr[6];
|
uint8_t macaddr[6];
|
||||||
|
int mmio_index;
|
||||||
} smc91c111_state;
|
} smc91c111_state;
|
||||||
|
|
||||||
#define RCR_SOFT_RST 0x8000
|
#define RCR_SOFT_RST 0x8000
|
||||||
@@ -690,24 +691,32 @@ static CPUWriteMemoryFunc *smc91c111_writefn[] = {
|
|||||||
smc91c111_writel
|
smc91c111_writel
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void smc91c111_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
smc91c111_state *s = vc->opaque;
|
||||||
|
|
||||||
|
cpu_unregister_io_memory(s->mmio_index);
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq)
|
void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq)
|
||||||
{
|
{
|
||||||
smc91c111_state *s;
|
smc91c111_state *s;
|
||||||
int iomemtype;
|
|
||||||
|
|
||||||
qemu_check_nic_model(nd, "smc91c111");
|
qemu_check_nic_model(nd, "smc91c111");
|
||||||
|
|
||||||
s = (smc91c111_state *)qemu_mallocz(sizeof(smc91c111_state));
|
s = (smc91c111_state *)qemu_mallocz(sizeof(smc91c111_state));
|
||||||
iomemtype = cpu_register_io_memory(0, smc91c111_readfn,
|
s->mmio_index = cpu_register_io_memory(0, smc91c111_readfn,
|
||||||
smc91c111_writefn, s);
|
smc91c111_writefn, s);
|
||||||
cpu_register_physical_memory(base, 16, iomemtype);
|
cpu_register_physical_memory(base, 16, s->mmio_index);
|
||||||
s->irq = irq;
|
s->irq = irq;
|
||||||
memcpy(s->macaddr, nd->macaddr, 6);
|
memcpy(s->macaddr, nd->macaddr, 6);
|
||||||
|
|
||||||
smc91c111_reset(s);
|
smc91c111_reset(s);
|
||||||
|
|
||||||
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
smc91c111_receive, smc91c111_can_receive, s);
|
smc91c111_receive, smc91c111_can_receive,
|
||||||
|
smc91c111_cleanup, s);
|
||||||
qemu_format_nic_info_str(s->vc, s->macaddr);
|
qemu_format_nic_info_str(s->vc, s->macaddr);
|
||||||
/* ??? Save/restore. */
|
/* ??? Save/restore. */
|
||||||
}
|
}
|
||||||
|
@@ -69,6 +69,7 @@ typedef struct {
|
|||||||
VLANClientState *vc;
|
VLANClientState *vc;
|
||||||
qemu_irq irq;
|
qemu_irq irq;
|
||||||
uint8_t macaddr[6];
|
uint8_t macaddr[6];
|
||||||
|
int mmio_index;
|
||||||
} stellaris_enet_state;
|
} stellaris_enet_state;
|
||||||
|
|
||||||
static void stellaris_enet_update(stellaris_enet_state *s)
|
static void stellaris_enet_update(stellaris_enet_state *s)
|
||||||
@@ -384,23 +385,35 @@ static int stellaris_enet_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stellaris_enet_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
stellaris_enet_state *s = vc->opaque;
|
||||||
|
|
||||||
|
unregister_savevm("stellaris_enet", s);
|
||||||
|
|
||||||
|
cpu_unregister_io_memory(s->mmio_index);
|
||||||
|
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
void stellaris_enet_init(NICInfo *nd, uint32_t base, qemu_irq irq)
|
void stellaris_enet_init(NICInfo *nd, uint32_t base, qemu_irq irq)
|
||||||
{
|
{
|
||||||
stellaris_enet_state *s;
|
stellaris_enet_state *s;
|
||||||
int iomemtype;
|
|
||||||
|
|
||||||
qemu_check_nic_model(nd, "stellaris");
|
qemu_check_nic_model(nd, "stellaris");
|
||||||
|
|
||||||
s = (stellaris_enet_state *)qemu_mallocz(sizeof(stellaris_enet_state));
|
s = (stellaris_enet_state *)qemu_mallocz(sizeof(stellaris_enet_state));
|
||||||
iomemtype = cpu_register_io_memory(0, stellaris_enet_readfn,
|
s->mmio_index = cpu_register_io_memory(0, stellaris_enet_readfn,
|
||||||
stellaris_enet_writefn, s);
|
stellaris_enet_writefn, s);
|
||||||
cpu_register_physical_memory(base, 0x00001000, iomemtype);
|
cpu_register_physical_memory(base, 0x00001000, s->mmio_index);
|
||||||
s->irq = irq;
|
s->irq = irq;
|
||||||
memcpy(s->macaddr, nd->macaddr, 6);
|
memcpy(s->macaddr, nd->macaddr, 6);
|
||||||
|
|
||||||
if (nd->vlan) {
|
if (nd->vlan) {
|
||||||
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
stellaris_enet_receive, stellaris_enet_can_receive, s);
|
stellaris_enet_receive,
|
||||||
|
stellaris_enet_can_receive,
|
||||||
|
stellaris_enet_cleanup, s);
|
||||||
qemu_format_nic_info_str(s->vc, s->macaddr);
|
qemu_format_nic_info_str(s->vc, s->macaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
hw/usb-net.c
14
hw/usb-net.c
@@ -1415,14 +1415,20 @@ static int usbnet_can_receive(void *opaque)
|
|||||||
return !s->in_len;
|
return !s->in_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void usbnet_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
USBNetState *s = vc->opaque;
|
||||||
|
|
||||||
|
rndis_clear_responsequeue(s);
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
static void usb_net_handle_destroy(USBDevice *dev)
|
static void usb_net_handle_destroy(USBDevice *dev)
|
||||||
{
|
{
|
||||||
USBNetState *s = (USBNetState *) dev;
|
USBNetState *s = (USBNetState *) dev;
|
||||||
|
|
||||||
/* TODO: remove the nd_table[] entry */
|
/* TODO: remove the nd_table[] entry */
|
||||||
qemu_del_vlan_client(s->vc);
|
qemu_del_vlan_client(s->vc);
|
||||||
rndis_clear_responsequeue(s);
|
|
||||||
qemu_free(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
USBDevice *usb_net_init(NICInfo *nd)
|
USBDevice *usb_net_init(NICInfo *nd)
|
||||||
@@ -1452,7 +1458,9 @@ USBDevice *usb_net_init(NICInfo *nd)
|
|||||||
pstrcpy(s->dev.devname, sizeof(s->dev.devname),
|
pstrcpy(s->dev.devname, sizeof(s->dev.devname),
|
||||||
"QEMU USB Network Interface");
|
"QEMU USB Network Interface");
|
||||||
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
usbnet_receive, usbnet_can_receive, s);
|
usbnet_receive,
|
||||||
|
usbnet_can_receive,
|
||||||
|
usbnet_cleanup, s);
|
||||||
|
|
||||||
qemu_format_nic_info_str(s->vc, s->mac);
|
qemu_format_nic_info_str(s->vc, s->mac);
|
||||||
|
|
||||||
|
1
hw/vga.c
1
hw/vga.c
@@ -2678,4 +2678,5 @@ static void vga_screen_dump(void *opaque, const char *filename)
|
|||||||
vga_screen_dump_graphic(s, filename);
|
vga_screen_dump_graphic(s, filename);
|
||||||
else
|
else
|
||||||
vga_screen_dump_text(s, filename);
|
vga_screen_dump_text(s, filename);
|
||||||
|
vga_invalidate_display(s);
|
||||||
}
|
}
|
||||||
|
@@ -338,11 +338,6 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
|
|||||||
if (n->promisc)
|
if (n->promisc)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#ifdef TAP_VNET_HDR
|
|
||||||
if (tap_has_vnet_hdr(n->vc->vlan->first_client))
|
|
||||||
ptr += sizeof(struct virtio_net_hdr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!memcmp(&ptr[12], vlan, sizeof(vlan))) {
|
if (!memcmp(&ptr[12], vlan, sizeof(vlan))) {
|
||||||
int vid = be16_to_cpup((uint16_t *)(ptr + 14)) & 0xfff;
|
int vid = be16_to_cpup((uint16_t *)(ptr + 14)) & 0xfff;
|
||||||
if (!(n->vlans[vid >> 5] & (1U << (vid & 0x1f))))
|
if (!(n->vlans[vid >> 5] & (1U << (vid & 0x1f))))
|
||||||
@@ -575,6 +570,21 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_net_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
VirtIONet *n = vc->opaque;
|
||||||
|
|
||||||
|
unregister_savevm("virtio-net", n);
|
||||||
|
|
||||||
|
qemu_free(n->mac_table.macs);
|
||||||
|
qemu_free(n->vlans);
|
||||||
|
|
||||||
|
qemu_del_timer(n->tx_timer);
|
||||||
|
qemu_free_timer(n->tx_timer);
|
||||||
|
|
||||||
|
virtio_cleanup(&n->vdev);
|
||||||
|
}
|
||||||
|
|
||||||
PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
|
PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
|
||||||
{
|
{
|
||||||
VirtIONet *n;
|
VirtIONet *n;
|
||||||
@@ -603,7 +613,9 @@ PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
|
|||||||
memcpy(n->mac, nd->macaddr, ETH_ALEN);
|
memcpy(n->mac, nd->macaddr, ETH_ALEN);
|
||||||
n->status = VIRTIO_NET_S_LINK_UP;
|
n->status = VIRTIO_NET_S_LINK_UP;
|
||||||
n->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
n->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
|
||||||
virtio_net_receive, virtio_net_can_receive, n);
|
virtio_net_receive,
|
||||||
|
virtio_net_can_receive,
|
||||||
|
virtio_net_cleanup, n);
|
||||||
n->vc->link_status_changed = virtio_net_set_link_status;
|
n->vc->link_status_changed = virtio_net_set_link_status;
|
||||||
|
|
||||||
qemu_format_nic_info_str(n->vc, n->mac);
|
qemu_format_nic_info_str(n->vc, n->mac);
|
||||||
|
@@ -815,6 +815,13 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
|||||||
virtio_update_irq(vdev);
|
virtio_update_irq(vdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void virtio_cleanup(VirtIODevice *vdev)
|
||||||
|
{
|
||||||
|
if (vdev->config)
|
||||||
|
qemu_free(vdev->config);
|
||||||
|
qemu_free(vdev->vq);
|
||||||
|
}
|
||||||
|
|
||||||
VirtIODevice *virtio_init_pci(PCIBus *bus, const char *name,
|
VirtIODevice *virtio_init_pci(PCIBus *bus, const char *name,
|
||||||
uint16_t vendor, uint16_t device,
|
uint16_t vendor, uint16_t device,
|
||||||
uint16_t subvendor, uint16_t subdevice,
|
uint16_t subvendor, uint16_t subdevice,
|
||||||
|
@@ -117,6 +117,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f);
|
|||||||
|
|
||||||
void virtio_load(VirtIODevice *vdev, QEMUFile *f);
|
void virtio_load(VirtIODevice *vdev, QEMUFile *f);
|
||||||
|
|
||||||
|
void virtio_cleanup(VirtIODevice *vdev);
|
||||||
|
|
||||||
void virtio_notify_config(VirtIODevice *vdev);
|
void virtio_notify_config(VirtIODevice *vdev);
|
||||||
|
|
||||||
void virtio_queue_set_notification(VirtQueue *vq, int enable);
|
void virtio_queue_set_notification(VirtQueue *vq, int enable);
|
||||||
|
18
kvm-all.c
18
kvm-all.c
@@ -656,3 +656,21 @@ int kvm_has_sync_mmu(void)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kvm_setup_guest_memory(void *start, size_t size)
|
||||||
|
{
|
||||||
|
if (!kvm_has_sync_mmu()) {
|
||||||
|
#ifdef MADV_DONTFORK
|
||||||
|
int ret = madvise(start, size, MADV_DONTFORK);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
perror("madvice");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
fprintf(stderr,
|
||||||
|
"Need MADV_DONTFORK in absence of synchronous KVM MMU\n");
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
kvm.h
2
kvm.h
@@ -46,6 +46,8 @@ int kvm_log_stop(target_phys_addr_t phys_addr, target_phys_addr_t len);
|
|||||||
|
|
||||||
int kvm_has_sync_mmu(void);
|
int kvm_has_sync_mmu(void);
|
||||||
|
|
||||||
|
void kvm_setup_guest_memory(void *start, size_t size);
|
||||||
|
|
||||||
int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
|
int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
|
||||||
int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
|
int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
|
||||||
|
|
||||||
|
119
net.c
119
net.c
@@ -329,6 +329,7 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
|
|||||||
const char *name,
|
const char *name,
|
||||||
IOReadHandler *fd_read,
|
IOReadHandler *fd_read,
|
||||||
IOCanRWHandler *fd_can_read,
|
IOCanRWHandler *fd_can_read,
|
||||||
|
NetCleanup *cleanup,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
VLANClientState *vc, **pvc;
|
VLANClientState *vc, **pvc;
|
||||||
@@ -340,6 +341,7 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
|
|||||||
vc->name = assign_name(vc, model);
|
vc->name = assign_name(vc, model);
|
||||||
vc->fd_read = fd_read;
|
vc->fd_read = fd_read;
|
||||||
vc->fd_can_read = fd_can_read;
|
vc->fd_can_read = fd_can_read;
|
||||||
|
vc->cleanup = cleanup;
|
||||||
vc->opaque = opaque;
|
vc->opaque = opaque;
|
||||||
vc->vlan = vlan;
|
vc->vlan = vlan;
|
||||||
|
|
||||||
@@ -358,9 +360,12 @@ void qemu_del_vlan_client(VLANClientState *vc)
|
|||||||
while (*pvc != NULL)
|
while (*pvc != NULL)
|
||||||
if (*pvc == vc) {
|
if (*pvc == vc) {
|
||||||
*pvc = vc->next;
|
*pvc = vc->next;
|
||||||
|
if (vc->cleanup) {
|
||||||
|
vc->cleanup(vc);
|
||||||
|
}
|
||||||
free(vc->name);
|
free(vc->name);
|
||||||
free(vc->model);
|
free(vc->model);
|
||||||
free(vc);
|
qemu_free(vc);
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
pvc = &(*pvc)->next;
|
pvc = &(*pvc)->next;
|
||||||
@@ -517,7 +522,7 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name)
|
|||||||
slirp_init(slirp_restrict, slirp_ip);
|
slirp_init(slirp_restrict, slirp_ip);
|
||||||
}
|
}
|
||||||
slirp_vc = qemu_new_vlan_client(vlan, model, name,
|
slirp_vc = qemu_new_vlan_client(vlan, model, name,
|
||||||
slirp_receive, NULL, NULL);
|
slirp_receive, NULL, NULL, NULL);
|
||||||
slirp_vc->info_str[0] = '\0';
|
slirp_vc->info_str[0] = '\0';
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -698,7 +703,8 @@ typedef struct TAPState {
|
|||||||
char down_script_arg[128];
|
char down_script_arg[128];
|
||||||
} TAPState;
|
} TAPState;
|
||||||
|
|
||||||
#ifdef HAVE_IOVEC
|
static int launch_script(const char *setup_script, const char *ifname, int fd);
|
||||||
|
|
||||||
static ssize_t tap_receive_iov(void *opaque, const struct iovec *iov,
|
static ssize_t tap_receive_iov(void *opaque, const struct iovec *iov,
|
||||||
int iovcnt)
|
int iovcnt)
|
||||||
{
|
{
|
||||||
@@ -711,7 +717,6 @@ static ssize_t tap_receive_iov(void *opaque, const struct iovec *iov,
|
|||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void tap_receive(void *opaque, const uint8_t *buf, int size)
|
static void tap_receive(void *opaque, const uint8_t *buf, int size)
|
||||||
{
|
{
|
||||||
@@ -746,6 +751,18 @@ static void tap_send(void *opaque)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tap_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
TAPState *s = vc->opaque;
|
||||||
|
|
||||||
|
if (s->down_script[0])
|
||||||
|
launch_script(s->down_script, s->down_script_arg, s->fd);
|
||||||
|
|
||||||
|
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
|
||||||
|
close(s->fd);
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
/* fd support */
|
/* fd support */
|
||||||
|
|
||||||
static TAPState *net_tap_fd_init(VLANState *vlan,
|
static TAPState *net_tap_fd_init(VLANState *vlan,
|
||||||
@@ -757,10 +774,9 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
|
|||||||
|
|
||||||
s = qemu_mallocz(sizeof(TAPState));
|
s = qemu_mallocz(sizeof(TAPState));
|
||||||
s->fd = fd;
|
s->fd = fd;
|
||||||
s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive, NULL, s);
|
s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive,
|
||||||
#ifdef HAVE_IOVEC
|
NULL, tap_cleanup, s);
|
||||||
s->vc->fd_readv = tap_receive_iov;
|
s->vc->fd_readv = tap_receive_iov;
|
||||||
#endif
|
|
||||||
qemu_set_fd_handler(s->fd, tap_send, NULL, s);
|
qemu_set_fd_handler(s->fd, tap_send, NULL, s);
|
||||||
snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
|
snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
|
||||||
return s;
|
return s;
|
||||||
@@ -1015,8 +1031,6 @@ static int net_tap_init(VLANState *vlan, const char *model,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
s = net_tap_fd_init(vlan, model, name, fd);
|
s = net_tap_fd_init(vlan, model, name, fd);
|
||||||
if (!s)
|
|
||||||
return -1;
|
|
||||||
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
|
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
|
||||||
"ifname=%s,script=%s,downscript=%s",
|
"ifname=%s,script=%s,downscript=%s",
|
||||||
ifname, setup_script, down_script);
|
ifname, setup_script, down_script);
|
||||||
@@ -1060,6 +1074,14 @@ static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vde_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
VDEState *s = vc->opaque;
|
||||||
|
qemu_set_fd_handler(vde_datafd(s->vde), NULL, NULL, NULL);
|
||||||
|
vde_close(s->vde);
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
static int net_vde_init(VLANState *vlan, const char *model,
|
static int net_vde_init(VLANState *vlan, const char *model,
|
||||||
const char *name, const char *sock,
|
const char *name, const char *sock,
|
||||||
int port, const char *group, int mode)
|
int port, const char *group, int mode)
|
||||||
@@ -1080,7 +1102,8 @@ static int net_vde_init(VLANState *vlan, const char *model,
|
|||||||
free(s);
|
free(s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
s->vc = qemu_new_vlan_client(vlan, model, name, vde_from_qemu, NULL, s);
|
s->vc = qemu_new_vlan_client(vlan, model, name, vde_from_qemu,
|
||||||
|
NULL, vde_cleanup, s);
|
||||||
qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
|
qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
|
||||||
snprintf(s->vc->info_str, sizeof(s->vc->info_str), "sock=%s,fd=%d",
|
snprintf(s->vc->info_str, sizeof(s->vc->info_str), "sock=%s,fd=%d",
|
||||||
sock, vde_datafd(s->vde));
|
sock, vde_datafd(s->vde));
|
||||||
@@ -1265,6 +1288,14 @@ fail:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void net_socket_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
NetSocketState *s = vc->opaque;
|
||||||
|
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
|
||||||
|
close(s->fd);
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
|
static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
|
||||||
const char *model,
|
const char *model,
|
||||||
const char *name,
|
const char *name,
|
||||||
@@ -1309,7 +1340,8 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
|
|||||||
s = qemu_mallocz(sizeof(NetSocketState));
|
s = qemu_mallocz(sizeof(NetSocketState));
|
||||||
s->fd = fd;
|
s->fd = fd;
|
||||||
|
|
||||||
s->vc = qemu_new_vlan_client(vlan, model, name, net_socket_receive_dgram, NULL, s);
|
s->vc = qemu_new_vlan_client(vlan, model, name, net_socket_receive_dgram,
|
||||||
|
NULL, net_socket_cleanup, s);
|
||||||
qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
|
qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
|
||||||
|
|
||||||
/* mcast: save bound address as dst */
|
/* mcast: save bound address as dst */
|
||||||
@@ -1336,8 +1368,8 @@ static NetSocketState *net_socket_fd_init_stream(VLANState *vlan,
|
|||||||
NetSocketState *s;
|
NetSocketState *s;
|
||||||
s = qemu_mallocz(sizeof(NetSocketState));
|
s = qemu_mallocz(sizeof(NetSocketState));
|
||||||
s->fd = fd;
|
s->fd = fd;
|
||||||
s->vc = qemu_new_vlan_client(vlan, model, name,
|
s->vc = qemu_new_vlan_client(vlan, model, name, net_socket_receive,
|
||||||
net_socket_receive, NULL, s);
|
NULL, net_socket_cleanup, s);
|
||||||
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
|
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
|
||||||
"socket: fd=%d", fd);
|
"socket: fd=%d", fd);
|
||||||
if (is_connected) {
|
if (is_connected) {
|
||||||
@@ -1596,10 +1628,7 @@ int net_client_init(const char *device, const char *p)
|
|||||||
vlan_id = strtol(buf, NULL, 0);
|
vlan_id = strtol(buf, NULL, 0);
|
||||||
}
|
}
|
||||||
vlan = qemu_find_vlan(vlan_id);
|
vlan = qemu_find_vlan(vlan_id);
|
||||||
if (!vlan) {
|
|
||||||
fprintf(stderr, "Could not create vlan %d\n", vlan_id);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (get_param_value(buf, sizeof(buf), "name", p)) {
|
if (get_param_value(buf, sizeof(buf), "name", p)) {
|
||||||
name = strdup(buf);
|
name = strdup(buf);
|
||||||
}
|
}
|
||||||
@@ -1610,7 +1639,8 @@ int net_client_init(const char *device, const char *p)
|
|||||||
|
|
||||||
if (idx == -1 || nb_nics >= MAX_NICS) {
|
if (idx == -1 || nb_nics >= MAX_NICS) {
|
||||||
fprintf(stderr, "Too Many NICs\n");
|
fprintf(stderr, "Too Many NICs\n");
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
nd = &nd_table[idx];
|
nd = &nd_table[idx];
|
||||||
macaddr = nd->macaddr;
|
macaddr = nd->macaddr;
|
||||||
@@ -1624,7 +1654,8 @@ int net_client_init(const char *device, const char *p)
|
|||||||
if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
|
if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
|
||||||
if (parse_macaddr(macaddr, buf) < 0) {
|
if (parse_macaddr(macaddr, buf) < 0) {
|
||||||
fprintf(stderr, "invalid syntax for ethernet address\n");
|
fprintf(stderr, "invalid syntax for ethernet address\n");
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (get_param_value(buf, sizeof(buf), "model", p)) {
|
if (get_param_value(buf, sizeof(buf), "model", p)) {
|
||||||
@@ -1664,8 +1695,9 @@ int net_client_init(const char *device, const char *p)
|
|||||||
port = strtol(p, &devname, 10);
|
port = strtol(p, &devname, 10);
|
||||||
devname++;
|
devname++;
|
||||||
if (port < 1 || port > 65535) {
|
if (port < 1 || port > 65535) {
|
||||||
fprintf(stderr, "vmchannel wrong port number\n");
|
fprintf(stderr, "vmchannel wrong port number\n");
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
vmc = malloc(sizeof(struct VMChannel));
|
vmc = malloc(sizeof(struct VMChannel));
|
||||||
snprintf(name, 20, "vmchannel%ld", port);
|
snprintf(name, 20, "vmchannel%ld", port);
|
||||||
@@ -1673,7 +1705,8 @@ int net_client_init(const char *device, const char *p)
|
|||||||
if (!vmc->hd) {
|
if (!vmc->hd) {
|
||||||
fprintf(stderr, "qemu: could not open vmchannel device"
|
fprintf(stderr, "qemu: could not open vmchannel device"
|
||||||
"'%s'\n", devname);
|
"'%s'\n", devname);
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
vmc->port = port;
|
vmc->port = port;
|
||||||
slirp_add_exec(3, vmc->hd, 4, port);
|
slirp_add_exec(3, vmc->hd, 4, port);
|
||||||
@@ -1687,7 +1720,8 @@ int net_client_init(const char *device, const char *p)
|
|||||||
char ifname[64];
|
char ifname[64];
|
||||||
if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
|
if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
|
||||||
fprintf(stderr, "tap: no interface name\n");
|
fprintf(stderr, "tap: no interface name\n");
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
vlan->nb_host_devs++;
|
vlan->nb_host_devs++;
|
||||||
ret = tap_win32_init(vlan, device, name, ifname);
|
ret = tap_win32_init(vlan, device, name, ifname);
|
||||||
@@ -1702,9 +1736,8 @@ int net_client_init(const char *device, const char *p)
|
|||||||
if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
|
if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
|
||||||
fd = strtol(buf, NULL, 0);
|
fd = strtol(buf, NULL, 0);
|
||||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||||
ret = -1;
|
net_tap_fd_init(vlan, device, name, fd);
|
||||||
if (net_tap_fd_init(vlan, device, name, fd))
|
ret = 0;
|
||||||
ret = 0;
|
|
||||||
} else {
|
} else {
|
||||||
if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
|
if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
|
||||||
ifname[0] = '\0';
|
ifname[0] = '\0';
|
||||||
@@ -1734,7 +1767,8 @@ int net_client_init(const char *device, const char *p)
|
|||||||
ret = net_socket_mcast_init(vlan, device, name, buf);
|
ret = net_socket_mcast_init(vlan, device, name, buf);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown socket options: %s\n", p);
|
fprintf(stderr, "Unknown socket options: %s\n", p);
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
vlan->nb_host_devs++;
|
vlan->nb_host_devs++;
|
||||||
} else
|
} else
|
||||||
@@ -1764,13 +1798,13 @@ int net_client_init(const char *device, const char *p)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unknown network device: %s\n", device);
|
fprintf(stderr, "Unknown network device: %s\n", device);
|
||||||
if (name)
|
ret = -1;
|
||||||
free(name);
|
goto out;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Could not initialize device '%s'\n", device);
|
fprintf(stderr, "Could not initialize device '%s'\n", device);
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
if (name)
|
if (name)
|
||||||
free(name);
|
free(name);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1819,10 +1853,6 @@ void net_host_device_remove(int vlan_id, const char *device)
|
|||||||
VLANClientState *vc;
|
VLANClientState *vc;
|
||||||
|
|
||||||
vlan = qemu_find_vlan(vlan_id);
|
vlan = qemu_find_vlan(vlan_id);
|
||||||
if (!vlan) {
|
|
||||||
term_printf("can't find vlan %d\n", vlan_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(vc = vlan->first_client; vc != NULL; vc = vc->next)
|
for(vc = vlan->first_client; vc != NULL; vc = vc->next)
|
||||||
if (!strcmp(vc->name, device))
|
if (!strcmp(vc->name, device))
|
||||||
@@ -1901,27 +1931,18 @@ void net_cleanup(void)
|
|||||||
{
|
{
|
||||||
VLANState *vlan;
|
VLANState *vlan;
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
/* close network clients */
|
/* close network clients */
|
||||||
for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
|
for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
|
||||||
VLANClientState *vc;
|
VLANClientState *vc = vlan->first_client;
|
||||||
|
|
||||||
for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
|
while (vc) {
|
||||||
if (vc->fd_read == tap_receive) {
|
VLANClientState *next = vc->next;
|
||||||
TAPState *s = vc->opaque;
|
|
||||||
|
|
||||||
if (s->down_script[0])
|
qemu_del_vlan_client(vc);
|
||||||
launch_script(s->down_script, s->down_script_arg, s->fd);
|
|
||||||
}
|
vc = next;
|
||||||
#if defined(CONFIG_VDE)
|
|
||||||
if (vc->fd_read == vde_from_qemu) {
|
|
||||||
VDEState *s = vc->opaque;
|
|
||||||
vde_close(s->vde);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_client_check(void)
|
void net_client_check(void)
|
||||||
|
3
net.h
3
net.h
@@ -9,6 +9,7 @@ typedef ssize_t (IOReadvHandler)(void *, const struct iovec *, int);
|
|||||||
|
|
||||||
typedef struct VLANClientState VLANClientState;
|
typedef struct VLANClientState VLANClientState;
|
||||||
|
|
||||||
|
typedef void (NetCleanup) (VLANClientState *);
|
||||||
typedef void (LinkStatusChanged)(VLANClientState *);
|
typedef void (LinkStatusChanged)(VLANClientState *);
|
||||||
|
|
||||||
struct VLANClientState {
|
struct VLANClientState {
|
||||||
@@ -17,6 +18,7 @@ struct VLANClientState {
|
|||||||
/* Packets may still be sent if this returns zero. It's used to
|
/* Packets may still be sent if this returns zero. It's used to
|
||||||
rate-limit the slirp code. */
|
rate-limit the slirp code. */
|
||||||
IOCanRWHandler *fd_can_read;
|
IOCanRWHandler *fd_can_read;
|
||||||
|
NetCleanup *cleanup;
|
||||||
LinkStatusChanged *link_status_changed;
|
LinkStatusChanged *link_status_changed;
|
||||||
int link_down;
|
int link_down;
|
||||||
void *opaque;
|
void *opaque;
|
||||||
@@ -40,6 +42,7 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
|
|||||||
const char *name,
|
const char *name,
|
||||||
IOReadHandler *fd_read,
|
IOReadHandler *fd_read,
|
||||||
IOCanRWHandler *fd_can_read,
|
IOCanRWHandler *fd_can_read,
|
||||||
|
NetCleanup *cleanup,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
void qemu_del_vlan_client(VLANClientState *vc);
|
void qemu_del_vlan_client(VLANClientState *vc);
|
||||||
VLANClientState *qemu_find_vlan_client(VLANState *vlan, void *opaque);
|
VLANClientState *qemu_find_vlan_client(VLANState *vlan, void *opaque);
|
||||||
|
@@ -0,0 +1,38 @@
|
|||||||
|
Fix non-ACPI Timer Interrupt Routing (Beth Kon)
|
||||||
|
|
||||||
|
Replicate ACPI irq0->inti2 override in mp table for non-acpi case.
|
||||||
|
|
||||||
|
v1 -> v2 adds comment suggested by Ryan.
|
||||||
|
|
||||||
|
Signed-off-by: Beth Kon <eak@us.ibm.com>
|
||||||
|
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
||||||
|
|
||||||
|
diff --git a/bios/rombios32.c b/bios/rombios32.c
|
||||||
|
index 7be4216..dc7b5f3 100644
|
||||||
|
--- a/bios/rombios32.c
|
||||||
|
+++ b/bios/rombios32.c
|
||||||
|
@@ -1168,6 +1168,12 @@ static void mptable_init(void)
|
||||||
|
|
||||||
|
/* irqs */
|
||||||
|
for(i = 0; i < 16; i++) {
|
||||||
|
+#ifdef BX_QEMU
|
||||||
|
+ /* One entry per ioapic input. Input 2 is covered by
|
||||||
|
+ irq0->inti2 override (i == 0). irq 2 is unused */
|
||||||
|
+ if (i == 2)
|
||||||
|
+ continue;
|
||||||
|
+#endif
|
||||||
|
putb(&q, 3); /* entry type = I/O interrupt */
|
||||||
|
putb(&q, 0); /* interrupt type = vectored interrupt */
|
||||||
|
putb(&q, 0); /* flags: po=0, el=0 */
|
||||||
|
@@ -1175,7 +1181,11 @@ static void mptable_init(void)
|
||||||
|
putb(&q, 0); /* source bus ID = ISA */
|
||||||
|
putb(&q, i); /* source bus IRQ */
|
||||||
|
putb(&q, ioapic_id); /* dest I/O APIC ID */
|
||||||
|
+#ifdef BX_QEMU
|
||||||
|
+ putb(&q, i == 0 ? 2 : i); /* dest I/O APIC interrupt in */
|
||||||
|
+#else
|
||||||
|
putb(&q, i); /* dest I/O APIC interrupt in */
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
/* patch length */
|
||||||
|
len = q - mp_config_table;
|
@@ -0,0 +1,20 @@
|
|||||||
|
Enable power button event generation.
|
||||||
|
|
||||||
|
Signed-off-by: Gleb Natapov <gleb@redhat.com>
|
||||||
|
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
||||||
|
|
||||||
|
diff --git a/bios/rombios32.c b/bios/rombios32.c
|
||||||
|
index 81e3bad..9986531 100644
|
||||||
|
--- a/bios/rombios32.c
|
||||||
|
+++ b/bios/rombios32.c
|
||||||
|
@@ -1767,8 +1767,8 @@ void acpi_bios_init(void)
|
||||||
|
fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
|
||||||
|
fadt->gpe0_blk = cpu_to_le32(0xafe0);
|
||||||
|
fadt->gpe0_blk_len = 4;
|
||||||
|
- /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */
|
||||||
|
- fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));
|
||||||
|
+ /* WBINVD + PROC_C1 + SLP_BUTTON + FIX_RTC */
|
||||||
|
+ fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 6));
|
||||||
|
acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
|
||||||
|
sizeof(*fadt), 1);
|
||||||
|
|
@@ -9,3 +9,5 @@
|
|||||||
0009_qemu-bios-pci-hotplug-support.patch
|
0009_qemu-bios-pci-hotplug-support.patch
|
||||||
0010_bios-mark-the-acpi-sci-interrupt-as-connected-to-irq-9.patch
|
0010_bios-mark-the-acpi-sci-interrupt-as-connected-to-irq-9.patch
|
||||||
0011_read-additional-acpi-tables-from-a-vm.patch
|
0011_read-additional-acpi-tables-from-a-vm.patch
|
||||||
|
0013_fix-non-acpi-timer-interrupt-routing.patch
|
||||||
|
0015_enable-power-button-even-generation.patch
|
||||||
|
BIN
pc-bios/bios.bin
BIN
pc-bios/bios.bin
Binary file not shown.
@@ -290,6 +290,8 @@ static int img_create(int argc, char **argv)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ret == -ENOTSUP) {
|
if (ret == -ENOTSUP) {
|
||||||
error("Formatting or formatting option not supported for file format '%s'", fmt);
|
error("Formatting or formatting option not supported for file format '%s'", fmt);
|
||||||
|
} else if (ret == -EFBIG) {
|
||||||
|
error("The image size is too large for file format '%s'", fmt);
|
||||||
} else {
|
} else {
|
||||||
error("Error while formatting");
|
error("Error while formatting");
|
||||||
}
|
}
|
||||||
@@ -477,7 +479,9 @@ static int img_convert(int argc, char **argv)
|
|||||||
ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
|
ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ret == -ENOTSUP) {
|
if (ret == -ENOTSUP) {
|
||||||
error("Formatting not supported for file format '%s'", fmt);
|
error("Formatting not supported for file format '%s'", out_fmt);
|
||||||
|
} else if (ret == -EFBIG) {
|
||||||
|
error("The image size is too large for file format '%s'", out_fmt);
|
||||||
} else {
|
} else {
|
||||||
error("Error while formatting '%s'", out_filename);
|
error("Error while formatting '%s'", out_filename);
|
||||||
}
|
}
|
||||||
|
17
savevm.c
17
savevm.c
@@ -643,6 +643,22 @@ int register_savevm(const char *idstr,
|
|||||||
NULL, save_state, load_state, opaque);
|
NULL, save_state, load_state, opaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unregister_savevm(const char *idstr, void *opaque)
|
||||||
|
{
|
||||||
|
SaveStateEntry **pse;
|
||||||
|
|
||||||
|
pse = &first_se;
|
||||||
|
while (*pse != NULL) {
|
||||||
|
if (strcmp((*pse)->idstr, idstr) == 0 && (*pse)->opaque == opaque) {
|
||||||
|
SaveStateEntry *next = (*pse)->next;
|
||||||
|
qemu_free(*pse);
|
||||||
|
*pse = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pse = &(*pse)->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define QEMU_VM_FILE_MAGIC 0x5145564d
|
#define QEMU_VM_FILE_MAGIC 0x5145564d
|
||||||
#define QEMU_VM_FILE_VERSION_COMPAT 0x00000002
|
#define QEMU_VM_FILE_VERSION_COMPAT 0x00000002
|
||||||
#define QEMU_VM_FILE_VERSION 0x00000003
|
#define QEMU_VM_FILE_VERSION 0x00000003
|
||||||
@@ -835,6 +851,7 @@ static int qemu_loadvm_state_v2(QEMUFile *f)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
|
fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
|
||||||
instance_id, idstr);
|
instance_id, idstr);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* always seek to exact end of record */
|
/* always seek to exact end of record */
|
||||||
|
4
sdl.c
4
sdl.c
@@ -161,9 +161,9 @@ static int check_for_evdev(void)
|
|||||||
keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes);
|
keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes);
|
||||||
if (keycodes == NULL)
|
if (keycodes == NULL)
|
||||||
fprintf(stderr, "could not lookup keycode name\n");
|
fprintf(stderr, "could not lookup keycode name\n");
|
||||||
else if (strstart(keycodes, "evdev_", NULL))
|
else if (strstart(keycodes, "evdev", NULL))
|
||||||
has_evdev = 1;
|
has_evdev = 1;
|
||||||
else if (!strstart(keycodes, "xfree86_", NULL))
|
else if (!strstart(keycodes, "xfree86", NULL))
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"unknown keycodes `%s', please report to qemu-devel@nongnu.org\n",
|
"unknown keycodes `%s', please report to qemu-devel@nongnu.org\n",
|
||||||
keycodes);
|
keycodes);
|
||||||
|
15
tap-win32.c
15
tap-win32.c
@@ -639,6 +639,18 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle,
|
|||||||
tap_win32_overlapped_t *handle;
|
tap_win32_overlapped_t *handle;
|
||||||
} TAPState;
|
} TAPState;
|
||||||
|
|
||||||
|
static void tap_cleanup(VLANClientState *vc)
|
||||||
|
{
|
||||||
|
TAPState *s = vc->opaque;
|
||||||
|
|
||||||
|
qemu_del_wait_object(s->handle->tap_semaphore, NULL, NULL);
|
||||||
|
|
||||||
|
/* FIXME: need to kill thread and close file handle:
|
||||||
|
tap_win32_close(s);
|
||||||
|
*/
|
||||||
|
qemu_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
static void tap_receive(void *opaque, const uint8_t *buf, int size)
|
static void tap_receive(void *opaque, const uint8_t *buf, int size)
|
||||||
{
|
{
|
||||||
TAPState *s = opaque;
|
TAPState *s = opaque;
|
||||||
@@ -673,7 +685,8 @@ int tap_win32_init(VLANState *vlan, const char *model,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive, NULL, s);
|
s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive,
|
||||||
|
NULL, tap_cleanup, s);
|
||||||
|
|
||||||
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
|
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
|
||||||
"tap: ifname=%s", ifname);
|
"tap: ifname=%s", ifname);
|
||||||
|
@@ -40,12 +40,11 @@ int kvm_arch_init_vcpu(CPUState *env)
|
|||||||
struct kvm_cpuid_entry2 entries[100];
|
struct kvm_cpuid_entry2 entries[100];
|
||||||
} __attribute__((packed)) cpuid_data;
|
} __attribute__((packed)) cpuid_data;
|
||||||
uint32_t limit, i, j, cpuid_i;
|
uint32_t limit, i, j, cpuid_i;
|
||||||
uint32_t eax, ebx, ecx, edx;
|
uint32_t unused;
|
||||||
|
|
||||||
cpuid_i = 0;
|
cpuid_i = 0;
|
||||||
|
|
||||||
cpu_x86_cpuid(env, 0, 0, &eax, &ebx, &ecx, &edx);
|
cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
|
||||||
limit = eax;
|
|
||||||
|
|
||||||
for (i = 0; i <= limit; i++) {
|
for (i = 0; i <= limit; i++) {
|
||||||
struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
|
struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
|
||||||
@@ -55,26 +54,17 @@ int kvm_arch_init_vcpu(CPUState *env)
|
|||||||
/* Keep reading function 2 till all the input is received */
|
/* Keep reading function 2 till all the input is received */
|
||||||
int times;
|
int times;
|
||||||
|
|
||||||
cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
|
|
||||||
times = eax & 0xff;
|
|
||||||
|
|
||||||
c->function = i;
|
c->function = i;
|
||||||
c->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
|
c->flags = KVM_CPUID_FLAG_STATEFUL_FUNC |
|
||||||
c->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
|
KVM_CPUID_FLAG_STATE_READ_NEXT;
|
||||||
c->eax = eax;
|
cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
|
||||||
c->ebx = ebx;
|
times = c->eax & 0xff;
|
||||||
c->ecx = ecx;
|
|
||||||
c->edx = edx;
|
|
||||||
|
|
||||||
for (j = 1; j < times; ++j) {
|
for (j = 1; j < times; ++j) {
|
||||||
cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
|
c = &cpuid_data.entries[cpuid_i++];
|
||||||
c->function = i;
|
c->function = i;
|
||||||
c->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
|
c->flags = KVM_CPUID_FLAG_STATEFUL_FUNC;
|
||||||
c->eax = eax;
|
cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
|
||||||
c->ebx = ebx;
|
|
||||||
c->ecx = ecx;
|
|
||||||
c->edx = edx;
|
|
||||||
c = &cpuid_data.entries[++cpuid_i];
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -82,46 +72,36 @@ int kvm_arch_init_vcpu(CPUState *env)
|
|||||||
case 0xb:
|
case 0xb:
|
||||||
case 0xd:
|
case 0xd:
|
||||||
for (j = 0; ; j++) {
|
for (j = 0; ; j++) {
|
||||||
cpu_x86_cpuid(env, i, j, &eax, &ebx, &ecx, &edx);
|
|
||||||
c->function = i;
|
c->function = i;
|
||||||
c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
|
c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
|
||||||
c->index = j;
|
c->index = j;
|
||||||
c->eax = eax;
|
cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->edx);
|
||||||
c->ebx = ebx;
|
|
||||||
c->ecx = ecx;
|
|
||||||
c->edx = edx;
|
|
||||||
c = &cpuid_data.entries[++cpuid_i];
|
|
||||||
|
|
||||||
if (i == 4 && eax == 0)
|
if (i == 4 && c->eax == 0)
|
||||||
break;
|
break;
|
||||||
if (i == 0xb && !(ecx & 0xff00))
|
if (i == 0xb && !(c->ecx & 0xff00))
|
||||||
break;
|
break;
|
||||||
if (i == 0xd && eax == 0)
|
if (i == 0xd && c->eax == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
c = &cpuid_data.entries[cpuid_i++];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
|
|
||||||
c->function = i;
|
c->function = i;
|
||||||
c->eax = eax;
|
c->flags = 0;
|
||||||
c->ebx = ebx;
|
cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
|
||||||
c->ecx = ecx;
|
|
||||||
c->edx = edx;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cpu_x86_cpuid(env, 0x80000000, 0, &eax, &ebx, &ecx, &edx);
|
cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused);
|
||||||
limit = eax;
|
|
||||||
|
|
||||||
for (i = 0x80000000; i <= limit; i++) {
|
for (i = 0x80000000; i <= limit; i++) {
|
||||||
struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
|
struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
|
||||||
|
|
||||||
cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);
|
|
||||||
c->function = i;
|
c->function = i;
|
||||||
c->eax = eax;
|
c->flags = 0;
|
||||||
c->ebx = ebx;
|
cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
|
||||||
c->ecx = ecx;
|
|
||||||
c->edx = edx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuid_data.cpuid.nent = cpuid_i;
|
cpuid_data.cpuid.nent = cpuid_i;
|
||||||
|
3
vl.c
3
vl.c
@@ -2566,7 +2566,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
|
|||||||
drives_table[drives_table_idx].unit = unit_id;
|
drives_table[drives_table_idx].unit = unit_id;
|
||||||
drives_table[drives_table_idx].onerror = onerror;
|
drives_table[drives_table_idx].onerror = onerror;
|
||||||
drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
|
drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
|
||||||
strncpy(drives_table[nb_drives].serial, serial, sizeof(serial));
|
strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
|
||||||
nb_drives++;
|
nb_drives++;
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
@@ -5485,6 +5485,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
cpu_exec_init_all(tb_size * 1024 * 1024);
|
cpu_exec_init_all(tb_size * 1024 * 1024);
|
||||||
|
|
||||||
bdrv_init();
|
bdrv_init();
|
||||||
|
dma_helper_init();
|
||||||
|
|
||||||
/* we always create the cdrom drive, even if no disk is there */
|
/* we always create the cdrom drive, even if no disk is there */
|
||||||
|
|
||||||
|
9
vnc.c
9
vnc.c
@@ -1216,30 +1216,39 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
|
|||||||
case 0xb8: /* Right ALT */
|
case 0xb8: /* Right ALT */
|
||||||
break;
|
break;
|
||||||
case 0xc8:
|
case 0xc8:
|
||||||
|
case 0x48:
|
||||||
kbd_put_keysym(QEMU_KEY_UP);
|
kbd_put_keysym(QEMU_KEY_UP);
|
||||||
break;
|
break;
|
||||||
case 0xd0:
|
case 0xd0:
|
||||||
|
case 0x50:
|
||||||
kbd_put_keysym(QEMU_KEY_DOWN);
|
kbd_put_keysym(QEMU_KEY_DOWN);
|
||||||
break;
|
break;
|
||||||
case 0xcb:
|
case 0xcb:
|
||||||
|
case 0x4b:
|
||||||
kbd_put_keysym(QEMU_KEY_LEFT);
|
kbd_put_keysym(QEMU_KEY_LEFT);
|
||||||
break;
|
break;
|
||||||
case 0xcd:
|
case 0xcd:
|
||||||
|
case 0x4d:
|
||||||
kbd_put_keysym(QEMU_KEY_RIGHT);
|
kbd_put_keysym(QEMU_KEY_RIGHT);
|
||||||
break;
|
break;
|
||||||
case 0xd3:
|
case 0xd3:
|
||||||
|
case 0x53:
|
||||||
kbd_put_keysym(QEMU_KEY_DELETE);
|
kbd_put_keysym(QEMU_KEY_DELETE);
|
||||||
break;
|
break;
|
||||||
case 0xc7:
|
case 0xc7:
|
||||||
|
case 0x47:
|
||||||
kbd_put_keysym(QEMU_KEY_HOME);
|
kbd_put_keysym(QEMU_KEY_HOME);
|
||||||
break;
|
break;
|
||||||
case 0xcf:
|
case 0xcf:
|
||||||
|
case 0x4f:
|
||||||
kbd_put_keysym(QEMU_KEY_END);
|
kbd_put_keysym(QEMU_KEY_END);
|
||||||
break;
|
break;
|
||||||
case 0xc9:
|
case 0xc9:
|
||||||
|
case 0x49:
|
||||||
kbd_put_keysym(QEMU_KEY_PAGEUP);
|
kbd_put_keysym(QEMU_KEY_PAGEUP);
|
||||||
break;
|
break;
|
||||||
case 0xd1:
|
case 0xd1:
|
||||||
|
case 0x51:
|
||||||
kbd_put_keysym(QEMU_KEY_PAGEDOWN);
|
kbd_put_keysym(QEMU_KEY_PAGEDOWN);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Reference in New Issue
Block a user