Compare commits
273 Commits
pull-gtk-2
...
qemu-2.2.0
Author | SHA1 | Date | |
---|---|---|---|
|
45e1611de8 | ||
|
d00e6cddc2 | ||
|
54f3a180a3 | ||
|
0d7954c288 | ||
|
b19ca18802 | ||
|
bf25983345 | ||
|
d3532a0db0 | ||
|
db12451dec | ||
|
771b6ed37e | ||
|
4cae4d5aca | ||
|
490309fcfb | ||
|
3ef4ebcc5c | ||
|
dc622deb2d | ||
|
f3b3766899 | ||
|
d1048bef9d | ||
|
2528043f1f | ||
|
df5b2adb73 | ||
|
ca6028185d | ||
|
dd0247e09a | ||
|
6c150fbd34 | ||
|
8e815eeefe | ||
|
4f99ab7a78 | ||
|
ad5b88b1f1 | ||
|
109e90e470 | ||
|
085f8e88ba | ||
|
b03541fa77 | ||
|
3d4a70f80f | ||
|
a31a7475e9 | ||
|
5224c88dd3 | ||
|
8092cb7132 | ||
|
60e68042cf | ||
|
24bf10dac3 | ||
|
0c0de1b681 | ||
|
91aa70ab2a | ||
|
a2b257d621 | ||
|
92a37a04d6 | ||
|
34dde13685 | ||
|
b8865591d4 | ||
|
c409572678 | ||
|
0e88f47850 | ||
|
a00c117338 | ||
|
b0af844007 | ||
|
7b50d00911 | ||
|
8db804ac41 | ||
|
7a8919dc29 | ||
|
b310a2a609 | ||
|
8a0f9b5263 | ||
|
9c7074da5e | ||
|
ff323a6b54 | ||
|
76cb658419 | ||
|
f2a64032a1 | ||
|
3ade1a055c | ||
|
f75ad80f6c | ||
|
6c1b663c4c | ||
|
af3ff19b48 | ||
|
6b896ab261 | ||
|
8336e465ac | ||
|
b1b1e81fb5 | ||
|
ed6273e26f | ||
|
776ec96f79 | ||
|
b73e8bd414 | ||
|
1ab8f867ef | ||
|
ea5b201a0a | ||
|
444b1996cb | ||
|
0be839a270 | ||
|
098ffa6674 | ||
|
731de38052 | ||
|
39411cf3c3 | ||
|
f874bf905f | ||
|
8676785302 | ||
|
d1f06fe665 | ||
|
c4875e5b22 | ||
|
be2ebc6dad | ||
|
d6be29e3fb | ||
|
1aba4be97e | ||
|
a9be76576e | ||
|
d8edf52a51 | ||
|
fae38221e7 | ||
|
0e8b439ae5 | ||
|
86d10328a0 | ||
|
6cfcd864a4 | ||
|
720fdd6fa9 | ||
|
ddd2eab72f | ||
|
1def74548d | ||
|
77e205a528 | ||
|
d4754a9531 | ||
|
35fb5b73a2 | ||
|
4e70f9271d | ||
|
77374582ab | ||
|
5bbebf6228 | ||
|
b87dcdd074 | ||
|
2f01dfacb5 | ||
|
91ab2ed722 | ||
|
5f58330790 | ||
|
f3a9cfddae | ||
|
107f0d4677 | ||
|
102e56254d | ||
|
36ab3c3400 | ||
|
1cbdd96813 | ||
|
72a065dbb1 | ||
|
3251bdcf1c | ||
|
bef1301acb | ||
|
36334faf35 | ||
|
a395f3fa2f | ||
|
c52e67924f | ||
|
3ef0eab178 | ||
|
f4ec5cd29d | ||
|
1154d84dcc | ||
|
e6a33e45c2 | ||
|
c2c00148ec | ||
|
b56cb28895 | ||
|
e08d300450 | ||
|
953ea14d66 | ||
|
410bd787bf | ||
|
51fc44768a | ||
|
935fb91522 | ||
|
79ae25af15 | ||
|
ae67dc72e4 | ||
|
f69c111585 | ||
|
6012ca8159 | ||
|
c9cf45c1a4 | ||
|
e0d0041ec6 | ||
|
7f06a3b14d | ||
|
4cc47f8b3c | ||
|
f73adec709 | ||
|
776346cd63 | ||
|
705be728c0 | ||
|
00c2275c95 | ||
|
8f9d989cac | ||
|
d208a85f15 | ||
|
8447414510 | ||
|
ed4b43265d | ||
|
59c4f2ecef | ||
|
c0787c8dd1 | ||
|
f05d9999f4 | ||
|
b5e9476c0f | ||
|
7f151e6f71 | ||
|
f2ad97ff81 | ||
|
1e03e40784 | ||
|
aecc88616a | ||
|
ccf661f827 | ||
|
c21fd2c79e | ||
|
f17b069010 | ||
|
5b009e4008 | ||
|
7912d04be6 | ||
|
9df98352b7 | ||
|
558c2c8ddf | ||
|
09c7fbef76 | ||
|
1b3e71f8ee | ||
|
7a8dda7e5d | ||
|
2d9177588b | ||
|
25aaa2c568 | ||
|
7b4b7c5fc7 | ||
|
ea3beed41d | ||
|
d20418ee51 | ||
|
d21de4d97f | ||
|
55783a5521 | ||
|
cb269f273f | ||
|
342368aff7 | ||
|
854795753c | ||
|
e30614d517 | ||
|
70409e6726 | ||
|
c3543fb5fe | ||
|
272f458dc8 | ||
|
dff4021730 | ||
|
7eb7311427 | ||
|
c4d01535dc | ||
|
e56934bece | ||
|
cc4d3ee435 | ||
|
bb3e9e1fd7 | ||
|
87f2eff016 | ||
|
b3191432cf | ||
|
f0d4dc18ce | ||
|
80765f0734 | ||
|
6e76d125f2 | ||
|
3752ac8932 | ||
|
30de46db50 | ||
|
44dd33ba8f | ||
|
d4827355f6 | ||
|
63c693f8d0 | ||
|
c8d943303d | ||
|
9e3f973335 | ||
|
abe60a439b | ||
|
4007b8de6e | ||
|
24e669ba53 | ||
|
36cbde7c30 | ||
|
fdfb7f2cdb | ||
|
f70873438d | ||
|
7634fe3c27 | ||
|
471a9bc144 | ||
|
b797318666 | ||
|
33cd52b5d7 | ||
|
eb5722801c | ||
|
f8833a37c0 | ||
|
c47493f24f | ||
|
cc64b1a194 | ||
|
f58aa48314 | ||
|
016f775898 | ||
|
b88e77f493 | ||
|
228aa992fc | ||
|
81f194dd69 | ||
|
54ff58bb10 | ||
|
bf362e9610 | ||
|
b8c867ed09 | ||
|
4171853cf4 | ||
|
9ac58dc59a | ||
|
4aee73623d | ||
|
0691e8ebce | ||
|
8412d11276 | ||
|
0b6ff57640 | ||
|
8f9fb7ac49 | ||
|
e57d02022c | ||
|
ebbd8b40a9 | ||
|
72189ea41d | ||
|
d298118060 | ||
|
d5b4dc3b50 | ||
|
31bed5509d | ||
|
5185f0e0a6 | ||
|
43c95d782d | ||
|
2bb41e5d30 | ||
|
1bc8dae31b | ||
|
75d373ef97 | ||
|
e93abc147f | ||
|
b9fc20bccf | ||
|
864867b91b | ||
|
45da08fa8a | ||
|
6943109011 | ||
|
9fae24f554 | ||
|
b5c633c5bd | ||
|
f4df22102a | ||
|
7dcc1f894d | ||
|
b53d8923a5 | ||
|
d614a51378 | ||
|
2b51668fca | ||
|
d780615520 | ||
|
e3b561be48 | ||
|
1cadaa9482 | ||
|
179b9f40f2 | ||
|
3a0614c6c7 | ||
|
55a2201e79 | ||
|
ed8a933f97 | ||
|
f7685877f5 | ||
|
3bdeb68866 | ||
|
cbe50b9a8e | ||
|
7d05b9c86f | ||
|
1e608ec14e | ||
|
28f99f08cf | ||
|
d4cf28dec2 | ||
|
80e7159184 | ||
|
4c7895465e | ||
|
5692c6e1f8 | ||
|
42daa9bed4 | ||
|
863f264d10 | ||
|
239dfebe12 | ||
|
4cf8a45f56 | ||
|
b7651e9521 | ||
|
b10ac20446 | ||
|
e97a391d20 | ||
|
2d9e48bc04 | ||
|
f31b035a9f | ||
|
ba801af429 | ||
|
a63eb0ce0f | ||
|
339cd2a82a | ||
|
faf1f68ba1 | ||
|
460c81f14a | ||
|
aea14095ea | ||
|
9456c2fbcd | ||
|
92ceb440d4 | ||
|
7207c7f9d7 | ||
|
2fb58b7374 | ||
|
9f6bcedba6 | ||
|
55e9409366 | ||
|
e98c0d179f |
20
MAINTAINERS
20
MAINTAINERS
@@ -880,6 +880,12 @@ S: Maintained
|
||||
F: qobject/
|
||||
T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
|
||||
|
||||
QEMU Guest Agent
|
||||
M: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
S: Maintained
|
||||
F: qga/
|
||||
T: git git://github.com/mdroth/qemu.git qga
|
||||
|
||||
QOM
|
||||
M: Anthony Liguori <aliguori@amazon.com>
|
||||
M: Andreas Färber <afaerber@suse.de>
|
||||
@@ -920,6 +926,15 @@ M: Blue Swirl <blauwirbel@gmail.com>
|
||||
S: Odd Fixes
|
||||
F: scripts/checkpatch.pl
|
||||
|
||||
Migration
|
||||
M: Juan Quintela <quintela@redhat.com>
|
||||
S: Maintained
|
||||
F: include/migration/
|
||||
F: migration*
|
||||
F: savevm.c
|
||||
F: arch_init.c
|
||||
F: vmstate.c
|
||||
|
||||
Seccomp
|
||||
M: Eduardo Otubo <eduardo.otubo@profitbricks.com>
|
||||
S: Supported
|
||||
@@ -1078,3 +1093,8 @@ M: Chrysostomos Nanakos <cnanakos@grnet.gr>
|
||||
M: Chrysostomos Nanakos <chris@include.gr>
|
||||
S: Maintained
|
||||
F: block/archipelago.c
|
||||
|
||||
Bootdevice
|
||||
M: Gonglei <arei.gonglei@huawei.com>
|
||||
S: Maintained
|
||||
F: bootdevice.c
|
||||
|
20
arch_init.c
20
arch_init.c
@@ -486,15 +486,23 @@ static void migration_bitmap_sync_range(ram_addr_t start, ram_addr_t length)
|
||||
|
||||
|
||||
/* Needs iothread lock! */
|
||||
/* Fix me: there are too many global variables used in migration process. */
|
||||
static int64_t start_time;
|
||||
static int64_t bytes_xfer_prev;
|
||||
static int64_t num_dirty_pages_period;
|
||||
|
||||
static void migration_bitmap_sync_init(void)
|
||||
{
|
||||
start_time = 0;
|
||||
bytes_xfer_prev = 0;
|
||||
num_dirty_pages_period = 0;
|
||||
}
|
||||
|
||||
static void migration_bitmap_sync(void)
|
||||
{
|
||||
RAMBlock *block;
|
||||
uint64_t num_dirty_pages_init = migration_dirty_pages;
|
||||
MigrationState *s = migrate_get_current();
|
||||
static int64_t start_time;
|
||||
static int64_t bytes_xfer_prev;
|
||||
static int64_t num_dirty_pages_period;
|
||||
int64_t end_time;
|
||||
int64_t bytes_xfer_now;
|
||||
static uint64_t xbzrle_cache_miss_prev;
|
||||
@@ -774,6 +782,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
||||
mig_throttle_on = false;
|
||||
dirty_rate_high_cnt = 0;
|
||||
bitmap_sync_count = 0;
|
||||
migration_bitmap_sync_init();
|
||||
|
||||
if (migrate_use_xbzrle()) {
|
||||
XBZRLE_cache_lock();
|
||||
@@ -1006,7 +1015,7 @@ static inline void *host_from_stream_offset(QEMUFile *f,
|
||||
uint8_t len;
|
||||
|
||||
if (flags & RAM_SAVE_FLAG_CONTINUE) {
|
||||
if (!block) {
|
||||
if (!block || block->length <= offset) {
|
||||
error_report("Ack, bad migration stream!");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1019,8 +1028,9 @@ static inline void *host_from_stream_offset(QEMUFile *f,
|
||||
id[len] = 0;
|
||||
|
||||
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
||||
if (!strncmp(id, block->idstr, sizeof(id)))
|
||||
if (!strncmp(id, block->idstr, sizeof(id)) && block->length > offset) {
|
||||
return memory_region_get_ram_ptr(block->mr) + offset;
|
||||
}
|
||||
}
|
||||
|
||||
error_report("Can't find block %s!", id);
|
||||
|
15
block.c
15
block.c
@@ -2790,8 +2790,8 @@ int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags)
|
||||
if (nb_sectors <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (nb_sectors > INT_MAX) {
|
||||
nb_sectors = INT_MAX;
|
||||
if (nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) {
|
||||
nb_sectors = INT_MAX / BDRV_SECTOR_SIZE;
|
||||
}
|
||||
ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n);
|
||||
if (ret < 0) {
|
||||
@@ -3903,9 +3903,9 @@ typedef struct BdrvCoGetBlockStatusData {
|
||||
} BdrvCoGetBlockStatusData;
|
||||
|
||||
/*
|
||||
* Returns true iff the specified sector is present in the disk image. Drivers
|
||||
* not implementing the functionality are assumed to not support backing files,
|
||||
* hence all their sectors are reported as allocated.
|
||||
* Returns the allocation status of the specified sectors.
|
||||
* Drivers not implementing the functionality are assumed to not support
|
||||
* backing files, hence all their sectors are reported as allocated.
|
||||
*
|
||||
* If 'sector_num' is beyond the end of the disk image the return value is 0
|
||||
* and 'pnum' is set to 0.
|
||||
@@ -5608,11 +5608,6 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
||||
ret = bdrv_open(&bs, backing_file, NULL, NULL, back_flags,
|
||||
backing_drv, &local_err);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Could not open '%s': %s",
|
||||
backing_file,
|
||||
error_get_pretty(local_err));
|
||||
error_free(local_err);
|
||||
local_err = NULL;
|
||||
goto out;
|
||||
}
|
||||
size = bdrv_getlength(bs);
|
||||
|
26
block/qapi.c
26
block/qapi.c
@@ -29,13 +29,6 @@
|
||||
#include "qapi/qmp-output-visitor.h"
|
||||
#include "qapi/qmp/types.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#ifdef __linux__
|
||||
#include <linux/fs.h>
|
||||
#include <sys/ioctl.h>
|
||||
#ifndef FS_NOCOW_FL
|
||||
#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)
|
||||
{
|
||||
@@ -180,9 +173,6 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||
int ret;
|
||||
Error *err = NULL;
|
||||
ImageInfo *info;
|
||||
#ifdef __linux__
|
||||
int fd, attr;
|
||||
#endif
|
||||
|
||||
size = bdrv_getlength(bs);
|
||||
if (size < 0) {
|
||||
@@ -212,18 +202,6 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||
info->format_specific = bdrv_get_specific_info(bs);
|
||||
info->has_format_specific = info->format_specific != NULL;
|
||||
|
||||
#ifdef __linux__
|
||||
/* get NOCOW info */
|
||||
fd = qemu_open(bs->filename, O_RDONLY | O_NONBLOCK);
|
||||
if (fd >= 0) {
|
||||
if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0 && (attr & FS_NOCOW_FL)) {
|
||||
info->has_nocow = true;
|
||||
info->nocow = true;
|
||||
}
|
||||
qemu_close(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
backing_filename = bs->backing_file;
|
||||
if (backing_filename[0] != '\0') {
|
||||
info->backing_filename = g_strdup(backing_filename);
|
||||
@@ -655,8 +633,4 @@ void bdrv_image_info_dump(fprintf_function func_fprintf, void *f,
|
||||
func_fprintf(f, "Format specific information:\n");
|
||||
bdrv_image_info_specific_dump(func_fprintf, f, info->format_specific);
|
||||
}
|
||||
|
||||
if (info->has_nocow && info->nocow) {
|
||||
func_fprintf(f, "NOCOW flag: set\n");
|
||||
}
|
||||
}
|
||||
|
@@ -60,9 +60,6 @@
|
||||
#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_FIEMAP
|
||||
#include <linux/fiemap.h>
|
||||
#endif
|
||||
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
|
||||
#include <linux/falloc.h>
|
||||
#endif
|
||||
@@ -151,9 +148,6 @@ typedef struct BDRVRawState {
|
||||
bool has_write_zeroes:1;
|
||||
bool discard_zeroes:1;
|
||||
bool needs_alignment;
|
||||
#ifdef CONFIG_FIEMAP
|
||||
bool skip_fiemap;
|
||||
#endif
|
||||
} BDRVRawState;
|
||||
|
||||
typedef struct BDRVRawReopenState {
|
||||
@@ -1457,9 +1451,16 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||
"Could not write to the new file");
|
||||
break;
|
||||
}
|
||||
left -= num;
|
||||
left -= result;
|
||||
}
|
||||
if (result >= 0) {
|
||||
result = fsync(fd);
|
||||
if (result < 0) {
|
||||
result = -errno;
|
||||
error_setg_errno(errp, -result,
|
||||
"Could not flush new file to disk");
|
||||
}
|
||||
}
|
||||
fsync(fd);
|
||||
g_free(buf);
|
||||
break;
|
||||
}
|
||||
@@ -1481,83 +1482,93 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
static int try_fiemap(BlockDriverState *bs, off_t start, off_t *data,
|
||||
off_t *hole, int nb_sectors)
|
||||
{
|
||||
#ifdef CONFIG_FIEMAP
|
||||
BDRVRawState *s = bs->opaque;
|
||||
int ret = 0;
|
||||
struct {
|
||||
struct fiemap fm;
|
||||
struct fiemap_extent fe;
|
||||
} f;
|
||||
|
||||
if (s->skip_fiemap) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
f.fm.fm_start = start;
|
||||
f.fm.fm_length = (int64_t)nb_sectors * BDRV_SECTOR_SIZE;
|
||||
f.fm.fm_flags = FIEMAP_FLAG_SYNC;
|
||||
f.fm.fm_extent_count = 1;
|
||||
f.fm.fm_reserved = 0;
|
||||
if (ioctl(s->fd, FS_IOC_FIEMAP, &f) == -1) {
|
||||
s->skip_fiemap = true;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (f.fm.fm_mapped_extents == 0) {
|
||||
/* No extents found, data is beyond f.fm.fm_start + f.fm.fm_length.
|
||||
* f.fm.fm_start + f.fm.fm_length must be clamped to the file size!
|
||||
*/
|
||||
off_t length = lseek(s->fd, 0, SEEK_END);
|
||||
*hole = f.fm.fm_start;
|
||||
*data = MIN(f.fm.fm_start + f.fm.fm_length, length);
|
||||
} else {
|
||||
*data = f.fe.fe_logical;
|
||||
*hole = f.fe.fe_logical + f.fe.fe_length;
|
||||
if (f.fe.fe_flags & FIEMAP_EXTENT_UNWRITTEN) {
|
||||
ret |= BDRV_BLOCK_ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int try_seek_hole(BlockDriverState *bs, off_t start, off_t *data,
|
||||
off_t *hole)
|
||||
/*
|
||||
* Find allocation range in @bs around offset @start.
|
||||
* May change underlying file descriptor's file offset.
|
||||
* If @start is not in a hole, store @start in @data, and the
|
||||
* beginning of the next hole in @hole, and return 0.
|
||||
* If @start is in a non-trailing hole, store @start in @hole and the
|
||||
* beginning of the next non-hole in @data, and return 0.
|
||||
* If @start is in a trailing hole or beyond EOF, return -ENXIO.
|
||||
* If we can't find out, return a negative errno other than -ENXIO.
|
||||
*/
|
||||
static int find_allocation(BlockDriverState *bs, off_t start,
|
||||
off_t *data, off_t *hole)
|
||||
{
|
||||
#if defined SEEK_HOLE && defined SEEK_DATA
|
||||
BDRVRawState *s = bs->opaque;
|
||||
off_t offs;
|
||||
|
||||
*hole = lseek(s->fd, start, SEEK_HOLE);
|
||||
if (*hole == -1) {
|
||||
return -errno;
|
||||
/*
|
||||
* SEEK_DATA cases:
|
||||
* D1. offs == start: start is in data
|
||||
* D2. offs > start: start is in a hole, next data at offs
|
||||
* D3. offs < 0, errno = ENXIO: either start is in a trailing hole
|
||||
* or start is beyond EOF
|
||||
* If the latter happens, the file has been truncated behind
|
||||
* our back since we opened it. All bets are off then.
|
||||
* Treating like a trailing hole is simplest.
|
||||
* D4. offs < 0, errno != ENXIO: we learned nothing
|
||||
*/
|
||||
offs = lseek(s->fd, start, SEEK_DATA);
|
||||
if (offs < 0) {
|
||||
return -errno; /* D3 or D4 */
|
||||
}
|
||||
assert(offs >= start);
|
||||
|
||||
if (offs > start) {
|
||||
/* D2: in hole, next data at offs */
|
||||
*hole = start;
|
||||
*data = offs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*hole > start) {
|
||||
/* D1: in data, end not yet known */
|
||||
|
||||
/*
|
||||
* SEEK_HOLE cases:
|
||||
* H1. offs == start: start is in a hole
|
||||
* If this happens here, a hole has been dug behind our back
|
||||
* since the previous lseek().
|
||||
* H2. offs > start: either start is in data, next hole at offs,
|
||||
* or start is in trailing hole, EOF at offs
|
||||
* Linux treats trailing holes like any other hole: offs ==
|
||||
* start. Solaris seeks to EOF instead: offs > start (blech).
|
||||
* If that happens here, a hole has been dug behind our back
|
||||
* since the previous lseek().
|
||||
* H3. offs < 0, errno = ENXIO: start is beyond EOF
|
||||
* If this happens, the file has been truncated behind our
|
||||
* back since we opened it. Treat it like a trailing hole.
|
||||
* H4. offs < 0, errno != ENXIO: we learned nothing
|
||||
* Pretend we know nothing at all, i.e. "forget" about D1.
|
||||
*/
|
||||
offs = lseek(s->fd, start, SEEK_HOLE);
|
||||
if (offs < 0) {
|
||||
return -errno; /* D1 and (H3 or H4) */
|
||||
}
|
||||
assert(offs >= start);
|
||||
|
||||
if (offs > start) {
|
||||
/*
|
||||
* D1 and H2: either in data, next hole at offs, or it was in
|
||||
* data but is now in a trailing hole. In the latter case,
|
||||
* all bets are off. Treating it as if it there was data all
|
||||
* the way to EOF is safe, so simply do that.
|
||||
*/
|
||||
*data = start;
|
||||
} else {
|
||||
/* On a hole. We need another syscall to find its end. */
|
||||
*data = lseek(s->fd, start, SEEK_DATA);
|
||||
if (*data == -1) {
|
||||
*data = lseek(s->fd, 0, SEEK_END);
|
||||
}
|
||||
*hole = offs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* D1 and H1 */
|
||||
return -EBUSY;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true iff the specified sector is present in the disk image. Drivers
|
||||
* not implementing the functionality are assumed to not support backing files,
|
||||
* hence all their sectors are reported as allocated.
|
||||
* Returns the allocation status of the specified sectors.
|
||||
*
|
||||
* If 'sector_num' is beyond the end of the disk image the return value is 0
|
||||
* and 'pnum' is set to 0.
|
||||
@@ -1593,28 +1604,26 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
|
||||
nb_sectors = DIV_ROUND_UP(total_size - start, BDRV_SECTOR_SIZE);
|
||||
}
|
||||
|
||||
ret = try_seek_hole(bs, start, &data, &hole);
|
||||
if (ret < 0) {
|
||||
ret = try_fiemap(bs, start, &data, &hole, nb_sectors);
|
||||
if (ret < 0) {
|
||||
/* Assume everything is allocated. */
|
||||
data = 0;
|
||||
hole = start + nb_sectors * BDRV_SECTOR_SIZE;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
assert(ret >= 0);
|
||||
|
||||
if (data <= start) {
|
||||
ret = find_allocation(bs, start, &data, &hole);
|
||||
if (ret == -ENXIO) {
|
||||
/* Trailing hole */
|
||||
*pnum = nb_sectors;
|
||||
ret = BDRV_BLOCK_ZERO;
|
||||
} else if (ret < 0) {
|
||||
/* No info available, so pretend there are no holes */
|
||||
*pnum = nb_sectors;
|
||||
ret = BDRV_BLOCK_DATA;
|
||||
} else if (data == start) {
|
||||
/* On a data extent, compute sectors to the end of the extent. */
|
||||
*pnum = MIN(nb_sectors, (hole - start) / BDRV_SECTOR_SIZE);
|
||||
return ret | BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | start;
|
||||
ret = BDRV_BLOCK_DATA;
|
||||
} else {
|
||||
/* On a hole, compute sectors to the beginning of the next extent. */
|
||||
assert(hole == start);
|
||||
*pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
|
||||
return ret | BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID | start;
|
||||
ret = BDRV_BLOCK_ZERO;
|
||||
}
|
||||
return ret | BDRV_BLOCK_OFFSET_VALID | start;
|
||||
}
|
||||
|
||||
static coroutine_fn BlockAIOCB *raw_aio_discard(BlockDriverState *bs,
|
||||
|
14
block/vdi.c
14
block/vdi.c
@@ -120,8 +120,18 @@ typedef unsigned char uuid_t[16];
|
||||
|
||||
#define VDI_IS_ALLOCATED(X) ((X) < VDI_DISCARDED)
|
||||
|
||||
/* max blocks in image is (0xffffffff / 4) */
|
||||
#define VDI_BLOCKS_IN_IMAGE_MAX 0x3fffffff
|
||||
/* The bmap will take up VDI_BLOCKS_IN_IMAGE_MAX * sizeof(uint32_t) bytes; since
|
||||
* the bmap is read and written in a single operation, its size needs to be
|
||||
* limited to INT_MAX; furthermore, when opening an image, the bmap size is
|
||||
* rounded up to be aligned on BDRV_SECTOR_SIZE.
|
||||
* Therefore this should satisfy the following:
|
||||
* VDI_BLOCKS_IN_IMAGE_MAX * sizeof(uint32_t) + BDRV_SECTOR_SIZE == INT_MAX + 1
|
||||
* (INT_MAX + 1 is the first value not representable as an int)
|
||||
* This guarantees that any value below or equal to the constant will, when
|
||||
* multiplied by sizeof(uint32_t) and rounded up to a BDRV_SECTOR_SIZE boundary,
|
||||
* still be below or equal to INT_MAX. */
|
||||
#define VDI_BLOCKS_IN_IMAGE_MAX \
|
||||
((unsigned)((INT_MAX + 1u - BDRV_SECTOR_SIZE) / sizeof(uint32_t)))
|
||||
#define VDI_DISK_SIZE_MAX ((uint64_t)VDI_BLOCKS_IN_IMAGE_MAX * \
|
||||
(uint64_t)DEFAULT_CLUSTER_SIZE)
|
||||
|
||||
|
22
block/vmdk.c
22
block/vmdk.c
@@ -2137,23 +2137,29 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs)
|
||||
return spec_info;
|
||||
}
|
||||
|
||||
static bool vmdk_extents_type_eq(const VmdkExtent *a, const VmdkExtent *b)
|
||||
{
|
||||
return a->flat == b->flat &&
|
||||
a->compressed == b->compressed &&
|
||||
(a->flat || a->cluster_sectors == b->cluster_sectors);
|
||||
}
|
||||
|
||||
static int vmdk_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
int i;
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
assert(s->num_extents);
|
||||
|
||||
/* See if we have multiple extents but they have different cases */
|
||||
for (i = 1; i < s->num_extents; i++) {
|
||||
if (!vmdk_extents_type_eq(&s->extents[0], &s->extents[i])) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
bdi->needs_compressed_writes = s->extents[0].compressed;
|
||||
if (!s->extents[0].flat) {
|
||||
bdi->cluster_size = s->extents[0].cluster_sectors << BDRV_SECTOR_BITS;
|
||||
}
|
||||
/* See if we have multiple extents but they have different cases */
|
||||
for (i = 1; i < s->num_extents; i++) {
|
||||
if (bdi->needs_compressed_writes != s->extents[i].compressed ||
|
||||
(bdi->cluster_size && bdi->cluster_size !=
|
||||
s->extents[i].cluster_sectors << BDRV_SECTOR_BITS)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
3
configure
vendored
3
configure
vendored
@@ -1823,7 +1823,8 @@ fi
|
||||
# libseccomp check
|
||||
|
||||
if test "$seccomp" != "no" ; then
|
||||
if $pkg_config --atleast-version=2.1.0 libseccomp; then
|
||||
if test "$cpu" = "i386" || test "$cpu" = "x86_64" &&
|
||||
$pkg_config --atleast-version=2.1.1 libseccomp; then
|
||||
libs_softmmu="$libs_softmmu `$pkg_config --libs libseccomp`"
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS `$pkg_config --cflags libseccomp`"
|
||||
seccomp="yes"
|
||||
|
@@ -155,7 +155,7 @@ Coroutine *qemu_coroutine_new(void)
|
||||
stack_t oss;
|
||||
sigset_t sigs;
|
||||
sigset_t osigs;
|
||||
jmp_buf old_env;
|
||||
sigjmp_buf old_env;
|
||||
|
||||
/* The way to manipulate stack is with the sigaltstack function. We
|
||||
* prepare a stack, with it delivering a signal to ourselves and then
|
||||
|
@@ -32,6 +32,5 @@ CONFIG_G364FB=y
|
||||
CONFIG_I8259=y
|
||||
CONFIG_JAZZ_LED=y
|
||||
CONFIG_MC146818RTC=y
|
||||
CONFIG_VT82C686=y
|
||||
CONFIG_ISA_TESTDEV=y
|
||||
CONFIG_EMPTY_SLOT=y
|
||||
|
@@ -32,6 +32,5 @@ CONFIG_G364FB=y
|
||||
CONFIG_I8259=y
|
||||
CONFIG_JAZZ_LED=y
|
||||
CONFIG_MC146818RTC=y
|
||||
CONFIG_VT82C686=y
|
||||
CONFIG_ISA_TESTDEV=y
|
||||
CONFIG_EMPTY_SLOT=y
|
||||
|
@@ -32,6 +32,5 @@ CONFIG_G364FB=y
|
||||
CONFIG_I8259=y
|
||||
CONFIG_JAZZ_LED=y
|
||||
CONFIG_MC146818RTC=y
|
||||
CONFIG_VT82C686=y
|
||||
CONFIG_ISA_TESTDEV=y
|
||||
CONFIG_EMPTY_SLOT=y
|
||||
|
718
disas/mips.c
718
disas/mips.c
@@ -220,6 +220,28 @@ see <http://www.gnu.org/licenses/>. */
|
||||
#define OP_SH_MTACC_D 13
|
||||
#define OP_MASK_MTACC_D 0x3
|
||||
|
||||
/* MSA */
|
||||
#define OP_MASK_1BIT 0x1
|
||||
#define OP_SH_1BIT 16
|
||||
#define OP_MASK_2BIT 0x3
|
||||
#define OP_SH_2BIT 16
|
||||
#define OP_MASK_3BIT 0x7
|
||||
#define OP_SH_3BIT 16
|
||||
#define OP_MASK_4BIT 0xf
|
||||
#define OP_SH_4BIT 16
|
||||
#define OP_MASK_5BIT 0x1f
|
||||
#define OP_SH_5BIT 16
|
||||
#define OP_MASK_10BIT 0x3ff
|
||||
#define OP_SH_10BIT 11
|
||||
#define OP_MASK_MSACR11 0x1f
|
||||
#define OP_SH_MSACR11 11
|
||||
#define OP_MASK_MSACR6 0x1f
|
||||
#define OP_SH_MSACR6 6
|
||||
#define OP_MASK_GPR 0x1f
|
||||
#define OP_SH_GPR 6
|
||||
#define OP_MASK_1_TO_4 0x3
|
||||
#define OP_SH_1_TO_4 6
|
||||
|
||||
#define OP_OP_COP0 0x10
|
||||
#define OP_OP_COP1 0x11
|
||||
#define OP_OP_COP2 0x12
|
||||
@@ -510,6 +532,9 @@ struct mips_opcode
|
||||
/* Instruction writes MDMX accumulator. */
|
||||
#define INSN2_WRITE_MDMX_ACC 0x00000004
|
||||
|
||||
/* Reads the general purpose register in OP_*_RD. */
|
||||
#define INSN2_READ_GPR_D 0x00000200
|
||||
|
||||
/* Instruction is actually a macro. It should be ignored by the
|
||||
disassembler, and requires special treatment by the assembler. */
|
||||
#define INSN_MACRO 0xffffffff
|
||||
@@ -567,7 +592,12 @@ struct mips_opcode
|
||||
#define INSN_5500 0x02000000
|
||||
|
||||
/* MDMX ASE */
|
||||
#define INSN_MDMX 0x04000000
|
||||
#define INSN_MDMX 0x00000000 /* Deprecated */
|
||||
|
||||
/* MIPS MSA Extension */
|
||||
#define INSN_MSA 0x04000000
|
||||
#define INSN_MSA64 0x04000000
|
||||
|
||||
/* MT ASE */
|
||||
#define INSN_MT 0x08000000
|
||||
/* SmartMIPS ASE */
|
||||
@@ -1204,6 +1234,17 @@ extern const int bfd_mips16_num_opcodes;
|
||||
/* MIPS MT ASE support. */
|
||||
#define MT32 INSN_MT
|
||||
|
||||
/* MSA */
|
||||
#define MSA INSN_MSA
|
||||
#define MSA64 INSN_MSA64
|
||||
#define WR_VD INSN_WRITE_FPR_D /* Reuse INSN_WRITE_FPR_D */
|
||||
#define RD_VD WR_VD /* Reuse WR_VD */
|
||||
#define RD_VT INSN_READ_FPR_T /* Reuse INSN_READ_FPR_T */
|
||||
#define RD_VS INSN_READ_FPR_S /* Reuse INSN_READ_FPR_S */
|
||||
#define RD_d INSN2_READ_GPR_D /* Reuse INSN2_READ_GPR_D */
|
||||
|
||||
#define RD_rd6 0
|
||||
|
||||
/* The order of overloaded instructions matters. Label arguments and
|
||||
register arguments look the same. Instructions that can have either
|
||||
for arguments must apear in the correct order in this table for the
|
||||
@@ -1363,6 +1404,541 @@ const struct mips_opcode mips_builtin_opcodes[] =
|
||||
{"cmp.sor.d", "D,S,T", 0x46a00019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sune.d", "D,S,T", 0x46a0001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sne.d", "D,S,T", 0x46a0001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
|
||||
/* MSA */
|
||||
{"sll.b", "+d,+e,+f", 0x7800000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"sll.h", "+d,+e,+f", 0x7820000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"sll.w", "+d,+e,+f", 0x7840000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"sll.d", "+d,+e,+f", 0x7860000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"slli.b", "+d,+e,+7", 0x78700009, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"slli.h", "+d,+e,+8", 0x78600009, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"slli.w", "+d,+e,+9", 0x78400009, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"slli.d", "+d,+e,'", 0x78000009, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"sra.b", "+d,+e,+f", 0x7880000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"sra.h", "+d,+e,+f", 0x78a0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"sra.w", "+d,+e,+f", 0x78c0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"sra.d", "+d,+e,+f", 0x78e0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srai.b", "+d,+e,+7", 0x78f00009, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srai.h", "+d,+e,+8", 0x78e00009, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srai.w", "+d,+e,+9", 0x78c00009, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srai.d", "+d,+e,'", 0x78800009, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srl.b", "+d,+e,+f", 0x7900000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srl.h", "+d,+e,+f", 0x7920000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srl.w", "+d,+e,+f", 0x7940000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srl.d", "+d,+e,+f", 0x7960000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srli.b", "+d,+e,+7", 0x79700009, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srli.h", "+d,+e,+8", 0x79600009, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srli.w", "+d,+e,+9", 0x79400009, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srli.d", "+d,+e,'", 0x79000009, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bclr.b", "+d,+e,+f", 0x7980000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bclr.h", "+d,+e,+f", 0x79a0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bclr.w", "+d,+e,+f", 0x79c0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bclr.d", "+d,+e,+f", 0x79e0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bclri.b", "+d,+e,+7", 0x79f00009, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bclri.h", "+d,+e,+8", 0x79e00009, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bclri.w", "+d,+e,+9", 0x79c00009, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bclri.d", "+d,+e,'", 0x79800009, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bset.b", "+d,+e,+f", 0x7a00000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bset.h", "+d,+e,+f", 0x7a20000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bset.w", "+d,+e,+f", 0x7a40000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bset.d", "+d,+e,+f", 0x7a60000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bseti.b", "+d,+e,+7", 0x7a700009, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bseti.h", "+d,+e,+8", 0x7a600009, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bseti.w", "+d,+e,+9", 0x7a400009, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bseti.d", "+d,+e,'", 0x7a000009, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bneg.b", "+d,+e,+f", 0x7a80000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bneg.h", "+d,+e,+f", 0x7aa0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bneg.w", "+d,+e,+f", 0x7ac0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bneg.d", "+d,+e,+f", 0x7ae0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bnegi.b", "+d,+e,+7", 0x7af00009, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bnegi.h", "+d,+e,+8", 0x7ae00009, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bnegi.w", "+d,+e,+9", 0x7ac00009, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bnegi.d", "+d,+e,'", 0x7a800009, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"binsl.b", "+d,+e,+f", 0x7b00000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"binsl.h", "+d,+e,+f", 0x7b20000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"binsl.w", "+d,+e,+f", 0x7b40000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"binsl.d", "+d,+e,+f", 0x7b60000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"binsli.b", "+d,+e,+7", 0x7b700009, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"binsli.h", "+d,+e,+8", 0x7b600009, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"binsli.w", "+d,+e,+9", 0x7b400009, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"binsli.d", "+d,+e,'", 0x7b000009, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"binsr.b", "+d,+e,+f", 0x7b80000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"binsr.h", "+d,+e,+f", 0x7ba0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"binsr.w", "+d,+e,+f", 0x7bc0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"binsr.d", "+d,+e,+f", 0x7be0000d, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"binsri.b", "+d,+e,+7", 0x7bf00009, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"binsri.h", "+d,+e,+8", 0x7be00009, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"binsri.w", "+d,+e,+9", 0x7bc00009, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"binsri.d", "+d,+e,'", 0x7b800009, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"addv.b", "+d,+e,+f", 0x7800000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"addv.h", "+d,+e,+f", 0x7820000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"addv.w", "+d,+e,+f", 0x7840000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"addv.d", "+d,+e,+f", 0x7860000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"addvi.b", "+d,+e,k", 0x78000006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"addvi.h", "+d,+e,k", 0x78200006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"addvi.w", "+d,+e,k", 0x78400006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"addvi.d", "+d,+e,k", 0x78600006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"subv.b", "+d,+e,+f", 0x7880000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subv.h", "+d,+e,+f", 0x78a0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subv.w", "+d,+e,+f", 0x78c0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subv.d", "+d,+e,+f", 0x78e0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subvi.b", "+d,+e,k", 0x78800006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"subvi.h", "+d,+e,k", 0x78a00006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"subvi.w", "+d,+e,k", 0x78c00006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"subvi.d", "+d,+e,k", 0x78e00006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"max_s.b", "+d,+e,+f", 0x7900000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"max_s.h", "+d,+e,+f", 0x7920000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"max_s.w", "+d,+e,+f", 0x7940000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"max_s.d", "+d,+e,+f", 0x7960000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"maxi_s.b", "+d,+e,+5", 0x79000006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"maxi_s.h", "+d,+e,+5", 0x79200006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"maxi_s.w", "+d,+e,+5", 0x79400006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"maxi_s.d", "+d,+e,+5", 0x79600006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"max_u.b", "+d,+e,+f", 0x7980000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"max_u.h", "+d,+e,+f", 0x79a0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"max_u.w", "+d,+e,+f", 0x79c0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"max_u.d", "+d,+e,+f", 0x79e0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"maxi_u.b", "+d,+e,k", 0x79800006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"maxi_u.h", "+d,+e,k", 0x79a00006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"maxi_u.w", "+d,+e,k", 0x79c00006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"maxi_u.d", "+d,+e,k", 0x79e00006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"min_s.b", "+d,+e,+f", 0x7a00000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"min_s.h", "+d,+e,+f", 0x7a20000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"min_s.w", "+d,+e,+f", 0x7a40000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"min_s.d", "+d,+e,+f", 0x7a60000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mini_s.b", "+d,+e,+5", 0x7a000006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"mini_s.h", "+d,+e,+5", 0x7a200006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"mini_s.w", "+d,+e,+5", 0x7a400006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"mini_s.d", "+d,+e,+5", 0x7a600006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"min_u.b", "+d,+e,+f", 0x7a80000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"min_u.h", "+d,+e,+f", 0x7aa0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"min_u.w", "+d,+e,+f", 0x7ac0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"min_u.d", "+d,+e,+f", 0x7ae0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mini_u.b", "+d,+e,k", 0x7a800006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"mini_u.h", "+d,+e,k", 0x7aa00006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"mini_u.w", "+d,+e,k", 0x7ac00006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"mini_u.d", "+d,+e,k", 0x7ae00006, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"max_a.b", "+d,+e,+f", 0x7b00000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"max_a.h", "+d,+e,+f", 0x7b20000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"max_a.w", "+d,+e,+f", 0x7b40000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"max_a.d", "+d,+e,+f", 0x7b60000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"min_a.b", "+d,+e,+f", 0x7b80000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"min_a.h", "+d,+e,+f", 0x7ba0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"min_a.w", "+d,+e,+f", 0x7bc0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"min_a.d", "+d,+e,+f", 0x7be0000e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ceq.b", "+d,+e,+f", 0x7800000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ceq.h", "+d,+e,+f", 0x7820000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ceq.w", "+d,+e,+f", 0x7840000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ceq.d", "+d,+e,+f", 0x7860000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ceqi.b", "+d,+e,+5", 0x78000007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ceqi.h", "+d,+e,+5", 0x78200007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ceqi.w", "+d,+e,+5", 0x78400007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ceqi.d", "+d,+e,+5", 0x78600007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clt_s.b", "+d,+e,+f", 0x7900000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"clt_s.h", "+d,+e,+f", 0x7920000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"clt_s.w", "+d,+e,+f", 0x7940000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"clt_s.d", "+d,+e,+f", 0x7960000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"clti_s.b", "+d,+e,+5", 0x79000007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clti_s.h", "+d,+e,+5", 0x79200007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clti_s.w", "+d,+e,+5", 0x79400007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clti_s.d", "+d,+e,+5", 0x79600007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clt_u.b", "+d,+e,+f", 0x7980000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"clt_u.h", "+d,+e,+f", 0x79a0000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"clt_u.w", "+d,+e,+f", 0x79c0000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"clt_u.d", "+d,+e,+f", 0x79e0000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"clti_u.b", "+d,+e,k", 0x79800007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clti_u.h", "+d,+e,k", 0x79a00007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clti_u.w", "+d,+e,k", 0x79c00007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clti_u.d", "+d,+e,k", 0x79e00007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"cle_s.b", "+d,+e,+f", 0x7a00000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"cle_s.h", "+d,+e,+f", 0x7a20000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"cle_s.w", "+d,+e,+f", 0x7a40000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"cle_s.d", "+d,+e,+f", 0x7a60000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"clei_s.b", "+d,+e,+5", 0x7a000007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clei_s.h", "+d,+e,+5", 0x7a200007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clei_s.w", "+d,+e,+5", 0x7a400007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clei_s.d", "+d,+e,+5", 0x7a600007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"cle_u.b", "+d,+e,+f", 0x7a80000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"cle_u.h", "+d,+e,+f", 0x7aa0000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"cle_u.w", "+d,+e,+f", 0x7ac0000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"cle_u.d", "+d,+e,+f", 0x7ae0000f, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"clei_u.b", "+d,+e,k", 0x7a800007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clei_u.h", "+d,+e,k", 0x7aa00007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clei_u.w", "+d,+e,k", 0x7ac00007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"clei_u.d", "+d,+e,k", 0x7ae00007, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ld.b", "+d,+^(d)", 0x78000020, 0xfc00003f, WR_VD|LDD, RD_d, MSA},
|
||||
{"ld.h", "+d,+#(d)", 0x78000021, 0xfc00003f, WR_VD|LDD, RD_d, MSA},
|
||||
{"ld.w", "+d,+$(d)", 0x78000022, 0xfc00003f, WR_VD|LDD, RD_d, MSA},
|
||||
{"ld.d", "+d,+%(d)", 0x78000023, 0xfc00003f, WR_VD|LDD, RD_d, MSA},
|
||||
{"st.b", "+d,+^(d)", 0x78000024, 0xfc00003f, RD_VD|SM, RD_d, MSA},
|
||||
{"st.h", "+d,+#(d)", 0x78000025, 0xfc00003f, RD_VD|SM, RD_d, MSA},
|
||||
{"st.w", "+d,+$(d)", 0x78000026, 0xfc00003f, RD_VD|SM, RD_d, MSA},
|
||||
{"st.d", "+d,+%(d)", 0x78000027, 0xfc00003f, RD_VD|SM, RD_d, MSA},
|
||||
{"sat_s.b", "+d,+e,+7", 0x7870000a, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"sat_s.h", "+d,+e,+8", 0x7860000a, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"sat_s.w", "+d,+e,+9", 0x7840000a, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"sat_s.d", "+d,+e,'", 0x7800000a, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"sat_u.b", "+d,+e,+7", 0x78f0000a, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"sat_u.h", "+d,+e,+8", 0x78e0000a, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"sat_u.w", "+d,+e,+9", 0x78c0000a, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"sat_u.d", "+d,+e,'", 0x7880000a, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"add_a.b", "+d,+e,+f", 0x78000010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"add_a.h", "+d,+e,+f", 0x78200010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"add_a.w", "+d,+e,+f", 0x78400010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"add_a.d", "+d,+e,+f", 0x78600010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_a.b", "+d,+e,+f", 0x78800010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_a.h", "+d,+e,+f", 0x78a00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_a.w", "+d,+e,+f", 0x78c00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_a.d", "+d,+e,+f", 0x78e00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_s.b", "+d,+e,+f", 0x79000010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_s.h", "+d,+e,+f", 0x79200010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_s.w", "+d,+e,+f", 0x79400010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_s.d", "+d,+e,+f", 0x79600010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_u.b", "+d,+e,+f", 0x79800010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_u.h", "+d,+e,+f", 0x79a00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_u.w", "+d,+e,+f", 0x79c00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"adds_u.d", "+d,+e,+f", 0x79e00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ave_s.b", "+d,+e,+f", 0x7a000010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ave_s.h", "+d,+e,+f", 0x7a200010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ave_s.w", "+d,+e,+f", 0x7a400010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ave_s.d", "+d,+e,+f", 0x7a600010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ave_u.b", "+d,+e,+f", 0x7a800010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ave_u.h", "+d,+e,+f", 0x7aa00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ave_u.w", "+d,+e,+f", 0x7ac00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ave_u.d", "+d,+e,+f", 0x7ae00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"aver_s.b", "+d,+e,+f", 0x7b000010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"aver_s.h", "+d,+e,+f", 0x7b200010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"aver_s.w", "+d,+e,+f", 0x7b400010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"aver_s.d", "+d,+e,+f", 0x7b600010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"aver_u.b", "+d,+e,+f", 0x7b800010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"aver_u.h", "+d,+e,+f", 0x7ba00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"aver_u.w", "+d,+e,+f", 0x7bc00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"aver_u.d", "+d,+e,+f", 0x7be00010, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subs_s.b", "+d,+e,+f", 0x78000011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subs_s.h", "+d,+e,+f", 0x78200011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subs_s.w", "+d,+e,+f", 0x78400011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subs_s.d", "+d,+e,+f", 0x78600011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subs_u.b", "+d,+e,+f", 0x78800011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subs_u.h", "+d,+e,+f", 0x78a00011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subs_u.w", "+d,+e,+f", 0x78c00011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subs_u.d", "+d,+e,+f", 0x78e00011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subsus_u.b", "+d,+e,+f", 0x79000011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subsus_u.h", "+d,+e,+f", 0x79200011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subsus_u.w", "+d,+e,+f", 0x79400011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subsus_u.d", "+d,+e,+f", 0x79600011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subsuu_s.b", "+d,+e,+f", 0x79800011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subsuu_s.h", "+d,+e,+f", 0x79a00011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subsuu_s.w", "+d,+e,+f", 0x79c00011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"subsuu_s.d", "+d,+e,+f", 0x79e00011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"asub_s.b", "+d,+e,+f", 0x7a000011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"asub_s.h", "+d,+e,+f", 0x7a200011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"asub_s.w", "+d,+e,+f", 0x7a400011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"asub_s.d", "+d,+e,+f", 0x7a600011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"asub_u.b", "+d,+e,+f", 0x7a800011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"asub_u.h", "+d,+e,+f", 0x7aa00011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"asub_u.w", "+d,+e,+f", 0x7ac00011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"asub_u.d", "+d,+e,+f", 0x7ae00011, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mulv.b", "+d,+e,+f", 0x78000012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mulv.h", "+d,+e,+f", 0x78200012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mulv.w", "+d,+e,+f", 0x78400012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mulv.d", "+d,+e,+f", 0x78600012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"maddv.b", "+d,+e,+f", 0x78800012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"maddv.h", "+d,+e,+f", 0x78a00012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"maddv.w", "+d,+e,+f", 0x78c00012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"maddv.d", "+d,+e,+f", 0x78e00012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"msubv.b", "+d,+e,+f", 0x79000012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"msubv.h", "+d,+e,+f", 0x79200012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"msubv.w", "+d,+e,+f", 0x79400012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"msubv.d", "+d,+e,+f", 0x79600012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"div_s.b", "+d,+e,+f", 0x7a000012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"div_s.h", "+d,+e,+f", 0x7a200012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"div_s.w", "+d,+e,+f", 0x7a400012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"div_s.d", "+d,+e,+f", 0x7a600012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"div_u.b", "+d,+e,+f", 0x7a800012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"div_u.h", "+d,+e,+f", 0x7aa00012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"div_u.w", "+d,+e,+f", 0x7ac00012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"div_u.d", "+d,+e,+f", 0x7ae00012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mod_s.b", "+d,+e,+f", 0x7b000012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mod_s.h", "+d,+e,+f", 0x7b200012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mod_s.w", "+d,+e,+f", 0x7b400012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mod_s.d", "+d,+e,+f", 0x7b600012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mod_u.b", "+d,+e,+f", 0x7b800012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mod_u.h", "+d,+e,+f", 0x7ba00012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mod_u.w", "+d,+e,+f", 0x7bc00012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mod_u.d", "+d,+e,+f", 0x7be00012, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dotp_s.h", "+d,+e,+f", 0x78200013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dotp_s.w", "+d,+e,+f", 0x78400013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dotp_s.d", "+d,+e,+f", 0x78600013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dotp_u.h", "+d,+e,+f", 0x78a00013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dotp_u.w", "+d,+e,+f", 0x78c00013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dotp_u.d", "+d,+e,+f", 0x78e00013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpadd_s.h", "+d,+e,+f", 0x79200013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpadd_s.w", "+d,+e,+f", 0x79400013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpadd_s.d", "+d,+e,+f", 0x79600013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpadd_u.h", "+d,+e,+f", 0x79a00013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpadd_u.w", "+d,+e,+f", 0x79c00013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpadd_u.d", "+d,+e,+f", 0x79e00013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpsub_s.h", "+d,+e,+f", 0x7a200013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpsub_s.w", "+d,+e,+f", 0x7a400013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpsub_s.d", "+d,+e,+f", 0x7a600013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpsub_u.h", "+d,+e,+f", 0x7aa00013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpsub_u.w", "+d,+e,+f", 0x7ac00013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"dpsub_u.d", "+d,+e,+f", 0x7ae00013, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"sld.b", "+d,+e[t]", 0x78000014, 0xffe0003f, WR_VD|RD_VS|RD_t, 0, MSA},
|
||||
{"sld.h", "+d,+e[t]", 0x78200014, 0xffe0003f, WR_VD|RD_VS|RD_t, 0, MSA},
|
||||
{"sld.w", "+d,+e[t]", 0x78400014, 0xffe0003f, WR_VD|RD_VS|RD_t, 0, MSA},
|
||||
{"sld.d", "+d,+e[t]", 0x78600014, 0xffe0003f, WR_VD|RD_VS|RD_t, 0, MSA},
|
||||
{"sldi.b", "+d,+e[+9]", 0x78000019, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"sldi.h", "+d,+e[+8]", 0x78200019, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"sldi.w", "+d,+e[+7]", 0x78300019, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"sldi.d", "+d,+e[+6]", 0x78380019, 0xfffc003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"splat.b", "+d,+e[t]", 0x78800014, 0xffe0003f, WR_VD|RD_VS|RD_t, 0, MSA},
|
||||
{"splat.h", "+d,+e[t]", 0x78a00014, 0xffe0003f, WR_VD|RD_VS|RD_t, 0, MSA},
|
||||
{"splat.w", "+d,+e[t]", 0x78c00014, 0xffe0003f, WR_VD|RD_VS|RD_t, 0, MSA},
|
||||
{"splat.d", "+d,+e[t]", 0x78e00014, 0xffe0003f, WR_VD|RD_VS|RD_t, 0, MSA},
|
||||
{"splati.b", "+d,+e[+9]", 0x78400019, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"splati.h", "+d,+e[+8]", 0x78600019, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"splati.w", "+d,+e[+7]", 0x78700019, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"splati.d", "+d,+e[+6]", 0x78780019, 0xfffc003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"pckev.b", "+d,+e,+f", 0x79000014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"pckev.h", "+d,+e,+f", 0x79200014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"pckev.w", "+d,+e,+f", 0x79400014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"pckev.d", "+d,+e,+f", 0x79600014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"pckod.b", "+d,+e,+f", 0x79800014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"pckod.h", "+d,+e,+f", 0x79a00014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"pckod.w", "+d,+e,+f", 0x79c00014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"pckod.d", "+d,+e,+f", 0x79e00014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvl.b", "+d,+e,+f", 0x7a000014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvl.h", "+d,+e,+f", 0x7a200014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvl.w", "+d,+e,+f", 0x7a400014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvl.d", "+d,+e,+f", 0x7a600014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvr.b", "+d,+e,+f", 0x7a800014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvr.h", "+d,+e,+f", 0x7aa00014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvr.w", "+d,+e,+f", 0x7ac00014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvr.d", "+d,+e,+f", 0x7ae00014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvev.b", "+d,+e,+f", 0x7b000014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvev.h", "+d,+e,+f", 0x7b200014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvev.w", "+d,+e,+f", 0x7b400014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvev.d", "+d,+e,+f", 0x7b600014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvod.b", "+d,+e,+f", 0x7b800014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvod.h", "+d,+e,+f", 0x7ba00014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvod.w", "+d,+e,+f", 0x7bc00014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ilvod.d", "+d,+e,+f", 0x7be00014, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"vshf.b", "+d,+e,+f", 0x78000015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"vshf.h", "+d,+e,+f", 0x78200015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"vshf.w", "+d,+e,+f", 0x78400015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"vshf.d", "+d,+e,+f", 0x78600015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srar.b", "+d,+e,+f", 0x78800015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srar.h", "+d,+e,+f", 0x78a00015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srar.w", "+d,+e,+f", 0x78c00015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srar.d", "+d,+e,+f", 0x78e00015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srari.b", "+d,+e,+7", 0x7970000a, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srari.h", "+d,+e,+8", 0x7960000a, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srari.w", "+d,+e,+9", 0x7940000a, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srari.d", "+d,+e,'", 0x7900000a, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srlr.b", "+d,+e,+f", 0x79000015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srlr.h", "+d,+e,+f", 0x79200015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srlr.w", "+d,+e,+f", 0x79400015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srlr.d", "+d,+e,+f", 0x79600015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"srlri.b", "+d,+e,+7", 0x79f0000a, 0xfff8003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srlri.h", "+d,+e,+8", 0x79e0000a, 0xfff0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srlri.w", "+d,+e,+9", 0x79c0000a, 0xffe0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"srlri.d", "+d,+e,'", 0x7980000a, 0xffc0003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"hadd_s.h", "+d,+e,+f", 0x7a200015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"hadd_s.w", "+d,+e,+f", 0x7a400015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"hadd_s.d", "+d,+e,+f", 0x7a600015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"hadd_u.h", "+d,+e,+f", 0x7aa00015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"hadd_u.w", "+d,+e,+f", 0x7ac00015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"hadd_u.d", "+d,+e,+f", 0x7ae00015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"hsub_s.h", "+d,+e,+f", 0x7b200015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"hsub_s.w", "+d,+e,+f", 0x7b400015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"hsub_s.d", "+d,+e,+f", 0x7b600015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"hsub_u.h", "+d,+e,+f", 0x7ba00015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"hsub_u.w", "+d,+e,+f", 0x7bc00015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"hsub_u.d", "+d,+e,+f", 0x7be00015, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"and.v", "+d,+e,+f", 0x7800001e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"andi.b", "+d,+e,5", 0x78000000, 0xff00003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"or.v", "+d,+e,+f", 0x7820001e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ori.b", "+d,+e,5", 0x79000000, 0xff00003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"nor.v", "+d,+e,+f", 0x7840001e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"nori.b", "+d,+e,5", 0x7a000000, 0xff00003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"xor.v", "+d,+e,+f", 0x7860001e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"xori.b", "+d,+e,5", 0x7b000000, 0xff00003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bmnz.v", "+d,+e,+f", 0x7880001e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bmnzi.b", "+d,+e,5", 0x78000001, 0xff00003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bmz.v", "+d,+e,+f", 0x78a0001e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bmzi.b", "+d,+e,5", 0x79000001, 0xff00003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bsel.v", "+d,+e,+f", 0x78c0001e, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"bseli.b", "+d,+e,5", 0x7a000001, 0xff00003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"shf.b", "+d,+e,5", 0x78000002, 0xff00003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"shf.h", "+d,+e,5", 0x79000002, 0xff00003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"shf.w", "+d,+e,5", 0x7a000002, 0xff00003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"bnz.v", "+f,p", 0x45e00000, 0xffe00000, CBD|RD_VT, 0, MSA},
|
||||
{"bz.v", "+f,p", 0x45600000, 0xffe00000, CBD|RD_VT, 0, MSA},
|
||||
{"fill.b", "+d,d", 0x7b00001e, 0xffff003f, WR_VD, RD_d, MSA},
|
||||
{"fill.h", "+d,d", 0x7b01001e, 0xffff003f, WR_VD, RD_d, MSA},
|
||||
{"fill.w", "+d,d", 0x7b02001e, 0xffff003f, WR_VD, RD_d, MSA},
|
||||
{"fill.d", "+d,d", 0x7b03001e, 0xffff003f, WR_VD, RD_d, MSA64},
|
||||
{"pcnt.b", "+d,+e", 0x7b04001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"pcnt.h", "+d,+e", 0x7b05001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"pcnt.w", "+d,+e", 0x7b06001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"pcnt.d", "+d,+e", 0x7b07001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"nloc.b", "+d,+e", 0x7b08001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"nloc.h", "+d,+e", 0x7b09001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"nloc.w", "+d,+e", 0x7b0a001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"nloc.d", "+d,+e", 0x7b0b001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"nlzc.b", "+d,+e", 0x7b0c001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"nlzc.h", "+d,+e", 0x7b0d001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"nlzc.w", "+d,+e", 0x7b0e001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"nlzc.d", "+d,+e", 0x7b0f001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"copy_s.b", "+i,+e[+9]", 0x78800019, 0xffe0003f, RD_VS, RD_rd6, MSA},
|
||||
{"copy_s.h", "+i,+e[+8]", 0x78a00019, 0xfff0003f, RD_VS, RD_rd6, MSA},
|
||||
{"copy_s.w", "+i,+e[+7]", 0x78b00019, 0xfff8003f, RD_VS, RD_rd6, MSA},
|
||||
{"copy_s.d", "+i,+e[+6]", 0x78b80019, 0xfffc003f, RD_VS, RD_rd6, MSA64},
|
||||
{"copy_u.b", "+i,+e[+9]", 0x78c00019, 0xffe0003f, RD_VS, RD_rd6, MSA},
|
||||
{"copy_u.h", "+i,+e[+8]", 0x78e00019, 0xfff0003f, RD_VS, RD_rd6, MSA},
|
||||
{"copy_u.w", "+i,+e[+7]", 0x78f00019, 0xfff8003f, RD_VS, RD_rd6, MSA},
|
||||
{"copy_u.d", "+i,+e[+6]", 0x78f80019, 0xfffc003f, RD_VS, RD_rd6, MSA64},
|
||||
{"insert.b", "+d[+9],d", 0x79000019, 0xffe0003f, WR_VD|RD_VD, RD_d, MSA},
|
||||
{"insert.h", "+d[+8],d", 0x79200019, 0xfff0003f, WR_VD|RD_VD, RD_d, MSA},
|
||||
{"insert.w", "+d[+7],d", 0x79300019, 0xfff8003f, WR_VD|RD_VD, RD_d, MSA},
|
||||
{"insert.d", "+d[+6],d", 0x79380019, 0xfffc003f, WR_VD|RD_VD, RD_d, MSA64},
|
||||
{"insve.b", "+d[+9],+e[+~]", 0x79400019, 0xffe0003f, WR_VD|RD_VD|RD_VS, 0, MSA},
|
||||
{"insve.h", "+d[+8],+e[+~]", 0x79600019, 0xfff0003f, WR_VD|RD_VD|RD_VS, 0, MSA},
|
||||
{"insve.w", "+d[+7],+e[+~]", 0x79700019, 0xfff8003f, WR_VD|RD_VD|RD_VS, 0, MSA},
|
||||
{"insve.d", "+d[+6],+e[+~]", 0x79780019, 0xfffc003f, WR_VD|RD_VD|RD_VS, 0, MSA},
|
||||
{"bnz.b", "+f,p", 0x47800000, 0xffe00000, CBD|RD_VT, 0, MSA},
|
||||
{"bnz.h", "+f,p", 0x47a00000, 0xffe00000, CBD|RD_VT, 0, MSA},
|
||||
{"bnz.w", "+f,p", 0x47c00000, 0xffe00000, CBD|RD_VT, 0, MSA},
|
||||
{"bnz.d", "+f,p", 0x47e00000, 0xffe00000, CBD|RD_VT, 0, MSA},
|
||||
{"bz.b", "+f,p", 0x47000000, 0xffe00000, CBD|RD_VT, 0, MSA},
|
||||
{"bz.h", "+f,p", 0x47200000, 0xffe00000, CBD|RD_VT, 0, MSA},
|
||||
{"bz.w", "+f,p", 0x47400000, 0xffe00000, CBD|RD_VT, 0, MSA},
|
||||
{"bz.d", "+f,p", 0x47600000, 0xffe00000, CBD|RD_VT, 0, MSA},
|
||||
{"ldi.b", "+d,+0", 0x7b000007, 0xffe0003f, WR_VD, 0, MSA},
|
||||
{"ldi.h", "+d,+0", 0x7b200007, 0xffe0003f, WR_VD, 0, MSA},
|
||||
{"ldi.w", "+d,+0", 0x7b400007, 0xffe0003f, WR_VD, 0, MSA},
|
||||
{"ldi.d", "+d,+0", 0x7b600007, 0xffe0003f, WR_VD, 0, MSA},
|
||||
{"fcaf.w", "+d,+e,+f", 0x7800001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcaf.d", "+d,+e,+f", 0x7820001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcun.w", "+d,+e,+f", 0x7840001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcun.d", "+d,+e,+f", 0x7860001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fceq.w", "+d,+e,+f", 0x7880001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fceq.d", "+d,+e,+f", 0x78a0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcueq.w", "+d,+e,+f", 0x78c0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcueq.d", "+d,+e,+f", 0x78e0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fclt.w", "+d,+e,+f", 0x7900001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fclt.d", "+d,+e,+f", 0x7920001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcult.w", "+d,+e,+f", 0x7940001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcult.d", "+d,+e,+f", 0x7960001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcle.w", "+d,+e,+f", 0x7980001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcle.d", "+d,+e,+f", 0x79a0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcule.w", "+d,+e,+f", 0x79c0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcule.d", "+d,+e,+f", 0x79e0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsaf.w", "+d,+e,+f", 0x7a00001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsaf.d", "+d,+e,+f", 0x7a20001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsun.w", "+d,+e,+f", 0x7a40001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsun.d", "+d,+e,+f", 0x7a60001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fseq.w", "+d,+e,+f", 0x7a80001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fseq.d", "+d,+e,+f", 0x7aa0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsueq.w", "+d,+e,+f", 0x7ac0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsueq.d", "+d,+e,+f", 0x7ae0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fslt.w", "+d,+e,+f", 0x7b00001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fslt.d", "+d,+e,+f", 0x7b20001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsult.w", "+d,+e,+f", 0x7b40001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsult.d", "+d,+e,+f", 0x7b60001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsle.w", "+d,+e,+f", 0x7b80001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsle.d", "+d,+e,+f", 0x7ba0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsule.w", "+d,+e,+f", 0x7bc0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsule.d", "+d,+e,+f", 0x7be0001a, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fadd.w", "+d,+e,+f", 0x7800001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fadd.d", "+d,+e,+f", 0x7820001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsub.w", "+d,+e,+f", 0x7840001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsub.d", "+d,+e,+f", 0x7860001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmul.w", "+d,+e,+f", 0x7880001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmul.d", "+d,+e,+f", 0x78a0001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fdiv.w", "+d,+e,+f", 0x78c0001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fdiv.d", "+d,+e,+f", 0x78e0001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmadd.w", "+d,+e,+f", 0x7900001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmadd.d", "+d,+e,+f", 0x7920001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmsub.w", "+d,+e,+f", 0x7940001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmsub.d", "+d,+e,+f", 0x7960001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fexp2.w", "+d,+e,+f", 0x79c0001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fexp2.d", "+d,+e,+f", 0x79e0001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fexdo.h", "+d,+e,+f", 0x7a00001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fexdo.w", "+d,+e,+f", 0x7a20001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ftq.h", "+d,+e,+f", 0x7a80001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"ftq.w", "+d,+e,+f", 0x7aa0001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmin.w", "+d,+e,+f", 0x7b00001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmin.d", "+d,+e,+f", 0x7b20001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmin_a.w", "+d,+e,+f", 0x7b40001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmin_a.d", "+d,+e,+f", 0x7b60001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmax.w", "+d,+e,+f", 0x7b80001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmax.d", "+d,+e,+f", 0x7ba0001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmax_a.w", "+d,+e,+f", 0x7bc0001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fmax_a.d", "+d,+e,+f", 0x7be0001b, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcor.w", "+d,+e,+f", 0x7840001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcor.d", "+d,+e,+f", 0x7860001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcune.w", "+d,+e,+f", 0x7880001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcune.d", "+d,+e,+f", 0x78a0001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcne.w", "+d,+e,+f", 0x78c0001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fcne.d", "+d,+e,+f", 0x78e0001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mul_q.h", "+d,+e,+f", 0x7900001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mul_q.w", "+d,+e,+f", 0x7920001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"madd_q.h", "+d,+e,+f", 0x7940001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"madd_q.w", "+d,+e,+f", 0x7960001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"msub_q.h", "+d,+e,+f", 0x7980001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"msub_q.w", "+d,+e,+f", 0x79a0001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsor.w", "+d,+e,+f", 0x7a40001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsor.d", "+d,+e,+f", 0x7a60001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsune.w", "+d,+e,+f", 0x7a80001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsune.d", "+d,+e,+f", 0x7aa0001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsne.w", "+d,+e,+f", 0x7ac0001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fsne.d", "+d,+e,+f", 0x7ae0001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mulr_q.h", "+d,+e,+f", 0x7b00001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"mulr_q.w", "+d,+e,+f", 0x7b20001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"maddr_q.h", "+d,+e,+f", 0x7b40001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"maddr_q.w", "+d,+e,+f", 0x7b60001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"msubr_q.h", "+d,+e,+f", 0x7b80001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"msubr_q.w", "+d,+e,+f", 0x7ba0001c, 0xffe0003f, WR_VD|RD_VS|RD_VT, 0, MSA},
|
||||
{"fclass.w", "+d,+e", 0x7b20001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"fclass.d", "+d,+e", 0x7b21001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"fsqrt.w", "+d,+e", 0x7b26001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"fsqrt.d", "+d,+e", 0x7b27001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"frsqrt.w", "+d,+e", 0x7b28001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"frsqrt.d", "+d,+e", 0x7b29001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"frcp.w", "+d,+e", 0x7b2a001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"frcp.d", "+d,+e", 0x7b2b001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"frint.w", "+d,+e", 0x7b2c001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"frint.d", "+d,+e", 0x7b2d001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"flog2.w", "+d,+e", 0x7b2e001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"flog2.d", "+d,+e", 0x7b2f001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"fexupl.w", "+d,+e", 0x7b30001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"fexupl.d", "+d,+e", 0x7b31001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"fexupr.w", "+d,+e", 0x7b32001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"fexupr.d", "+d,+e", 0x7b33001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ffql.w", "+d,+e", 0x7b34001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ffql.d", "+d,+e", 0x7b35001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ffqr.w", "+d,+e", 0x7b36001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ffqr.d", "+d,+e", 0x7b37001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ftint_s.w", "+d,+e", 0x7b38001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ftint_s.d", "+d,+e", 0x7b39001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ftint_u.w", "+d,+e", 0x7b3a001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ftint_u.d", "+d,+e", 0x7b3b001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ffint_s.w", "+d,+e", 0x7b3c001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ffint_s.d", "+d,+e", 0x7b3d001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ffint_u.w", "+d,+e", 0x7b3e001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ffint_u.d", "+d,+e", 0x7b3f001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ftrunc_s.w", "+d,+e", 0x7b40001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ftrunc_s.d", "+d,+e", 0x7b41001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ftrunc_u.w", "+d,+e", 0x7b42001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ftrunc_u.d", "+d,+e", 0x7b43001e, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"ctcmsa", "+h,d", 0x783e0019, 0xffff003f, COD, RD_d, MSA},
|
||||
{"cfcmsa", "+i,+g", 0x787e0019, 0xffff003f, COD, 0, MSA},
|
||||
{"move.v", "+d,+e", 0x78be0019, 0xffff003f, WR_VD|RD_VS, 0, MSA},
|
||||
{"lsa", "d,v,t,+@", 0x00000005, 0xfc00073f, WR_d|RD_s|RD_t, 0, MSA},
|
||||
{"dlsa", "d,v,t,+@", 0x00000015, 0xfc00073f, WR_d|RD_s|RD_t, 0, MSA64},
|
||||
|
||||
{"pref", "k,o(b)", 0xcc000000, 0xfc000000, RD_b, 0, I4|I32|G3 },
|
||||
{"prefx", "h,t(b)", 0x4c00000f, 0xfc0007ff, RD_b|RD_t, 0, I4|I33 },
|
||||
{"nop", "", 0x00000000, 0xffffffff, 0, INSN2_ALIAS, I1 }, /* sll */
|
||||
@@ -2410,6 +2986,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
|
||||
{"tlbp", "", 0x42000008, 0xffffffff, INSN_TLB, 0, I1 },
|
||||
{"tlbr", "", 0x42000001, 0xffffffff, INSN_TLB, 0, I1 },
|
||||
{"tlbwi", "", 0x42000002, 0xffffffff, INSN_TLB, 0, I1 },
|
||||
{"tlbinv", "", 0x42000003, 0xffffffff, INSN_TLB, 0, I32 },
|
||||
{"tlbinvf", "", 0x42000004, 0xffffffff, INSN_TLB, 0, I32 },
|
||||
{"tlbwr", "", 0x42000006, 0xffffffff, INSN_TLB, 0, I1 },
|
||||
{"tlti", "s,j", 0x040a0000, 0xfc1f0000, RD_s|TRAP, 0, I2 },
|
||||
{"tlt", "s,t", 0x00000032, 0xfc00ffff, RD_s|RD_t|TRAP, 0, I2 },
|
||||
@@ -2998,6 +3576,13 @@ static const char * const mips_fpr_names_64[32] =
|
||||
"fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
|
||||
};
|
||||
|
||||
static const char * const mips_wr_names[32] = {
|
||||
"w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7",
|
||||
"w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15",
|
||||
"w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23",
|
||||
"w24", "w25", "w26", "w27", "w28", "w29", "w30", "w31"
|
||||
};
|
||||
|
||||
static const char * const mips_cp0_names_numeric[32] =
|
||||
{
|
||||
"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
|
||||
@@ -3216,6 +3801,20 @@ static const char * const mips_hwr_names_mips3264r2[32] =
|
||||
"$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
|
||||
};
|
||||
|
||||
static const char * const mips_msa_control_names_numeric[32] = {
|
||||
"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
|
||||
"$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
|
||||
"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
|
||||
"$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
|
||||
};
|
||||
|
||||
static const char * const mips_msa_control_names_mips3264r2[32] = {
|
||||
"MSAIR", "MSACSR", "$2", "$3", "$4", "$5", "$6", "$7",
|
||||
"$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
|
||||
"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
|
||||
"$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
|
||||
};
|
||||
|
||||
struct mips_abi_choice
|
||||
{
|
||||
const char *name;
|
||||
@@ -3333,7 +3932,7 @@ static const struct mips_arch_choice mips_arch_choices[] =
|
||||
|
||||
{ "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
|
||||
(ISA_MIPS32R2 | INSN_MIPS16 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
|
||||
| INSN_MIPS3D | INSN_MT),
|
||||
| INSN_MIPS3D | INSN_MT | INSN_MSA),
|
||||
mips_cp0_names_mips3264r2,
|
||||
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
|
||||
mips_hwr_names_mips3264r2 },
|
||||
@@ -3687,6 +4286,89 @@ print_insn_args (const char *d,
|
||||
(l >> OP_SH_UDI4) & OP_MASK_UDI4);
|
||||
break;
|
||||
|
||||
case '5': /* 5-bit signed immediate in bit 16 */
|
||||
delta = ((l >> OP_SH_RT) & OP_MASK_RT);
|
||||
if (delta & 0x10) { /* test sign bit */
|
||||
delta |= ~OP_MASK_RT;
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, "%d", delta);
|
||||
break;
|
||||
|
||||
case '6':
|
||||
(*info->fprintf_func) (info->stream, "0x%lx",
|
||||
(l >> OP_SH_2BIT) & OP_MASK_2BIT);
|
||||
break;
|
||||
|
||||
case '7':
|
||||
(*info->fprintf_func) (info->stream, "0x%lx",
|
||||
(l >> OP_SH_3BIT) & OP_MASK_3BIT);
|
||||
break;
|
||||
|
||||
case '8':
|
||||
(*info->fprintf_func) (info->stream, "0x%lx",
|
||||
(l >> OP_SH_4BIT) & OP_MASK_4BIT);
|
||||
break;
|
||||
|
||||
case '9':
|
||||
(*info->fprintf_func) (info->stream, "0x%lx",
|
||||
(l >> OP_SH_5BIT) & OP_MASK_5BIT);
|
||||
break;
|
||||
|
||||
case ':':
|
||||
(*info->fprintf_func) (info->stream, "0x%lx",
|
||||
(l >> OP_SH_1BIT) & OP_MASK_1BIT);
|
||||
break;
|
||||
|
||||
case '!': /* 10-bit pc-relative target in bit 11 */
|
||||
delta = ((l >> OP_SH_10BIT) & OP_MASK_10BIT);
|
||||
if (delta & 0x200) { /* test sign bit */
|
||||
delta |= ~OP_MASK_10BIT;
|
||||
}
|
||||
info->target = (delta << 2) + pc + INSNLEN;
|
||||
(*info->print_address_func) (info->target, info);
|
||||
break;
|
||||
|
||||
case '~':
|
||||
(*info->fprintf_func) (info->stream, "0");
|
||||
break;
|
||||
|
||||
case '@':
|
||||
(*info->fprintf_func) (info->stream, "0x%lx",
|
||||
((l >> OP_SH_1_TO_4) & OP_MASK_1_TO_4)+1);
|
||||
break;
|
||||
|
||||
case '^': /* 10-bit signed immediate << 0 in bit 16 */
|
||||
delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10);
|
||||
if (delta & 0x200) { /* test sign bit */
|
||||
delta |= ~OP_MASK_IMM10;
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, "%d", delta);
|
||||
break;
|
||||
|
||||
case '#': /* 10-bit signed immediate << 1 in bit 16 */
|
||||
delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10);
|
||||
if (delta & 0x200) { /* test sign bit */
|
||||
delta |= ~OP_MASK_IMM10;
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, "%d", delta << 1);
|
||||
break;
|
||||
|
||||
case '$': /* 10-bit signed immediate << 2 in bit 16 */
|
||||
delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10);
|
||||
if (delta & 0x200) { /* test sign bit */
|
||||
delta |= ~OP_MASK_IMM10;
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, "%d", delta << 2);
|
||||
break;
|
||||
|
||||
case '%': /* 10-bit signed immediate << 3 in bit 16 */
|
||||
delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10);
|
||||
if (delta & 0x200) { /* test sign bit */
|
||||
delta |= ~OP_MASK_IMM10;
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, "%d", delta << 3);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
case 'H':
|
||||
msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD;
|
||||
@@ -3794,6 +4476,38 @@ print_insn_args (const char *d,
|
||||
break;
|
||||
}
|
||||
|
||||
case 'd':
|
||||
(*info->fprintf_func) (info->stream, "%s",
|
||||
mips_wr_names[(l >> OP_SH_FD) & OP_MASK_FD]);
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
(*info->fprintf_func) (info->stream, "%s",
|
||||
mips_wr_names[(l >> OP_SH_FS) & OP_MASK_FS]);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
(*info->fprintf_func) (info->stream, "%s",
|
||||
mips_wr_names[(l >> OP_SH_FT) & OP_MASK_FT]);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
(*info->fprintf_func) (info->stream, "%s",
|
||||
mips_msa_control_names_mips3264r2[(l >> OP_SH_MSACR11)
|
||||
& OP_MASK_MSACR11]);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
(*info->fprintf_func) (info->stream, "%s",
|
||||
mips_msa_control_names_mips3264r2[(l >> OP_SH_MSACR6)
|
||||
& OP_MASK_MSACR6]);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
(*info->fprintf_func) (info->stream, "%s",
|
||||
mips_gpr_names[(l >> OP_SH_GPR) & OP_MASK_GPR]);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* xgettext:c-format */
|
||||
(*info->fprintf_func) (info->stream,
|
||||
|
@@ -139,12 +139,12 @@ events are not tightly coupled to a specific trace backend, such as LTTng or
|
||||
SystemTap. Support for trace backends can be added by extending the "tracetool"
|
||||
script.
|
||||
|
||||
The trace backend is chosen at configure time and only one trace backend can
|
||||
be built into the binary:
|
||||
The trace backends are chosen at configure time:
|
||||
|
||||
./configure --trace-backends=simple
|
||||
./configure --enable-trace-backends=simple
|
||||
|
||||
For a list of supported trace backends, try ./configure --help or see below.
|
||||
If multiple backends are enabled, the trace is sent to them all.
|
||||
|
||||
The following subsections describe the supported trace backends.
|
||||
|
||||
|
15
exec.c
15
exec.c
@@ -909,14 +909,15 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
|
||||
uint16_t section);
|
||||
static subpage_t *subpage_init(AddressSpace *as, hwaddr base);
|
||||
|
||||
static void *(*phys_mem_alloc)(size_t size) = qemu_anon_ram_alloc;
|
||||
static void *(*phys_mem_alloc)(size_t size, uint64_t *align) =
|
||||
qemu_anon_ram_alloc;
|
||||
|
||||
/*
|
||||
* Set a custom physical guest memory alloator.
|
||||
* Accelerators with unusual needs may need this. Hopefully, we can
|
||||
* get rid of it eventually.
|
||||
*/
|
||||
void phys_mem_set_alloc(void *(*alloc)(size_t))
|
||||
void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align))
|
||||
{
|
||||
phys_mem_alloc = alloc;
|
||||
}
|
||||
@@ -1098,6 +1099,7 @@ static void *file_ram_alloc(RAMBlock *block,
|
||||
error_propagate(errp, local_err);
|
||||
goto error;
|
||||
}
|
||||
block->mr->align = hpagesize;
|
||||
|
||||
if (memory < hpagesize) {
|
||||
error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
|
||||
@@ -1309,7 +1311,8 @@ static ram_addr_t ram_block_add(RAMBlock *new_block, Error **errp)
|
||||
if (xen_enabled()) {
|
||||
xen_ram_alloc(new_block->offset, new_block->length, new_block->mr);
|
||||
} else {
|
||||
new_block->host = phys_mem_alloc(new_block->length);
|
||||
new_block->host = phys_mem_alloc(new_block->length,
|
||||
&new_block->mr->align);
|
||||
if (!new_block->host) {
|
||||
error_setg_errno(errp, errno,
|
||||
"cannot set up guest memory '%s'",
|
||||
@@ -2066,10 +2069,8 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||
static void invalidate_and_set_dirty(hwaddr addr,
|
||||
hwaddr length)
|
||||
{
|
||||
if (cpu_physical_memory_is_clean(addr)) {
|
||||
/* invalidate code */
|
||||
tb_invalidate_phys_page_range(addr, addr + length, 0);
|
||||
/* set dirty bit */
|
||||
if (cpu_physical_memory_range_includes_clean(addr, length)) {
|
||||
tb_invalidate_phys_range(addr, addr + length, 0);
|
||||
cpu_physical_memory_set_dirty_range_nocode(addr, length);
|
||||
}
|
||||
xen_modified_memory(addr, length);
|
||||
|
@@ -823,7 +823,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||
action = *p++;
|
||||
signal = 0;
|
||||
if (action == 'C' || action == 'S') {
|
||||
signal = strtoul(p, (char **)&p, 16);
|
||||
signal = gdb_signal_to_target(strtoul(p, (char **)&p, 16));
|
||||
if (signal == -1) {
|
||||
signal = 0;
|
||||
}
|
||||
} else if (action != 'c' && action != 's') {
|
||||
res = 0;
|
||||
break;
|
||||
|
@@ -376,8 +376,11 @@ static void acpi_notify_wakeup(Notifier *notifier, void *data)
|
||||
/* ACPI PM1a EVT */
|
||||
uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar)
|
||||
{
|
||||
int64_t d = acpi_pm_tmr_get_clock();
|
||||
if (d >= ar->tmr.overflow_time) {
|
||||
/* Compare ns-clock, not PM timer ticks, because
|
||||
acpi_pm_tmr_update function uses ns for setting the timer. */
|
||||
int64_t d = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
if (d >= muldiv64(ar->tmr.overflow_time,
|
||||
get_ticks_per_sec(), PM_TIMER_FREQUENCY)) {
|
||||
ar->pm1.evt.sts |= ACPI_BITMASK_TIMER_STATUS;
|
||||
}
|
||||
return ar->pm1.evt.sts;
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "hw/mem/pc-dimm.h"
|
||||
#include "hw/acpi/memory_hotplug.h"
|
||||
#include "hw/acpi/acpi_dev_interface.h"
|
||||
#include "hw/xen/xen.h"
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
@@ -501,6 +502,9 @@ I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
|
||||
s->irq = sci_irq;
|
||||
s->smi_irq = smi_irq;
|
||||
s->kvm_enabled = kvm_enabled;
|
||||
if (xen_enabled()) {
|
||||
s->use_acpi_pci_hotplug = false;
|
||||
}
|
||||
|
||||
qdev_init_nofail(dev);
|
||||
|
||||
|
@@ -389,7 +389,7 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
|
||||
qemu_fdt_setprop(vbi->fdt, nodename, "clock-names",
|
||||
clocknames, sizeof(clocknames));
|
||||
|
||||
qemu_fdt_setprop_string(vbi->fdt, "/chosen", "linux,stdout-path", nodename);
|
||||
qemu_fdt_setprop_string(vbi->fdt, "/chosen", "stdout-path", nodename);
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
|
@@ -583,8 +583,7 @@ static int nvme_start_ctrl(NvmeCtrl *n)
|
||||
NVME_CC_IOCQES(n->bar.cc) > NVME_CTRL_CQES_MAX(n->id_ctrl.cqes) ||
|
||||
NVME_CC_IOSQES(n->bar.cc) < NVME_CTRL_SQES_MIN(n->id_ctrl.sqes) ||
|
||||
NVME_CC_IOSQES(n->bar.cc) > NVME_CTRL_SQES_MAX(n->id_ctrl.sqes) ||
|
||||
!NVME_AQA_ASQS(n->bar.aqa) || NVME_AQA_ASQS(n->bar.aqa) > 4095 ||
|
||||
!NVME_AQA_ACQS(n->bar.aqa) || NVME_AQA_ACQS(n->bar.aqa) > 4095) {
|
||||
!NVME_AQA_ASQS(n->bar.aqa) || !NVME_AQA_ACQS(n->bar.aqa)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@@ -59,6 +59,13 @@ struct PersistentGrant {
|
||||
|
||||
typedef struct PersistentGrant PersistentGrant;
|
||||
|
||||
struct PersistentRegion {
|
||||
void *addr;
|
||||
int num;
|
||||
};
|
||||
|
||||
typedef struct PersistentRegion PersistentRegion;
|
||||
|
||||
struct ioreq {
|
||||
blkif_request_t req;
|
||||
int16_t status;
|
||||
@@ -118,6 +125,7 @@ struct XenBlkDev {
|
||||
gboolean feature_discard;
|
||||
gboolean feature_persistent;
|
||||
GTree *persistent_gnts;
|
||||
GSList *persistent_regions;
|
||||
unsigned int persistent_gnt_count;
|
||||
unsigned int max_grants;
|
||||
|
||||
@@ -177,6 +185,23 @@ static void destroy_grant(gpointer pgnt)
|
||||
g_free(grant);
|
||||
}
|
||||
|
||||
static void remove_persistent_region(gpointer data, gpointer dev)
|
||||
{
|
||||
PersistentRegion *region = data;
|
||||
struct XenBlkDev *blkdev = dev;
|
||||
XenGnttab gnt = blkdev->xendev.gnttabdev;
|
||||
|
||||
if (xc_gnttab_munmap(gnt, region->addr, region->num) != 0) {
|
||||
xen_be_printf(&blkdev->xendev, 0,
|
||||
"xc_gnttab_munmap region %p failed: %s\n",
|
||||
region->addr, strerror(errno));
|
||||
}
|
||||
xen_be_printf(&blkdev->xendev, 3,
|
||||
"unmapped grant region %p with %d pages\n",
|
||||
region->addr, region->num);
|
||||
g_free(region);
|
||||
}
|
||||
|
||||
static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
|
||||
{
|
||||
struct ioreq *ioreq = NULL;
|
||||
@@ -343,6 +368,7 @@ static int ioreq_map(struct ioreq *ioreq)
|
||||
void *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
|
||||
int i, j, new_maps = 0;
|
||||
PersistentGrant *grant;
|
||||
PersistentRegion *region;
|
||||
/* domids and refs variables will contain the information necessary
|
||||
* to map the grants that are needed to fulfill this request.
|
||||
*
|
||||
@@ -421,7 +447,22 @@ static int ioreq_map(struct ioreq *ioreq)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ioreq->blkdev->feature_persistent) {
|
||||
if (ioreq->blkdev->feature_persistent && new_maps != 0 &&
|
||||
(!batch_maps || (ioreq->blkdev->persistent_gnt_count + new_maps <=
|
||||
ioreq->blkdev->max_grants))) {
|
||||
/*
|
||||
* If we are using persistent grants and batch mappings only
|
||||
* add the new maps to the list of persistent grants if the whole
|
||||
* area can be persistently mapped.
|
||||
*/
|
||||
if (batch_maps) {
|
||||
region = g_malloc0(sizeof(*region));
|
||||
region->addr = ioreq->pages;
|
||||
region->num = new_maps;
|
||||
ioreq->blkdev->persistent_regions = g_slist_append(
|
||||
ioreq->blkdev->persistent_regions,
|
||||
region);
|
||||
}
|
||||
while ((ioreq->blkdev->persistent_gnt_count < ioreq->blkdev->max_grants)
|
||||
&& new_maps) {
|
||||
/* Go through the list of newly mapped grants and add as many
|
||||
@@ -447,6 +488,7 @@ static int ioreq_map(struct ioreq *ioreq)
|
||||
grant);
|
||||
ioreq->blkdev->persistent_gnt_count++;
|
||||
}
|
||||
assert(!batch_maps || new_maps == 0);
|
||||
}
|
||||
for (i = 0; i < ioreq->v.niov; i++) {
|
||||
ioreq->v.iov[i].iov_base += (uintptr_t)page[i];
|
||||
@@ -971,7 +1013,10 @@ static int blk_connect(struct XenDevice *xendev)
|
||||
blkdev->max_grants = max_requests * BLKIF_MAX_SEGMENTS_PER_REQUEST;
|
||||
blkdev->persistent_gnts = g_tree_new_full((GCompareDataFunc)int_cmp,
|
||||
NULL, NULL,
|
||||
batch_maps ?
|
||||
(GDestroyNotify)g_free :
|
||||
(GDestroyNotify)destroy_grant);
|
||||
blkdev->persistent_regions = NULL;
|
||||
blkdev->persistent_gnt_count = 0;
|
||||
}
|
||||
|
||||
@@ -1000,6 +1045,26 @@ static void blk_disconnect(struct XenDevice *xendev)
|
||||
blkdev->cnt_map--;
|
||||
blkdev->sring = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unmap persistent grants before switching to the closed state
|
||||
* so the frontend can free them.
|
||||
*
|
||||
* In the !batch_maps case g_tree_destroy will take care of unmapping
|
||||
* the grant, but in the batch_maps case we need to iterate over every
|
||||
* region in persistent_regions and unmap it.
|
||||
*/
|
||||
if (blkdev->feature_persistent) {
|
||||
g_tree_destroy(blkdev->persistent_gnts);
|
||||
assert(batch_maps || blkdev->persistent_gnt_count == 0);
|
||||
if (batch_maps) {
|
||||
blkdev->persistent_gnt_count = 0;
|
||||
g_slist_foreach(blkdev->persistent_regions,
|
||||
(GFunc)remove_persistent_region, blkdev);
|
||||
g_slist_free(blkdev->persistent_regions);
|
||||
}
|
||||
blkdev->feature_persistent = false;
|
||||
}
|
||||
}
|
||||
|
||||
static int blk_free(struct XenDevice *xendev)
|
||||
@@ -1011,11 +1076,6 @@ static int blk_free(struct XenDevice *xendev)
|
||||
blk_disconnect(xendev);
|
||||
}
|
||||
|
||||
/* Free persistent grants */
|
||||
if (blkdev->feature_persistent) {
|
||||
g_tree_destroy(blkdev->persistent_gnts);
|
||||
}
|
||||
|
||||
while (!QLIST_EMPTY(&blkdev->freelist)) {
|
||||
ioreq = QLIST_FIRST(&blkdev->freelist);
|
||||
QLIST_REMOVE(ioreq, list);
|
||||
|
@@ -52,7 +52,8 @@ typedef struct SCLPConsoleLM {
|
||||
* event_pending is set when a newline character is encountered
|
||||
*
|
||||
* The maximum command line length is limited by the maximum
|
||||
* space available in an SCCB
|
||||
* space available in an SCCB. Line mode console input is sent
|
||||
* truncated to the guest in case it doesn't fit into the SCCB.
|
||||
*/
|
||||
|
||||
static int chr_can_read(void *opaque)
|
||||
@@ -61,10 +62,8 @@ static int chr_can_read(void *opaque)
|
||||
|
||||
if (scon->event.event_pending) {
|
||||
return 0;
|
||||
} else if (SIZE_CONSOLE_BUFFER - scon->length) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void chr_read(void *opaque, const uint8_t *buf, int size)
|
||||
@@ -78,6 +77,10 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
|
||||
sclp_service_interrupt(0);
|
||||
return;
|
||||
}
|
||||
if (scon->length == SIZE_CONSOLE_BUFFER) {
|
||||
/* Eat the character, but still process CR and LF. */
|
||||
return;
|
||||
}
|
||||
scon->buf[scon->length] = *buf;
|
||||
scon->length += 1;
|
||||
if (scon->echo) {
|
||||
@@ -125,6 +128,7 @@ static int get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
|
||||
cons->length = 0;
|
||||
/* data provided and no more data pending */
|
||||
event->event_pending = false;
|
||||
qemu_notify_event();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -36,6 +36,7 @@ typedef struct SCLPConsole {
|
||||
uint32_t iov_bs; /* offset in buf for char layer read operation */
|
||||
uint32_t iov_data_len; /* length of byte stream in buffer */
|
||||
uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
|
||||
bool notify; /* qemu_notify_event() req'd if true */
|
||||
} SCLPConsole;
|
||||
|
||||
/* character layer call-back functions */
|
||||
@@ -44,8 +45,12 @@ typedef struct SCLPConsole {
|
||||
static int chr_can_read(void *opaque)
|
||||
{
|
||||
SCLPConsole *scon = opaque;
|
||||
int avail = SIZE_BUFFER_VT220 - scon->iov_data_len;
|
||||
|
||||
return SIZE_BUFFER_VT220 - scon->iov_data_len;
|
||||
if (avail == 0) {
|
||||
scon->notify = true;
|
||||
}
|
||||
return avail;
|
||||
}
|
||||
|
||||
/* Send data from a char device over to the guest */
|
||||
@@ -113,6 +118,10 @@ static void get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
|
||||
cons->iov_sclp += avail;
|
||||
/* more data pending */
|
||||
}
|
||||
if (cons->notify) {
|
||||
cons->notify = false;
|
||||
qemu_notify_event();
|
||||
}
|
||||
}
|
||||
|
||||
static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
|
||||
@@ -229,6 +238,7 @@ static void console_reset(DeviceState *dev)
|
||||
scon->iov_bs = 0;
|
||||
scon->iov_data_len = 0;
|
||||
scon->iov_sclp_rest = 0;
|
||||
scon->notify = false;
|
||||
}
|
||||
|
||||
static int console_exit(SCLPEvent *event)
|
||||
|
@@ -871,7 +871,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
if (find_port_by_name(port->name)) {
|
||||
if (port->name != NULL && find_port_by_name(port->name)) {
|
||||
error_setg(errp, "virtio-serial-bus: A port already exists by name %s",
|
||||
port->name);
|
||||
return;
|
||||
|
@@ -14,3 +14,4 @@ common-obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += null-machine.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += loader.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += platform-bus.o
|
||||
|
@@ -80,6 +80,13 @@ int load_image(const char *filename, uint8_t *addr)
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
size = lseek(fd, 0, SEEK_END);
|
||||
if (size == -1) {
|
||||
fprintf(stderr, "file %-20s: get size error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
if (read(fd, addr, size) != size) {
|
||||
close(fd);
|
||||
@@ -748,6 +755,12 @@ int rom_add_file(const char *file, const char *fw_dir,
|
||||
}
|
||||
rom->addr = addr;
|
||||
rom->romsize = lseek(fd, 0, SEEK_END);
|
||||
if (rom->romsize == -1) {
|
||||
fprintf(stderr, "rom: file %-20s: get size error: %s\n",
|
||||
rom->name, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
rom->datasize = rom->romsize;
|
||||
rom->data = g_malloc0(rom->datasize);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
@@ -798,12 +811,12 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
hwaddr addr, const char *fw_file_name,
|
||||
FWCfgReadCallback fw_callback, void *callback_opaque)
|
||||
{
|
||||
Rom *rom;
|
||||
void *data = NULL;
|
||||
ram_addr_t ret = RAM_ADDR_MAX;
|
||||
|
||||
rom = g_malloc0(sizeof(*rom));
|
||||
rom->name = g_strdup(name);
|
||||
@@ -815,11 +828,13 @@ void *rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
rom_insert(rom);
|
||||
if (fw_file_name && fw_cfg) {
|
||||
char devpath[100];
|
||||
void *data;
|
||||
|
||||
snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
|
||||
|
||||
if (rom_file_has_mr) {
|
||||
data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
|
||||
ret = memory_region_get_ram_addr(rom->mr);
|
||||
} else {
|
||||
data = rom->data;
|
||||
}
|
||||
@@ -828,7 +843,7 @@ void *rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
fw_callback, callback_opaque,
|
||||
data, rom->romsize);
|
||||
}
|
||||
return data;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This function is specific for elf program because we don't need to allocate
|
||||
|
@@ -12,6 +12,9 @@
|
||||
|
||||
#include "hw/boards.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
static char *machine_get_accel(Object *obj, Error **errp)
|
||||
{
|
||||
@@ -257,8 +260,35 @@ static void machine_set_iommu(Object *obj, bool value, Error **errp)
|
||||
ms->iommu = value;
|
||||
}
|
||||
|
||||
static int error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
error_report("Option '-device %s' cannot be handled by this machine",
|
||||
object_class_get_name(object_get_class(OBJECT(sbdev))));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void machine_init_notify(Notifier *notifier, void *data)
|
||||
{
|
||||
Object *machine = qdev_get_machine();
|
||||
ObjectClass *oc = object_get_class(machine);
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
if (mc->has_dynamic_sysbus) {
|
||||
/* Our machine can handle dynamic sysbus devices, we're all good */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop through all dynamically created devices and check whether there
|
||||
* are sysbus devices among them. If there are, error out.
|
||||
*/
|
||||
foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL);
|
||||
}
|
||||
|
||||
static void machine_initfn(Object *obj)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
object_property_add_str(obj, "accel",
|
||||
machine_get_accel, machine_set_accel, NULL);
|
||||
object_property_add_bool(obj, "kernel-irqchip",
|
||||
@@ -303,6 +333,10 @@ static void machine_initfn(Object *obj)
|
||||
object_property_add_bool(obj, "iommu",
|
||||
machine_get_iommu,
|
||||
machine_set_iommu, NULL);
|
||||
|
||||
/* Register notifier when init is done for sysbus sanity checks */
|
||||
ms->sysbus_notifier.notify = machine_init_notify;
|
||||
qemu_add_machine_init_done_notifier(&ms->sysbus_notifier);
|
||||
}
|
||||
|
||||
static void machine_finalize(Object *obj)
|
||||
|
253
hw/core/platform-bus.c
Normal file
253
hw/core/platform-bus.c
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Platform Bus device to support dynamic Sysbus devices
|
||||
*
|
||||
* Copyright (C) 2014 Freescale Semiconductor, Inc. All rights reserved.
|
||||
*
|
||||
* Author: Alexander Graf, <agraf@suse.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "hw/platform-bus.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
|
||||
|
||||
/*
|
||||
* Returns the PlatformBus IRQ number for a SysBusDevice irq number or -1 if
|
||||
* the IRQ is not mapped on this Platform bus.
|
||||
*/
|
||||
int platform_bus_get_irqn(PlatformBusDevice *pbus, SysBusDevice *sbdev,
|
||||
int n)
|
||||
{
|
||||
qemu_irq sbirq = sysbus_get_connected_irq(sbdev, n);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pbus->num_irqs; i++) {
|
||||
if (pbus->irqs[i] == sbirq) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/* IRQ not mapped on platform bus */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the PlatformBus MMIO region offset for Region n of a SysBusDevice or
|
||||
* -1 if the region is not mapped on this Platform bus.
|
||||
*/
|
||||
hwaddr platform_bus_get_mmio_addr(PlatformBusDevice *pbus, SysBusDevice *sbdev,
|
||||
int n)
|
||||
{
|
||||
MemoryRegion *pbus_mr = &pbus->mmio;
|
||||
MemoryRegion *sbdev_mr = sysbus_mmio_get_region(sbdev, n);
|
||||
Object *pbus_mr_obj = OBJECT(pbus_mr);
|
||||
Object *parent_mr;
|
||||
|
||||
if (!memory_region_is_mapped(sbdev_mr)) {
|
||||
/* Region is not mapped? */
|
||||
return -1;
|
||||
}
|
||||
|
||||
parent_mr = object_property_get_link(OBJECT(sbdev_mr), "container", NULL);
|
||||
|
||||
assert(parent_mr);
|
||||
if (parent_mr != pbus_mr_obj) {
|
||||
/* MMIO region is not mapped on platform bus */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return object_property_get_int(OBJECT(sbdev_mr), "addr", NULL);
|
||||
}
|
||||
|
||||
static int platform_bus_count_irqs(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
PlatformBusDevice *pbus = opaque;
|
||||
qemu_irq sbirq;
|
||||
int n, i;
|
||||
|
||||
for (n = 0; ; n++) {
|
||||
if (!sysbus_has_irq(sbdev, n)) {
|
||||
break;
|
||||
}
|
||||
|
||||
sbirq = sysbus_get_connected_irq(sbdev, n);
|
||||
for (i = 0; i < pbus->num_irqs; i++) {
|
||||
if (pbus->irqs[i] == sbirq) {
|
||||
bitmap_set(pbus->used_irqs, i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop through all sysbus devices and look for unassigned IRQ lines as well as
|
||||
* unassociated MMIO regions. Connect them to the platform bus if available.
|
||||
*/
|
||||
static void plaform_bus_refresh_irqs(PlatformBusDevice *pbus)
|
||||
{
|
||||
bitmap_zero(pbus->used_irqs, pbus->num_irqs);
|
||||
foreach_dynamic_sysbus_device(platform_bus_count_irqs, pbus);
|
||||
pbus->done_gathering = true;
|
||||
}
|
||||
|
||||
static int platform_bus_map_irq(PlatformBusDevice *pbus, SysBusDevice *sbdev,
|
||||
int n)
|
||||
{
|
||||
int max_irqs = pbus->num_irqs;
|
||||
int irqn;
|
||||
|
||||
if (sysbus_is_irq_connected(sbdev, n)) {
|
||||
/* IRQ is already mapped, nothing to do */
|
||||
return 0;
|
||||
}
|
||||
|
||||
irqn = find_first_zero_bit(pbus->used_irqs, max_irqs);
|
||||
if (irqn >= max_irqs) {
|
||||
hw_error("Platform Bus: Can not fit IRQ line");
|
||||
return -1;
|
||||
}
|
||||
|
||||
set_bit(irqn, pbus->used_irqs);
|
||||
sysbus_connect_irq(sbdev, n, pbus->irqs[irqn]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int platform_bus_map_mmio(PlatformBusDevice *pbus, SysBusDevice *sbdev,
|
||||
int n)
|
||||
{
|
||||
MemoryRegion *sbdev_mr = sysbus_mmio_get_region(sbdev, n);
|
||||
uint64_t size = memory_region_size(sbdev_mr);
|
||||
uint64_t alignment = (1ULL << (63 - clz64(size + size - 1)));
|
||||
uint64_t off;
|
||||
bool found_region = false;
|
||||
|
||||
if (memory_region_is_mapped(sbdev_mr)) {
|
||||
/* Region is already mapped, nothing to do */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for empty space in the MMIO space that is naturally aligned with
|
||||
* the target device's memory region
|
||||
*/
|
||||
for (off = 0; off < pbus->mmio_size; off += alignment) {
|
||||
if (!memory_region_find(&pbus->mmio, off, size).mr) {
|
||||
found_region = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_region) {
|
||||
hw_error("Platform Bus: Can not fit MMIO region of size %"PRIx64, size);
|
||||
}
|
||||
|
||||
/* Map the device's region into our Platform Bus MMIO space */
|
||||
memory_region_add_subregion(&pbus->mmio, off, sbdev_mr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* For each sysbus device, look for unassigned IRQ lines as well as
|
||||
* unassociated MMIO regions. Connect them to the platform bus if available.
|
||||
*/
|
||||
static int link_sysbus_device(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
PlatformBusDevice *pbus = opaque;
|
||||
int i;
|
||||
|
||||
for (i = 0; sysbus_has_irq(sbdev, i); i++) {
|
||||
platform_bus_map_irq(pbus, sbdev, i);
|
||||
}
|
||||
|
||||
for (i = 0; sysbus_has_mmio(sbdev, i); i++) {
|
||||
platform_bus_map_mmio(pbus, sbdev, i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void platform_bus_init_notify(Notifier *notifier, void *data)
|
||||
{
|
||||
PlatformBusDevice *pb = container_of(notifier, PlatformBusDevice, notifier);
|
||||
|
||||
/*
|
||||
* Generate a bitmap of used IRQ lines, as the user might have specified
|
||||
* them on the command line.
|
||||
*/
|
||||
plaform_bus_refresh_irqs(pb);
|
||||
|
||||
foreach_dynamic_sysbus_device(link_sysbus_device, pb);
|
||||
}
|
||||
|
||||
static void platform_bus_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PlatformBusDevice *pbus;
|
||||
SysBusDevice *d;
|
||||
int i;
|
||||
|
||||
d = SYS_BUS_DEVICE(dev);
|
||||
pbus = PLATFORM_BUS_DEVICE(dev);
|
||||
|
||||
memory_region_init(&pbus->mmio, NULL, "platform bus", pbus->mmio_size);
|
||||
sysbus_init_mmio(d, &pbus->mmio);
|
||||
|
||||
pbus->used_irqs = bitmap_new(pbus->num_irqs);
|
||||
pbus->irqs = g_new0(qemu_irq, pbus->num_irqs);
|
||||
for (i = 0; i < pbus->num_irqs; i++) {
|
||||
sysbus_init_irq(d, &pbus->irqs[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register notifier that allows us to gather dangling devices once the
|
||||
* machine is completely assembled
|
||||
*/
|
||||
pbus->notifier.notify = platform_bus_init_notify;
|
||||
qemu_add_machine_init_done_notifier(&pbus->notifier);
|
||||
}
|
||||
|
||||
static Property platform_bus_properties[] = {
|
||||
DEFINE_PROP_UINT32("num_irqs", PlatformBusDevice, num_irqs, 0),
|
||||
DEFINE_PROP_UINT32("mmio_size", PlatformBusDevice, mmio_size, 0),
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
static void platform_bus_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->realize = platform_bus_realize;
|
||||
dc->props = platform_bus_properties;
|
||||
}
|
||||
|
||||
static const TypeInfo platform_bus_info = {
|
||||
.name = TYPE_PLATFORM_BUS_DEVICE,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(PlatformBusDevice),
|
||||
.class_init = platform_bus_class_init,
|
||||
};
|
||||
|
||||
static void platform_bus_register_types(void)
|
||||
{
|
||||
type_register_static(&platform_bus_info);
|
||||
}
|
||||
|
||||
type_init(platform_bus_register_types)
|
@@ -453,6 +453,17 @@ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
|
||||
g_free(propname);
|
||||
}
|
||||
|
||||
qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
|
||||
{
|
||||
char *propname = g_strdup_printf("%s[%d]",
|
||||
name ? name : "unnamed-gpio-out", n);
|
||||
|
||||
qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
|
||||
NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* disconnect a GPIO ouput, returning the disconnected input (if any) */
|
||||
|
||||
static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
|
||||
@@ -924,7 +935,7 @@ void qdev_alias_all_properties(DeviceState *target, Object *source)
|
||||
} while (class != object_class_by_name(TYPE_DEVICE));
|
||||
}
|
||||
|
||||
int qdev_build_hotpluggable_device_list(Object *obj, void *opaque)
|
||||
static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
|
||||
{
|
||||
GSList **list = opaque;
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
@@ -933,10 +944,18 @@ int qdev_build_hotpluggable_device_list(Object *obj, void *opaque)
|
||||
*list = g_slist_append(*list, dev);
|
||||
}
|
||||
|
||||
object_child_foreach(obj, qdev_build_hotpluggable_device_list, opaque);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
|
||||
{
|
||||
GSList *list = NULL;
|
||||
|
||||
object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static bool device_get_realized(Object *obj, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
|
@@ -24,6 +24,51 @@
|
||||
static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
|
||||
static char *sysbus_get_fw_dev_path(DeviceState *dev);
|
||||
|
||||
typedef struct SysBusFind {
|
||||
void *opaque;
|
||||
FindSysbusDeviceFunc *func;
|
||||
} SysBusFind;
|
||||
|
||||
/* Run func() for every sysbus device, traverse the tree for everything else */
|
||||
static int find_sysbus_device(Object *obj, void *opaque)
|
||||
{
|
||||
SysBusFind *find = opaque;
|
||||
Object *dev;
|
||||
SysBusDevice *sbdev;
|
||||
|
||||
dev = object_dynamic_cast(obj, TYPE_SYS_BUS_DEVICE);
|
||||
sbdev = (SysBusDevice *)dev;
|
||||
|
||||
if (!sbdev) {
|
||||
/* Container, traverse it for children */
|
||||
return object_child_foreach(obj, find_sysbus_device, opaque);
|
||||
}
|
||||
|
||||
find->func(sbdev, find->opaque);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop through all dynamically created sysbus devices and call
|
||||
* func() for each instance.
|
||||
*/
|
||||
void foreach_dynamic_sysbus_device(FindSysbusDeviceFunc *func, void *opaque)
|
||||
{
|
||||
Object *container;
|
||||
SysBusFind find = {
|
||||
.func = func,
|
||||
.opaque = opaque,
|
||||
};
|
||||
|
||||
/* Loop through all sysbus devices that were spawened outside the machine */
|
||||
container = container_get(qdev_get_machine(), "/peripheral");
|
||||
find_sysbus_device(container, &find);
|
||||
container = container_get(qdev_get_machine(), "/peripheral-anon");
|
||||
find_sysbus_device(container, &find);
|
||||
}
|
||||
|
||||
|
||||
static void system_bus_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
BusClass *k = BUS_CLASS(klass);
|
||||
@@ -39,11 +84,38 @@ static const TypeInfo system_bus_info = {
|
||||
.class_init = system_bus_class_init,
|
||||
};
|
||||
|
||||
/* Check whether an IRQ source exists */
|
||||
bool sysbus_has_irq(SysBusDevice *dev, int n)
|
||||
{
|
||||
char *prop = g_strdup_printf("%s[%d]", SYSBUS_DEVICE_GPIO_IRQ, n);
|
||||
ObjectProperty *r;
|
||||
|
||||
r = object_property_find(OBJECT(dev), prop, NULL);
|
||||
return (r != NULL);
|
||||
}
|
||||
|
||||
bool sysbus_is_irq_connected(SysBusDevice *dev, int n)
|
||||
{
|
||||
return !!sysbus_get_connected_irq(dev, n);
|
||||
}
|
||||
|
||||
qemu_irq sysbus_get_connected_irq(SysBusDevice *dev, int n)
|
||||
{
|
||||
DeviceState *d = DEVICE(dev);
|
||||
return qdev_get_gpio_out_connector(d, SYSBUS_DEVICE_GPIO_IRQ, n);
|
||||
}
|
||||
|
||||
void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
|
||||
{
|
||||
qdev_connect_gpio_out_named(DEVICE(dev), SYSBUS_DEVICE_GPIO_IRQ, n, irq);
|
||||
}
|
||||
|
||||
/* Check whether an MMIO region exists */
|
||||
bool sysbus_has_mmio(SysBusDevice *dev, unsigned int n)
|
||||
{
|
||||
return (n < dev->num_mmio);
|
||||
}
|
||||
|
||||
static void sysbus_mmio_map_common(SysBusDevice *dev, int n, hwaddr addr,
|
||||
bool may_overlap, int priority)
|
||||
{
|
||||
@@ -238,13 +310,6 @@ static void sysbus_device_class_init(ObjectClass *klass, void *data)
|
||||
DeviceClass *k = DEVICE_CLASS(klass);
|
||||
k->init = sysbus_device_init;
|
||||
k->bus_type = TYPE_SYSTEM_BUS;
|
||||
/*
|
||||
* device_add plugs devices into suitable bus. For "real" buses,
|
||||
* that actually connects the device. For sysbus, the connections
|
||||
* need to be made separately, and device_add can't do that. The
|
||||
* device would be left unconnected, and could not possibly work.
|
||||
*/
|
||||
k->cannot_instantiate_with_device_add_yet = true;
|
||||
}
|
||||
|
||||
static const TypeInfo sysbus_device_type_info = {
|
||||
|
@@ -73,11 +73,11 @@ typedef struct ICCBridgeState {
|
||||
MemoryRegion apic_container;
|
||||
} ICCBridgeState;
|
||||
|
||||
#define ICC_BRIGDE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE)
|
||||
#define ICC_BRIDGE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE)
|
||||
|
||||
static void icc_bridge_init(Object *obj)
|
||||
{
|
||||
ICCBridgeState *s = ICC_BRIGDE(obj);
|
||||
ICCBridgeState *s = ICC_BRIDGE(obj);
|
||||
SysBusDevice *sb = SYS_BUS_DEVICE(obj);
|
||||
|
||||
qbus_create_inplace(&s->icc_bus, sizeof(s->icc_bus), TYPE_ICC_BUS,
|
||||
|
@@ -173,20 +173,6 @@
|
||||
|
||||
#define CIRRUS_PNPMMIO_SIZE 0x1000
|
||||
|
||||
#define BLTUNSAFE(s) \
|
||||
( \
|
||||
( /* check dst is within bounds */ \
|
||||
(s)->cirrus_blt_height * ABS((s)->cirrus_blt_dstpitch) \
|
||||
+ ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \
|
||||
(s)->vga.vram_size \
|
||||
) || \
|
||||
( /* check src is within bounds */ \
|
||||
(s)->cirrus_blt_height * ABS((s)->cirrus_blt_srcpitch) \
|
||||
+ ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \
|
||||
(s)->vga.vram_size \
|
||||
) \
|
||||
)
|
||||
|
||||
struct CirrusVGAState;
|
||||
typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
|
||||
uint8_t * dst, const uint8_t * src,
|
||||
@@ -279,6 +265,50 @@ static void cirrus_update_memory_access(CirrusVGAState *s);
|
||||
*
|
||||
***************************************/
|
||||
|
||||
static bool blit_region_is_unsafe(struct CirrusVGAState *s,
|
||||
int32_t pitch, int32_t addr)
|
||||
{
|
||||
if (pitch < 0) {
|
||||
int64_t min = addr
|
||||
+ ((int64_t)s->cirrus_blt_height-1) * pitch;
|
||||
int32_t max = addr
|
||||
+ s->cirrus_blt_width;
|
||||
if (min < 0 || max >= s->vga.vram_size) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
int64_t max = addr
|
||||
+ ((int64_t)s->cirrus_blt_height-1) * pitch
|
||||
+ s->cirrus_blt_width;
|
||||
if (max >= s->vga.vram_size) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool blit_is_unsafe(struct CirrusVGAState *s)
|
||||
{
|
||||
/* should be the case, see cirrus_bitblt_start */
|
||||
assert(s->cirrus_blt_width > 0);
|
||||
assert(s->cirrus_blt_height > 0);
|
||||
|
||||
if (s->cirrus_blt_width > CIRRUS_BLTBUFSIZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
|
||||
s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) {
|
||||
return true;
|
||||
}
|
||||
if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
|
||||
s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
|
||||
uint8_t *dst,const uint8_t *src,
|
||||
int dstpitch,int srcpitch,
|
||||
@@ -636,7 +666,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
|
||||
|
||||
dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
|
||||
|
||||
if (BLTUNSAFE(s))
|
||||
if (blit_is_unsafe(s))
|
||||
return 0;
|
||||
|
||||
(*s->cirrus_rop) (s, dst, src,
|
||||
@@ -654,8 +684,9 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
|
||||
{
|
||||
cirrus_fill_t rop_func;
|
||||
|
||||
if (BLTUNSAFE(s))
|
||||
if (blit_is_unsafe(s)) {
|
||||
return 0;
|
||||
}
|
||||
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
|
||||
rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
|
||||
s->cirrus_blt_dstpitch,
|
||||
@@ -752,7 +783,7 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
||||
|
||||
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
|
||||
{
|
||||
if (BLTUNSAFE(s))
|
||||
if (blit_is_unsafe(s))
|
||||
return 0;
|
||||
|
||||
cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
|
||||
|
@@ -2,5 +2,6 @@ common-obj-$(CONFIG_MAX7310) += max7310.o
|
||||
common-obj-$(CONFIG_PL061) += pl061.o
|
||||
common-obj-$(CONFIG_PUV3) += puv3_gpio.o
|
||||
common-obj-$(CONFIG_ZAURUS) += zaurus.o
|
||||
common-obj-$(CONFIG_E500) += mpc8xxx.o
|
||||
|
||||
obj-$(CONFIG_OMAP) += omap_gpio.o
|
||||
|
217
hw/gpio/mpc8xxx.c
Normal file
217
hw/gpio/mpc8xxx.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* GPIO Controller for a lot of Freescale SoCs
|
||||
*
|
||||
* Copyright (C) 2014 Freescale Semiconductor, Inc. All rights reserved.
|
||||
*
|
||||
* Author: Alexander Graf, <agraf@suse.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
#define TYPE_MPC8XXX_GPIO "mpc8xxx_gpio"
|
||||
#define MPC8XXX_GPIO(obj) OBJECT_CHECK(MPC8XXXGPIOState, (obj), TYPE_MPC8XXX_GPIO)
|
||||
|
||||
typedef struct MPC8XXXGPIOState {
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
MemoryRegion iomem;
|
||||
qemu_irq irq;
|
||||
qemu_irq out[32];
|
||||
|
||||
uint32_t dir;
|
||||
uint32_t odr;
|
||||
uint32_t dat;
|
||||
uint32_t ier;
|
||||
uint32_t imr;
|
||||
uint32_t icr;
|
||||
} MPC8XXXGPIOState;
|
||||
|
||||
static const VMStateDescription vmstate_mpc8xxx_gpio = {
|
||||
.name = "mpc8xxx_gpio",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(dir, MPC8XXXGPIOState),
|
||||
VMSTATE_UINT32(odr, MPC8XXXGPIOState),
|
||||
VMSTATE_UINT32(dat, MPC8XXXGPIOState),
|
||||
VMSTATE_UINT32(ier, MPC8XXXGPIOState),
|
||||
VMSTATE_UINT32(imr, MPC8XXXGPIOState),
|
||||
VMSTATE_UINT32(icr, MPC8XXXGPIOState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static void mpc8xxx_gpio_update(MPC8XXXGPIOState *s)
|
||||
{
|
||||
qemu_set_irq(s->irq, !!(s->ier & s->imr));
|
||||
}
|
||||
|
||||
static uint64_t mpc8xxx_gpio_read(void *opaque, hwaddr offset,
|
||||
unsigned size)
|
||||
{
|
||||
MPC8XXXGPIOState *s = (MPC8XXXGPIOState *)opaque;
|
||||
|
||||
if (size != 4) {
|
||||
/* All registers are 32bit */
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (offset) {
|
||||
case 0x0: /* Direction */
|
||||
return s->dir;
|
||||
case 0x4: /* Open Drain */
|
||||
return s->odr;
|
||||
case 0x8: /* Data */
|
||||
return s->dat;
|
||||
case 0xC: /* Interrupt Event */
|
||||
return s->ier;
|
||||
case 0x10: /* Interrupt Mask */
|
||||
return s->imr;
|
||||
case 0x14: /* Interrupt Control */
|
||||
return s->icr;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc8xxx_write_data(MPC8XXXGPIOState *s, uint32_t new_data)
|
||||
{
|
||||
uint32_t old_data = s->dat;
|
||||
uint32_t diff = old_data ^ new_data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
uint32_t mask = 0x80000000 >> i;
|
||||
if (!(diff & mask)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (s->dir & mask) {
|
||||
/* Output */
|
||||
qemu_set_irq(s->out[i], (new_data & mask) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
s->dat = new_data;
|
||||
}
|
||||
|
||||
static void mpc8xxx_gpio_write(void *opaque, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
MPC8XXXGPIOState *s = (MPC8XXXGPIOState *)opaque;
|
||||
|
||||
if (size != 4) {
|
||||
/* All registers are 32bit */
|
||||
return;
|
||||
}
|
||||
|
||||
switch (offset) {
|
||||
case 0x0: /* Direction */
|
||||
s->dir = value;
|
||||
break;
|
||||
case 0x4: /* Open Drain */
|
||||
s->odr = value;
|
||||
break;
|
||||
case 0x8: /* Data */
|
||||
mpc8xxx_write_data(s, value);
|
||||
break;
|
||||
case 0xC: /* Interrupt Event */
|
||||
s->ier &= ~value;
|
||||
break;
|
||||
case 0x10: /* Interrupt Mask */
|
||||
s->imr = value;
|
||||
break;
|
||||
case 0x14: /* Interrupt Control */
|
||||
s->icr = value;
|
||||
break;
|
||||
}
|
||||
|
||||
mpc8xxx_gpio_update(s);
|
||||
}
|
||||
|
||||
static void mpc8xxx_gpio_reset(MPC8XXXGPIOState *s)
|
||||
{
|
||||
s->dir = 0;
|
||||
s->odr = 0;
|
||||
s->dat = 0;
|
||||
s->ier = 0;
|
||||
s->imr = 0;
|
||||
s->icr = 0;
|
||||
}
|
||||
|
||||
static void mpc8xxx_gpio_set_irq(void * opaque, int irq, int level)
|
||||
{
|
||||
MPC8XXXGPIOState *s = (MPC8XXXGPIOState *)opaque;
|
||||
uint32_t mask;
|
||||
|
||||
mask = 0x80000000 >> irq;
|
||||
if ((s->dir & mask) == 0) {
|
||||
uint32_t old_value = s->dat & mask;
|
||||
|
||||
s->dat &= ~mask;
|
||||
if (level)
|
||||
s->dat |= mask;
|
||||
|
||||
if (!(s->icr & irq) || (old_value && !level)) {
|
||||
s->ier |= mask;
|
||||
}
|
||||
|
||||
mpc8xxx_gpio_update(s);
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps mpc8xxx_gpio_ops = {
|
||||
.read = mpc8xxx_gpio_read,
|
||||
.write = mpc8xxx_gpio_write,
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
};
|
||||
|
||||
static int mpc8xxx_gpio_initfn(SysBusDevice *sbd)
|
||||
{
|
||||
DeviceState *dev = DEVICE(sbd);
|
||||
MPC8XXXGPIOState *s = MPC8XXX_GPIO(dev);
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &mpc8xxx_gpio_ops, s, "mpc8xxx_gpio", 0x1000);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
qdev_init_gpio_in(dev, mpc8xxx_gpio_set_irq, 32);
|
||||
qdev_init_gpio_out(dev, s->out, 32);
|
||||
mpc8xxx_gpio_reset(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mpc8xxx_gpio_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = mpc8xxx_gpio_initfn;
|
||||
dc->vmsd = &vmstate_mpc8xxx_gpio;
|
||||
}
|
||||
|
||||
static const TypeInfo mpc8xxx_gpio_info = {
|
||||
.name = TYPE_MPC8XXX_GPIO,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(MPC8XXXGPIOState),
|
||||
.class_init = mpc8xxx_gpio_class_init,
|
||||
};
|
||||
|
||||
static void mpc8xxx_gpio_register_types(void)
|
||||
{
|
||||
type_register_static(&mpc8xxx_gpio_info);
|
||||
}
|
||||
|
||||
type_init(mpc8xxx_gpio_register_types)
|
@@ -56,6 +56,7 @@
|
||||
|
||||
#include "qapi/qmp/qint.h"
|
||||
#include "qom/qom-qobject.h"
|
||||
#include "exec/ram_addr.h"
|
||||
|
||||
/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
|
||||
* -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
|
||||
@@ -1269,8 +1270,7 @@ acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
|
||||
}
|
||||
|
||||
static void
|
||||
build_srat(GArray *table_data, GArray *linker,
|
||||
AcpiCpuInfo *cpu, PcGuestInfo *guest_info)
|
||||
build_srat(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
|
||||
{
|
||||
AcpiSystemResourceAffinityTable *srat;
|
||||
AcpiSratProcessorAffinity *core;
|
||||
@@ -1300,11 +1300,7 @@ build_srat(GArray *table_data, GArray *linker,
|
||||
core->proximity_lo = curnode;
|
||||
memset(core->proximity_hi, 0, 3);
|
||||
core->local_sapic_eid = 0;
|
||||
if (test_bit(i, cpu->found_cpus)) {
|
||||
core->flags = cpu_to_le32(1);
|
||||
} else {
|
||||
core->flags = cpu_to_le32(0);
|
||||
}
|
||||
core->flags = cpu_to_le32(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1511,7 +1507,7 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
|
||||
typedef
|
||||
struct AcpiBuildState {
|
||||
/* Copy of table in RAM (for patching). */
|
||||
uint8_t *table_ram;
|
||||
ram_addr_t table_ram;
|
||||
uint32_t table_size;
|
||||
/* Is table patched? */
|
||||
uint8_t patched;
|
||||
@@ -1622,7 +1618,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
||||
}
|
||||
if (guest_info->numa_nodes) {
|
||||
acpi_add_table(table_offsets, tables->table_data);
|
||||
build_srat(tables->table_data, tables->linker, &cpu, guest_info);
|
||||
build_srat(tables->table_data, tables->linker, guest_info);
|
||||
}
|
||||
if (acpi_get_mcfg(&mcfg)) {
|
||||
acpi_add_table(table_offsets, tables->table_data);
|
||||
@@ -1716,9 +1712,12 @@ static void acpi_build_update(void *build_opaque, uint32_t offset)
|
||||
acpi_build(build_state->guest_info, &tables);
|
||||
|
||||
assert(acpi_data_len(tables.table_data) == build_state->table_size);
|
||||
memcpy(build_state->table_ram, tables.table_data->data,
|
||||
memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data,
|
||||
build_state->table_size);
|
||||
|
||||
cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram,
|
||||
build_state->table_size);
|
||||
|
||||
acpi_build_tables_cleanup(&tables, true);
|
||||
}
|
||||
|
||||
@@ -1728,7 +1727,7 @@ static void acpi_build_reset(void *build_opaque)
|
||||
build_state->patched = 0;
|
||||
}
|
||||
|
||||
static void *acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob,
|
||||
static ram_addr_t acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob,
|
||||
const char *name)
|
||||
{
|
||||
return rom_add_blob(name, blob->data, acpi_data_len(blob), -1, name,
|
||||
@@ -1777,6 +1776,7 @@ void acpi_setup(PcGuestInfo *guest_info)
|
||||
/* Now expose it all to Guest */
|
||||
build_state->table_ram = acpi_add_rom_blob(build_state, tables.table_data,
|
||||
ACPI_BUILD_TABLE_FILE);
|
||||
assert(build_state->table_ram != RAM_ADDR_MAX);
|
||||
build_state->table_size = acpi_data_len(tables.table_data);
|
||||
|
||||
acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader");
|
||||
|
176
hw/i386/acpi-dsdt-mem-hotplug.dsl
Normal file
176
hw/i386/acpi-dsdt-mem-hotplug.dsl
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj)
|
||||
|
||||
Scope(\_SB.PCI0) {
|
||||
Device(MEMORY_HOTPLUG_DEVICE) {
|
||||
Name(_HID, "PNP0A06")
|
||||
Name(_UID, "Memory hotplug resources")
|
||||
External(MEMORY_SLOTS_NUMBER, IntObj)
|
||||
|
||||
/* Memory hotplug IO registers */
|
||||
OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO,
|
||||
ACPI_MEMORY_HOTPLUG_BASE,
|
||||
ACPI_MEMORY_HOTPLUG_IO_LEN)
|
||||
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE,
|
||||
0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO)
|
||||
})
|
||||
|
||||
Method(_STA, 0) {
|
||||
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
|
||||
Return(0x0)
|
||||
}
|
||||
/* present, functioning, decoding, not shown in UI */
|
||||
Return(0xB)
|
||||
}
|
||||
|
||||
Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
|
||||
MEMORY_SLOT_ADDR_LOW, 32, // read only
|
||||
MEMORY_SLOT_ADDR_HIGH, 32, // read only
|
||||
MEMORY_SLOT_SIZE_LOW, 32, // read only
|
||||
MEMORY_SLOT_SIZE_HIGH, 32, // read only
|
||||
MEMORY_SLOT_PROXIMITY, 32, // read only
|
||||
}
|
||||
Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) {
|
||||
Offset(20),
|
||||
MEMORY_SLOT_ENABLED, 1, // 1 if enabled, read only
|
||||
MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert event. (write) 1 to clear event
|
||||
}
|
||||
|
||||
Mutex (MEMORY_SLOT_LOCK, 0)
|
||||
Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
|
||||
MEMORY_SLOT_SLECTOR, 32, // DIMM selector, write only
|
||||
MEMORY_SLOT_OST_EVENT, 32, // _OST event code, write only
|
||||
MEMORY_SLOT_OST_STATUS, 32, // _OST status code, write only
|
||||
}
|
||||
|
||||
Method(MEMORY_SLOT_SCAN_METHOD, 0) {
|
||||
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
|
||||
Return(Zero)
|
||||
}
|
||||
|
||||
Store(Zero, Local0) // Mem devs iterrator
|
||||
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
|
||||
while (LLess(Local0, MEMORY_SLOTS_NUMBER)) {
|
||||
Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM
|
||||
If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory device needs check
|
||||
MEMORY_SLOT_NOTIFY_METHOD(Local0, 1)
|
||||
Store(1, MEMORY_SLOT_INSERT_EVENT)
|
||||
}
|
||||
// TODO: handle memory eject request
|
||||
Add(Local0, One, Local0) // goto next DIMM
|
||||
}
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
Return(One)
|
||||
}
|
||||
|
||||
Method(MEMORY_SLOT_STATUS_METHOD, 1) {
|
||||
Store(Zero, Local0)
|
||||
|
||||
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
|
||||
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
|
||||
|
||||
If (LEqual(MEMORY_SLOT_ENABLED, One)) {
|
||||
Store(0xF, Local0)
|
||||
}
|
||||
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
Return(Local0)
|
||||
}
|
||||
|
||||
Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) {
|
||||
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
|
||||
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
|
||||
|
||||
Name(MR64, ResourceTemplate() {
|
||||
QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x0000000000000000, // Address Space Granularity
|
||||
0x0000000000000000, // Address Range Minimum
|
||||
0xFFFFFFFFFFFFFFFE, // Address Range Maximum
|
||||
0x0000000000000000, // Address Translation Offset
|
||||
0xFFFFFFFFFFFFFFFF, // Address Length
|
||||
,, MW64, AddressRangeMemory, TypeStatic)
|
||||
})
|
||||
|
||||
CreateDWordField(MR64, 14, MINL)
|
||||
CreateDWordField(MR64, 18, MINH)
|
||||
CreateDWordField(MR64, 38, LENL)
|
||||
CreateDWordField(MR64, 42, LENH)
|
||||
CreateDWordField(MR64, 22, MAXL)
|
||||
CreateDWordField(MR64, 26, MAXH)
|
||||
|
||||
Store(MEMORY_SLOT_ADDR_HIGH, MINH)
|
||||
Store(MEMORY_SLOT_ADDR_LOW, MINL)
|
||||
Store(MEMORY_SLOT_SIZE_HIGH, LENH)
|
||||
Store(MEMORY_SLOT_SIZE_LOW, LENL)
|
||||
|
||||
// 64-bit math: MAX = MIN + LEN - 1
|
||||
Add(MINL, LENL, MAXL)
|
||||
Add(MINH, LENH, MAXH)
|
||||
If (LLess(MAXL, MINL)) {
|
||||
Add(MAXH, One, MAXH)
|
||||
}
|
||||
If (LLess(MAXL, One)) {
|
||||
Subtract(MAXH, One, MAXH)
|
||||
}
|
||||
Subtract(MAXL, One, MAXL)
|
||||
|
||||
If (LEqual(MAXH, Zero)){
|
||||
Name(MR32, ResourceTemplate() {
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, // Address Space Granularity
|
||||
0x00000000, // Address Range Minimum
|
||||
0xFFFFFFFE, // Address Range Maximum
|
||||
0x00000000, // Address Translation Offset
|
||||
0xFFFFFFFF, // Address Length
|
||||
,, MW32, AddressRangeMemory, TypeStatic)
|
||||
})
|
||||
CreateDWordField(MR32, MW32._MIN, MIN)
|
||||
CreateDWordField(MR32, MW32._MAX, MAX)
|
||||
CreateDWordField(MR32, MW32._LEN, LEN)
|
||||
Store(MINL, MIN)
|
||||
Store(MAXL, MAX)
|
||||
Store(LENL, LEN)
|
||||
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
Return(MR32)
|
||||
}
|
||||
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
Return(MR64)
|
||||
}
|
||||
|
||||
Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) {
|
||||
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
|
||||
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
|
||||
Store(MEMORY_SLOT_PROXIMITY, Local0)
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
Return(Local0)
|
||||
}
|
||||
|
||||
Method(MEMORY_SLOT_OST_METHOD, 4) {
|
||||
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
|
||||
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
|
||||
Store(Arg1, MEMORY_SLOT_OST_EVENT)
|
||||
Store(Arg2, MEMORY_SLOT_OST_STATUS)
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
}
|
||||
} // Device()
|
||||
} // Scope()
|
@@ -297,13 +297,12 @@ DefinitionBlock (
|
||||
#include "hw/acpi/pc-hotplug.h"
|
||||
#define CPU_STATUS_BASE PIIX4_CPU_HOTPLUG_IO_BASE
|
||||
#include "acpi-dsdt-cpu-hotplug.dsl"
|
||||
#include "acpi-dsdt-mem-hotplug.dsl"
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* General purpose events
|
||||
****************************************************************/
|
||||
External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj)
|
||||
|
||||
Scope(\_GPE) {
|
||||
Name(_HID, "ACPI0006")
|
||||
|
||||
|
@@ -3,12 +3,12 @@ static unsigned char AcpiDsdtAmlCode[] = {
|
||||
0x53,
|
||||
0x44,
|
||||
0x54,
|
||||
0xf7,
|
||||
0xa,
|
||||
0x8,
|
||||
0xe,
|
||||
0x0,
|
||||
0x0,
|
||||
0x1,
|
||||
0x1f,
|
||||
0xfc,
|
||||
0x42,
|
||||
0x58,
|
||||
0x50,
|
||||
@@ -32,8 +32,8 @@ static unsigned char AcpiDsdtAmlCode[] = {
|
||||
0x54,
|
||||
0x4c,
|
||||
0x28,
|
||||
0x5,
|
||||
0x10,
|
||||
0x8,
|
||||
0x14,
|
||||
0x20,
|
||||
0x10,
|
||||
0x49,
|
||||
@@ -2593,6 +2593,791 @@ static unsigned char AcpiDsdtAmlCode[] = {
|
||||
0xa,
|
||||
0xb,
|
||||
0x10,
|
||||
0x40,
|
||||
0x31,
|
||||
0x2e,
|
||||
0x5f,
|
||||
0x53,
|
||||
0x42,
|
||||
0x5f,
|
||||
0x50,
|
||||
0x43,
|
||||
0x49,
|
||||
0x30,
|
||||
0x5b,
|
||||
0x82,
|
||||
0x43,
|
||||
0x30,
|
||||
0x4d,
|
||||
0x48,
|
||||
0x50,
|
||||
0x44,
|
||||
0x8,
|
||||
0x5f,
|
||||
0x48,
|
||||
0x49,
|
||||
0x44,
|
||||
0xd,
|
||||
0x50,
|
||||
0x4e,
|
||||
0x50,
|
||||
0x30,
|
||||
0x41,
|
||||
0x30,
|
||||
0x36,
|
||||
0x0,
|
||||
0x8,
|
||||
0x5f,
|
||||
0x55,
|
||||
0x49,
|
||||
0x44,
|
||||
0xd,
|
||||
0x4d,
|
||||
0x65,
|
||||
0x6d,
|
||||
0x6f,
|
||||
0x72,
|
||||
0x79,
|
||||
0x20,
|
||||
0x68,
|
||||
0x6f,
|
||||
0x74,
|
||||
0x70,
|
||||
0x6c,
|
||||
0x75,
|
||||
0x67,
|
||||
0x20,
|
||||
0x72,
|
||||
0x65,
|
||||
0x73,
|
||||
0x6f,
|
||||
0x75,
|
||||
0x72,
|
||||
0x63,
|
||||
0x65,
|
||||
0x73,
|
||||
0x0,
|
||||
0x5b,
|
||||
0x80,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x1,
|
||||
0xb,
|
||||
0x0,
|
||||
0xa,
|
||||
0xa,
|
||||
0x18,
|
||||
0x8,
|
||||
0x5f,
|
||||
0x43,
|
||||
0x52,
|
||||
0x53,
|
||||
0x11,
|
||||
0xd,
|
||||
0xa,
|
||||
0xa,
|
||||
0x47,
|
||||
0x1,
|
||||
0x0,
|
||||
0xa,
|
||||
0x0,
|
||||
0xa,
|
||||
0x0,
|
||||
0x18,
|
||||
0x79,
|
||||
0x0,
|
||||
0x14,
|
||||
0x13,
|
||||
0x5f,
|
||||
0x53,
|
||||
0x54,
|
||||
0x41,
|
||||
0x0,
|
||||
0xa0,
|
||||
0x9,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x52,
|
||||
0x0,
|
||||
0xa4,
|
||||
0x0,
|
||||
0xa4,
|
||||
0xa,
|
||||
0xb,
|
||||
0x5b,
|
||||
0x81,
|
||||
0x1f,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x3,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x4c,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x48,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x48,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x50,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x20,
|
||||
0x5b,
|
||||
0x81,
|
||||
0x13,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x1,
|
||||
0x0,
|
||||
0x40,
|
||||
0xa,
|
||||
0x4d,
|
||||
0x45,
|
||||
0x53,
|
||||
0x5f,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x53,
|
||||
0x1,
|
||||
0x5b,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0x0,
|
||||
0x5b,
|
||||
0x81,
|
||||
0x15,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x3,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x45,
|
||||
0x56,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x53,
|
||||
0x43,
|
||||
0x20,
|
||||
0x14,
|
||||
0x4a,
|
||||
0x4,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x43,
|
||||
0x4e,
|
||||
0x0,
|
||||
0xa0,
|
||||
0x9,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x52,
|
||||
0x0,
|
||||
0xa4,
|
||||
0x0,
|
||||
0x70,
|
||||
0x0,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0xa2,
|
||||
0x25,
|
||||
0x95,
|
||||
0x60,
|
||||
0x4d,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x52,
|
||||
0x70,
|
||||
0x60,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0xa0,
|
||||
0x13,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x53,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x54,
|
||||
0x46,
|
||||
0x59,
|
||||
0x60,
|
||||
0x1,
|
||||
0x70,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x53,
|
||||
0x72,
|
||||
0x60,
|
||||
0x1,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x1,
|
||||
0x14,
|
||||
0x2d,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x53,
|
||||
0x54,
|
||||
0x1,
|
||||
0x70,
|
||||
0x0,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0xa0,
|
||||
0xb,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x45,
|
||||
0x53,
|
||||
0x5f,
|
||||
0x1,
|
||||
0x70,
|
||||
0xa,
|
||||
0xf,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x60,
|
||||
0x14,
|
||||
0x41,
|
||||
0x18,
|
||||
0x4d,
|
||||
0x43,
|
||||
0x52,
|
||||
0x53,
|
||||
0x9,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x8,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0x11,
|
||||
0x33,
|
||||
0xa,
|
||||
0x30,
|
||||
0x8a,
|
||||
0x2b,
|
||||
0x0,
|
||||
0x0,
|
||||
0xc,
|
||||
0x3,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xfe,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x79,
|
||||
0x0,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0xe,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x12,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x26,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x2a,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x16,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x1a,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x48,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x48,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x72,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x72,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0xa0,
|
||||
0x14,
|
||||
0x95,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x72,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0xa0,
|
||||
0x11,
|
||||
0x95,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x1,
|
||||
0x74,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x74,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0xa0,
|
||||
0x44,
|
||||
0x7,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x0,
|
||||
0x8,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0x11,
|
||||
0x1f,
|
||||
0xa,
|
||||
0x1c,
|
||||
0x87,
|
||||
0x17,
|
||||
0x0,
|
||||
0x0,
|
||||
0xc,
|
||||
0x3,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xfe,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x79,
|
||||
0x0,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0xa,
|
||||
0xa,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0xa,
|
||||
0xe,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0xa,
|
||||
0x16,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x70,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0x14,
|
||||
0x24,
|
||||
0x4d,
|
||||
0x50,
|
||||
0x58,
|
||||
0x4d,
|
||||
0x1,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x50,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x60,
|
||||
0x14,
|
||||
0x28,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x53,
|
||||
0x54,
|
||||
0x4,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x70,
|
||||
0x69,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x45,
|
||||
0x56,
|
||||
0x70,
|
||||
0x6a,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x53,
|
||||
0x43,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0x10,
|
||||
0x45,
|
||||
0xd,
|
||||
0x5f,
|
||||
|
@@ -175,6 +175,9 @@ static void kvm_apic_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(dev);
|
||||
|
||||
/* Not used by KVM, which uses the CPU mp_state instead. */
|
||||
s->wait_for_sipi = 0;
|
||||
|
||||
memory_region_init_io(&s->io_memory, NULL, &kvm_apic_io_ops, s, "kvm-apic-msi",
|
||||
APIC_SPACE_SIZE);
|
||||
|
||||
|
@@ -127,7 +127,21 @@ static void kvmclock_vm_state_change(void *opaque, int running,
|
||||
}
|
||||
|
||||
cpu_synchronize_all_states();
|
||||
/* In theory, the cpu_synchronize_all_states() call above wouldn't
|
||||
* affect the rest of the code, as the VCPU state inside CPUState
|
||||
* is supposed to always match the VCPU state on the kernel side.
|
||||
*
|
||||
* In practice, calling cpu_synchronize_state() too soon will load the
|
||||
* kernel-side APIC state into X86CPU.apic_state too early, APIC state
|
||||
* won't be reloaded later because CPUState.vcpu_dirty==true, and
|
||||
* outdated APIC state may be migrated to another host.
|
||||
*
|
||||
* The real fix would be to make sure outdated APIC state is read
|
||||
* from the kernel again when necessary. While this is not fixed, we
|
||||
* need the cpu_clean_all_dirty() call below.
|
||||
*/
|
||||
cpu_clean_all_dirty();
|
||||
|
||||
ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
|
||||
|
102
hw/i386/pc.c
102
hw/i386/pc.c
@@ -61,6 +61,7 @@
|
||||
#include "hw/mem/pc-dimm.h"
|
||||
#include "trace.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "qapi-visit.h"
|
||||
|
||||
/* debug PC/ISA interrupts */
|
||||
//#define DEBUG_IRQ
|
||||
@@ -1247,6 +1248,11 @@ FWCfgState *pc_memory_init(MachineState *machine,
|
||||
pcms->hotplug_memory_base =
|
||||
ROUND_UP(0x100000000ULL + above_4g_mem_size, 1ULL << 30);
|
||||
|
||||
if (pcms->enforce_aligned_dimm) {
|
||||
/* size hotplug region assuming 1G page max alignment per slot */
|
||||
hotplug_mem_size += (1ULL << 30) * machine->ram_slots;
|
||||
}
|
||||
|
||||
if ((pcms->hotplug_memory_base + hotplug_mem_size) <
|
||||
hotplug_mem_size) {
|
||||
error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT,
|
||||
@@ -1545,6 +1551,37 @@ void qemu_register_pc_machine(QEMUMachine *m)
|
||||
g_free(name);
|
||||
}
|
||||
|
||||
static int pc_dimm_count(Object *obj, void *opaque)
|
||||
{
|
||||
int *count = opaque;
|
||||
|
||||
if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
object_child_foreach(obj, pc_dimm_count, opaque);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pc_existing_dimms_capacity(Object *obj, void *opaque)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
uint64_t *size = opaque;
|
||||
|
||||
if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
|
||||
(*size) += object_property_get_int(obj, PC_DIMM_SIZE_PROP, &local_err);
|
||||
|
||||
if (local_err) {
|
||||
qerror_report_err(local_err);
|
||||
error_free(local_err);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
object_child_foreach(obj, pc_dimm_count, opaque);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pc_dimm_plug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
@@ -1556,20 +1593,40 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
|
||||
PCDIMMDevice *dimm = PC_DIMM(dev);
|
||||
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
|
||||
MemoryRegion *mr = ddc->get_memory_region(dimm);
|
||||
uint64_t addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP,
|
||||
&local_err);
|
||||
uint64_t existing_dimms_capacity = 0;
|
||||
uint64_t align = TARGET_PAGE_SIZE;
|
||||
uint64_t addr;
|
||||
|
||||
addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err);
|
||||
if (local_err) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (memory_region_get_alignment(mr) && pcms->enforce_aligned_dimm) {
|
||||
align = memory_region_get_alignment(mr);
|
||||
}
|
||||
|
||||
addr = pc_dimm_get_free_addr(pcms->hotplug_memory_base,
|
||||
memory_region_size(&pcms->hotplug_memory),
|
||||
!addr ? NULL : &addr,
|
||||
!addr ? NULL : &addr, align,
|
||||
memory_region_size(mr), &local_err);
|
||||
if (local_err) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pc_existing_dimms_capacity(OBJECT(machine), &existing_dimms_capacity)) {
|
||||
error_setg(&local_err, "failed to get total size of existing DIMMs");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (existing_dimms_capacity + memory_region_size(mr) >
|
||||
machine->maxram_size - machine->ram_size) {
|
||||
error_setg(&local_err, "not enough space, currently 0x%" PRIx64
|
||||
" in use of total 0x" RAM_ADDR_FMT,
|
||||
existing_dimms_capacity, machine->maxram_size);
|
||||
goto out;
|
||||
}
|
||||
|
||||
object_property_set_int(OBJECT(dev), addr, PC_DIMM_ADDR_PROP, &local_err);
|
||||
if (local_err) {
|
||||
goto out;
|
||||
@@ -1598,6 +1655,11 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (kvm_enabled() && !kvm_has_free_slot(machine)) {
|
||||
error_setg(&local_err, "hypervisor has no free memory slots left");
|
||||
goto out;
|
||||
}
|
||||
|
||||
memory_region_add_subregion(&pcms->hotplug_memory,
|
||||
addr - pcms->hotplug_memory_base, mr);
|
||||
vmstate_register_ram(mr, dev);
|
||||
@@ -1711,18 +1773,28 @@ static void pc_machine_set_max_ram_below_4g(Object *obj, Visitor *v,
|
||||
pcms->max_ram_below_4g = value;
|
||||
}
|
||||
|
||||
static bool pc_machine_get_vmport(Object *obj, Error **errp)
|
||||
static void pc_machine_get_vmport(Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(obj);
|
||||
OnOffAuto vmport = pcms->vmport;
|
||||
|
||||
return pcms->vmport;
|
||||
visit_type_OnOffAuto(v, &vmport, name, errp);
|
||||
}
|
||||
|
||||
static void pc_machine_set_vmport(Object *obj, bool value, Error **errp)
|
||||
static void pc_machine_set_vmport(Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(obj);
|
||||
|
||||
pcms->vmport = value;
|
||||
visit_type_OnOffAuto(v, &pcms->vmport, name, errp);
|
||||
}
|
||||
|
||||
static bool pc_machine_get_aligned_dimm(Object *obj, Error **errp)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(obj);
|
||||
|
||||
return pcms->enforce_aligned_dimm;
|
||||
}
|
||||
|
||||
static void pc_machine_initfn(Object *obj)
|
||||
@@ -1737,11 +1809,17 @@ static void pc_machine_initfn(Object *obj)
|
||||
pc_machine_get_max_ram_below_4g,
|
||||
pc_machine_set_max_ram_below_4g,
|
||||
NULL, NULL, NULL);
|
||||
pcms->vmport = !xen_enabled();
|
||||
object_property_add_bool(obj, PC_MACHINE_VMPORT,
|
||||
pc_machine_get_vmport,
|
||||
pc_machine_set_vmport,
|
||||
NULL);
|
||||
|
||||
pcms->vmport = ON_OFF_AUTO_AUTO;
|
||||
object_property_add(obj, PC_MACHINE_VMPORT, "OnOffAuto",
|
||||
pc_machine_get_vmport,
|
||||
pc_machine_set_vmport,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
pcms->enforce_aligned_dimm = true;
|
||||
object_property_add_bool(obj, PC_MACHINE_ENFORCE_ALIGNED_DIMM,
|
||||
pc_machine_get_aligned_dimm,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||
|
@@ -234,9 +234,14 @@ static void pc_init1(MachineState *machine,
|
||||
|
||||
pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
|
||||
|
||||
assert(pc_machine->vmport != ON_OFF_AUTO_MAX);
|
||||
if (pc_machine->vmport == ON_OFF_AUTO_AUTO) {
|
||||
pc_machine->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
|
||||
}
|
||||
|
||||
/* init basic PC hardware */
|
||||
pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy,
|
||||
!pc_machine->vmport, 0x4);
|
||||
(pc_machine->vmport != ON_OFF_AUTO_ON), 0x4);
|
||||
|
||||
pc_nic_init(isa_bus, pci_bus);
|
||||
|
||||
@@ -305,7 +310,12 @@ static void pc_init_pci(MachineState *machine)
|
||||
|
||||
static void pc_compat_2_1(MachineState *machine)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(machine);
|
||||
smbios_uuid_encoded = false;
|
||||
x86_cpu_compat_set_features("coreduo", FEAT_1_ECX, CPUID_EXT_VMX, 0);
|
||||
x86_cpu_compat_set_features("core2duo", FEAT_1_ECX, CPUID_EXT_VMX, 0);
|
||||
x86_cpu_compat_kvm_no_autodisable(FEAT_8000_0001_ECX, CPUID_EXT3_SVM);
|
||||
pcms->enforce_aligned_dimm = false;
|
||||
}
|
||||
|
||||
static void pc_compat_2_0(MachineState *machine)
|
||||
@@ -340,7 +350,7 @@ static void pc_compat_1_7(MachineState *machine)
|
||||
gigabyte_align = false;
|
||||
option_rom_has_mr = true;
|
||||
legacy_acpi_table_size = 6414;
|
||||
x86_cpu_compat_disable_kvm_features(FEAT_1_ECX, CPUID_EXT_X2APIC);
|
||||
x86_cpu_compat_kvm_no_autoenable(FEAT_1_ECX, CPUID_EXT_X2APIC);
|
||||
}
|
||||
|
||||
static void pc_compat_1_6(MachineState *machine)
|
||||
@@ -372,7 +382,7 @@ static void pc_compat_1_3(MachineState *machine)
|
||||
static void pc_compat_1_2(MachineState *machine)
|
||||
{
|
||||
pc_compat_1_3(machine);
|
||||
x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI);
|
||||
x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, KVM_FEATURE_PV_EOI);
|
||||
}
|
||||
|
||||
static void pc_init_pci_2_1(MachineState *machine)
|
||||
@@ -443,7 +453,7 @@ static void pc_init_isa(MachineState *machine)
|
||||
if (!machine->cpu_model) {
|
||||
machine->cpu_model = "486";
|
||||
}
|
||||
x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI);
|
||||
x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, KVM_FEATURE_PV_EOI);
|
||||
enable_compat_apic_id_mode();
|
||||
pc_init1(machine, 0, 1);
|
||||
}
|
||||
@@ -913,17 +923,6 @@ static QEMUMachine xenfv_machine = {
|
||||
.max_cpus = HVM_MAX_VCPUS,
|
||||
.default_machine_opts = "accel=xen",
|
||||
.hot_add_cpu = pc_hot_add_cpu,
|
||||
.compat_props = (GlobalProperty[]) {
|
||||
/* xenfv has no fwcfg and so does not load acpi from QEMU.
|
||||
* as such new acpi features don't work.
|
||||
*/
|
||||
{
|
||||
.driver = "PIIX4_PM",
|
||||
.property = "acpi-pci-hotplug-with-bridge-support",
|
||||
.value = "off",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@@ -242,9 +242,14 @@ static void pc_q35_init(MachineState *machine)
|
||||
|
||||
pc_register_ferr_irq(gsi[13]);
|
||||
|
||||
assert(pc_machine->vmport != ON_OFF_AUTO_MAX);
|
||||
if (pc_machine->vmport == ON_OFF_AUTO_AUTO) {
|
||||
pc_machine->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
|
||||
}
|
||||
|
||||
/* init basic PC hardware */
|
||||
pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy,
|
||||
!pc_machine->vmport, 0xff0104);
|
||||
(pc_machine->vmport != ON_OFF_AUTO_ON), 0xff0104);
|
||||
|
||||
/* connect pm stuff to lpc */
|
||||
ich9_lpc_pm_init(lpc);
|
||||
@@ -284,7 +289,13 @@ static void pc_q35_init(MachineState *machine)
|
||||
|
||||
static void pc_compat_2_1(MachineState *machine)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(machine);
|
||||
|
||||
pcms->enforce_aligned_dimm = false;
|
||||
smbios_uuid_encoded = false;
|
||||
x86_cpu_compat_set_features("coreduo", FEAT_1_ECX, CPUID_EXT_VMX, 0);
|
||||
x86_cpu_compat_set_features("core2duo", FEAT_1_ECX, CPUID_EXT_VMX, 0);
|
||||
x86_cpu_compat_kvm_no_autodisable(FEAT_8000_0001_ECX, CPUID_EXT3_SVM);
|
||||
}
|
||||
|
||||
static void pc_compat_2_0(MachineState *machine)
|
||||
@@ -301,7 +312,7 @@ static void pc_compat_1_7(MachineState *machine)
|
||||
smbios_defaults = false;
|
||||
gigabyte_align = false;
|
||||
option_rom_has_mr = true;
|
||||
x86_cpu_compat_disable_kvm_features(FEAT_1_ECX, CPUID_EXT_X2APIC);
|
||||
x86_cpu_compat_kvm_no_autoenable(FEAT_1_ECX, CPUID_EXT_X2APIC);
|
||||
}
|
||||
|
||||
static void pc_compat_1_6(MachineState *machine)
|
||||
|
@@ -405,13 +405,12 @@ DefinitionBlock (
|
||||
#include "hw/acpi/pc-hotplug.h"
|
||||
#define CPU_STATUS_BASE ICH9_CPU_HOTPLUG_IO_BASE
|
||||
#include "acpi-dsdt-cpu-hotplug.dsl"
|
||||
#include "acpi-dsdt-mem-hotplug.dsl"
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* General purpose events
|
||||
****************************************************************/
|
||||
External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj)
|
||||
|
||||
Scope(\_GPE) {
|
||||
Name(_HID, "ACPI0006")
|
||||
|
||||
|
@@ -3,12 +3,12 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
|
||||
0x53,
|
||||
0x44,
|
||||
0x54,
|
||||
0xe5,
|
||||
0x1c,
|
||||
0xf6,
|
||||
0x1f,
|
||||
0x0,
|
||||
0x0,
|
||||
0x1,
|
||||
0xb7,
|
||||
0x91,
|
||||
0x42,
|
||||
0x58,
|
||||
0x50,
|
||||
@@ -31,9 +31,9 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
|
||||
0x4e,
|
||||
0x54,
|
||||
0x4c,
|
||||
0x15,
|
||||
0x11,
|
||||
0x13,
|
||||
0x28,
|
||||
0x8,
|
||||
0x14,
|
||||
0x20,
|
||||
0x10,
|
||||
0x49,
|
||||
@@ -7234,6 +7234,791 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
|
||||
0xa,
|
||||
0xb,
|
||||
0x10,
|
||||
0x40,
|
||||
0x31,
|
||||
0x2e,
|
||||
0x5f,
|
||||
0x53,
|
||||
0x42,
|
||||
0x5f,
|
||||
0x50,
|
||||
0x43,
|
||||
0x49,
|
||||
0x30,
|
||||
0x5b,
|
||||
0x82,
|
||||
0x43,
|
||||
0x30,
|
||||
0x4d,
|
||||
0x48,
|
||||
0x50,
|
||||
0x44,
|
||||
0x8,
|
||||
0x5f,
|
||||
0x48,
|
||||
0x49,
|
||||
0x44,
|
||||
0xd,
|
||||
0x50,
|
||||
0x4e,
|
||||
0x50,
|
||||
0x30,
|
||||
0x41,
|
||||
0x30,
|
||||
0x36,
|
||||
0x0,
|
||||
0x8,
|
||||
0x5f,
|
||||
0x55,
|
||||
0x49,
|
||||
0x44,
|
||||
0xd,
|
||||
0x4d,
|
||||
0x65,
|
||||
0x6d,
|
||||
0x6f,
|
||||
0x72,
|
||||
0x79,
|
||||
0x20,
|
||||
0x68,
|
||||
0x6f,
|
||||
0x74,
|
||||
0x70,
|
||||
0x6c,
|
||||
0x75,
|
||||
0x67,
|
||||
0x20,
|
||||
0x72,
|
||||
0x65,
|
||||
0x73,
|
||||
0x6f,
|
||||
0x75,
|
||||
0x72,
|
||||
0x63,
|
||||
0x65,
|
||||
0x73,
|
||||
0x0,
|
||||
0x5b,
|
||||
0x80,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x1,
|
||||
0xb,
|
||||
0x0,
|
||||
0xa,
|
||||
0xa,
|
||||
0x18,
|
||||
0x8,
|
||||
0x5f,
|
||||
0x43,
|
||||
0x52,
|
||||
0x53,
|
||||
0x11,
|
||||
0xd,
|
||||
0xa,
|
||||
0xa,
|
||||
0x47,
|
||||
0x1,
|
||||
0x0,
|
||||
0xa,
|
||||
0x0,
|
||||
0xa,
|
||||
0x0,
|
||||
0x18,
|
||||
0x79,
|
||||
0x0,
|
||||
0x14,
|
||||
0x13,
|
||||
0x5f,
|
||||
0x53,
|
||||
0x54,
|
||||
0x41,
|
||||
0x0,
|
||||
0xa0,
|
||||
0x9,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x52,
|
||||
0x0,
|
||||
0xa4,
|
||||
0x0,
|
||||
0xa4,
|
||||
0xa,
|
||||
0xb,
|
||||
0x5b,
|
||||
0x81,
|
||||
0x1f,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x3,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x4c,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x48,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x48,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x50,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x20,
|
||||
0x5b,
|
||||
0x81,
|
||||
0x13,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x1,
|
||||
0x0,
|
||||
0x40,
|
||||
0xa,
|
||||
0x4d,
|
||||
0x45,
|
||||
0x53,
|
||||
0x5f,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x53,
|
||||
0x1,
|
||||
0x5b,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0x0,
|
||||
0x5b,
|
||||
0x81,
|
||||
0x15,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x3,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x45,
|
||||
0x56,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x53,
|
||||
0x43,
|
||||
0x20,
|
||||
0x14,
|
||||
0x4a,
|
||||
0x4,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x43,
|
||||
0x4e,
|
||||
0x0,
|
||||
0xa0,
|
||||
0x9,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x52,
|
||||
0x0,
|
||||
0xa4,
|
||||
0x0,
|
||||
0x70,
|
||||
0x0,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0xa2,
|
||||
0x25,
|
||||
0x95,
|
||||
0x60,
|
||||
0x4d,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x52,
|
||||
0x70,
|
||||
0x60,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0xa0,
|
||||
0x13,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x53,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x54,
|
||||
0x46,
|
||||
0x59,
|
||||
0x60,
|
||||
0x1,
|
||||
0x70,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x53,
|
||||
0x72,
|
||||
0x60,
|
||||
0x1,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x1,
|
||||
0x14,
|
||||
0x2d,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x53,
|
||||
0x54,
|
||||
0x1,
|
||||
0x70,
|
||||
0x0,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0xa0,
|
||||
0xb,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x45,
|
||||
0x53,
|
||||
0x5f,
|
||||
0x1,
|
||||
0x70,
|
||||
0xa,
|
||||
0xf,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x60,
|
||||
0x14,
|
||||
0x41,
|
||||
0x18,
|
||||
0x4d,
|
||||
0x43,
|
||||
0x52,
|
||||
0x53,
|
||||
0x9,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x8,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0x11,
|
||||
0x33,
|
||||
0xa,
|
||||
0x30,
|
||||
0x8a,
|
||||
0x2b,
|
||||
0x0,
|
||||
0x0,
|
||||
0xc,
|
||||
0x3,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xfe,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x79,
|
||||
0x0,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0xe,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x12,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x26,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x2a,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x16,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x1a,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x48,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x48,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x72,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x72,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0xa0,
|
||||
0x14,
|
||||
0x95,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x72,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0xa0,
|
||||
0x11,
|
||||
0x95,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x1,
|
||||
0x74,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x74,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0xa0,
|
||||
0x44,
|
||||
0x7,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x0,
|
||||
0x8,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0x11,
|
||||
0x1f,
|
||||
0xa,
|
||||
0x1c,
|
||||
0x87,
|
||||
0x17,
|
||||
0x0,
|
||||
0x0,
|
||||
0xc,
|
||||
0x3,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xfe,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x79,
|
||||
0x0,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0xa,
|
||||
0xa,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0xa,
|
||||
0xe,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0xa,
|
||||
0x16,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x70,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0x14,
|
||||
0x24,
|
||||
0x4d,
|
||||
0x50,
|
||||
0x58,
|
||||
0x4d,
|
||||
0x1,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x50,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x60,
|
||||
0x14,
|
||||
0x28,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x53,
|
||||
0x54,
|
||||
0x4,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x70,
|
||||
0x69,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x45,
|
||||
0x56,
|
||||
0x70,
|
||||
0x6a,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x53,
|
||||
0x43,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0x10,
|
||||
0x42,
|
||||
0xa,
|
||||
0x5f,
|
||||
|
@@ -645,7 +645,7 @@ static void smbios_build_type_4_table(unsigned instance)
|
||||
|
||||
static void smbios_build_type_16_table(unsigned dimm_cnt)
|
||||
{
|
||||
ram_addr_t size_kb;
|
||||
uint64_t size_kb;
|
||||
|
||||
SMBIOS_BUILD_TABLE_PRE(16, 0x1000, true); /* required */
|
||||
|
||||
@@ -669,10 +669,10 @@ static void smbios_build_type_16_table(unsigned dimm_cnt)
|
||||
#define MAX_T17_STD_SZ 0x7FFF /* (32G - 1M), in Megabytes */
|
||||
#define MAX_T17_EXT_SZ 0x80000000 /* 2P, in Megabytes */
|
||||
|
||||
static void smbios_build_type_17_table(unsigned instance, ram_addr_t size)
|
||||
static void smbios_build_type_17_table(unsigned instance, uint64_t size)
|
||||
{
|
||||
char loc_str[128];
|
||||
ram_addr_t size_mb;
|
||||
uint64_t size_mb;
|
||||
|
||||
SMBIOS_BUILD_TABLE_PRE(17, 0x1100 + instance, true); /* required */
|
||||
|
||||
@@ -711,9 +711,9 @@ static void smbios_build_type_17_table(unsigned instance, ram_addr_t size)
|
||||
}
|
||||
|
||||
static void smbios_build_type_19_table(unsigned instance,
|
||||
ram_addr_t start, ram_addr_t size)
|
||||
uint64_t start, uint64_t size)
|
||||
{
|
||||
ram_addr_t end, start_kb, end_kb;
|
||||
uint64_t end, start_kb, end_kb;
|
||||
|
||||
SMBIOS_BUILD_TABLE_PRE(19, 0x1300 + instance, true); /* required */
|
||||
|
||||
|
@@ -11,7 +11,7 @@ static unsigned char ssdm_mem_aml[] = {
|
||||
0x0,
|
||||
0x0,
|
||||
0x2,
|
||||
0x71,
|
||||
0x66,
|
||||
0x42,
|
||||
0x58,
|
||||
0x50,
|
||||
@@ -34,9 +34,9 @@ static unsigned char ssdm_mem_aml[] = {
|
||||
0x4e,
|
||||
0x54,
|
||||
0x4c,
|
||||
0x15,
|
||||
0x11,
|
||||
0x13,
|
||||
0x28,
|
||||
0x8,
|
||||
0x14,
|
||||
0x20,
|
||||
0x10,
|
||||
0x42,
|
||||
|
@@ -36,6 +36,8 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
|
||||
Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
|
||||
ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length
|
||||
Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
|
||||
ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
|
||||
Name(MEMORY_SLOTS_NUMBER, 0x12345678)
|
||||
}
|
||||
|
||||
|
||||
@@ -117,167 +119,4 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj)
|
||||
Scope(\_SB.PCI0) {
|
||||
Device(MEMORY_HOTPLUG_DEVICE) {
|
||||
Name(_HID, "PNP0A06")
|
||||
Name(_UID, "Memory hotplug resources")
|
||||
|
||||
ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
|
||||
Name(MEMORY_SLOTS_NUMBER, 0x12345678)
|
||||
|
||||
/* Memory hotplug IO registers */
|
||||
OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO,
|
||||
ACPI_MEMORY_HOTPLUG_BASE,
|
||||
ACPI_MEMORY_HOTPLUG_IO_LEN)
|
||||
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE,
|
||||
0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO)
|
||||
})
|
||||
|
||||
Method(_STA, 0) {
|
||||
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
|
||||
Return(0x0)
|
||||
}
|
||||
/* present, functioning, decoding, not shown in UI */
|
||||
Return(0xB)
|
||||
}
|
||||
|
||||
Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
|
||||
MEMORY_SLOT_ADDR_LOW, 32, // read only
|
||||
MEMORY_SLOT_ADDR_HIGH, 32, // read only
|
||||
MEMORY_SLOT_SIZE_LOW, 32, // read only
|
||||
MEMORY_SLOT_SIZE_HIGH, 32, // read only
|
||||
MEMORY_SLOT_PROXIMITY, 32, // read only
|
||||
}
|
||||
Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) {
|
||||
Offset(20),
|
||||
MEMORY_SLOT_ENABLED, 1, // 1 if enabled, read only
|
||||
MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert event. (write) 1 to clear event
|
||||
}
|
||||
|
||||
Mutex (MEMORY_SLOT_LOCK, 0)
|
||||
Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
|
||||
MEMORY_SLOT_SLECTOR, 32, // DIMM selector, write only
|
||||
MEMORY_SLOT_OST_EVENT, 32, // _OST event code, write only
|
||||
MEMORY_SLOT_OST_STATUS, 32, // _OST status code, write only
|
||||
}
|
||||
|
||||
Method(MEMORY_SLOT_SCAN_METHOD, 0) {
|
||||
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
|
||||
Return(Zero)
|
||||
}
|
||||
|
||||
Store(Zero, Local0) // Mem devs iterrator
|
||||
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
|
||||
while (LLess(Local0, MEMORY_SLOTS_NUMBER)) {
|
||||
Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM
|
||||
If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory device needs check
|
||||
MEMORY_SLOT_NOTIFY_METHOD(Local0, 1)
|
||||
Store(1, MEMORY_SLOT_INSERT_EVENT)
|
||||
}
|
||||
// TODO: handle memory eject request
|
||||
Add(Local0, One, Local0) // goto next DIMM
|
||||
}
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
Return(One)
|
||||
}
|
||||
|
||||
Method(MEMORY_SLOT_STATUS_METHOD, 1) {
|
||||
Store(Zero, Local0)
|
||||
|
||||
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
|
||||
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
|
||||
|
||||
If (LEqual(MEMORY_SLOT_ENABLED, One)) {
|
||||
Store(0xF, Local0)
|
||||
}
|
||||
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
Return(Local0)
|
||||
}
|
||||
|
||||
Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) {
|
||||
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
|
||||
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
|
||||
|
||||
Name(MR64, ResourceTemplate() {
|
||||
QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x0000000000000000, // Address Space Granularity
|
||||
0x0000000000000000, // Address Range Minimum
|
||||
0xFFFFFFFFFFFFFFFE, // Address Range Maximum
|
||||
0x0000000000000000, // Address Translation Offset
|
||||
0xFFFFFFFFFFFFFFFF, // Address Length
|
||||
,, MW64, AddressRangeMemory, TypeStatic)
|
||||
})
|
||||
|
||||
CreateDWordField(MR64, 14, MINL)
|
||||
CreateDWordField(MR64, 18, MINH)
|
||||
CreateDWordField(MR64, 38, LENL)
|
||||
CreateDWordField(MR64, 42, LENH)
|
||||
CreateDWordField(MR64, 22, MAXL)
|
||||
CreateDWordField(MR64, 26, MAXH)
|
||||
|
||||
Store(MEMORY_SLOT_ADDR_HIGH, MINH)
|
||||
Store(MEMORY_SLOT_ADDR_LOW, MINL)
|
||||
Store(MEMORY_SLOT_SIZE_HIGH, LENH)
|
||||
Store(MEMORY_SLOT_SIZE_LOW, LENL)
|
||||
|
||||
// 64-bit math: MAX = MIN + LEN - 1
|
||||
Add(MINL, LENL, MAXL)
|
||||
Add(MINH, LENH, MAXH)
|
||||
If (LLess(MAXL, MINL)) {
|
||||
Add(MAXH, One, MAXH)
|
||||
}
|
||||
If (LLess(MAXL, One)) {
|
||||
Subtract(MAXH, One, MAXH)
|
||||
}
|
||||
Subtract(MAXL, One, MAXL)
|
||||
|
||||
If (LEqual(MAXH, Zero)){
|
||||
Name(MR32, ResourceTemplate() {
|
||||
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, // Address Space Granularity
|
||||
0x00000000, // Address Range Minimum
|
||||
0xFFFFFFFE, // Address Range Maximum
|
||||
0x00000000, // Address Translation Offset
|
||||
0xFFFFFFFF, // Address Length
|
||||
,, MW32, AddressRangeMemory, TypeStatic)
|
||||
})
|
||||
CreateDWordField(MR32, MW32._MIN, MIN)
|
||||
CreateDWordField(MR32, MW32._MAX, MAX)
|
||||
CreateDWordField(MR32, MW32._LEN, LEN)
|
||||
Store(MINL, MIN)
|
||||
Store(MAXL, MAX)
|
||||
Store(LENL, LEN)
|
||||
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
Return(MR32)
|
||||
}
|
||||
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
Return(MR64)
|
||||
}
|
||||
|
||||
Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) {
|
||||
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
|
||||
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
|
||||
Store(MEMORY_SLOT_PROXIMITY, Local0)
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
Return(Local0)
|
||||
}
|
||||
|
||||
Method(MEMORY_SLOT_OST_METHOD, 4) {
|
||||
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
|
||||
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
|
||||
Store(Arg1, MEMORY_SLOT_OST_EVENT)
|
||||
Store(Arg2, MEMORY_SLOT_OST_STATUS)
|
||||
Release(MEMORY_SLOT_LOCK)
|
||||
}
|
||||
} // Device()
|
||||
} // Scope()
|
||||
}
|
||||
|
@@ -2,13 +2,13 @@ static unsigned char acpi_pci64_length[] = {
|
||||
0x6f
|
||||
};
|
||||
static unsigned char acpi_s4_pkg[] = {
|
||||
0x8f
|
||||
0x99
|
||||
};
|
||||
static unsigned short ssdt_mctrl_nr_slots[] = {
|
||||
0x1aa
|
||||
static unsigned char ssdt_mctrl_nr_slots[] = {
|
||||
0x7d
|
||||
};
|
||||
static unsigned char acpi_s3_name[] = {
|
||||
0x7c
|
||||
0x86
|
||||
};
|
||||
static unsigned char acpi_pci32_start[] = {
|
||||
0x2f
|
||||
@@ -21,12 +21,12 @@ static unsigned char ssdp_misc_aml[] = {
|
||||
0x53,
|
||||
0x44,
|
||||
0x54,
|
||||
0x7e,
|
||||
0x4,
|
||||
0x6c,
|
||||
0x1,
|
||||
0x0,
|
||||
0x0,
|
||||
0x1,
|
||||
0x8b,
|
||||
0x3,
|
||||
0x42,
|
||||
0x58,
|
||||
0x50,
|
||||
@@ -49,12 +49,12 @@ static unsigned char ssdp_misc_aml[] = {
|
||||
0x4e,
|
||||
0x54,
|
||||
0x4c,
|
||||
0x15,
|
||||
0x11,
|
||||
0x13,
|
||||
0x28,
|
||||
0x8,
|
||||
0x14,
|
||||
0x20,
|
||||
0x10,
|
||||
0x42,
|
||||
0x4c,
|
||||
0x5,
|
||||
0x5c,
|
||||
0x0,
|
||||
@@ -136,6 +136,16 @@ static unsigned char ssdp_misc_aml[] = {
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x8,
|
||||
0x4d,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x52,
|
||||
0xc,
|
||||
0x78,
|
||||
0x56,
|
||||
0x34,
|
||||
0x12,
|
||||
0x10,
|
||||
0x29,
|
||||
0x5c,
|
||||
@@ -370,809 +380,13 @@ static unsigned char ssdp_misc_aml[] = {
|
||||
0x49,
|
||||
0x4f,
|
||||
0x4d,
|
||||
0x58,
|
||||
0x10,
|
||||
0x4b,
|
||||
0x31,
|
||||
0x5c,
|
||||
0x2e,
|
||||
0x5f,
|
||||
0x53,
|
||||
0x42,
|
||||
0x5f,
|
||||
0x50,
|
||||
0x43,
|
||||
0x49,
|
||||
0x30,
|
||||
0x5b,
|
||||
0x82,
|
||||
0x4d,
|
||||
0x30,
|
||||
0x4d,
|
||||
0x48,
|
||||
0x50,
|
||||
0x44,
|
||||
0x8,
|
||||
0x5f,
|
||||
0x48,
|
||||
0x49,
|
||||
0x44,
|
||||
0xd,
|
||||
0x50,
|
||||
0x4e,
|
||||
0x50,
|
||||
0x30,
|
||||
0x41,
|
||||
0x30,
|
||||
0x36,
|
||||
0x0,
|
||||
0x8,
|
||||
0x5f,
|
||||
0x55,
|
||||
0x49,
|
||||
0x44,
|
||||
0xd,
|
||||
0x4d,
|
||||
0x65,
|
||||
0x6d,
|
||||
0x6f,
|
||||
0x72,
|
||||
0x79,
|
||||
0x20,
|
||||
0x68,
|
||||
0x6f,
|
||||
0x74,
|
||||
0x70,
|
||||
0x6c,
|
||||
0x75,
|
||||
0x67,
|
||||
0x20,
|
||||
0x72,
|
||||
0x65,
|
||||
0x73,
|
||||
0x6f,
|
||||
0x75,
|
||||
0x72,
|
||||
0x63,
|
||||
0x65,
|
||||
0x73,
|
||||
0x0,
|
||||
0x8,
|
||||
0x4d,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x52,
|
||||
0xc,
|
||||
0x78,
|
||||
0x56,
|
||||
0x34,
|
||||
0x12,
|
||||
0x5b,
|
||||
0x80,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x1,
|
||||
0xb,
|
||||
0x0,
|
||||
0xa,
|
||||
0xa,
|
||||
0x18,
|
||||
0x8,
|
||||
0x5f,
|
||||
0x43,
|
||||
0x52,
|
||||
0x53,
|
||||
0x11,
|
||||
0xd,
|
||||
0xa,
|
||||
0xa,
|
||||
0x47,
|
||||
0x1,
|
||||
0x0,
|
||||
0xa,
|
||||
0x0,
|
||||
0xa,
|
||||
0x0,
|
||||
0x18,
|
||||
0x79,
|
||||
0x0,
|
||||
0x14,
|
||||
0x13,
|
||||
0x5f,
|
||||
0x53,
|
||||
0x54,
|
||||
0x41,
|
||||
0x0,
|
||||
0xa0,
|
||||
0x9,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x52,
|
||||
0x0,
|
||||
0xa4,
|
||||
0x0,
|
||||
0xa4,
|
||||
0xa,
|
||||
0xb,
|
||||
0x5b,
|
||||
0x81,
|
||||
0x1f,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x3,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x4c,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x48,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x48,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x50,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x20,
|
||||
0x5b,
|
||||
0x81,
|
||||
0x13,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x1,
|
||||
0x0,
|
||||
0x40,
|
||||
0xa,
|
||||
0x4d,
|
||||
0x45,
|
||||
0x53,
|
||||
0x5f,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x53,
|
||||
0x1,
|
||||
0x5b,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0x0,
|
||||
0x5b,
|
||||
0x81,
|
||||
0x15,
|
||||
0x48,
|
||||
0x50,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x3,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x45,
|
||||
0x56,
|
||||
0x20,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x53,
|
||||
0x43,
|
||||
0x20,
|
||||
0x14,
|
||||
0x4a,
|
||||
0x4,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x43,
|
||||
0x4e,
|
||||
0x0,
|
||||
0xa0,
|
||||
0x9,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x52,
|
||||
0x0,
|
||||
0xa4,
|
||||
0x0,
|
||||
0x70,
|
||||
0x0,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0xa2,
|
||||
0x25,
|
||||
0x95,
|
||||
0x60,
|
||||
0x4d,
|
||||
0x44,
|
||||
0x4e,
|
||||
0x52,
|
||||
0x70,
|
||||
0x60,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0xa0,
|
||||
0x13,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x53,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x54,
|
||||
0x46,
|
||||
0x59,
|
||||
0x60,
|
||||
0x1,
|
||||
0x70,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x53,
|
||||
0x72,
|
||||
0x60,
|
||||
0x1,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x1,
|
||||
0x14,
|
||||
0x2d,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x53,
|
||||
0x54,
|
||||
0x1,
|
||||
0x70,
|
||||
0x0,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0xa0,
|
||||
0xb,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x45,
|
||||
0x53,
|
||||
0x5f,
|
||||
0x1,
|
||||
0x70,
|
||||
0xa,
|
||||
0xf,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x60,
|
||||
0x14,
|
||||
0x41,
|
||||
0x18,
|
||||
0x4d,
|
||||
0x43,
|
||||
0x52,
|
||||
0x53,
|
||||
0x9,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x8,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0x11,
|
||||
0x33,
|
||||
0xa,
|
||||
0x30,
|
||||
0x8a,
|
||||
0x2b,
|
||||
0x0,
|
||||
0x0,
|
||||
0xc,
|
||||
0x3,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xfe,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x79,
|
||||
0x0,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0xe,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x12,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x26,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x2a,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x16,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0xa,
|
||||
0x1a,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x48,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x42,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x48,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x72,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x72,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x48,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0xa0,
|
||||
0x14,
|
||||
0x95,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x72,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0xa0,
|
||||
0x11,
|
||||
0x95,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x1,
|
||||
0x74,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x74,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x1,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0xa0,
|
||||
0x44,
|
||||
0x7,
|
||||
0x93,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x48,
|
||||
0x0,
|
||||
0x8,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0x11,
|
||||
0x1f,
|
||||
0xa,
|
||||
0x1c,
|
||||
0x87,
|
||||
0x17,
|
||||
0x0,
|
||||
0x0,
|
||||
0xc,
|
||||
0x3,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xfe,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x79,
|
||||
0x0,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0xa,
|
||||
0xa,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0xa,
|
||||
0xe,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x8a,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0xa,
|
||||
0x16,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x49,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x4c,
|
||||
0x4d,
|
||||
0x41,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x70,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x4c,
|
||||
0x4c,
|
||||
0x45,
|
||||
0x4e,
|
||||
0x5f,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x33,
|
||||
0x32,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x4d,
|
||||
0x52,
|
||||
0x36,
|
||||
0x34,
|
||||
0x14,
|
||||
0x24,
|
||||
0x4d,
|
||||
0x50,
|
||||
0x58,
|
||||
0x4d,
|
||||
0x1,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x70,
|
||||
0x4d,
|
||||
0x50,
|
||||
0x58,
|
||||
0x5f,
|
||||
0x60,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xa4,
|
||||
0x60,
|
||||
0x14,
|
||||
0x28,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x53,
|
||||
0x54,
|
||||
0x4,
|
||||
0x5b,
|
||||
0x23,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b,
|
||||
0xff,
|
||||
0xff,
|
||||
0x70,
|
||||
0x99,
|
||||
0x68,
|
||||
0x0,
|
||||
0x4d,
|
||||
0x53,
|
||||
0x45,
|
||||
0x4c,
|
||||
0x70,
|
||||
0x69,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x45,
|
||||
0x56,
|
||||
0x70,
|
||||
0x6a,
|
||||
0x4d,
|
||||
0x4f,
|
||||
0x53,
|
||||
0x43,
|
||||
0x5b,
|
||||
0x27,
|
||||
0x4d,
|
||||
0x4c,
|
||||
0x43,
|
||||
0x4b
|
||||
0x58
|
||||
};
|
||||
static unsigned char ssdt_isa_pest[] = {
|
||||
0xd0
|
||||
0xda
|
||||
};
|
||||
static unsigned char acpi_s4_name[] = {
|
||||
0x88
|
||||
0x92
|
||||
};
|
||||
static unsigned char acpi_pci64_start[] = {
|
||||
0x4d
|
||||
|
279
hw/ide/ahci.c
279
hw/ide/ahci.c
@@ -730,7 +730,8 @@ static int prdt_tbl_entry_size(const AHCI_SG *tbl)
|
||||
return (le32_to_cpu(tbl->flags_size) & AHCI_PRDT_SIZE_MASK) + 1;
|
||||
}
|
||||
|
||||
static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset)
|
||||
static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist,
|
||||
int32_t offset)
|
||||
{
|
||||
AHCICmdHdr *cmd = ad->cur_cmd;
|
||||
uint32_t opts = le32_to_cpu(cmd->opts);
|
||||
@@ -741,13 +742,21 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset)
|
||||
uint8_t *prdt;
|
||||
int i;
|
||||
int r = 0;
|
||||
int sum = 0;
|
||||
uint64_t sum = 0;
|
||||
int off_idx = -1;
|
||||
int off_pos = -1;
|
||||
int64_t off_pos = -1;
|
||||
int tbl_entry_size;
|
||||
IDEBus *bus = &ad->port;
|
||||
BusState *qbus = BUS(bus);
|
||||
|
||||
/*
|
||||
* Note: AHCI PRDT can describe up to 256GiB. SATA/ATA only support
|
||||
* transactions of up to 32MiB as of ATA8-ACS3 rev 1b, assuming a
|
||||
* 512 byte sector size. We limit the PRDT in this implementation to
|
||||
* a reasonably large 2GiB, which can accommodate the maximum transfer
|
||||
* request for sector sizes up to 32K.
|
||||
*/
|
||||
|
||||
if (!sglist_alloc_hint) {
|
||||
DPRINTF(ad->port_no, "no sg list given by guest: 0x%08x\n", opts);
|
||||
return -1;
|
||||
@@ -782,7 +791,7 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset)
|
||||
}
|
||||
if ((off_idx == -1) || (off_pos < 0) || (off_pos > tbl_entry_size)) {
|
||||
DPRINTF(ad->port_no, "%s: Incorrect offset! "
|
||||
"off_idx: %d, off_pos: %d\n",
|
||||
"off_idx: %d, off_pos: %"PRId64"\n",
|
||||
__func__, off_idx, off_pos);
|
||||
r = -1;
|
||||
goto out;
|
||||
@@ -797,6 +806,13 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset)
|
||||
/* flags_size is zero-based */
|
||||
qemu_sglist_add(sglist, le64_to_cpu(tbl[i].addr),
|
||||
prdt_tbl_entry_size(&tbl[i]));
|
||||
if (sglist->size > INT32_MAX) {
|
||||
error_report("AHCI Physical Region Descriptor Table describes "
|
||||
"more than 2 GiB.\n");
|
||||
qemu_sglist_destroy(sglist);
|
||||
r = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -838,6 +854,21 @@ static void ncq_cb(void *opaque, int ret)
|
||||
ncq_tfs->used = 0;
|
||||
}
|
||||
|
||||
static int is_ncq(uint8_t ata_cmd)
|
||||
{
|
||||
/* Based on SATA 3.2 section 13.6.3.2 */
|
||||
switch (ata_cmd) {
|
||||
case READ_FPDMA_QUEUED:
|
||||
case WRITE_FPDMA_QUEUED:
|
||||
case NCQ_NON_DATA:
|
||||
case RECEIVE_FPDMA_QUEUED:
|
||||
case SEND_FPDMA_QUEUED:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
|
||||
int slot)
|
||||
{
|
||||
@@ -903,16 +934,106 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
|
||||
ncq_cb, ncq_tfs);
|
||||
break;
|
||||
default:
|
||||
DPRINTF(port, "error: tried to process non-NCQ command as NCQ\n");
|
||||
if (is_ncq(cmd_fis[2])) {
|
||||
DPRINTF(port,
|
||||
"error: unsupported NCQ command (0x%02x) received\n",
|
||||
cmd_fis[2]);
|
||||
} else {
|
||||
DPRINTF(port,
|
||||
"error: tried to process non-NCQ command as NCQ\n");
|
||||
}
|
||||
qemu_sglist_destroy(&ncq_tfs->sglist);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_reg_h2d_fis(AHCIState *s, int port,
|
||||
int slot, uint8_t *cmd_fis)
|
||||
{
|
||||
IDEState *ide_state = &s->dev[port].port.ifs[0];
|
||||
AHCICmdHdr *cmd = s->dev[port].cur_cmd;
|
||||
uint32_t opts = le32_to_cpu(cmd->opts);
|
||||
|
||||
if (cmd_fis[1] & 0x0F) {
|
||||
DPRINTF(port, "Port Multiplier not supported."
|
||||
" cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
|
||||
cmd_fis[0], cmd_fis[1], cmd_fis[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd_fis[1] & 0x70) {
|
||||
DPRINTF(port, "Reserved flags set in H2D Register FIS."
|
||||
" cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
|
||||
cmd_fis[0], cmd_fis[1], cmd_fis[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(cmd_fis[1] & SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER)) {
|
||||
switch (s->dev[port].port_state) {
|
||||
case STATE_RUN:
|
||||
if (cmd_fis[15] & ATA_SRST) {
|
||||
s->dev[port].port_state = STATE_RESET;
|
||||
}
|
||||
break;
|
||||
case STATE_RESET:
|
||||
if (!(cmd_fis[15] & ATA_SRST)) {
|
||||
ahci_reset_port(s, port);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for NCQ command */
|
||||
if (is_ncq(cmd_fis[2])) {
|
||||
process_ncq_command(s, port, cmd_fis, slot);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decompose the FIS:
|
||||
* AHCI does not interpret FIS packets, it only forwards them.
|
||||
* SATA 1.0 describes how to decode LBA28 and CHS FIS packets.
|
||||
* Later specifications, e.g, SATA 3.2, describe LBA48 FIS packets.
|
||||
*
|
||||
* ATA4 describes sector number for LBA28/CHS commands.
|
||||
* ATA6 describes sector number for LBA48 commands.
|
||||
* ATA8 deprecates CHS fully, describing only LBA28/48.
|
||||
*
|
||||
* We dutifully convert the FIS into IDE registers, and allow the
|
||||
* core layer to interpret them as needed. */
|
||||
ide_state->feature = cmd_fis[3];
|
||||
ide_state->sector = cmd_fis[4]; /* LBA 7:0 */
|
||||
ide_state->lcyl = cmd_fis[5]; /* LBA 15:8 */
|
||||
ide_state->hcyl = cmd_fis[6]; /* LBA 23:16 */
|
||||
ide_state->select = cmd_fis[7]; /* LBA 27:24 (LBA28) */
|
||||
ide_state->hob_sector = cmd_fis[8]; /* LBA 31:24 */
|
||||
ide_state->hob_lcyl = cmd_fis[9]; /* LBA 39:32 */
|
||||
ide_state->hob_hcyl = cmd_fis[10]; /* LBA 47:40 */
|
||||
ide_state->hob_feature = cmd_fis[11];
|
||||
ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]);
|
||||
/* 14, 16, 17, 18, 19: Reserved (SATA 1.0) */
|
||||
/* 15: Only valid when UPDATE_COMMAND not set. */
|
||||
|
||||
/* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
|
||||
* table to ide_state->io_buffer */
|
||||
if (opts & AHCI_CMD_ATAPI) {
|
||||
memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
|
||||
debug_print_fis(ide_state->io_buffer, 0x10);
|
||||
s->dev[port].done_atapi_packet = false;
|
||||
/* XXX send PIO setup FIS */
|
||||
}
|
||||
|
||||
ide_state->error = 0;
|
||||
|
||||
/* Reset transferred byte counter */
|
||||
cmd->status = 0;
|
||||
|
||||
/* We're ready to process the command in FIS byte 2. */
|
||||
ide_exec_cmd(&s->dev[port].port, cmd_fis[2]);
|
||||
}
|
||||
|
||||
static int handle_cmd(AHCIState *s, int port, int slot)
|
||||
{
|
||||
IDEState *ide_state;
|
||||
uint32_t opts;
|
||||
uint64_t tbl_addr;
|
||||
AHCICmdHdr *cmd;
|
||||
uint8_t *cmd_fis;
|
||||
@@ -924,142 +1045,48 @@ static int handle_cmd(AHCIState *s, int port, int slot)
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd = &((AHCICmdHdr *)s->dev[port].lst)[slot];
|
||||
|
||||
if (!s->dev[port].lst) {
|
||||
DPRINTF(port, "error: lst not given but cmd handled");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd = &((AHCICmdHdr *)s->dev[port].lst)[slot];
|
||||
/* remember current slot handle for later */
|
||||
s->dev[port].cur_cmd = cmd;
|
||||
|
||||
opts = le32_to_cpu(cmd->opts);
|
||||
tbl_addr = le64_to_cpu(cmd->tbl_addr);
|
||||
|
||||
cmd_len = 0x80;
|
||||
cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
|
||||
DMA_DIRECTION_FROM_DEVICE);
|
||||
|
||||
if (!cmd_fis) {
|
||||
DPRINTF(port, "error: guest passed us an invalid cmd fis\n");
|
||||
/* The device we are working for */
|
||||
ide_state = &s->dev[port].port.ifs[0];
|
||||
if (!ide_state->blk) {
|
||||
DPRINTF(port, "error: guest accessed unused port");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The device we are working for */
|
||||
ide_state = &s->dev[port].port.ifs[0];
|
||||
|
||||
if (!ide_state->blk) {
|
||||
DPRINTF(port, "error: guest accessed unused port");
|
||||
tbl_addr = le64_to_cpu(cmd->tbl_addr);
|
||||
cmd_len = 0x80;
|
||||
cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
|
||||
DMA_DIRECTION_FROM_DEVICE);
|
||||
if (!cmd_fis) {
|
||||
DPRINTF(port, "error: guest passed us an invalid cmd fis\n");
|
||||
return -1;
|
||||
} else if (cmd_len != 0x80) {
|
||||
ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_HBUS_ERR);
|
||||
DPRINTF(port, "error: dma_memory_map failed: "
|
||||
"(len(%02"PRIx64") != 0x80)\n",
|
||||
cmd_len);
|
||||
goto out;
|
||||
}
|
||||
|
||||
debug_print_fis(cmd_fis, 0x90);
|
||||
//debug_print_fis(cmd_fis, (opts & AHCI_CMD_HDR_CMD_FIS_LEN) * 4);
|
||||
debug_print_fis(cmd_fis, 0x80);
|
||||
|
||||
switch (cmd_fis[0]) {
|
||||
case SATA_FIS_TYPE_REGISTER_H2D:
|
||||
handle_reg_h2d_fis(s, port, slot, cmd_fis);
|
||||
break;
|
||||
default:
|
||||
DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
|
||||
"cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
|
||||
cmd_fis[2]);
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cmd_fis[1]) {
|
||||
case SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER:
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
|
||||
"cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
|
||||
cmd_fis[2]);
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (s->dev[port].port_state) {
|
||||
case STATE_RUN:
|
||||
if (cmd_fis[15] & ATA_SRST) {
|
||||
s->dev[port].port_state = STATE_RESET;
|
||||
}
|
||||
break;
|
||||
case STATE_RESET:
|
||||
if (!(cmd_fis[15] & ATA_SRST)) {
|
||||
ahci_reset_port(s, port);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmd_fis[1] == SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER) {
|
||||
|
||||
/* Check for NCQ command */
|
||||
if ((cmd_fis[2] == READ_FPDMA_QUEUED) ||
|
||||
(cmd_fis[2] == WRITE_FPDMA_QUEUED)) {
|
||||
process_ncq_command(s, port, cmd_fis, slot);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Decompose the FIS */
|
||||
ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]);
|
||||
ide_state->feature = cmd_fis[3];
|
||||
if (!ide_state->nsector) {
|
||||
ide_state->nsector = 256;
|
||||
}
|
||||
|
||||
if (ide_state->drive_kind != IDE_CD) {
|
||||
/*
|
||||
* We set the sector depending on the sector defined in the FIS.
|
||||
* Unfortunately, the spec isn't exactly obvious on this one.
|
||||
*
|
||||
* Apparently LBA48 commands set fis bytes 10,9,8,6,5,4 to the
|
||||
* 48 bit sector number. ATA_CMD_READ_DMA_EXT is an example for
|
||||
* such a command.
|
||||
*
|
||||
* Non-LBA48 commands however use 7[lower 4 bits],6,5,4 to define a
|
||||
* 28-bit sector number. ATA_CMD_READ_DMA is an example for such
|
||||
* a command.
|
||||
*
|
||||
* Since the spec doesn't explicitly state what each field should
|
||||
* do, I simply assume non-used fields as reserved and OR everything
|
||||
* together, independent of the command.
|
||||
*/
|
||||
ide_set_sector(ide_state, ((uint64_t)cmd_fis[10] << 40)
|
||||
| ((uint64_t)cmd_fis[9] << 32)
|
||||
/* This is used for LBA48 commands */
|
||||
| ((uint64_t)cmd_fis[8] << 24)
|
||||
/* This is used for non-LBA48 commands */
|
||||
| ((uint64_t)(cmd_fis[7] & 0xf) << 24)
|
||||
| ((uint64_t)cmd_fis[6] << 16)
|
||||
| ((uint64_t)cmd_fis[5] << 8)
|
||||
| cmd_fis[4]);
|
||||
}
|
||||
|
||||
/* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
|
||||
* table to ide_state->io_buffer
|
||||
*/
|
||||
if (opts & AHCI_CMD_ATAPI) {
|
||||
memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
|
||||
ide_state->lcyl = 0x14;
|
||||
ide_state->hcyl = 0xeb;
|
||||
debug_print_fis(ide_state->io_buffer, 0x10);
|
||||
ide_state->feature = IDE_FEATURE_DMA;
|
||||
s->dev[port].done_atapi_packet = false;
|
||||
/* XXX send PIO setup FIS */
|
||||
}
|
||||
|
||||
ide_state->error = 0;
|
||||
|
||||
/* Reset transferred byte counter */
|
||||
cmd->status = 0;
|
||||
|
||||
/* We're ready to process the command in FIS byte 2. */
|
||||
ide_exec_cmd(&s->dev[port].port, cmd_fis[2]);
|
||||
}
|
||||
|
||||
out:
|
||||
dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_FROM_DEVICE,
|
||||
cmd_len);
|
||||
@@ -1089,10 +1116,11 @@ static void ahci_start_transfer(IDEDMA *dma)
|
||||
if (is_atapi && !ad->done_atapi_packet) {
|
||||
/* already prepopulated iobuffer */
|
||||
ad->done_atapi_packet = true;
|
||||
size = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ahci_populate_sglist(ad, &s->sg, 0)) {
|
||||
if (ahci_dma_prepare_buf(dma, is_write)) {
|
||||
has_sglist = 1;
|
||||
}
|
||||
|
||||
@@ -1139,16 +1167,19 @@ static void ahci_start_dma(IDEDMA *dma, IDEState *s,
|
||||
* Not currently invoked by PIO R/W chains,
|
||||
* which invoke ahci_populate_sglist via ahci_start_transfer.
|
||||
*/
|
||||
static int ahci_dma_prepare_buf(IDEDMA *dma, int is_write)
|
||||
static int32_t ahci_dma_prepare_buf(IDEDMA *dma, int is_write)
|
||||
{
|
||||
AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
|
||||
IDEState *s = &ad->port.ifs[0];
|
||||
|
||||
ahci_populate_sglist(ad, &s->sg, 0);
|
||||
if (ahci_populate_sglist(ad, &s->sg, s->io_buffer_offset) == -1) {
|
||||
DPRINTF(ad->port_no, "ahci_dma_prepare_buf failed.\n");
|
||||
return -1;
|
||||
}
|
||||
s->io_buffer_size = s->sg.size;
|
||||
|
||||
DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
|
||||
return s->io_buffer_size != 0;
|
||||
return s->io_buffer_size;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -186,6 +186,9 @@
|
||||
|
||||
#define READ_FPDMA_QUEUED 0x60
|
||||
#define WRITE_FPDMA_QUEUED 0x61
|
||||
#define NCQ_NON_DATA 0x63
|
||||
#define RECEIVE_FPDMA_QUEUED 0x65
|
||||
#define SEND_FPDMA_QUEUED 0x64
|
||||
|
||||
#define RES_FIS_DSFIS 0x00
|
||||
#define RES_FIS_PSFIS 0x20
|
||||
|
@@ -592,6 +592,7 @@ static void ide_sector_read_cb(void *opaque, int ret)
|
||||
|
||||
ide_set_sector(s, ide_get_sector(s) + n);
|
||||
s->nsector -= n;
|
||||
s->io_buffer_offset += 512 * n;
|
||||
}
|
||||
|
||||
void ide_sector_read(IDEState *s)
|
||||
@@ -730,10 +731,11 @@ void ide_dma_cb(void *opaque, int ret)
|
||||
n = s->nsector;
|
||||
s->io_buffer_index = 0;
|
||||
s->io_buffer_size = n * 512;
|
||||
if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_read(s)) == 0) {
|
||||
if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_read(s)) < 512) {
|
||||
/* The PRDs were too short. Reset the Active bit, but don't raise an
|
||||
* interrupt. */
|
||||
s->status = READY_STAT | SEEK_STAT;
|
||||
dma_buf_commit(s, 0);
|
||||
goto eot;
|
||||
}
|
||||
|
||||
@@ -832,6 +834,8 @@ static void ide_sector_write_cb(void *opaque, int ret)
|
||||
n = s->req_nb_sectors;
|
||||
}
|
||||
s->nsector -= n;
|
||||
s->io_buffer_offset += 512 * n;
|
||||
|
||||
if (s->nsector == 0) {
|
||||
/* no more sectors to write */
|
||||
ide_transfer_stop(s);
|
||||
@@ -1824,6 +1828,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
|
||||
|
||||
s->status = READY_STAT | BUSY_STAT;
|
||||
s->error = 0;
|
||||
s->io_buffer_offset = 0;
|
||||
|
||||
complete = ide_cmd_table[val].handler(s, val);
|
||||
if (complete) {
|
||||
@@ -2309,12 +2314,17 @@ static int ide_nop_int(IDEDMA *dma, int x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t ide_nop_int32(IDEDMA *dma, int x)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ide_nop_restart(void *opaque, int x, RunState y)
|
||||
{
|
||||
}
|
||||
|
||||
static const IDEDMAOps ide_dma_nop_ops = {
|
||||
.prepare_buf = ide_nop_int,
|
||||
.prepare_buf = ide_nop_int32,
|
||||
.rw_buf = ide_nop_int,
|
||||
.set_unit = ide_nop_int,
|
||||
.restart_cb = ide_nop_restart,
|
||||
@@ -2391,7 +2401,7 @@ static int ide_drive_post_load(void *opaque, int version_id)
|
||||
{
|
||||
IDEState *s = opaque;
|
||||
|
||||
if (s->identify_set) {
|
||||
if (s->blk && s->identify_set) {
|
||||
blk_set_enable_write_cache(s->blk, !!(s->identify_data[85] & (1 << 5)));
|
||||
}
|
||||
return 0;
|
||||
|
@@ -322,6 +322,7 @@ typedef void EndTransferFunc(IDEState *);
|
||||
typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockCompletionFunc *);
|
||||
typedef void DMAVoidFunc(IDEDMA *);
|
||||
typedef int DMAIntFunc(IDEDMA *, int);
|
||||
typedef int32_t DMAInt32Func(IDEDMA *, int);
|
||||
typedef void DMAu32Func(IDEDMA *, uint32_t);
|
||||
typedef void DMAStopFunc(IDEDMA *, bool);
|
||||
typedef void DMARestartFunc(void *, int, RunState);
|
||||
@@ -385,7 +386,7 @@ struct IDEState {
|
||||
uint8_t cdrom_changed;
|
||||
int packet_transfer_size;
|
||||
int elementary_transfer_size;
|
||||
int io_buffer_index;
|
||||
int32_t io_buffer_index;
|
||||
int lba;
|
||||
int cd_sector_size;
|
||||
int atapi_dma; /* true if dma is requested for the packet cmd */
|
||||
@@ -394,8 +395,8 @@ struct IDEState {
|
||||
struct iovec iov;
|
||||
QEMUIOVector qiov;
|
||||
/* ATA DMA state */
|
||||
int io_buffer_offset;
|
||||
int io_buffer_size;
|
||||
int32_t io_buffer_offset;
|
||||
int32_t io_buffer_size;
|
||||
QEMUSGList sg;
|
||||
/* PIO transfer handling */
|
||||
int req_nb_sectors; /* number of sectors per interrupt */
|
||||
@@ -405,8 +406,8 @@ struct IDEState {
|
||||
uint8_t *io_buffer;
|
||||
/* PIO save/restore */
|
||||
int32_t io_buffer_total_len;
|
||||
int cur_io_buffer_offset;
|
||||
int cur_io_buffer_len;
|
||||
int32_t cur_io_buffer_offset;
|
||||
int32_t cur_io_buffer_len;
|
||||
uint8_t end_transfer_fn_idx;
|
||||
QEMUTimer *sector_write_timer; /* only used for win2k install hack */
|
||||
uint32_t irq_count; /* counts IRQs when using win2k install hack */
|
||||
@@ -430,7 +431,7 @@ struct IDEState {
|
||||
struct IDEDMAOps {
|
||||
DMAStartFunc *start_dma;
|
||||
DMAVoidFunc *start_transfer;
|
||||
DMAIntFunc *prepare_buf;
|
||||
DMAInt32Func *prepare_buf;
|
||||
DMAu32Func *commit_buf;
|
||||
DMAIntFunc *rw_buf;
|
||||
DMAIntFunc *set_unit;
|
||||
|
@@ -553,6 +553,11 @@ static int ide_nop_int(IDEDMA *dma, int x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t ide_nop_int32(IDEDMA *dma, int x)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ide_nop_restart(void *opaque, int x, RunState y)
|
||||
{
|
||||
}
|
||||
@@ -569,7 +574,7 @@ static void ide_dbdma_start(IDEDMA *dma, IDEState *s,
|
||||
|
||||
static const IDEDMAOps dbdma_ops = {
|
||||
.start_dma = ide_dbdma_start,
|
||||
.prepare_buf = ide_nop_int,
|
||||
.prepare_buf = ide_nop_int32,
|
||||
.rw_buf = ide_nop_int,
|
||||
.set_unit = ide_nop_int,
|
||||
.restart_cb = ide_nop_restart,
|
||||
|
27
hw/ide/pci.c
27
hw/ide/pci.c
@@ -28,7 +28,7 @@
|
||||
#include <hw/isa/isa.h>
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "sysemu/dma.h"
|
||||
|
||||
#include "qemu/error-report.h"
|
||||
#include <hw/ide/pci.h>
|
||||
|
||||
#define BMDMA_PAGE_SIZE 4096
|
||||
@@ -55,8 +55,11 @@ static void bmdma_start_dma(IDEDMA *dma, IDEState *s,
|
||||
}
|
||||
}
|
||||
|
||||
/* return 0 if buffer completed */
|
||||
static int bmdma_prepare_buf(IDEDMA *dma, int is_write)
|
||||
/**
|
||||
* Return the number of bytes successfully prepared.
|
||||
* -1 on error.
|
||||
*/
|
||||
static int32_t bmdma_prepare_buf(IDEDMA *dma, int is_write)
|
||||
{
|
||||
BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
|
||||
IDEState *s = bmdma_active_if(bm);
|
||||
@@ -74,8 +77,9 @@ static int bmdma_prepare_buf(IDEDMA *dma, int is_write)
|
||||
if (bm->cur_prd_len == 0) {
|
||||
/* end of table (with a fail safe of one page) */
|
||||
if (bm->cur_prd_last ||
|
||||
(bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE)
|
||||
return s->io_buffer_size != 0;
|
||||
(bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE) {
|
||||
return s->io_buffer_size;
|
||||
}
|
||||
pci_dma_read(pci_dev, bm->cur_addr, &prd, 8);
|
||||
bm->cur_addr += 8;
|
||||
prd.addr = le32_to_cpu(prd.addr);
|
||||
@@ -90,12 +94,23 @@ static int bmdma_prepare_buf(IDEDMA *dma, int is_write)
|
||||
l = bm->cur_prd_len;
|
||||
if (l > 0) {
|
||||
qemu_sglist_add(&s->sg, bm->cur_prd_addr, l);
|
||||
|
||||
/* Note: We limit the max transfer to be 2GiB.
|
||||
* This should accommodate the largest ATA transaction
|
||||
* for LBA48 (65,536 sectors) and 32K sector sizes. */
|
||||
if (s->sg.size > INT32_MAX) {
|
||||
error_report("IDE: sglist describes more than 2GiB.\n");
|
||||
break;
|
||||
}
|
||||
bm->cur_prd_addr += l;
|
||||
bm->cur_prd_len -= l;
|
||||
s->io_buffer_size += l;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
qemu_sglist_destroy(&s->sg);
|
||||
s->io_buffer_size = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* return 0 if buffer completed */
|
||||
|
@@ -188,7 +188,7 @@ void apic_deliver_pic_intr(DeviceState *dev, int level)
|
||||
apic_reset_bit(s->irr, lvt & 0xff);
|
||||
/* fall through */
|
||||
case APIC_DM_EXTINT:
|
||||
cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_HARD);
|
||||
apic_update_irq(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -349,6 +349,11 @@ static int apic_get_arb_pri(APICCommonState *s)
|
||||
static int apic_irq_pending(APICCommonState *s)
|
||||
{
|
||||
int irrv, ppr;
|
||||
|
||||
if (!(s->spurious_vec & APIC_SV_ENABLE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
irrv = get_highest_priority_int(s->irr);
|
||||
if (irrv < 0) {
|
||||
return 0;
|
||||
@@ -366,14 +371,13 @@ static void apic_update_irq(APICCommonState *s)
|
||||
{
|
||||
CPUState *cpu;
|
||||
|
||||
if (!(s->spurious_vec & APIC_SV_ENABLE)) {
|
||||
return;
|
||||
}
|
||||
cpu = CPU(s->cpu);
|
||||
if (!qemu_cpu_is_self(cpu)) {
|
||||
cpu_interrupt(cpu, CPU_INTERRUPT_POLL);
|
||||
} else if (apic_irq_pending(s) > 0) {
|
||||
cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
|
||||
} else if (!apic_accept_pic_intr(&s->busdev.qdev) || !pic_get_output(isa_pic)) {
|
||||
cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,7 +571,10 @@ int apic_get_interrupt(DeviceState *dev)
|
||||
apic_sync_vapic(s, SYNC_FROM_VAPIC);
|
||||
intno = apic_irq_pending(s);
|
||||
|
||||
if (intno == 0) {
|
||||
/* if there is an interrupt from the 8259, let the caller handle
|
||||
* that first since ExtINT interrupts ignore the priority.
|
||||
*/
|
||||
if (intno == 0 || apic_check_pic(s)) {
|
||||
apic_sync_vapic(s, SYNC_TO_VAPIC);
|
||||
return -1;
|
||||
} else if (intno < 0) {
|
||||
@@ -578,9 +585,6 @@ int apic_get_interrupt(DeviceState *dev)
|
||||
apic_set_bit(s->isr, intno);
|
||||
apic_sync_vapic(s, SYNC_TO_VAPIC);
|
||||
|
||||
/* re-inject if there is still a pending PIC interrupt */
|
||||
apic_check_pic(s);
|
||||
|
||||
apic_update_irq(s);
|
||||
|
||||
return intno;
|
||||
|
@@ -324,6 +324,19 @@ static void apic_common_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
}
|
||||
|
||||
static int apic_pre_load(void *opaque)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(opaque);
|
||||
|
||||
/* The default is !cpu_is_bsp(s->cpu), but the common value is 0
|
||||
* so that's what apic_common_sipi_needed checks for. Reset to
|
||||
* the value that is assumed when the apic_sipi subsection is
|
||||
* absent.
|
||||
*/
|
||||
s->wait_for_sipi = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apic_dispatch_pre_save(void *opaque)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(opaque);
|
||||
@@ -345,12 +358,30 @@ static int apic_dispatch_post_load(void *opaque, int version_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool apic_common_sipi_needed(void *opaque)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(opaque);
|
||||
return s->wait_for_sipi != 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_apic_common_sipi = {
|
||||
.name = "apic_sipi",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32(sipi_vector, APICCommonState),
|
||||
VMSTATE_INT32(wait_for_sipi, APICCommonState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_apic_common = {
|
||||
.name = "apic",
|
||||
.version_id = 3,
|
||||
.minimum_version_id = 3,
|
||||
.minimum_version_id_old = 1,
|
||||
.load_state_old = apic_load_old,
|
||||
.pre_load = apic_pre_load,
|
||||
.pre_save = apic_dispatch_pre_save,
|
||||
.post_load = apic_dispatch_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
@@ -375,6 +406,13 @@ static const VMStateDescription vmstate_apic_common = {
|
||||
VMSTATE_INT64(timer_expiry,
|
||||
APICCommonState), /* open-coded timer state */
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (VMStateSubsection[]) {
|
||||
{
|
||||
.vmsd = &vmstate_apic_common_sipi,
|
||||
.needed = apic_common_sipi_needed,
|
||||
},
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -45,6 +45,7 @@ typedef struct KVMOpenPICState {
|
||||
MemoryListener mem_listener;
|
||||
uint32_t fd;
|
||||
uint32_t model;
|
||||
hwaddr mapped;
|
||||
} KVMOpenPICState;
|
||||
|
||||
static void kvm_openpic_set_irq(void *opaque, int n_IRQ, int level)
|
||||
@@ -128,7 +129,16 @@ static void kvm_openpic_region_add(MemoryListener *listener,
|
||||
return;
|
||||
}
|
||||
|
||||
if (opp->mapped) {
|
||||
/*
|
||||
* We can only map the MPIC once. Since we are already mapped,
|
||||
* the best we can do is ignore new maps.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
reg_base = section->offset_within_address_space;
|
||||
opp->mapped = reg_base;
|
||||
|
||||
attr.group = KVM_DEV_MPIC_GRP_MISC;
|
||||
attr.attr = KVM_DEV_MPIC_BASE_ADDR;
|
||||
@@ -155,6 +165,15 @@ static void kvm_openpic_region_del(MemoryListener *listener,
|
||||
return;
|
||||
}
|
||||
|
||||
if (section->offset_within_address_space != opp->mapped) {
|
||||
/*
|
||||
* We can only map the MPIC once. This mapping was a secondary
|
||||
* one that we couldn't fulfill. Ignore it.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
opp->mapped = 0;
|
||||
|
||||
attr.group = KVM_DEV_MPIC_GRP_MISC;
|
||||
attr.attr = KVM_DEV_MPIC_BASE_ADDR;
|
||||
attr.addr = (uint64_t)(unsigned long)®_base;
|
||||
|
@@ -139,19 +139,34 @@ static int pc_dimm_built_list(Object *obj, void *opaque)
|
||||
|
||||
uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
|
||||
uint64_t address_space_size,
|
||||
uint64_t *hint, uint64_t size,
|
||||
uint64_t *hint, uint64_t align, uint64_t size,
|
||||
Error **errp)
|
||||
{
|
||||
GSList *list = NULL, *item;
|
||||
uint64_t new_addr, ret = 0;
|
||||
uint64_t address_space_end = address_space_start + address_space_size;
|
||||
|
||||
g_assert(QEMU_ALIGN_UP(address_space_start, align) == address_space_start);
|
||||
g_assert(QEMU_ALIGN_UP(address_space_size, align) == address_space_size);
|
||||
|
||||
if (!address_space_size) {
|
||||
error_setg(errp, "memory hotplug is not enabled, "
|
||||
"please add maxmem option");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hint && QEMU_ALIGN_UP(*hint, align) != *hint) {
|
||||
error_setg(errp, "address must be aligned to 0x%" PRIx64 " bytes",
|
||||
align);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (QEMU_ALIGN_UP(size, align) != size) {
|
||||
error_setg(errp, "backend memory size must be multiple of 0x%"
|
||||
PRIx64, align);
|
||||
goto out;
|
||||
}
|
||||
|
||||
assert(address_space_end > address_space_start);
|
||||
object_child_foreach(qdev_get_machine(), pc_dimm_built_list, &list);
|
||||
|
||||
@@ -177,7 +192,7 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
|
||||
error_setg(errp, "address range conflicts with '%s'", d->id);
|
||||
goto out;
|
||||
}
|
||||
new_addr = dimm->addr + dimm_size;
|
||||
new_addr = QEMU_ALIGN_UP(dimm->addr + dimm_size, align);
|
||||
}
|
||||
}
|
||||
ret = new_addr;
|
||||
|
@@ -197,7 +197,7 @@ mips_mipssim_init(MachineState *machine)
|
||||
!kernel_filename && !qtest_enabled()) {
|
||||
/* Bail out if we have neither a kernel image nor boot vector code. */
|
||||
error_report("Could not load MIPS bios '%s', and no "
|
||||
"-kernel argument was specified", filename);
|
||||
"-kernel argument was specified", bios_name);
|
||||
exit(1);
|
||||
} else {
|
||||
/* We have a boot vector start address. */
|
||||
|
@@ -1212,7 +1212,7 @@ static void pcnet_transmit(PCNetState *s)
|
||||
hwaddr xmit_cxda = 0;
|
||||
int count = CSR_XMTRL(s)-1;
|
||||
int add_crc = 0;
|
||||
|
||||
int bcnt;
|
||||
s->xmit_pos = -1;
|
||||
|
||||
if (!CSR_TXON(s)) {
|
||||
@@ -1247,35 +1247,40 @@ static void pcnet_transmit(PCNetState *s)
|
||||
s->xmit_pos = -1;
|
||||
goto txdone;
|
||||
}
|
||||
if (!GET_FIELD(tmd.status, TMDS, ENP)) {
|
||||
int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
|
||||
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
|
||||
s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
|
||||
s->xmit_pos += bcnt;
|
||||
} else if (s->xmit_pos >= 0) {
|
||||
int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
|
||||
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
|
||||
s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
|
||||
s->xmit_pos += bcnt;
|
||||
#ifdef PCNET_DEBUG
|
||||
printf("pcnet_transmit size=%d\n", s->xmit_pos);
|
||||
#endif
|
||||
if (CSR_LOOP(s)) {
|
||||
if (BCR_SWSTYLE(s) == 1)
|
||||
add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
|
||||
s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
|
||||
pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
|
||||
s->looptest = 0;
|
||||
} else
|
||||
if (s->nic)
|
||||
qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
|
||||
s->xmit_pos);
|
||||
|
||||
s->csr[0] &= ~0x0008; /* clear TDMD */
|
||||
s->csr[4] |= 0x0004; /* set TXSTRT */
|
||||
s->xmit_pos = -1;
|
||||
if (s->xmit_pos < 0) {
|
||||
goto txdone;
|
||||
}
|
||||
|
||||
bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
|
||||
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
|
||||
s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
|
||||
s->xmit_pos += bcnt;
|
||||
|
||||
if (!GET_FIELD(tmd.status, TMDS, ENP)) {
|
||||
goto txdone;
|
||||
}
|
||||
|
||||
#ifdef PCNET_DEBUG
|
||||
printf("pcnet_transmit size=%d\n", s->xmit_pos);
|
||||
#endif
|
||||
if (CSR_LOOP(s)) {
|
||||
if (BCR_SWSTYLE(s) == 1)
|
||||
add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
|
||||
s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
|
||||
pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
|
||||
s->looptest = 0;
|
||||
} else {
|
||||
if (s->nic) {
|
||||
qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
|
||||
s->xmit_pos);
|
||||
}
|
||||
}
|
||||
|
||||
s->csr[0] &= ~0x0008; /* clear TDMD */
|
||||
s->csr[4] |= 0x0004; /* set TXSTRT */
|
||||
s->xmit_pos = -1;
|
||||
|
||||
txdone:
|
||||
SET_FIELD(&tmd.status, TMDS, OWN, 0);
|
||||
TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
|
||||
|
@@ -1775,6 +1775,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
|
||||
int do_interrupt, const uint8_t *dot1q_buf)
|
||||
{
|
||||
struct iovec *iov = NULL;
|
||||
struct iovec vlan_iov[3];
|
||||
|
||||
if (!size)
|
||||
{
|
||||
@@ -1789,6 +1790,9 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
|
||||
{ .iov_base = buf + ETHER_ADDR_LEN * 2,
|
||||
.iov_len = size - ETHER_ADDR_LEN * 2 },
|
||||
};
|
||||
|
||||
memcpy(vlan_iov, iov, sizeof(vlan_iov));
|
||||
iov = vlan_iov;
|
||||
}
|
||||
|
||||
if (TxLoopBack == (s->TxConfig & TxLoopBack))
|
||||
|
@@ -798,7 +798,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
|
||||
VirtQueueElement elem;
|
||||
size_t s;
|
||||
struct iovec *iov;
|
||||
struct iovec *iov, *iov2;
|
||||
unsigned int iov_cnt;
|
||||
|
||||
while (virtqueue_pop(vq, &elem)) {
|
||||
@@ -808,8 +808,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
iov = elem.out_sg;
|
||||
iov_cnt = elem.out_num;
|
||||
iov2 = iov = g_memdup(elem.out_sg, sizeof(struct iovec) * elem.out_num);
|
||||
s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
|
||||
iov_discard_front(&iov, &iov_cnt, sizeof(ctrl));
|
||||
if (s != sizeof(ctrl)) {
|
||||
@@ -833,6 +833,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
|
||||
virtqueue_push(vq, &elem, sizeof(status));
|
||||
virtio_notify(vdev, vq);
|
||||
g_free(iov2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -523,6 +523,7 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
|
||||
void *data, size_t len)
|
||||
{
|
||||
int i, index;
|
||||
void *ptr = NULL;
|
||||
|
||||
assert(s->files);
|
||||
|
||||
@@ -531,8 +532,10 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
|
||||
|
||||
for (i = 0; i < index; i++) {
|
||||
if (strcmp(filename, s->files->f[i].name) == 0) {
|
||||
return fw_cfg_modify_bytes_read(s, FW_CFG_FILE_FIRST + i,
|
||||
data, len);
|
||||
ptr = fw_cfg_modify_bytes_read(s, FW_CFG_FILE_FIRST + i,
|
||||
data, len);
|
||||
s->files->f[i].size = cpu_to_be32(len);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
/* add new one */
|
||||
|
@@ -52,7 +52,6 @@ static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
{
|
||||
sPAPRNVRAM *nvram = spapr->nvram;
|
||||
hwaddr offset, buffer, len;
|
||||
int alen;
|
||||
void *membuf;
|
||||
|
||||
if ((nargs != 3) || (nret != 2)) {
|
||||
@@ -77,19 +76,14 @@ static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
return;
|
||||
}
|
||||
|
||||
membuf = cpu_physical_memory_map(buffer, &len, 1);
|
||||
if (nvram->blk) {
|
||||
alen = blk_pread(nvram->blk, offset, membuf, len);
|
||||
} else {
|
||||
assert(nvram->buf);
|
||||
assert(nvram->buf);
|
||||
|
||||
memcpy(membuf, nvram->buf + offset, len);
|
||||
alen = len;
|
||||
}
|
||||
membuf = cpu_physical_memory_map(buffer, &len, 1);
|
||||
memcpy(membuf, nvram->buf + offset, len);
|
||||
cpu_physical_memory_unmap(membuf, len, 1, len);
|
||||
|
||||
rtas_st(rets, 0, (alen < len) ? RTAS_OUT_HW_ERROR : RTAS_OUT_SUCCESS);
|
||||
rtas_st(rets, 1, (alen < 0) ? 0 : alen);
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
rtas_st(rets, 1, len);
|
||||
}
|
||||
|
||||
static void rtas_nvram_store(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
@@ -123,14 +117,15 @@ static void rtas_nvram_store(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
}
|
||||
|
||||
membuf = cpu_physical_memory_map(buffer, &len, 0);
|
||||
|
||||
alen = len;
|
||||
if (nvram->blk) {
|
||||
alen = blk_pwrite(nvram->blk, offset, membuf, len);
|
||||
} else {
|
||||
assert(nvram->buf);
|
||||
|
||||
memcpy(nvram->buf + offset, membuf, len);
|
||||
alen = len;
|
||||
}
|
||||
|
||||
assert(nvram->buf);
|
||||
memcpy(nvram->buf + offset, membuf, len);
|
||||
|
||||
cpu_physical_memory_unmap(membuf, len, 0, len);
|
||||
|
||||
rtas_st(rets, 0, (alen < len) ? RTAS_OUT_HW_ERROR : RTAS_OUT_SUCCESS);
|
||||
@@ -145,15 +140,24 @@ static int spapr_nvram_init(VIOsPAPRDevice *dev)
|
||||
nvram->size = blk_getlength(nvram->blk);
|
||||
} else {
|
||||
nvram->size = DEFAULT_NVRAM_SIZE;
|
||||
nvram->buf = g_malloc0(nvram->size);
|
||||
}
|
||||
|
||||
nvram->buf = g_malloc0(nvram->size);
|
||||
|
||||
if ((nvram->size < MIN_NVRAM_SIZE) || (nvram->size > MAX_NVRAM_SIZE)) {
|
||||
fprintf(stderr, "spapr-nvram must be between %d and %d bytes in size\n",
|
||||
MIN_NVRAM_SIZE, MAX_NVRAM_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nvram->blk) {
|
||||
int alen = blk_pread(nvram->blk, 0, nvram->buf, nvram->size);
|
||||
|
||||
if (alen != nvram->size) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
spapr_rtas_register(RTAS_NVRAM_FETCH, "nvram-fetch", rtas_nvram_fetch);
|
||||
spapr_rtas_register(RTAS_NVRAM_STORE, "nvram-store", rtas_nvram_store);
|
||||
|
||||
@@ -167,6 +171,48 @@ static int spapr_nvram_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
|
||||
return fdt_setprop_cell(fdt, node_off, "#bytes", nvram->size);
|
||||
}
|
||||
|
||||
static int spapr_nvram_pre_load(void *opaque)
|
||||
{
|
||||
sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(opaque);
|
||||
|
||||
g_free(nvram->buf);
|
||||
nvram->buf = NULL;
|
||||
nvram->size = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spapr_nvram_post_load(void *opaque, int version_id)
|
||||
{
|
||||
sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(opaque);
|
||||
|
||||
if (nvram->blk) {
|
||||
int alen = blk_pwrite(nvram->blk, 0, nvram->buf, nvram->size);
|
||||
|
||||
if (alen < 0) {
|
||||
return alen;
|
||||
}
|
||||
if (alen != nvram->size) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_spapr_nvram = {
|
||||
.name = "spapr_nvram",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.pre_load = spapr_nvram_pre_load,
|
||||
.post_load = spapr_nvram_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(size, sPAPRNVRAM),
|
||||
VMSTATE_VBUFFER_ALLOC_UINT32(buf, sPAPRNVRAM, 1, NULL, 0, size),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
||||
static Property spapr_nvram_properties[] = {
|
||||
DEFINE_SPAPR_PROPERTIES(sPAPRNVRAM, sdev),
|
||||
DEFINE_PROP_DRIVE("drive", sPAPRNVRAM, blk),
|
||||
@@ -185,6 +231,7 @@ static void spapr_nvram_class_init(ObjectClass *klass, void *data)
|
||||
k->dt_compatible = "qemu,spapr-nvram";
|
||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
dc->props = spapr_nvram_properties;
|
||||
dc->vmsd = &vmstate_spapr_nvram;
|
||||
}
|
||||
|
||||
static const TypeInfo spapr_nvram_type_info = {
|
||||
|
@@ -145,7 +145,7 @@ void pcie_cap_deverr_init(PCIDevice *dev)
|
||||
PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE);
|
||||
pci_long_test_and_set_mask(dev->w1cmask + pos + PCI_EXP_DEVSTA,
|
||||
PCI_EXP_DEVSTA_CED | PCI_EXP_DEVSTA_NFED |
|
||||
PCI_EXP_DEVSTA_URD | PCI_EXP_DEVSTA_URD);
|
||||
PCI_EXP_DEVSTA_FED | PCI_EXP_DEVSTA_URD);
|
||||
}
|
||||
|
||||
void pcie_cap_deverr_reset(PCIDevice *dev)
|
||||
@@ -229,7 +229,7 @@ static void pcie_cap_slot_hotplug_common(PCIDevice *hotplug_dev,
|
||||
/* the slot is electromechanically locked.
|
||||
* This error is propagated up to qdev and then to HMP/QMP.
|
||||
*/
|
||||
error_setg_errno(errp, -EBUSY, "slot is electromechanically locked");
|
||||
error_setg_errno(errp, EBUSY, "slot is electromechanically locked");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -559,8 +559,9 @@ void shpc_device_hot_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
uint8_t led;
|
||||
int slot;
|
||||
|
||||
shpc_device_hotplug_common(PCI_DEVICE(dev), &slot, shpc, errp);
|
||||
shpc_device_hotplug_common(PCI_DEVICE(dev), &slot, shpc, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -662,6 +663,7 @@ void shpc_cleanup(PCIDevice *d, MemoryRegion *bar)
|
||||
SHPCDevice *shpc = d->shpc;
|
||||
d->cap_present &= ~QEMU_PCI_CAP_SHPC;
|
||||
memory_region_del_subregion(bar, &shpc->mmio);
|
||||
object_unparent(OBJECT(&shpc->mmio));
|
||||
/* TODO: cleanup config space changes? */
|
||||
g_free(shpc->config);
|
||||
g_free(shpc->cmask);
|
||||
|
@@ -20,4 +20,4 @@ obj-$(CONFIG_MAC) += mac_newworld.o
|
||||
obj-$(CONFIG_E500) += e500.o mpc8544ds.o e500plat.o
|
||||
obj-$(CONFIG_E500) += mpc8544_guts.o ppce500_spin.o
|
||||
# PowerPC 440 Xilinx ML507 reference board.
|
||||
obj-y += virtex_ml507.o
|
||||
obj-$(CONFIG_XILINX) += virtex_ml507.o
|
||||
|
199
hw/ppc/e500.c
199
hw/ppc/e500.c
@@ -36,6 +36,9 @@
|
||||
#include "exec/address-spaces.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "hw/pci-host/ppce500.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "hw/net/fsl_etsec/etsec.h"
|
||||
|
||||
#define EPAPR_MAGIC (0x45504150)
|
||||
#define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb"
|
||||
@@ -61,6 +64,8 @@
|
||||
#define MPC8544_PCI_IO 0xE1000000ULL
|
||||
#define MPC8544_UTIL_OFFSET 0xe0000ULL
|
||||
#define MPC8544_SPIN_BASE 0xEF000000ULL
|
||||
#define MPC8XXX_GPIO_OFFSET 0x000FF000ULL
|
||||
#define MPC8XXX_GPIO_IRQ 43
|
||||
|
||||
struct boot_info
|
||||
{
|
||||
@@ -122,6 +127,142 @@ static void dt_serial_create(void *fdt, unsigned long long offset,
|
||||
}
|
||||
}
|
||||
|
||||
static void create_dt_mpc8xxx_gpio(void *fdt, const char *soc, const char *mpic)
|
||||
{
|
||||
hwaddr mmio0 = MPC8XXX_GPIO_OFFSET;
|
||||
int irq0 = MPC8XXX_GPIO_IRQ;
|
||||
gchar *node = g_strdup_printf("%s/gpio@%"PRIx64, soc, mmio0);
|
||||
gchar *poweroff = g_strdup_printf("%s/power-off", soc);
|
||||
int gpio_ph;
|
||||
|
||||
qemu_fdt_add_subnode(fdt, node);
|
||||
qemu_fdt_setprop_string(fdt, node, "compatible", "fsl,qoriq-gpio");
|
||||
qemu_fdt_setprop_cells(fdt, node, "reg", mmio0, 0x1000);
|
||||
qemu_fdt_setprop_cells(fdt, node, "interrupts", irq0, 0x2);
|
||||
qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", mpic);
|
||||
qemu_fdt_setprop_cells(fdt, node, "#gpio-cells", 2);
|
||||
qemu_fdt_setprop(fdt, node, "gpio-controller", NULL, 0);
|
||||
gpio_ph = qemu_fdt_alloc_phandle(fdt);
|
||||
qemu_fdt_setprop_cell(fdt, node, "phandle", gpio_ph);
|
||||
qemu_fdt_setprop_cell(fdt, node, "linux,phandle", gpio_ph);
|
||||
|
||||
/* Power Off Pin */
|
||||
qemu_fdt_add_subnode(fdt, poweroff);
|
||||
qemu_fdt_setprop_string(fdt, poweroff, "compatible", "gpio-poweroff");
|
||||
qemu_fdt_setprop_cells(fdt, poweroff, "gpios", gpio_ph, 0, 0);
|
||||
|
||||
g_free(node);
|
||||
g_free(poweroff);
|
||||
}
|
||||
|
||||
typedef struct PlatformDevtreeData {
|
||||
void *fdt;
|
||||
const char *mpic;
|
||||
int irq_start;
|
||||
const char *node;
|
||||
PlatformBusDevice *pbus;
|
||||
} PlatformDevtreeData;
|
||||
|
||||
static int create_devtree_etsec(SysBusDevice *sbdev, PlatformDevtreeData *data)
|
||||
{
|
||||
eTSEC *etsec = ETSEC_COMMON(sbdev);
|
||||
PlatformBusDevice *pbus = data->pbus;
|
||||
hwaddr mmio0 = platform_bus_get_mmio_addr(pbus, sbdev, 0);
|
||||
int irq0 = platform_bus_get_irqn(pbus, sbdev, 0);
|
||||
int irq1 = platform_bus_get_irqn(pbus, sbdev, 1);
|
||||
int irq2 = platform_bus_get_irqn(pbus, sbdev, 2);
|
||||
gchar *node = g_strdup_printf("/platform/ethernet@%"PRIx64, mmio0);
|
||||
gchar *group = g_strdup_printf("%s/queue-group", node);
|
||||
void *fdt = data->fdt;
|
||||
|
||||
assert((int64_t)mmio0 >= 0);
|
||||
assert(irq0 >= 0);
|
||||
assert(irq1 >= 0);
|
||||
assert(irq2 >= 0);
|
||||
|
||||
qemu_fdt_add_subnode(fdt, node);
|
||||
qemu_fdt_setprop_string(fdt, node, "device_type", "network");
|
||||
qemu_fdt_setprop_string(fdt, node, "compatible", "fsl,etsec2");
|
||||
qemu_fdt_setprop_string(fdt, node, "model", "eTSEC");
|
||||
qemu_fdt_setprop(fdt, node, "local-mac-address", etsec->conf.macaddr.a, 6);
|
||||
qemu_fdt_setprop_cells(fdt, node, "fixed-link", 0, 1, 1000, 0, 0);
|
||||
|
||||
qemu_fdt_add_subnode(fdt, group);
|
||||
qemu_fdt_setprop_cells(fdt, group, "reg", mmio0, 0x1000);
|
||||
qemu_fdt_setprop_cells(fdt, group, "interrupts",
|
||||
data->irq_start + irq0, 0x2,
|
||||
data->irq_start + irq1, 0x2,
|
||||
data->irq_start + irq2, 0x2);
|
||||
|
||||
g_free(node);
|
||||
g_free(group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sysbus_device_create_devtree(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
PlatformDevtreeData *data = opaque;
|
||||
bool matched = false;
|
||||
|
||||
if (object_dynamic_cast(OBJECT(sbdev), TYPE_ETSEC_COMMON)) {
|
||||
create_devtree_etsec(sbdev, data);
|
||||
matched = true;
|
||||
}
|
||||
|
||||
if (!matched) {
|
||||
error_report("Device %s is not supported by this machine yet.",
|
||||
qdev_fw_name(DEVICE(sbdev)));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void platform_bus_create_devtree(PPCE500Params *params, void *fdt,
|
||||
const char *mpic)
|
||||
{
|
||||
gchar *node = g_strdup_printf("/platform@%"PRIx64, params->platform_bus_base);
|
||||
const char platcomp[] = "qemu,platform\0simple-bus";
|
||||
uint64_t addr = params->platform_bus_base;
|
||||
uint64_t size = params->platform_bus_size;
|
||||
int irq_start = params->platform_bus_first_irq;
|
||||
PlatformBusDevice *pbus;
|
||||
DeviceState *dev;
|
||||
|
||||
/* Create a /platform node that we can put all devices into */
|
||||
|
||||
qemu_fdt_add_subnode(fdt, node);
|
||||
qemu_fdt_setprop(fdt, node, "compatible", platcomp, sizeof(platcomp));
|
||||
|
||||
/* Our platform bus region is less than 32bit big, so 1 cell is enough for
|
||||
address and size */
|
||||
qemu_fdt_setprop_cells(fdt, node, "#size-cells", 1);
|
||||
qemu_fdt_setprop_cells(fdt, node, "#address-cells", 1);
|
||||
qemu_fdt_setprop_cells(fdt, node, "ranges", 0, addr >> 32, addr, size);
|
||||
|
||||
qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", mpic);
|
||||
|
||||
dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE);
|
||||
pbus = PLATFORM_BUS_DEVICE(dev);
|
||||
|
||||
/* We can only create dt nodes for dynamic devices when they're ready */
|
||||
if (pbus->done_gathering) {
|
||||
PlatformDevtreeData data = {
|
||||
.fdt = fdt,
|
||||
.mpic = mpic,
|
||||
.irq_start = irq_start,
|
||||
.node = node,
|
||||
.pbus = pbus,
|
||||
};
|
||||
|
||||
/* Loop through all dynamic sysbus devices and create nodes for them */
|
||||
foreach_dynamic_sysbus_device(sysbus_device_create_devtree, &data);
|
||||
}
|
||||
|
||||
g_free(node);
|
||||
}
|
||||
|
||||
static int ppce500_load_device_tree(MachineState *machine,
|
||||
PPCE500Params *params,
|
||||
hwaddr addr,
|
||||
@@ -379,6 +520,14 @@ static int ppce500_load_device_tree(MachineState *machine,
|
||||
qemu_fdt_setprop_cell(fdt, pci, "#address-cells", 3);
|
||||
qemu_fdt_setprop_string(fdt, "/aliases", "pci0", pci);
|
||||
|
||||
if (params->has_mpc8xxx_gpio) {
|
||||
create_dt_mpc8xxx_gpio(fdt, soc, mpic);
|
||||
}
|
||||
|
||||
if (params->has_platform_bus) {
|
||||
platform_bus_create_devtree(params, fdt, mpic);
|
||||
}
|
||||
|
||||
params->fixup_devtree(params, fdt);
|
||||
|
||||
if (toplevel_compat) {
|
||||
@@ -407,6 +556,7 @@ typedef struct DeviceTreeParams {
|
||||
hwaddr initrd_size;
|
||||
hwaddr kernel_base;
|
||||
hwaddr kernel_size;
|
||||
Notifier notifier;
|
||||
} DeviceTreeParams;
|
||||
|
||||
static void ppce500_reset_device_tree(void *opaque)
|
||||
@@ -417,6 +567,12 @@ static void ppce500_reset_device_tree(void *opaque)
|
||||
false);
|
||||
}
|
||||
|
||||
static void ppce500_init_notify(Notifier *notifier, void *data)
|
||||
{
|
||||
DeviceTreeParams *p = container_of(notifier, DeviceTreeParams, notifier);
|
||||
ppce500_reset_device_tree(p);
|
||||
}
|
||||
|
||||
static int ppce500_prep_device_tree(MachineState *machine,
|
||||
PPCE500Params *params,
|
||||
hwaddr addr,
|
||||
@@ -435,6 +591,8 @@ static int ppce500_prep_device_tree(MachineState *machine,
|
||||
p->kernel_size = kernel_size;
|
||||
|
||||
qemu_register_reset(ppce500_reset_device_tree, p);
|
||||
p->notifier.notify = ppce500_init_notify;
|
||||
qemu_add_machine_init_done_notifier(&p->notifier);
|
||||
|
||||
/* Issue the device tree loader once, so that we get the size of the blob */
|
||||
return ppce500_load_device_tree(machine, params, addr, initrd_base,
|
||||
@@ -618,6 +776,13 @@ static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr,
|
||||
return mpic;
|
||||
}
|
||||
|
||||
static void ppce500_power_off(void *opaque, int line, int on)
|
||||
{
|
||||
if (on) {
|
||||
qemu_system_shutdown_request();
|
||||
}
|
||||
}
|
||||
|
||||
void ppce500_init(MachineState *machine, PPCE500Params *params)
|
||||
{
|
||||
MemoryRegion *address_space_mem = get_system_memory();
|
||||
@@ -769,6 +934,40 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
|
||||
cur_base = (32 * 1024 * 1024);
|
||||
}
|
||||
|
||||
if (params->has_mpc8xxx_gpio) {
|
||||
qemu_irq poweroff_irq;
|
||||
|
||||
dev = qdev_create(NULL, "mpc8xxx_gpio");
|
||||
s = SYS_BUS_DEVICE(dev);
|
||||
qdev_init_nofail(dev);
|
||||
sysbus_connect_irq(s, 0, mpic[MPC8XXX_GPIO_IRQ]);
|
||||
memory_region_add_subregion(ccsr_addr_space, MPC8XXX_GPIO_OFFSET,
|
||||
sysbus_mmio_get_region(s, 0));
|
||||
|
||||
/* Power Off GPIO at Pin 0 */
|
||||
poweroff_irq = qemu_allocate_irq(ppce500_power_off, NULL, 0);
|
||||
qdev_connect_gpio_out(dev, 0, poweroff_irq);
|
||||
}
|
||||
|
||||
/* Platform Bus Device */
|
||||
if (params->has_platform_bus) {
|
||||
dev = qdev_create(NULL, TYPE_PLATFORM_BUS_DEVICE);
|
||||
dev->id = TYPE_PLATFORM_BUS_DEVICE;
|
||||
qdev_prop_set_uint32(dev, "num_irqs", params->platform_bus_num_irqs);
|
||||
qdev_prop_set_uint32(dev, "mmio_size", params->platform_bus_size);
|
||||
qdev_init_nofail(dev);
|
||||
s = SYS_BUS_DEVICE(dev);
|
||||
|
||||
for (i = 0; i < params->platform_bus_num_irqs; i++) {
|
||||
int irqn = params->platform_bus_first_irq + i;
|
||||
sysbus_connect_irq(s, i, mpic[irqn]);
|
||||
}
|
||||
|
||||
memory_region_add_subregion(address_space_mem,
|
||||
params->platform_bus_base,
|
||||
sysbus_mmio_get_region(s, 0));
|
||||
}
|
||||
|
||||
/* Load kernel. */
|
||||
if (machine->kernel_filename) {
|
||||
kernel_base = cur_base;
|
||||
|
@@ -11,6 +11,12 @@ typedef struct PPCE500Params {
|
||||
void (*fixup_devtree)(struct PPCE500Params *params, void *fdt);
|
||||
|
||||
int mpic_version;
|
||||
bool has_mpc8xxx_gpio;
|
||||
bool has_platform_bus;
|
||||
hwaddr platform_bus_base;
|
||||
hwaddr platform_bus_size;
|
||||
int platform_bus_first_irq;
|
||||
int platform_bus_num_irqs;
|
||||
} PPCE500Params;
|
||||
|
||||
void ppce500_init(MachineState *machine, PPCE500Params *params);
|
||||
|
@@ -35,6 +35,12 @@ static void e500plat_init(MachineState *machine)
|
||||
.pci_nr_slots = PCI_SLOT_MAX - 1,
|
||||
.fixup_devtree = e500plat_fixup_devtree,
|
||||
.mpic_version = OPENPIC_MODEL_FSL_MPIC_42,
|
||||
.has_mpc8xxx_gpio = true,
|
||||
.has_platform_bus = true,
|
||||
.platform_bus_base = 0xf00000000ULL,
|
||||
.platform_bus_size = (128ULL * 1024 * 1024),
|
||||
.platform_bus_first_irq = 5,
|
||||
.platform_bus_num_irqs = 10,
|
||||
};
|
||||
|
||||
/* Older KVM versions don't support EPR which breaks guests when we announce
|
||||
@@ -51,6 +57,7 @@ static QEMUMachine e500plat_machine = {
|
||||
.desc = "generic paravirt e500 platform",
|
||||
.init = e500plat_init,
|
||||
.max_cpus = 32,
|
||||
.has_dynamic_sysbus = true,
|
||||
};
|
||||
|
||||
static void e500plat_machine_init(void)
|
||||
|
@@ -92,30 +92,6 @@ typedef struct PPC4xxPCIState PPC4xxPCIState;
|
||||
|
||||
#define PCI_ALL_SIZE (PCI_REG_BASE + PCI_REG_SIZE)
|
||||
|
||||
static uint64_t pci4xx_cfgaddr_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
PPC4xxPCIState *ppc4xx_pci = opaque;
|
||||
PCIHostState *phb = PCI_HOST_BRIDGE(ppc4xx_pci);
|
||||
|
||||
return phb->config_reg;
|
||||
}
|
||||
|
||||
static void pci4xx_cfgaddr_write(void *opaque, hwaddr addr,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
PPC4xxPCIState *ppc4xx_pci = opaque;
|
||||
PCIHostState *phb = PCI_HOST_BRIDGE(ppc4xx_pci);
|
||||
|
||||
phb->config_reg = value & ~0x3;
|
||||
}
|
||||
|
||||
static const MemoryRegionOps pci4xx_cfgaddr_ops = {
|
||||
.read = pci4xx_cfgaddr_read,
|
||||
.write = pci4xx_cfgaddr_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static void ppc4xx_pci_reg_write4(void *opaque, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
|
@@ -850,11 +850,31 @@ static void spapr_reset_htab(sPAPREnvironment *spapr)
|
||||
}
|
||||
}
|
||||
|
||||
static int find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
bool matched = false;
|
||||
|
||||
if (object_dynamic_cast(OBJECT(sbdev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
|
||||
matched = true;
|
||||
}
|
||||
|
||||
if (!matched) {
|
||||
error_report("Device %s is not supported by this machine yet.",
|
||||
qdev_fw_name(DEVICE(sbdev)));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ppc_spapr_reset(void)
|
||||
{
|
||||
PowerPCCPU *first_ppc_cpu;
|
||||
uint32_t rtas_limit;
|
||||
|
||||
/* Check for unknown sysbus devices */
|
||||
foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
|
||||
|
||||
/* Reset the hash table & recalc the RMA */
|
||||
spapr_reset_htab(spapr);
|
||||
|
||||
@@ -1660,9 +1680,6 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
||||
FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
|
||||
NMIClass *nc = NMI_CLASS(oc);
|
||||
|
||||
mc->name = "pseries";
|
||||
mc->desc = "pSeries Logical Partition (PAPR compliant)";
|
||||
mc->is_default = 1;
|
||||
mc->init = ppc_spapr_init;
|
||||
mc->reset = ppc_spapr_reset;
|
||||
mc->block_default_type = IF_SCSI;
|
||||
@@ -1670,6 +1687,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->no_parallel = 1;
|
||||
mc->default_boot_order = NULL;
|
||||
mc->kvm_type = spapr_kvm_type;
|
||||
mc->has_dynamic_sysbus = true;
|
||||
|
||||
fwc->get_dev_path = spapr_get_fw_dev_path;
|
||||
nc->nmi_monitor_handler = spapr_nmi;
|
||||
@@ -1678,6 +1696,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
||||
static const TypeInfo spapr_machine_info = {
|
||||
.name = TYPE_SPAPR_MACHINE,
|
||||
.parent = TYPE_MACHINE,
|
||||
.abstract = true,
|
||||
.instance_size = sizeof(sPAPRMachineState),
|
||||
.instance_init = spapr_machine_initfn,
|
||||
.class_init = spapr_machine_class_init,
|
||||
@@ -1698,7 +1717,6 @@ static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
mc->name = "pseries-2.1";
|
||||
mc->desc = "pSeries Logical Partition (PAPR compliant) v2.1";
|
||||
mc->is_default = 0;
|
||||
mc->compat_props = compat_props;
|
||||
}
|
||||
|
||||
@@ -1708,10 +1726,27 @@ static const TypeInfo spapr_machine_2_1_info = {
|
||||
.class_init = spapr_machine_2_1_class_init,
|
||||
};
|
||||
|
||||
static void spapr_machine_2_2_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
mc->name = "pseries-2.2";
|
||||
mc->desc = "pSeries Logical Partition (PAPR compliant) v2.2";
|
||||
mc->alias = "pseries";
|
||||
mc->is_default = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo spapr_machine_2_2_info = {
|
||||
.name = TYPE_SPAPR_MACHINE "2.2",
|
||||
.parent = TYPE_SPAPR_MACHINE,
|
||||
.class_init = spapr_machine_2_2_class_init,
|
||||
};
|
||||
|
||||
static void spapr_machine_register_types(void)
|
||||
{
|
||||
type_register_static(&spapr_machine_info);
|
||||
type_register_static(&spapr_machine_2_1_info);
|
||||
type_register_static(&spapr_machine_2_2_info);
|
||||
}
|
||||
|
||||
type_init(spapr_machine_register_types)
|
||||
|
@@ -704,28 +704,34 @@ static const VMStateDescription vmstate_spapr_pci_msi = {
|
||||
},
|
||||
};
|
||||
|
||||
static void spapr_pci_fill_msi_devs(gpointer key, gpointer value,
|
||||
gpointer opaque)
|
||||
{
|
||||
sPAPRPHBState *sphb = opaque;
|
||||
|
||||
sphb->msi_devs[sphb->msi_devs_num].key = *(uint32_t *)key;
|
||||
sphb->msi_devs[sphb->msi_devs_num].value = *(spapr_pci_msi *)value;
|
||||
sphb->msi_devs_num++;
|
||||
}
|
||||
|
||||
static void spapr_pci_pre_save(void *opaque)
|
||||
{
|
||||
sPAPRPHBState *sphb = opaque;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
int i;
|
||||
int msi_devs_num;
|
||||
|
||||
if (sphb->msi_devs) {
|
||||
g_free(sphb->msi_devs);
|
||||
sphb->msi_devs = NULL;
|
||||
}
|
||||
sphb->msi_devs_num = g_hash_table_size(sphb->msi);
|
||||
if (!sphb->msi_devs_num) {
|
||||
sphb->msi_devs_num = 0;
|
||||
msi_devs_num = g_hash_table_size(sphb->msi);
|
||||
if (!msi_devs_num) {
|
||||
return;
|
||||
}
|
||||
sphb->msi_devs = g_malloc(sphb->msi_devs_num * sizeof(spapr_pci_msi_mig));
|
||||
sphb->msi_devs = g_malloc(msi_devs_num * sizeof(spapr_pci_msi_mig));
|
||||
|
||||
g_hash_table_iter_init(&iter, sphb->msi);
|
||||
for (i = 0; g_hash_table_iter_next(&iter, &key, &value); ++i) {
|
||||
sphb->msi_devs[i].key = *(uint32_t *) key;
|
||||
sphb->msi_devs[i].value = *(spapr_pci_msi *) value;
|
||||
}
|
||||
g_hash_table_foreach(sphb->msi, spapr_pci_fill_msi_devs, sphb);
|
||||
assert(sphb->msi_devs_num == msi_devs_num);
|
||||
}
|
||||
|
||||
static int spapr_pci_post_load(void *opaque, int version_id)
|
||||
|
@@ -268,6 +268,9 @@ static void esp_pci_dma_memory_rw(PCIESPState *pci, uint8_t *buf, int len,
|
||||
/* update status registers */
|
||||
pci->dma_regs[DMA_WBC] -= len;
|
||||
pci->dma_regs[DMA_WAC] += len;
|
||||
if (pci->dma_regs[DMA_WBC] == 0) {
|
||||
pci->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void esp_pci_dma_memory_read(void *opaque, uint8_t *buf, int len)
|
||||
|
@@ -364,7 +364,7 @@ void esp_hard_reset(ESPState *s)
|
||||
{
|
||||
memset(s->rregs, 0, ESP_REGS);
|
||||
memset(s->wregs, 0, ESP_REGS);
|
||||
s->rregs[ESP_TCHI] = s->chip_id;
|
||||
s->tchi_written = 0;
|
||||
s->ti_size = 0;
|
||||
s->ti_rptr = 0;
|
||||
s->ti_wptr = 0;
|
||||
@@ -422,6 +422,11 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
|
||||
esp_lower_irq(s);
|
||||
|
||||
return old_val;
|
||||
case ESP_TCHI:
|
||||
/* Return the unique id if the value has never been written */
|
||||
if (!s->tchi_written) {
|
||||
return s->chip_id;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -432,9 +437,11 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
|
||||
{
|
||||
trace_esp_mem_writeb(saddr, s->wregs[saddr], val);
|
||||
switch (saddr) {
|
||||
case ESP_TCHI:
|
||||
s->tchi_written = true;
|
||||
/* fall through */
|
||||
case ESP_TCLO:
|
||||
case ESP_TCMID:
|
||||
case ESP_TCHI:
|
||||
s->rregs[ESP_RSTAT] &= ~STAT_TC;
|
||||
break;
|
||||
case ESP_FIFO:
|
||||
|
@@ -233,6 +233,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
|
||||
vhost_dummy_handle_output);
|
||||
if (err != NULL) {
|
||||
error_propagate(errp, err);
|
||||
close(vhostfd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -92,9 +92,14 @@ VirtIOSCSIReq *virtio_scsi_pop_req_vring(VirtIOSCSI *s,
|
||||
|
||||
void virtio_scsi_vring_push_notify(VirtIOSCSIReq *req)
|
||||
{
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(req->vring->parent);
|
||||
|
||||
vring_push(&req->vring->vring, &req->elem,
|
||||
req->qsgl.size + req->resp_iov.size);
|
||||
event_notifier_set(&req->vring->guest_notifier);
|
||||
|
||||
if (vring_should_notify(vdev, &req->vring->vring)) {
|
||||
event_notifier_set(&req->vring->guest_notifier);
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_scsi_iothread_handle_ctrl(EventNotifier *notifier)
|
||||
@@ -230,7 +235,7 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s)
|
||||
if (!s->event_vring) {
|
||||
goto fail_vrings;
|
||||
}
|
||||
s->cmd_vrings = g_malloc0(sizeof(VirtIOSCSIVring) * vs->conf.num_queues);
|
||||
s->cmd_vrings = g_new(VirtIOSCSIVring *, vs->conf.num_queues);
|
||||
for (i = 0; i < vs->conf.num_queues; i++) {
|
||||
s->cmd_vrings[i] =
|
||||
virtio_scsi_vring_init(s, vs->cmd_vqs[i],
|
||||
|
@@ -118,6 +118,7 @@ static size_t qemu_sgl_concat(VirtIOSCSIReq *req, struct iovec *iov,
|
||||
static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
|
||||
unsigned req_size, unsigned resp_size)
|
||||
{
|
||||
VirtIODevice *vdev = (VirtIODevice *) req->dev;
|
||||
size_t in_size, out_size;
|
||||
|
||||
if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0,
|
||||
@@ -130,8 +131,24 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
|
||||
resp_size) < resp_size) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
req->resp_size = resp_size;
|
||||
|
||||
/* Old BIOSes left some padding by mistake after the req_size/resp_size.
|
||||
* As a workaround, always consider the first buffer as the virtio-scsi
|
||||
* request/response, making the payload start at the second element
|
||||
* of the iovec.
|
||||
*
|
||||
* The actual length of the response header, stored in req->resp_size,
|
||||
* does not change.
|
||||
*
|
||||
* TODO: always disable this workaround for virtio 1.0 devices.
|
||||
*/
|
||||
if ((vdev->guest_features & VIRTIO_F_ANY_LAYOUT) == 0) {
|
||||
req_size = req->elem.out_sg[0].iov_len;
|
||||
resp_size = req->elem.in_sg[0].iov_len;
|
||||
}
|
||||
|
||||
out_size = qemu_sgl_concat(req, req->elem.out_sg,
|
||||
&req->elem.out_addr[0], req->elem.out_num,
|
||||
req_size);
|
||||
|
@@ -608,6 +608,7 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
|
||||
USBDevice *dev;
|
||||
USBEndpoint *uep;
|
||||
int idx = epnum && dir;
|
||||
int id;
|
||||
int ttype;
|
||||
|
||||
/* ep->type[0,1] contains:
|
||||
@@ -625,8 +626,11 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
|
||||
/* A wild guess on the FADDR semantics... */
|
||||
dev = usb_find_device(&s->port, ep->faddr[idx]);
|
||||
uep = usb_ep_get(dev, pid, ep->type[idx] & 0xf);
|
||||
usb_packet_setup(&ep->packey[dir].p, pid, uep, 0,
|
||||
(dev->addr << 16) | (uep->nr << 8) | pid, false, true);
|
||||
id = pid;
|
||||
if (uep) {
|
||||
id |= (dev->addr << 16) | (uep->nr << 8);
|
||||
}
|
||||
usb_packet_setup(&ep->packey[dir].p, pid, uep, 0, id, false, true);
|
||||
usb_packet_addbuf(&ep->packey[dir].p, ep->buf[idx], len);
|
||||
ep->packey[dir].ep = ep;
|
||||
ep->packey[dir].dir = dir;
|
||||
|
@@ -2262,6 +2262,9 @@ static USBPort *xhci_lookup_uport(XHCIState *xhci, uint32_t *slot_ctx)
|
||||
int i, pos, port;
|
||||
|
||||
port = (slot_ctx[1]>>16) & 0xFF;
|
||||
if (port < 1 || port > xhci->numports) {
|
||||
return NULL;
|
||||
}
|
||||
port = xhci->ports[port-1].uport->index+1;
|
||||
pos = snprintf(path, sizeof(path), "%d", port);
|
||||
for (i = 0; i < 5; i++) {
|
||||
@@ -3706,6 +3709,12 @@ static int usb_xhci_post_load(void *opaque, int version_id)
|
||||
xhci_mask64(ldq_le_pci_dma(pci_dev, dcbaap + 8 * slotid));
|
||||
xhci_dma_read_u32s(xhci, slot->ctx, slot_ctx, sizeof(slot_ctx));
|
||||
slot->uport = xhci_lookup_uport(xhci, slot_ctx);
|
||||
if (!slot->uport) {
|
||||
/* should not happen, but may trigger on guest bugs */
|
||||
slot->enabled = 0;
|
||||
slot->addressed = 0;
|
||||
continue;
|
||||
}
|
||||
assert(slot->uport && slot->uport->dev);
|
||||
|
||||
for (epid = 1; epid <= 31; epid++) {
|
||||
|
@@ -143,6 +143,12 @@ static void usb_host_attach_kernel(USBHostDevice *s);
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#ifndef LIBUSB_LOG_LEVEL_WARNING /* older libusb didn't define these */
|
||||
#define LIBUSB_LOG_LEVEL_WARNING 2
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#define CONTROL_TIMEOUT 10000 /* 10 sec */
|
||||
#define BULK_TIMEOUT 0 /* unlimited */
|
||||
#define INTR_TIMEOUT 0 /* unlimited */
|
||||
@@ -743,13 +749,13 @@ static void usb_host_speed_compat(USBHostDevice *s)
|
||||
|
||||
udev->speedmask = (1 << udev->speed);
|
||||
if (udev->speed == USB_SPEED_SUPER && compat_high) {
|
||||
udev->speedmask |= USB_SPEED_HIGH;
|
||||
udev->speedmask |= USB_SPEED_MASK_HIGH;
|
||||
}
|
||||
if (udev->speed == USB_SPEED_SUPER && compat_full) {
|
||||
udev->speedmask |= USB_SPEED_FULL;
|
||||
udev->speedmask |= USB_SPEED_MASK_FULL;
|
||||
}
|
||||
if (udev->speed == USB_SPEED_HIGH && compat_full) {
|
||||
udev->speedmask |= USB_SPEED_FULL;
|
||||
udev->speedmask |= USB_SPEED_MASK_FULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -817,10 +817,12 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
|
||||
int i, r;
|
||||
|
||||
if (vhost_set_backend_type(hdev, backend_type) < 0) {
|
||||
close((uintptr_t)opaque);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hdev->vhost_ops->vhost_backend_init(hdev, opaque) < 0) {
|
||||
close((uintptr_t)opaque);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
@@ -113,20 +113,22 @@ static void virtio_rng_save(QEMUFile *f, void *opaque)
|
||||
|
||||
static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
VirtIORNG *vrng = opaque;
|
||||
int ret;
|
||||
|
||||
if (version_id != 1) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return virtio_load(VIRTIO_DEVICE(opaque), f, version_id);
|
||||
}
|
||||
ret = virtio_load(VIRTIO_DEVICE(vrng), f, version_id);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int virtio_rng_load_device(VirtIODevice *vdev, QEMUFile *f,
|
||||
int version_id)
|
||||
{
|
||||
/* We may have an element ready but couldn't process it due to a quota
|
||||
* limit. Make sure to try again after live migration when the quota may
|
||||
* have been reset.
|
||||
*/
|
||||
virtio_rng_process(VIRTIO_RNG(vdev));
|
||||
virtio_rng_process(vrng);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -231,7 +233,6 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data)
|
||||
vdc->realize = virtio_rng_device_realize;
|
||||
vdc->unrealize = virtio_rng_device_unrealize;
|
||||
vdc->get_features = get_features;
|
||||
vdc->load = virtio_rng_load_device;
|
||||
}
|
||||
|
||||
static void virtio_rng_initfn(Object *obj)
|
||||
|
@@ -83,7 +83,9 @@ typedef enum {
|
||||
#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
|
||||
#define BDRV_SECTOR_MASK ~(BDRV_SECTOR_SIZE - 1)
|
||||
|
||||
/* BDRV_BLOCK_DATA: data is read from bs->file or another file
|
||||
/*
|
||||
* Allocation status flags
|
||||
* BDRV_BLOCK_DATA: data is read from bs->file or another file
|
||||
* BDRV_BLOCK_ZERO: sectors read as zero
|
||||
* BDRV_BLOCK_OFFSET_VALID: sector stored in bs->file as raw data
|
||||
* BDRV_BLOCK_ALLOCATED: the content of the block is determined by this
|
||||
|
@@ -26,6 +26,12 @@ typedef struct CPUListState {
|
||||
FILE *file;
|
||||
} CPUListState;
|
||||
|
||||
typedef enum MMUAccessType {
|
||||
MMU_DATA_LOAD = 0,
|
||||
MMU_DATA_STORE = 1,
|
||||
MMU_INST_FETCH = 2
|
||||
} MMUAccessType;
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
|
||||
enum device_endian {
|
||||
|
@@ -333,7 +333,7 @@ extern uintptr_t tci_tb_ptr;
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
|
||||
void phys_mem_set_alloc(void *(*alloc)(size_t));
|
||||
void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align));
|
||||
|
||||
struct MemoryRegion *iotlb_to_region(AddressSpace *as, hwaddr index);
|
||||
bool io_mem_read(struct MemoryRegion *mr, hwaddr addr,
|
||||
|
@@ -146,6 +146,7 @@ struct MemoryRegion {
|
||||
hwaddr addr;
|
||||
void (*destructor)(MemoryRegion *mr);
|
||||
ram_addr_t ram_addr;
|
||||
uint64_t align;
|
||||
bool subpage;
|
||||
bool terminates;
|
||||
bool romd_mode;
|
||||
@@ -838,6 +839,7 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
|
||||
*/
|
||||
ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr);
|
||||
|
||||
uint64_t memory_region_get_alignment(const MemoryRegion *mr);
|
||||
/**
|
||||
* memory_region_del_subregion: Remove a subregion.
|
||||
*
|
||||
|
@@ -49,6 +49,21 @@ static inline bool cpu_physical_memory_get_dirty(ram_addr_t start,
|
||||
return next < end;
|
||||
}
|
||||
|
||||
static inline bool cpu_physical_memory_get_clean(ram_addr_t start,
|
||||
ram_addr_t length,
|
||||
unsigned client)
|
||||
{
|
||||
unsigned long end, page, next;
|
||||
|
||||
assert(client < DIRTY_MEMORY_NUM);
|
||||
|
||||
end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS;
|
||||
page = start >> TARGET_PAGE_BITS;
|
||||
next = find_next_zero_bit(ram_list.dirty_memory[client], end, page);
|
||||
|
||||
return next < end;
|
||||
}
|
||||
|
||||
static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr,
|
||||
unsigned client)
|
||||
{
|
||||
@@ -64,6 +79,16 @@ static inline bool cpu_physical_memory_is_clean(ram_addr_t addr)
|
||||
return !(vga && code && migration);
|
||||
}
|
||||
|
||||
static inline bool cpu_physical_memory_range_includes_clean(ram_addr_t start,
|
||||
ram_addr_t length)
|
||||
{
|
||||
bool vga = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_VGA);
|
||||
bool code = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_CODE);
|
||||
bool migration =
|
||||
cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_MIGRATION);
|
||||
return vga || code || migration;
|
||||
}
|
||||
|
||||
static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr,
|
||||
unsigned client)
|
||||
{
|
||||
|
@@ -36,7 +36,8 @@ struct QEMUMachine {
|
||||
use_sclp:1,
|
||||
no_floppy:1,
|
||||
no_cdrom:1,
|
||||
no_sdcard:1;
|
||||
no_sdcard:1,
|
||||
has_dynamic_sysbus:1;
|
||||
int is_default;
|
||||
const char *default_machine_opts;
|
||||
const char *default_boot_order;
|
||||
@@ -97,7 +98,8 @@ struct MachineClass {
|
||||
use_sclp:1,
|
||||
no_floppy:1,
|
||||
no_cdrom:1,
|
||||
no_sdcard:1;
|
||||
no_sdcard:1,
|
||||
has_dynamic_sysbus:1;
|
||||
int is_default;
|
||||
const char *default_machine_opts;
|
||||
const char *default_boot_order;
|
||||
@@ -115,6 +117,8 @@ struct MachineClass {
|
||||
struct MachineState {
|
||||
/*< private >*/
|
||||
Object parent_obj;
|
||||
Notifier sysbus_notifier;
|
||||
|
||||
/*< public >*/
|
||||
|
||||
char *accel;
|
||||
|
@@ -24,6 +24,8 @@
|
||||
* address space begins.
|
||||
* @hotplug_memory: hotplug memory addess space container
|
||||
* @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling
|
||||
* @enforce_aligned_dimm: check that DIMM's address/size is aligned by
|
||||
* backend's alignment value if provided
|
||||
*/
|
||||
struct PCMachineState {
|
||||
/*< private >*/
|
||||
@@ -37,13 +39,15 @@ struct PCMachineState {
|
||||
ISADevice *rtc;
|
||||
|
||||
uint64_t max_ram_below_4g;
|
||||
bool vmport;
|
||||
OnOffAuto vmport;
|
||||
bool enforce_aligned_dimm;
|
||||
};
|
||||
|
||||
#define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
|
||||
#define PC_MACHINE_MEMHP_REGION_SIZE "hotplug-memory-region-size"
|
||||
#define PC_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g"
|
||||
#define PC_MACHINE_VMPORT "vmport"
|
||||
#define PC_MACHINE_ENFORCE_ALIGNED_DIMM "enforce-aligned-dimm"
|
||||
|
||||
/**
|
||||
* PCMachineClass:
|
||||
|
@@ -59,7 +59,7 @@ extern bool rom_file_has_mr;
|
||||
int rom_add_file(const char *file, const char *fw_dir,
|
||||
hwaddr addr, int32_t bootindex,
|
||||
bool option_rom);
|
||||
void *rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
hwaddr addr, const char *fw_file_name,
|
||||
FWCfgReadCallback fw_callback, void *callback_opaque);
|
||||
int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
||||
|
@@ -72,7 +72,7 @@ typedef struct PCDIMMDeviceClass {
|
||||
|
||||
uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
|
||||
uint64_t address_space_size,
|
||||
uint64_t *hint, uint64_t size,
|
||||
uint64_t *hint, uint64_t align, uint64_t size,
|
||||
Error **errp);
|
||||
|
||||
int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
|
||||
|
57
include/hw/platform-bus.h
Normal file
57
include/hw/platform-bus.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef HW_PLATFORM_BUS_H
|
||||
#define HW_PLATFORM_BUS_H 1
|
||||
|
||||
/*
|
||||
* Platform Bus device to support dynamic Sysbus devices
|
||||
*
|
||||
* Copyright (C) 2014 Freescale Semiconductor, Inc. All rights reserved.
|
||||
*
|
||||
* Author: Alexander Graf, <agraf@suse.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
typedef struct PlatformBusDevice PlatformBusDevice;
|
||||
|
||||
#define TYPE_PLATFORM_BUS_DEVICE "platform-bus-device"
|
||||
#define PLATFORM_BUS_DEVICE(obj) \
|
||||
OBJECT_CHECK(PlatformBusDevice, (obj), TYPE_PLATFORM_BUS_DEVICE)
|
||||
#define PLATFORM_BUS_DEVICE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(PlatformBusDeviceClass, (klass), TYPE_PLATFORM_BUS_DEVICE)
|
||||
#define PLATFORM_BUS_DEVICE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(PlatformBusDeviceClass, (obj), TYPE_PLATFORM_BUS_DEVICE)
|
||||
|
||||
struct PlatformBusDevice {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
Notifier notifier;
|
||||
bool done_gathering;
|
||||
|
||||
/*< public >*/
|
||||
uint32_t mmio_size;
|
||||
MemoryRegion mmio;
|
||||
|
||||
uint32_t num_irqs;
|
||||
qemu_irq *irqs;
|
||||
unsigned long *used_irqs;
|
||||
};
|
||||
|
||||
int platform_bus_get_irqn(PlatformBusDevice *platform_bus, SysBusDevice *sbdev,
|
||||
int n);
|
||||
hwaddr platform_bus_get_mmio_addr(PlatformBusDevice *pbus, SysBusDevice *sbdev,
|
||||
int n);
|
||||
|
||||
#endif /* !HW_PLATFORM_BUS_H */
|
@@ -272,6 +272,7 @@ qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n);
|
||||
void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
|
||||
void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
|
||||
qemu_irq pin);
|
||||
qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n);
|
||||
qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
|
||||
const char *name, int n);
|
||||
|
||||
@@ -364,7 +365,7 @@ extern int qdev_hotplug;
|
||||
|
||||
char *qdev_get_dev_path(DeviceState *dev);
|
||||
|
||||
int qdev_build_hotpluggable_device_list(Object *obj, void *opaque);
|
||||
GSList *qdev_build_hotpluggable_device_list(Object *peripheral);
|
||||
|
||||
void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler,
|
||||
Error **errp);
|
||||
|
@@ -22,6 +22,7 @@ struct ESPState {
|
||||
uint8_t wregs[ESP_REGS];
|
||||
qemu_irq irq;
|
||||
uint8_t chip_id;
|
||||
bool tchi_written;
|
||||
int32_t ti_size;
|
||||
uint32_t ti_rptr, ti_wptr;
|
||||
uint32_t status;
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#define QDEV_MAX_PIO 32
|
||||
|
||||
#define TYPE_SYSTEM_BUS "System"
|
||||
#define SYSTEM_BUS(obj) OBJECT_CHECK(IDEBus, (obj), TYPE_IDE_BUS)
|
||||
#define SYSTEM_BUS(obj) OBJECT_CHECK(BusState, (obj), TYPE_SYSTEM_BUS)
|
||||
|
||||
typedef struct SysBusDevice SysBusDevice;
|
||||
|
||||
@@ -57,6 +57,8 @@ struct SysBusDevice {
|
||||
pio_addr_t pio[QDEV_MAX_PIO];
|
||||
};
|
||||
|
||||
typedef int FindSysbusDeviceFunc(SysBusDevice *sbdev, void *opaque);
|
||||
|
||||
void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory);
|
||||
MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n);
|
||||
void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
|
||||
@@ -64,7 +66,11 @@ void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target);
|
||||
void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
|
||||
|
||||
|
||||
bool sysbus_has_irq(SysBusDevice *dev, int n);
|
||||
bool sysbus_has_mmio(SysBusDevice *dev, unsigned int n);
|
||||
void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
|
||||
bool sysbus_is_irq_connected(SysBusDevice *dev, int n);
|
||||
qemu_irq sysbus_get_connected_irq(SysBusDevice *dev, int n);
|
||||
void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr);
|
||||
void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr,
|
||||
int priority);
|
||||
@@ -72,6 +78,9 @@ void sysbus_add_io(SysBusDevice *dev, hwaddr addr,
|
||||
MemoryRegion *mem);
|
||||
MemoryRegion *sysbus_address_space(SysBusDevice *dev);
|
||||
|
||||
/* Call func for every dynamically created sysbus device in the system */
|
||||
void foreach_dynamic_sysbus_device(FindSysbusDeviceFunc *func, void *opaque);
|
||||
|
||||
/* Legacy helper function for creating devices. */
|
||||
DeviceState *sysbus_create_varargs(const char *name,
|
||||
hwaddr addr, ...);
|
||||
|
@@ -209,7 +209,8 @@ typedef struct VirtIOSCSIReq {
|
||||
/* Note:
|
||||
* - fields before elem are initialized by virtio_scsi_init_req;
|
||||
* - elem is uninitialized at the time of allocation.
|
||||
* - fields after elem are zeroed by virtio_scsi_init_req.
|
||||
* - fields after elem (except the ending cdb[]) are zeroed by
|
||||
* virtio_scsi_init_req.
|
||||
* */
|
||||
|
||||
VirtQueueElement elem;
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef __OpenBSD__
|
||||
#include <sys/signal.h>
|
||||
@@ -103,7 +104,7 @@ typedef signed int int_fast16_t;
|
||||
int qemu_daemon(int nochdir, int noclose);
|
||||
void *qemu_try_memalign(size_t alignment, size_t size);
|
||||
void *qemu_memalign(size_t alignment, size_t size);
|
||||
void *qemu_anon_ram_alloc(size_t size);
|
||||
void *qemu_anon_ram_alloc(size_t size, uint64_t *align);
|
||||
void qemu_vfree(void *ptr);
|
||||
void qemu_anon_ram_free(void *ptr, size_t size);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user