Compare commits
26 Commits
pull-input
...
prep-for-u
Author | SHA1 | Date | |
---|---|---|---|
|
21143b615a | ||
|
fd3ece2533 | ||
|
2c3445bb85 | ||
|
7602e3e4a3 | ||
|
613c12ec28 | ||
|
5c1e1890bf | ||
|
c2804ee6c0 | ||
|
16c358e96e | ||
|
be813ef02d | ||
|
2a7a1a56d1 | ||
|
5d371f41b4 | ||
|
5223070c47 | ||
|
59ca664ef8 | ||
|
bceae7697f | ||
|
b0b58195e4 | ||
|
6299659f54 | ||
|
b86b05ed60 | ||
|
515b943a91 | ||
|
4b35991a3b | ||
|
dad1fcab91 | ||
|
13f65b2e10 | ||
|
b4e5a4bffd | ||
|
263cf4367f | ||
|
dc65540465 | ||
|
ac41881b48 | ||
|
98bc3ab0f2 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -13,6 +13,9 @@
|
||||
[submodule "roms/openbios"]
|
||||
path = roms/openbios
|
||||
url = git://git.qemu-project.org/openbios.git
|
||||
[submodule "roms/openhackware"]
|
||||
path = roms/openhackware
|
||||
url = git://git.qemu-project.org/openhackware.git
|
||||
[submodule "roms/qemu-palcode"]
|
||||
path = roms/qemu-palcode
|
||||
url = git://github.com/rth7680/qemu-palcode.git
|
||||
|
27
configure
vendored
27
configure
vendored
@@ -31,19 +31,6 @@ printf " '%s'" "$0" "$@" >> config.log
|
||||
echo >> config.log
|
||||
echo "#" >> config.log
|
||||
|
||||
# Save the configure command line for later reuse.
|
||||
cat <<EOD >config.status
|
||||
#!/bin/sh
|
||||
# Generated by configure.
|
||||
# Run this file to recreate the current configuration.
|
||||
# Compiler output produced by configure, useful for debugging
|
||||
# configure, is in config.log if it exists.
|
||||
EOD
|
||||
printf "exec" >>config.status
|
||||
printf " '%s'" "$0" "$@" >>config.status
|
||||
echo >>config.status
|
||||
chmod +x config.status
|
||||
|
||||
error_exit() {
|
||||
echo
|
||||
echo "ERROR: $1"
|
||||
@@ -5146,3 +5133,17 @@ done
|
||||
if test "$docs" = "yes" ; then
|
||||
mkdir -p QMP
|
||||
fi
|
||||
|
||||
# Save the configure command line for later reuse.
|
||||
cat <<EOD >config.status
|
||||
#!/bin/sh
|
||||
# Generated by configure.
|
||||
# Run this file to recreate the current configuration.
|
||||
# Compiler output produced by configure, useful for debugging
|
||||
# configure, is in config.log if it exists.
|
||||
EOD
|
||||
printf "exec" >>config.status
|
||||
printf " '%s'" "$0" "$@" >>config.status
|
||||
echo >>config.status
|
||||
chmod +x config.status
|
||||
|
||||
|
@@ -123,11 +123,12 @@ And it looks like this on the wire:
|
||||
|
||||
Flat union types avoid the nesting on the wire. They are used whenever a
|
||||
specific field of the base type is declared as the discriminator ('type' is
|
||||
then no longer generated). The discriminator must always be a string field.
|
||||
then no longer generated). The discriminator must be of enumeration type.
|
||||
The above example can then be modified as follows:
|
||||
|
||||
{ 'enum': 'BlockdevDriver', 'data': [ 'raw', 'qcow2' ] }
|
||||
{ 'type': 'BlockdevCommonOptions',
|
||||
'data': { 'driver': 'str', 'readonly': 'bool' } }
|
||||
'data': { 'driver': 'BlockdevDriver', 'readonly': 'bool' } }
|
||||
{ 'union': 'BlockdevOptions',
|
||||
'base': 'BlockdevCommonOptions',
|
||||
'discriminator': 'driver',
|
||||
|
@@ -54,7 +54,8 @@
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
bool rom_file_in_ram = true;
|
||||
bool option_rom_has_mr = false;
|
||||
bool rom_file_has_mr = true;
|
||||
|
||||
static int roms_loaded;
|
||||
|
||||
@@ -642,7 +643,8 @@ static void *rom_set_mr(Rom *rom, Object *owner, const char *name)
|
||||
}
|
||||
|
||||
int rom_add_file(const char *file, const char *fw_dir,
|
||||
hwaddr addr, int32_t bootindex)
|
||||
hwaddr addr, int32_t bootindex,
|
||||
bool option_rom)
|
||||
{
|
||||
Rom *rom;
|
||||
int rc, fd = -1;
|
||||
@@ -694,7 +696,7 @@ int rom_add_file(const char *file, const char *fw_dir,
|
||||
basename);
|
||||
snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
|
||||
|
||||
if (rom_file_in_ram) {
|
||||
if ((!option_rom || option_rom_has_mr) && rom_file_has_mr) {
|
||||
data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
|
||||
} else {
|
||||
data = rom->data;
|
||||
@@ -738,7 +740,7 @@ void *rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
|
||||
snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
|
||||
|
||||
if (rom_file_in_ram) {
|
||||
if (rom_file_has_mr) {
|
||||
data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
|
||||
} else {
|
||||
data = rom->data;
|
||||
@@ -773,12 +775,12 @@ int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
||||
|
||||
int rom_add_vga(const char *file)
|
||||
{
|
||||
return rom_add_file(file, "vgaroms", 0, -1);
|
||||
return rom_add_file(file, "vgaroms", 0, -1, true);
|
||||
}
|
||||
|
||||
int rom_add_option(const char *file, int32_t bootindex)
|
||||
{
|
||||
return rom_add_file(file, "genroms", 0, bootindex);
|
||||
return rom_add_file(file, "genroms", 0, bootindex, true);
|
||||
}
|
||||
|
||||
static void rom_reset(void *unused)
|
||||
|
@@ -466,9 +466,15 @@ static void acpi_align_size(GArray *blob, unsigned align)
|
||||
g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align));
|
||||
}
|
||||
|
||||
/* Get pointer within table in a safe manner */
|
||||
#define ACPI_BUILD_PTR(table, size, off, type) \
|
||||
((type *)(acpi_data_get_ptr(table, size, off, sizeof(type))))
|
||||
/* Set a value within table in a safe manner */
|
||||
#define ACPI_BUILD_SET_LE(table, size, off, bits, val) \
|
||||
do { \
|
||||
uint64_t ACPI_BUILD_SET_LE_val = cpu_to_le64(val); \
|
||||
memcpy(acpi_data_get_ptr(table, size, off, \
|
||||
(bits) / BITS_PER_BYTE), \
|
||||
&ACPI_BUILD_SET_LE_val, \
|
||||
(bits) / BITS_PER_BYTE); \
|
||||
} while (0)
|
||||
|
||||
static inline void *acpi_data_get_ptr(uint8_t *table_data, unsigned table_size,
|
||||
unsigned off, unsigned size)
|
||||
@@ -974,22 +980,17 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
|
||||
|
||||
static void patch_pci_windows(PcPciInfo *pci, uint8_t *start, unsigned size)
|
||||
{
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci32_start[0], uint32_t) =
|
||||
cpu_to_le32(pci->w32.begin);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci32_start[0], 32, pci->w32.begin);
|
||||
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci32_end[0], uint32_t) =
|
||||
cpu_to_le32(pci->w32.end - 1);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci32_end[0], 32, pci->w32.end - 1);
|
||||
|
||||
if (pci->w64.end || pci->w64.begin) {
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci64_valid[0], uint8_t) = 1;
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci64_start[0], uint64_t) =
|
||||
cpu_to_le64(pci->w64.begin);
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci64_end[0], uint64_t) =
|
||||
cpu_to_le64(pci->w64.end - 1);
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci64_length[0], uint64_t) =
|
||||
cpu_to_le64(pci->w64.end - pci->w64.begin);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci64_valid[0], 8, 1);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci64_start[0], 64, pci->w64.begin);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci64_end[0], 64, pci->w64.end - 1);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci64_length[0], 64, pci->w64.end - pci->w64.begin);
|
||||
} else {
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci64_valid[0], uint8_t) = 0;
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci64_valid[0], 8, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -266,13 +266,14 @@ static void pc_compat_1_7(QEMUMachineInitArgs *args)
|
||||
{
|
||||
smbios_type1_defaults = false;
|
||||
gigabyte_align = false;
|
||||
option_rom_has_mr = true;
|
||||
}
|
||||
|
||||
static void pc_compat_1_6(QEMUMachineInitArgs *args)
|
||||
{
|
||||
pc_compat_1_7(args);
|
||||
has_pci_info = false;
|
||||
rom_file_in_ram = false;
|
||||
rom_file_has_mr = false;
|
||||
has_acpi_build = false;
|
||||
}
|
||||
|
||||
|
@@ -244,13 +244,14 @@ static void pc_compat_1_7(QEMUMachineInitArgs *args)
|
||||
{
|
||||
smbios_type1_defaults = false;
|
||||
gigabyte_align = false;
|
||||
option_rom_has_mr = true;
|
||||
}
|
||||
|
||||
static void pc_compat_1_6(QEMUMachineInitArgs *args)
|
||||
{
|
||||
pc_compat_1_7(args);
|
||||
has_pci_info = false;
|
||||
rom_file_in_ram = false;
|
||||
rom_file_has_mr = false;
|
||||
has_acpi_build = false;
|
||||
}
|
||||
|
||||
|
@@ -272,7 +272,7 @@ static void mch_update_smram(MCHPCIState *mch)
|
||||
PCIDevice *pd = PCI_DEVICE(mch);
|
||||
|
||||
memory_region_transaction_begin();
|
||||
smram_update(&mch->smram_region, pd->config[MCH_HOST_BRDIGE_SMRAM],
|
||||
smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM],
|
||||
mch->smm_enabled);
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
@@ -283,7 +283,7 @@ static void mch_set_smm(int smm, void *arg)
|
||||
PCIDevice *pd = PCI_DEVICE(mch);
|
||||
|
||||
memory_region_transaction_begin();
|
||||
smram_set_smm(&mch->smm_enabled, smm, pd->config[MCH_HOST_BRDIGE_SMRAM],
|
||||
smram_set_smm(&mch->smm_enabled, smm, pd->config[MCH_HOST_BRIDGE_SMRAM],
|
||||
&mch->smram_region);
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
@@ -306,8 +306,8 @@ static void mch_write_config(PCIDevice *d,
|
||||
mch_update_pciexbar(mch);
|
||||
}
|
||||
|
||||
if (ranges_overlap(address, len, MCH_HOST_BRDIGE_SMRAM,
|
||||
MCH_HOST_BRDIGE_SMRAM_SIZE)) {
|
||||
if (ranges_overlap(address, len, MCH_HOST_BRIDGE_SMRAM,
|
||||
MCH_HOST_BRIDGE_SMRAM_SIZE)) {
|
||||
mch_update_smram(mch);
|
||||
}
|
||||
}
|
||||
@@ -347,7 +347,7 @@ static void mch_reset(DeviceState *qdev)
|
||||
pci_set_quad(d->config + MCH_HOST_BRIDGE_PCIEXBAR,
|
||||
MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT);
|
||||
|
||||
d->config[MCH_HOST_BRDIGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
|
||||
d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
|
||||
|
||||
mch_update(mch);
|
||||
}
|
||||
|
@@ -102,7 +102,7 @@ Object *ich9_lpc_find(void);
|
||||
#define ICH9_USB_UHCI1_DEV 29
|
||||
#define ICH9_USB_UHCI1_FUNC 0
|
||||
|
||||
/* D30:F0 DMI-to-PCI brdige */
|
||||
/* D30:F0 DMI-to-PCI bridge */
|
||||
#define ICH9_D2P_BRIDGE "ICH9 D2P BRIDGE"
|
||||
#define ICH9_D2P_BRIDGE_SAVEVM_VERSION 0
|
||||
|
||||
|
@@ -49,10 +49,12 @@ void pstrcpy_targphys(const char *name,
|
||||
hwaddr dest, int buf_size,
|
||||
const char *source);
|
||||
|
||||
extern bool rom_file_in_ram;
|
||||
extern bool option_rom_has_mr;
|
||||
extern bool rom_file_has_mr;
|
||||
|
||||
int rom_add_file(const char *file, const char *fw_dir,
|
||||
hwaddr addr, int32_t bootindex);
|
||||
hwaddr addr, int32_t bootindex,
|
||||
bool option_rom);
|
||||
void *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);
|
||||
@@ -66,7 +68,7 @@ void *rom_ptr(hwaddr addr);
|
||||
void do_info_roms(Monitor *mon, const QDict *qdict);
|
||||
|
||||
#define rom_add_file_fixed(_f, _a, _i) \
|
||||
rom_add_file(_f, NULL, _a, _i)
|
||||
rom_add_file(_f, NULL, _a, _i, false)
|
||||
#define rom_add_blob_fixed(_f, _b, _l, _a) \
|
||||
rom_add_blob(_f, _b, _l, _a, NULL, NULL, NULL)
|
||||
|
||||
|
@@ -125,8 +125,8 @@ typedef struct Q35PCIHost {
|
||||
#define MCH_HOST_BRIDGE_PAM_RE ((uint8_t)0x1)
|
||||
#define MCH_HOST_BRIDGE_PAM_MASK ((uint8_t)0x3)
|
||||
|
||||
#define MCH_HOST_BRDIGE_SMRAM 0x9d
|
||||
#define MCH_HOST_BRDIGE_SMRAM_SIZE 1
|
||||
#define MCH_HOST_BRIDGE_SMRAM 0x9d
|
||||
#define MCH_HOST_BRIDGE_SMRAM_SIZE 1
|
||||
#define MCH_HOST_BRIDGE_SMRAM_DEFAULT ((uint8_t)0x2)
|
||||
#define MCH_HOST_BRIDGE_SMRAM_D_OPEN ((uint8_t)(1 << 6))
|
||||
#define MCH_HOST_BRIDGE_SMRAM_D_CLS ((uint8_t)(1 << 5))
|
||||
@@ -140,16 +140,16 @@ typedef struct Q35PCIHost {
|
||||
#define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END 0x100000
|
||||
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC 0x9e
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 6))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_E_SMERR ((uint8_t)(1 << 5))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_SM_CACHE ((uint8_t)(1 << 4))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_SM_L1 ((uint8_t)(1 << 3))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_SM_L2 ((uint8_t)(1 << 2))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_MASK ((uint8_t)(0x3 << 1))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_1MB ((uint8_t)(0x0 << 1))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_2MB ((uint8_t)(0x1 << 1))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_8MB ((uint8_t)(0x2 << 1))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_T_EN ((uint8_t)1)
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 6))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_E_SMERR ((uint8_t)(1 << 5))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE ((uint8_t)(1 << 4))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_SM_L1 ((uint8_t)(1 << 3))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_SM_L2 ((uint8_t)(1 << 2))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK ((uint8_t)(0x3 << 1))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB ((uint8_t)(0x0 << 1))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB ((uint8_t)(0x1 << 1))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB ((uint8_t)(0x2 << 1))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_T_EN ((uint8_t)1)
|
||||
|
||||
/* D1:F0 PCIE* port*/
|
||||
#define MCH_PCIE_DEV 1
|
||||
|
@@ -159,7 +159,7 @@ void qerror_report_err(Error *err);
|
||||
ERROR_CLASS_GENERIC_ERROR, "Invalid JSON syntax"
|
||||
|
||||
#define QERR_KVM_MISSING_CAP \
|
||||
ERROR_CLASS_K_V_M_MISSING_CAP, "Using KVM without %s, %s unavailable"
|
||||
ERROR_CLASS_KVM_MISSING_CAP, "Using KVM without %s, %s unavailable"
|
||||
|
||||
#define QERR_MIGRATION_ACTIVE \
|
||||
ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress"
|
||||
|
@@ -529,7 +529,8 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
|
||||
"state directory=%s\n"
|
||||
"log file=%s/log.smbd\n"
|
||||
"smb passwd file=%s/smbpasswd\n"
|
||||
"security = share\n"
|
||||
"security = user\n"
|
||||
"map to guest = Bad User\n"
|
||||
"[qemu]\n"
|
||||
"path=%s\n"
|
||||
"read only=no\n"
|
||||
@@ -549,7 +550,8 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
|
||||
snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
|
||||
CONFIG_SMBD_COMMAND, smb_conf);
|
||||
|
||||
if (slirp_add_exec(s->slirp, 0, smb_cmdline, &vserver_addr, 139) < 0) {
|
||||
if (slirp_add_exec(s->slirp, 0, smb_cmdline, &vserver_addr, 139) < 0 ||
|
||||
slirp_add_exec(s->slirp, 0, smb_cmdline, &vserver_addr, 445) < 0) {
|
||||
slirp_smb_cleanup(s);
|
||||
error_report("conflicting/invalid smbserver address");
|
||||
return -1;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
project (http://www.nongnu.org/vgabios/).
|
||||
|
||||
- The PowerPC Open Hack'Ware Open Firmware Compatible BIOS is
|
||||
available at http://perso.magic.fr/l_indien/OpenHackWare/index.htm.
|
||||
available at http://repo.or.cz/w/openhackware.git.
|
||||
|
||||
- OpenBIOS (http://www.openbios.org/) is a free (GPL v2) portable
|
||||
firmware implementation. The goal is to implement a 100% IEEE
|
||||
|
1843
pc-bios/ohw.diff
1843
pc-bios/ohw.diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -4248,6 +4248,18 @@
|
||||
'*direct': 'bool',
|
||||
'*no-flush': 'bool' } }
|
||||
|
||||
##
|
||||
# @BlockdevDriver
|
||||
#
|
||||
# Drivers that are supported in block device operations.
|
||||
#
|
||||
# Since: 2.0
|
||||
##
|
||||
{ 'enum': 'BlockdevDriver',
|
||||
'data': [ 'file', 'http', 'https', 'ftp', 'ftps', 'tftp', 'vvfat', 'blkdebug',
|
||||
'blkverify', 'bochs', 'cloop', 'cow', 'dmg', 'parallels', 'qcow',
|
||||
'qcow2', 'qed', 'raw', 'vdi', 'vhdx', 'vmdk', 'vpc', 'quorum' ] }
|
||||
|
||||
##
|
||||
# @BlockdevOptionsBase
|
||||
#
|
||||
@@ -4272,7 +4284,7 @@
|
||||
# Since: 1.7
|
||||
##
|
||||
{ 'type': 'BlockdevOptionsBase',
|
||||
'data': { 'driver': 'str',
|
||||
'data': { 'driver': 'BlockdevDriver',
|
||||
'*id': 'str',
|
||||
'*node-name': 'str',
|
||||
'*discard': 'BlockdevDiscardOptions',
|
||||
|
1
roms/openhackware
Submodule
1
roms/openhackware
Submodule
Submodule roms/openhackware added at e9829b5584
@@ -127,16 +127,6 @@ const char *%(name)s_lookup[] = {
|
||||
''')
|
||||
return ret
|
||||
|
||||
def generate_enum_name(name):
|
||||
if name.isupper():
|
||||
return c_fun(name, False)
|
||||
new_name = ''
|
||||
for c in c_fun(name, False):
|
||||
if c.isupper():
|
||||
new_name += '_'
|
||||
new_name += c
|
||||
return new_name.lstrip('_').upper()
|
||||
|
||||
def generate_enum(name, values):
|
||||
lookup_decl = mcgen('''
|
||||
extern const char *%(name)s_lookup[];
|
||||
@@ -154,11 +144,11 @@ typedef enum %(name)s
|
||||
|
||||
i = 0
|
||||
for value in enum_values:
|
||||
enum_full_value = generate_enum_full_value(name, value)
|
||||
enum_decl += mcgen('''
|
||||
%(abbrev)s_%(value)s = %(i)d,
|
||||
%(enum_full_value)s = %(i)d,
|
||||
''',
|
||||
abbrev=de_camel_case(name).upper(),
|
||||
value=generate_enum_name(value),
|
||||
enum_full_value = enum_full_value,
|
||||
i=i)
|
||||
i += 1
|
||||
|
||||
@@ -211,14 +201,21 @@ def generate_union(expr):
|
||||
base = expr.get('base')
|
||||
discriminator = expr.get('discriminator')
|
||||
|
||||
enum_define = discriminator_find_enum_define(expr)
|
||||
if enum_define:
|
||||
discriminator_type_name = enum_define['enum_name']
|
||||
else:
|
||||
discriminator_type_name = '%sKind' % (name)
|
||||
|
||||
ret = mcgen('''
|
||||
struct %(name)s
|
||||
{
|
||||
%(name)sKind kind;
|
||||
%(discriminator_type_name)s kind;
|
||||
union {
|
||||
void *data;
|
||||
''',
|
||||
name=name)
|
||||
name=name,
|
||||
discriminator_type_name=discriminator_type_name)
|
||||
|
||||
for key in typeinfo:
|
||||
ret += mcgen('''
|
||||
@@ -399,8 +396,11 @@ for expr in exprs:
|
||||
fdef.write(generate_enum_lookup(expr['enum'], expr['data']))
|
||||
elif expr.has_key('union'):
|
||||
ret += generate_fwd_struct(expr['union'], expr['data']) + "\n"
|
||||
ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
|
||||
fdef.write(generate_enum_lookup('%sKind' % expr['union'], expr['data'].keys()))
|
||||
enum_define = discriminator_find_enum_define(expr)
|
||||
if not enum_define:
|
||||
ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
|
||||
fdef.write(generate_enum_lookup('%sKind' % expr['union'],
|
||||
expr['data'].keys()))
|
||||
if expr.get('discriminator') == {}:
|
||||
fdef.write(generate_anon_union_qtypes(expr))
|
||||
else:
|
||||
|
@@ -214,18 +214,22 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
|
||||
''',
|
||||
name=name)
|
||||
|
||||
# For anon union, always use the default enum type automatically generated
|
||||
# as "'%sKind' % (name)"
|
||||
disc_type = '%sKind' % (name)
|
||||
|
||||
for key in members:
|
||||
assert (members[key] in builtin_types
|
||||
or find_struct(members[key])
|
||||
or find_union(members[key])), "Invalid anonymous union member"
|
||||
|
||||
enum_full_value = generate_enum_full_value(disc_type, key)
|
||||
ret += mcgen('''
|
||||
case %(abbrev)s_KIND_%(enum)s:
|
||||
case %(enum_full_value)s:
|
||||
visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, name, &err);
|
||||
break;
|
||||
''',
|
||||
abbrev = de_camel_case(name).upper(),
|
||||
enum = c_fun(de_camel_case(key),False).upper(),
|
||||
enum_full_value = enum_full_value,
|
||||
c_type = type_name(members[key]),
|
||||
c_name = c_fun(key))
|
||||
|
||||
@@ -255,7 +259,16 @@ def generate_visit_union(expr):
|
||||
assert not base
|
||||
return generate_visit_anon_union(name, members)
|
||||
|
||||
ret = generate_visit_enum('%sKind' % name, members.keys())
|
||||
enum_define = discriminator_find_enum_define(expr)
|
||||
if enum_define:
|
||||
# Use the enum type as discriminator
|
||||
ret = ""
|
||||
disc_type = enum_define['enum_name']
|
||||
else:
|
||||
# There will always be a discriminator in the C switch code, by default it
|
||||
# is an enum type generated silently as "'%sKind' % (name)"
|
||||
ret = generate_visit_enum('%sKind' % name, members.keys())
|
||||
disc_type = '%sKind' % (name)
|
||||
|
||||
if base:
|
||||
base_fields = find_struct(base)['data']
|
||||
@@ -291,15 +304,16 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
|
||||
pop_indent()
|
||||
|
||||
if not discriminator:
|
||||
desc_type = "type"
|
||||
disc_key = "type"
|
||||
else:
|
||||
desc_type = discriminator
|
||||
disc_key = discriminator
|
||||
ret += mcgen('''
|
||||
visit_type_%(name)sKind(m, &(*obj)->kind, "%(type)s", &err);
|
||||
visit_type_%(disc_type)s(m, &(*obj)->kind, "%(disc_key)s", &err);
|
||||
if (!err) {
|
||||
switch ((*obj)->kind) {
|
||||
''',
|
||||
name=name, type=desc_type)
|
||||
disc_type = disc_type,
|
||||
disc_key = disc_key)
|
||||
|
||||
for key in members:
|
||||
if not discriminator:
|
||||
@@ -313,13 +327,13 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
|
||||
visit_end_implicit_struct(m, &err);
|
||||
}'''
|
||||
|
||||
enum_full_value = generate_enum_full_value(disc_type, key)
|
||||
ret += mcgen('''
|
||||
case %(abbrev)s_KIND_%(enum)s:
|
||||
case %(enum_full_value)s:
|
||||
''' + fmt + '''
|
||||
break;
|
||||
''',
|
||||
abbrev = de_camel_case(name).upper(),
|
||||
enum = c_fun(de_camel_case(key),False).upper(),
|
||||
enum_full_value = enum_full_value,
|
||||
c_type=type_name(members[key]),
|
||||
c_name=c_fun(key))
|
||||
|
||||
@@ -510,7 +524,11 @@ for expr in exprs:
|
||||
ret += generate_visit_list(expr['union'], expr['data'])
|
||||
fdef.write(ret)
|
||||
|
||||
ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys())
|
||||
enum_define = discriminator_find_enum_define(expr)
|
||||
ret = ""
|
||||
if not enum_define:
|
||||
ret = generate_decl_enum('%sKind' % expr['union'],
|
||||
expr['data'].keys())
|
||||
ret += generate_declaration(expr['union'], expr['data'])
|
||||
fdecl.write(ret)
|
||||
elif expr.has_key('enum'):
|
||||
|
179
scripts/qapi.py
179
scripts/qapi.py
@@ -39,12 +39,10 @@ class QAPISchemaError(Exception):
|
||||
def __init__(self, schema, msg):
|
||||
self.fp = schema.fp
|
||||
self.msg = msg
|
||||
self.line = self.col = 1
|
||||
for ch in schema.src[0:schema.pos]:
|
||||
if ch == '\n':
|
||||
self.line += 1
|
||||
self.col = 1
|
||||
elif ch == '\t':
|
||||
self.col = 1
|
||||
self.line = schema.line
|
||||
for ch in schema.src[schema.line_pos:schema.pos]:
|
||||
if ch == '\t':
|
||||
self.col = (self.col + 7) % 8 + 1
|
||||
else:
|
||||
self.col += 1
|
||||
@@ -52,6 +50,15 @@ class QAPISchemaError(Exception):
|
||||
def __str__(self):
|
||||
return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col, self.msg)
|
||||
|
||||
class QAPIExprError(Exception):
|
||||
def __init__(self, expr_info, msg):
|
||||
self.fp = expr_info['fp']
|
||||
self.line = expr_info['line']
|
||||
self.msg = msg
|
||||
|
||||
def __str__(self):
|
||||
return "%s:%s: %s" % (self.fp.name, self.line, self.msg)
|
||||
|
||||
class QAPISchema:
|
||||
|
||||
def __init__(self, fp):
|
||||
@@ -60,11 +67,16 @@ class QAPISchema:
|
||||
if self.src == '' or self.src[-1] != '\n':
|
||||
self.src += '\n'
|
||||
self.cursor = 0
|
||||
self.line = 1
|
||||
self.line_pos = 0
|
||||
self.exprs = []
|
||||
self.accept()
|
||||
|
||||
while self.tok != None:
|
||||
self.exprs.append(self.get_expr(False))
|
||||
expr_info = {'fp': fp, 'line': self.line}
|
||||
expr_elem = {'expr': self.get_expr(False),
|
||||
'info': expr_info}
|
||||
self.exprs.append(expr_elem)
|
||||
|
||||
def accept(self):
|
||||
while True:
|
||||
@@ -100,6 +112,8 @@ class QAPISchema:
|
||||
if self.cursor == len(self.src):
|
||||
self.tok = None
|
||||
return
|
||||
self.line += 1
|
||||
self.line_pos = self.cursor
|
||||
elif not self.tok.isspace():
|
||||
raise QAPISchemaError(self, 'Stray "%s"' % self.tok)
|
||||
|
||||
@@ -116,6 +130,8 @@ class QAPISchema:
|
||||
if self.tok != ':':
|
||||
raise QAPISchemaError(self, 'Expected ":"')
|
||||
self.accept()
|
||||
if key in expr:
|
||||
raise QAPISchemaError(self, 'Duplicate key "%s"' % key)
|
||||
expr[key] = self.get_expr(True)
|
||||
if self.tok == '}':
|
||||
self.accept()
|
||||
@@ -158,6 +174,95 @@ class QAPISchema:
|
||||
raise QAPISchemaError(self, 'Expected "{", "[" or string')
|
||||
return expr
|
||||
|
||||
def find_base_fields(base):
|
||||
base_struct_define = find_struct(base)
|
||||
if not base_struct_define:
|
||||
return None
|
||||
return base_struct_define['data']
|
||||
|
||||
# Return the discriminator enum define if discriminator is specified as an
|
||||
# enum type, otherwise return None.
|
||||
def discriminator_find_enum_define(expr):
|
||||
base = expr.get('base')
|
||||
discriminator = expr.get('discriminator')
|
||||
|
||||
if not (discriminator and base):
|
||||
return None
|
||||
|
||||
base_fields = find_base_fields(base)
|
||||
if not base_fields:
|
||||
return None
|
||||
|
||||
discriminator_type = base_fields.get(discriminator)
|
||||
if not discriminator_type:
|
||||
return None
|
||||
|
||||
return find_enum(discriminator_type)
|
||||
|
||||
def check_union(expr, expr_info):
|
||||
name = expr['union']
|
||||
base = expr.get('base')
|
||||
discriminator = expr.get('discriminator')
|
||||
members = expr['data']
|
||||
|
||||
# If the object has a member 'base', its value must name a complex type.
|
||||
if base:
|
||||
base_fields = find_base_fields(base)
|
||||
if not base_fields:
|
||||
raise QAPIExprError(expr_info,
|
||||
"Base '%s' is not a valid type"
|
||||
% base)
|
||||
|
||||
# If the union object has no member 'discriminator', it's an
|
||||
# ordinary union.
|
||||
if not discriminator:
|
||||
enum_define = None
|
||||
|
||||
# Else if the value of member 'discriminator' is {}, it's an
|
||||
# anonymous union.
|
||||
elif discriminator == {}:
|
||||
enum_define = None
|
||||
|
||||
# Else, it's a flat union.
|
||||
else:
|
||||
# The object must have a member 'base'.
|
||||
if not base:
|
||||
raise QAPIExprError(expr_info,
|
||||
"Flat union '%s' must have a base field"
|
||||
% name)
|
||||
# The value of member 'discriminator' must name a member of the
|
||||
# base type.
|
||||
discriminator_type = base_fields.get(discriminator)
|
||||
if not discriminator_type:
|
||||
raise QAPIExprError(expr_info,
|
||||
"Discriminator '%s' is not a member of base "
|
||||
"type '%s'"
|
||||
% (discriminator, base))
|
||||
enum_define = find_enum(discriminator_type)
|
||||
# Do not allow string discriminator
|
||||
if not enum_define:
|
||||
raise QAPIExprError(expr_info,
|
||||
"Discriminator '%s' must be of enumeration "
|
||||
"type" % discriminator)
|
||||
|
||||
# Check every branch
|
||||
for (key, value) in members.items():
|
||||
# If this named member's value names an enum type, then all members
|
||||
# of 'data' must also be members of the enum type.
|
||||
if enum_define and not key in enum_define['enum_values']:
|
||||
raise QAPIExprError(expr_info,
|
||||
"Discriminator value '%s' is not found in "
|
||||
"enum '%s'" %
|
||||
(key, enum_define["enum_name"]))
|
||||
# Todo: add checking for values. Key is checked as above, value can be
|
||||
# also checked here, but we need more functions to handle array case.
|
||||
|
||||
def check_exprs(schema):
|
||||
for expr_elem in schema.exprs:
|
||||
expr = expr_elem['expr']
|
||||
if expr.has_key('union'):
|
||||
check_union(expr, expr_elem['info'])
|
||||
|
||||
def parse_schema(fp):
|
||||
try:
|
||||
schema = QAPISchema(fp)
|
||||
@@ -167,16 +272,29 @@ def parse_schema(fp):
|
||||
|
||||
exprs = []
|
||||
|
||||
for expr in schema.exprs:
|
||||
for expr_elem in schema.exprs:
|
||||
expr = expr_elem['expr']
|
||||
if expr.has_key('enum'):
|
||||
add_enum(expr['enum'])
|
||||
add_enum(expr['enum'], expr['data'])
|
||||
elif expr.has_key('union'):
|
||||
add_union(expr)
|
||||
add_enum('%sKind' % expr['union'])
|
||||
elif expr.has_key('type'):
|
||||
add_struct(expr)
|
||||
exprs.append(expr)
|
||||
|
||||
# Try again for hidden UnionKind enum
|
||||
for expr_elem in schema.exprs:
|
||||
expr = expr_elem['expr']
|
||||
if expr.has_key('union'):
|
||||
if not discriminator_find_enum_define(expr):
|
||||
add_enum('%sKind' % expr['union'])
|
||||
|
||||
try:
|
||||
check_exprs(schema)
|
||||
except QAPIExprError, e:
|
||||
print >>sys.stderr, e
|
||||
exit(1)
|
||||
|
||||
return exprs
|
||||
|
||||
def parse_args(typeinfo):
|
||||
@@ -289,13 +407,19 @@ def find_union(name):
|
||||
return union
|
||||
return None
|
||||
|
||||
def add_enum(name):
|
||||
def add_enum(name, enum_values = None):
|
||||
global enum_types
|
||||
enum_types.append(name)
|
||||
enum_types.append({"enum_name": name, "enum_values": enum_values})
|
||||
|
||||
def find_enum(name):
|
||||
global enum_types
|
||||
for enum in enum_types:
|
||||
if enum['enum_name'] == name:
|
||||
return enum
|
||||
return None
|
||||
|
||||
def is_enum(name):
|
||||
global enum_types
|
||||
return (name in enum_types)
|
||||
return find_enum(name) != None
|
||||
|
||||
def c_type(name):
|
||||
if name == 'str':
|
||||
@@ -373,3 +497,30 @@ def guardend(name):
|
||||
|
||||
''',
|
||||
name=guardname(name))
|
||||
|
||||
# ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1
|
||||
# ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2
|
||||
# ENUM24_Name -> ENUM24_NAME
|
||||
def _generate_enum_string(value):
|
||||
c_fun_str = c_fun(value, False)
|
||||
if value.isupper():
|
||||
return c_fun_str
|
||||
|
||||
new_name = ''
|
||||
l = len(c_fun_str)
|
||||
for i in range(l):
|
||||
c = c_fun_str[i]
|
||||
# When c is upper and no "_" appears before, do more checks
|
||||
if c.isupper() and (i > 0) and c_fun_str[i - 1] != "_":
|
||||
# Case 1: next string is lower
|
||||
# Case 2: previous string is digit
|
||||
if (i < (l - 1) and c_fun_str[i + 1].islower()) or \
|
||||
c_fun_str[i - 1].isdigit():
|
||||
new_name += '_'
|
||||
new_name += c
|
||||
return new_name.lstrip('_').upper()
|
||||
|
||||
def generate_enum_full_value(enum_name, enum_value):
|
||||
abbrev_string = _generate_enum_string(enum_name)
|
||||
value_string = _generate_enum_string(enum_value)
|
||||
return "%s_%s" % (abbrev_string, value_string)
|
||||
|
@@ -315,7 +315,7 @@ typedef struct X86RegisterInfo32 {
|
||||
} X86RegisterInfo32;
|
||||
|
||||
#define REGISTER(reg) \
|
||||
[R_##reg] = { .name = #reg, .qapi_enum = X86_C_P_U_REGISTER32_##reg }
|
||||
[R_##reg] = { .name = #reg, .qapi_enum = X86_CPU_REGISTER32_##reg }
|
||||
X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
|
||||
REGISTER(EAX),
|
||||
REGISTER(ECX),
|
||||
|
@@ -458,7 +458,8 @@ static const sparc_def_t sparc_defs[] = {
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
|
||||
CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN,
|
||||
CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN |
|
||||
CPU_FEATURE_CASA,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
@@ -271,6 +271,7 @@ typedef struct sparc_def_t {
|
||||
#define CPU_FEATURE_ASR17 (1 << 15)
|
||||
#define CPU_FEATURE_CACHE_CTRL (1 << 16)
|
||||
#define CPU_FEATURE_POWERDOWN (1 << 17)
|
||||
#define CPU_FEATURE_CASA (1 << 18)
|
||||
|
||||
#ifndef TARGET_SPARC64
|
||||
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
|
||||
@@ -282,7 +283,8 @@ typedef struct sparc_def_t {
|
||||
CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
|
||||
CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
|
||||
CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \
|
||||
CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD)
|
||||
CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD | \
|
||||
CPU_FEATURE_CASA)
|
||||
enum {
|
||||
mmu_us_12, // Ultrasparc < III (64 entry TLB)
|
||||
mmu_us_3, // Ultrasparc III (512 entry TLB)
|
||||
|
@@ -22,7 +22,6 @@ DEF_HELPER_1(popc, tl, tl)
|
||||
DEF_HELPER_4(ldda_asi, void, env, tl, int, int)
|
||||
DEF_HELPER_5(ldf_asi, void, env, tl, int, int, int)
|
||||
DEF_HELPER_5(stf_asi, void, env, tl, int, int, int)
|
||||
DEF_HELPER_5(cas_asi, tl, env, tl, tl, tl, i32)
|
||||
DEF_HELPER_5(casx_asi, tl, env, tl, tl, tl, i32)
|
||||
DEF_HELPER_2(set_softint, void, env, i64)
|
||||
DEF_HELPER_2(clear_softint, void, env, i64)
|
||||
@@ -31,6 +30,9 @@ DEF_HELPER_2(tick_set_count, void, ptr, i64)
|
||||
DEF_HELPER_1(tick_get_count, i64, ptr)
|
||||
DEF_HELPER_2(tick_set_limit, void, ptr, i64)
|
||||
#endif
|
||||
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
|
||||
DEF_HELPER_5(cas_asi, tl, env, tl, tl, tl, i32)
|
||||
#endif
|
||||
DEF_HELPER_3(check_align, void, env, tl, i32)
|
||||
DEF_HELPER_1(debug, void, env)
|
||||
DEF_HELPER_1(save, void, env)
|
||||
|
@@ -584,6 +584,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
|
||||
}
|
||||
break;
|
||||
case 0xb: /* Supervisor data access */
|
||||
case 0x80:
|
||||
switch (size) {
|
||||
case 1:
|
||||
ret = cpu_ldub_kernel(env, addr);
|
||||
@@ -955,6 +956,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int asi,
|
||||
}
|
||||
break;
|
||||
case 0xb: /* Supervisor data access */
|
||||
case 0x80:
|
||||
switch (size) {
|
||||
case 1:
|
||||
cpu_stb_kernel(env, addr, val);
|
||||
@@ -2232,20 +2234,6 @@ void helper_stf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
|
||||
}
|
||||
}
|
||||
|
||||
target_ulong helper_cas_asi(CPUSPARCState *env, target_ulong addr,
|
||||
target_ulong val1, target_ulong val2, uint32_t asi)
|
||||
{
|
||||
target_ulong ret;
|
||||
|
||||
val2 &= 0xffffffffUL;
|
||||
ret = helper_ld_asi(env, addr, asi, 4, 0);
|
||||
ret &= 0xffffffffUL;
|
||||
if (val2 == ret) {
|
||||
helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, 4);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
|
||||
target_ulong val1, target_ulong val2,
|
||||
uint32_t asi)
|
||||
@@ -2260,6 +2248,22 @@ target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
|
||||
}
|
||||
#endif /* TARGET_SPARC64 */
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
|
||||
target_ulong helper_cas_asi(CPUSPARCState *env, target_ulong addr,
|
||||
target_ulong val1, target_ulong val2, uint32_t asi)
|
||||
{
|
||||
target_ulong ret;
|
||||
|
||||
val2 &= 0xffffffffUL;
|
||||
ret = helper_ld_asi(env, addr, asi, 4, 0);
|
||||
ret &= 0xffffffffUL;
|
||||
if (val2 == ret) {
|
||||
helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, 4);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) */
|
||||
|
||||
void helper_ldqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
|
||||
{
|
||||
/* XXX add 128 bit load */
|
||||
|
@@ -2107,18 +2107,6 @@ static inline void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
|
||||
tcg_temp_free_i64(t64);
|
||||
}
|
||||
|
||||
static inline void gen_cas_asi(DisasContext *dc, TCGv addr,
|
||||
TCGv val2, int insn, int rd)
|
||||
{
|
||||
TCGv val1 = gen_load_gpr(dc, rd);
|
||||
TCGv dst = gen_dest_gpr(dc, rd);
|
||||
TCGv_i32 r_asi = gen_get_asi(insn, addr);
|
||||
|
||||
gen_helper_cas_asi(dst, cpu_env, addr, val1, val2, r_asi);
|
||||
tcg_temp_free_i32(r_asi);
|
||||
gen_store_gpr(dc, rd, dst);
|
||||
}
|
||||
|
||||
static inline void gen_casx_asi(DisasContext *dc, TCGv addr,
|
||||
TCGv val2, int insn, int rd)
|
||||
{
|
||||
@@ -2229,6 +2217,22 @@ static inline void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
|
||||
static inline void gen_cas_asi(DisasContext *dc, TCGv addr,
|
||||
TCGv val2, int insn, int rd)
|
||||
{
|
||||
TCGv val1 = gen_load_gpr(dc, rd);
|
||||
TCGv dst = gen_dest_gpr(dc, rd);
|
||||
#ifdef TARGET_SPARC64
|
||||
TCGv_i32 r_asi = gen_get_asi(insn, addr);
|
||||
#else
|
||||
TCGv_i32 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
|
||||
#endif
|
||||
|
||||
gen_helper_cas_asi(dst, cpu_env, addr, val1, val2, r_asi);
|
||||
tcg_temp_free_i32(r_asi);
|
||||
gen_store_gpr(dc, rd, dst);
|
||||
}
|
||||
|
||||
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
|
||||
{
|
||||
TCGv_i64 r_val;
|
||||
@@ -5103,11 +5107,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
|
||||
}
|
||||
gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
|
||||
break;
|
||||
case 0x3c: /* V9 casa */
|
||||
rs2 = GET_FIELD(insn, 27, 31);
|
||||
cpu_src2 = gen_load_gpr(dc, rs2);
|
||||
gen_cas_asi(dc, cpu_addr, cpu_src2, insn, rd);
|
||||
break;
|
||||
case 0x3e: /* V9 casxa */
|
||||
rs2 = GET_FIELD(insn, 27, 31);
|
||||
cpu_src2 = gen_load_gpr(dc, rs2);
|
||||
@@ -5119,6 +5118,22 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
|
||||
case 0x36: /* stdcq */
|
||||
case 0x37: /* stdc */
|
||||
goto ncp_insn;
|
||||
#endif
|
||||
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
|
||||
case 0x3c: /* V9 or LEON3 casa */
|
||||
#ifndef TARGET_SPARC64
|
||||
CHECK_IU_FEATURE(dc, CASA);
|
||||
if (IS_IMM) {
|
||||
goto illegal_insn;
|
||||
}
|
||||
if (!supervisor(dc)) {
|
||||
goto priv_insn;
|
||||
}
|
||||
#endif
|
||||
rs2 = GET_FIELD(insn, 27, 31);
|
||||
cpu_src2 = gen_load_gpr(dc, rs2);
|
||||
gen_cas_asi(dc, cpu_addr, cpu_src2, insn, rd);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
goto illegal_insn;
|
||||
|
@@ -142,7 +142,11 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
|
||||
missing-comma-object.json non-objects.json \
|
||||
qapi-schema-test.json quoted-structural-chars.json \
|
||||
trailing-comma-list.json trailing-comma-object.json \
|
||||
unclosed-list.json unclosed-object.json unclosed-string.json)
|
||||
unclosed-list.json unclosed-object.json unclosed-string.json \
|
||||
duplicate-key.json union-invalid-base.json flat-union-no-base.json \
|
||||
flat-union-invalid-discriminator.json \
|
||||
flat-union-invalid-branch-key.json flat-union-reverse-define.json \
|
||||
flat-union-string-discriminator.json)
|
||||
|
||||
GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])])]
|
||||
['Status']
|
||||
[{'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']}]
|
||||
[]
|
||||
|
1
tests/qapi-schema/duplicate-key.err
Normal file
1
tests/qapi-schema/duplicate-key.err
Normal file
@@ -0,0 +1 @@
|
||||
<stdin>:2:10: Duplicate key "key"
|
1
tests/qapi-schema/duplicate-key.exit
Normal file
1
tests/qapi-schema/duplicate-key.exit
Normal file
@@ -0,0 +1 @@
|
||||
1
|
2
tests/qapi-schema/duplicate-key.json
Normal file
2
tests/qapi-schema/duplicate-key.json
Normal file
@@ -0,0 +1,2 @@
|
||||
{ 'key': 'value',
|
||||
'key': 'value' }
|
0
tests/qapi-schema/duplicate-key.out
Normal file
0
tests/qapi-schema/duplicate-key.out
Normal file
1
tests/qapi-schema/flat-union-invalid-branch-key.err
Normal file
1
tests/qapi-schema/flat-union-invalid-branch-key.err
Normal file
@@ -0,0 +1 @@
|
||||
<stdin>:13: Discriminator value 'value_wrong' is not found in enum 'TestEnum'
|
1
tests/qapi-schema/flat-union-invalid-branch-key.exit
Normal file
1
tests/qapi-schema/flat-union-invalid-branch-key.exit
Normal file
@@ -0,0 +1 @@
|
||||
1
|
17
tests/qapi-schema/flat-union-invalid-branch-key.json
Normal file
17
tests/qapi-schema/flat-union-invalid-branch-key.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{ 'enum': 'TestEnum',
|
||||
'data': [ 'value1', 'value2' ] }
|
||||
|
||||
{ 'type': 'TestBase',
|
||||
'data': { 'enum1': 'TestEnum' } }
|
||||
|
||||
{ 'type': 'TestTypeA',
|
||||
'data': { 'string': 'str' } }
|
||||
|
||||
{ 'type': 'TestTypeB',
|
||||
'data': { 'integer': 'int' } }
|
||||
|
||||
{ 'union': 'TestUnion',
|
||||
'base': 'TestBase',
|
||||
'discriminator': 'enum1',
|
||||
'data': { 'value_wrong': 'TestTypeA',
|
||||
'value2': 'TestTypeB' } }
|
0
tests/qapi-schema/flat-union-invalid-branch-key.out
Normal file
0
tests/qapi-schema/flat-union-invalid-branch-key.out
Normal file
1
tests/qapi-schema/flat-union-invalid-discriminator.err
Normal file
1
tests/qapi-schema/flat-union-invalid-discriminator.err
Normal file
@@ -0,0 +1 @@
|
||||
<stdin>:13: Discriminator 'enum_wrong' is not a member of base type 'TestBase'
|
1
tests/qapi-schema/flat-union-invalid-discriminator.exit
Normal file
1
tests/qapi-schema/flat-union-invalid-discriminator.exit
Normal file
@@ -0,0 +1 @@
|
||||
1
|
17
tests/qapi-schema/flat-union-invalid-discriminator.json
Normal file
17
tests/qapi-schema/flat-union-invalid-discriminator.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{ 'enum': 'TestEnum',
|
||||
'data': [ 'value1', 'value2' ] }
|
||||
|
||||
{ 'type': 'TestBase',
|
||||
'data': { 'enum1': 'TestEnum' } }
|
||||
|
||||
{ 'type': 'TestTypeA',
|
||||
'data': { 'string': 'str' } }
|
||||
|
||||
{ 'type': 'TestTypeB',
|
||||
'data': { 'integer': 'int' } }
|
||||
|
||||
{ 'union': 'TestUnion',
|
||||
'base': 'TestBase',
|
||||
'discriminator': 'enum_wrong',
|
||||
'data': { 'value1': 'TestTypeA',
|
||||
'value2': 'TestTypeB' } }
|
1
tests/qapi-schema/flat-union-no-base.err
Normal file
1
tests/qapi-schema/flat-union-no-base.err
Normal file
@@ -0,0 +1 @@
|
||||
<stdin>:7: Flat union 'TestUnion' must have a base field
|
1
tests/qapi-schema/flat-union-no-base.exit
Normal file
1
tests/qapi-schema/flat-union-no-base.exit
Normal file
@@ -0,0 +1 @@
|
||||
1
|
10
tests/qapi-schema/flat-union-no-base.json
Normal file
10
tests/qapi-schema/flat-union-no-base.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{ 'type': 'TestTypeA',
|
||||
'data': { 'string': 'str' } }
|
||||
|
||||
{ 'type': 'TestTypeB',
|
||||
'data': { 'integer': 'int' } }
|
||||
|
||||
{ 'union': 'TestUnion',
|
||||
'discriminator': 'enum1',
|
||||
'data': { 'value1': 'TestTypeA',
|
||||
'value2': 'TestTypeB' } }
|
0
tests/qapi-schema/flat-union-no-base.out
Normal file
0
tests/qapi-schema/flat-union-no-base.out
Normal file
0
tests/qapi-schema/flat-union-reverse-define.err
Normal file
0
tests/qapi-schema/flat-union-reverse-define.err
Normal file
1
tests/qapi-schema/flat-union-reverse-define.exit
Normal file
1
tests/qapi-schema/flat-union-reverse-define.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
17
tests/qapi-schema/flat-union-reverse-define.json
Normal file
17
tests/qapi-schema/flat-union-reverse-define.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{ 'union': 'TestUnion',
|
||||
'base': 'TestBase',
|
||||
'discriminator': 'enum1',
|
||||
'data': { 'value1': 'TestTypeA',
|
||||
'value2': 'TestTypeB' } }
|
||||
|
||||
{ 'type': 'TestBase',
|
||||
'data': { 'enum1': 'TestEnum' } }
|
||||
|
||||
{ 'enum': 'TestEnum',
|
||||
'data': [ 'value1', 'value2' ] }
|
||||
|
||||
{ 'type': 'TestTypeA',
|
||||
'data': { 'string': 'str' } }
|
||||
|
||||
{ 'type': 'TestTypeB',
|
||||
'data': { 'integer': 'int' } }
|
9
tests/qapi-schema/flat-union-reverse-define.out
Normal file
9
tests/qapi-schema/flat-union-reverse-define.out
Normal file
@@ -0,0 +1,9 @@
|
||||
[OrderedDict([('union', 'TestUnion'), ('base', 'TestBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'TestTypeA'), ('value2', 'TestTypeB')]))]),
|
||||
OrderedDict([('type', 'TestBase'), ('data', OrderedDict([('enum1', 'TestEnum')]))]),
|
||||
OrderedDict([('enum', 'TestEnum'), ('data', ['value1', 'value2'])]),
|
||||
OrderedDict([('type', 'TestTypeA'), ('data', OrderedDict([('string', 'str')]))]),
|
||||
OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))])]
|
||||
[{'enum_name': 'TestEnum', 'enum_values': ['value1', 'value2']}]
|
||||
[OrderedDict([('type', 'TestBase'), ('data', OrderedDict([('enum1', 'TestEnum')]))]),
|
||||
OrderedDict([('type', 'TestTypeA'), ('data', OrderedDict([('string', 'str')]))]),
|
||||
OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))])]
|
1
tests/qapi-schema/flat-union-string-discriminator.err
Normal file
1
tests/qapi-schema/flat-union-string-discriminator.err
Normal file
@@ -0,0 +1 @@
|
||||
<stdin>:13: Discriminator 'kind' must be of enumeration type
|
1
tests/qapi-schema/flat-union-string-discriminator.exit
Normal file
1
tests/qapi-schema/flat-union-string-discriminator.exit
Normal file
@@ -0,0 +1 @@
|
||||
1
|
17
tests/qapi-schema/flat-union-string-discriminator.json
Normal file
17
tests/qapi-schema/flat-union-string-discriminator.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{ 'enum': 'TestEnum',
|
||||
'data': [ 'value1', 'value2' ] }
|
||||
|
||||
{ 'type': 'TestBase',
|
||||
'data': { 'enum1': 'TestEnum', 'kind': 'str' } }
|
||||
|
||||
{ 'type': 'TestTypeA',
|
||||
'data': { 'string': 'str' } }
|
||||
|
||||
{ 'type': 'TestTypeB',
|
||||
'data': { 'integer': 'int' } }
|
||||
|
||||
{ 'union': 'TestUnion',
|
||||
'base': 'TestBase',
|
||||
'discriminator': 'kind',
|
||||
'data': { 'kind1': 'TestTypeA',
|
||||
'kind2': 'TestTypeB' } }
|
@@ -37,10 +37,13 @@
|
||||
'base': 'UserDefZero',
|
||||
'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
|
||||
|
||||
{ 'type': 'UserDefUnionBase',
|
||||
'data': { 'string': 'str', 'enum1': 'EnumOne' } }
|
||||
|
||||
{ 'union': 'UserDefFlatUnion',
|
||||
'base': 'UserDefOne',
|
||||
'discriminator': 'string',
|
||||
'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
|
||||
'base': 'UserDefUnionBase',
|
||||
'discriminator': 'enum1',
|
||||
'data': { 'value1' : 'UserDefA', 'value2' : 'UserDefB', 'value3' : 'UserDefB' } }
|
||||
# FIXME generated struct UserDefFlatUnion has members for direct base
|
||||
# UserDefOne, but lacks members for indirect base UserDefZero
|
||||
|
||||
|
@@ -7,7 +7,8 @@
|
||||
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
|
||||
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
|
||||
OrderedDict([('union', 'UserDefUnion'), ('base', 'UserDefZero'), ('data', OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
|
||||
OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefOne'), ('discriminator', 'string'), ('data', OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
|
||||
OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
|
||||
OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefUnionBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefA'), ('value2', 'UserDefB'), ('value3', 'UserDefB')]))]),
|
||||
OrderedDict([('union', 'UserDefAnonUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
|
||||
OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str'])]))]),
|
||||
OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
|
||||
@@ -15,11 +16,10 @@
|
||||
OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 'UserDefOne'), ('*ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')]),
|
||||
OrderedDict([('command', 'user_def_cmd3'), ('data', OrderedDict([('a', 'int'), ('*b', 'int')])), ('returns', 'int')]),
|
||||
OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
|
||||
['EnumOne',
|
||||
'UserDefUnionKind',
|
||||
'UserDefFlatUnionKind',
|
||||
'UserDefAnonUnionKind',
|
||||
'UserDefNativeListUnionKind']
|
||||
[{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
|
||||
{'enum_name': 'UserDefUnionKind', 'enum_values': None},
|
||||
{'enum_name': 'UserDefAnonUnionKind', 'enum_values': None},
|
||||
{'enum_name': 'UserDefNativeListUnionKind', 'enum_values': None}]
|
||||
[OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
|
||||
OrderedDict([('type', 'UserDefZero'), ('data', OrderedDict([('integer', 'int')]))]),
|
||||
OrderedDict([('type', 'UserDefOne'), ('base', 'UserDefZero'), ('data', OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
|
||||
@@ -27,4 +27,5 @@
|
||||
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
|
||||
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
|
||||
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
|
||||
OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
|
||||
OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
|
||||
|
1
tests/qapi-schema/union-invalid-base.err
Normal file
1
tests/qapi-schema/union-invalid-base.err
Normal file
@@ -0,0 +1 @@
|
||||
<stdin>:7: Base 'TestBaseWrong' is not a valid type
|
1
tests/qapi-schema/union-invalid-base.exit
Normal file
1
tests/qapi-schema/union-invalid-base.exit
Normal file
@@ -0,0 +1 @@
|
||||
1
|
10
tests/qapi-schema/union-invalid-base.json
Normal file
10
tests/qapi-schema/union-invalid-base.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{ 'type': 'TestTypeA',
|
||||
'data': { 'string': 'str' } }
|
||||
|
||||
{ 'type': 'TestTypeB',
|
||||
'data': { 'integer': 'int' } }
|
||||
|
||||
{ 'union': 'TestUnion',
|
||||
'base': 'TestBaseWrong',
|
||||
'data': { 'value1': 'TestTypeA',
|
||||
'value2': 'TestTypeB' } }
|
0
tests/qapi-schema/union-invalid-base.out
Normal file
0
tests/qapi-schema/union-invalid-base.out
Normal file
@@ -141,7 +141,7 @@ static void test_dispatch_cmd_io(void)
|
||||
|
||||
ret3 = qobject_to_qint(test_qmp_dispatch(req));
|
||||
assert(qint_get_int(ret3) == 66);
|
||||
QDECREF(ret);
|
||||
QDECREF(ret3);
|
||||
|
||||
QDECREF(req);
|
||||
}
|
||||
|
@@ -146,7 +146,10 @@ static void test_validate_union_flat(TestInputVisitorData *data,
|
||||
Visitor *v;
|
||||
Error *errp = NULL;
|
||||
|
||||
v = validate_test_init(data, "{ 'string': 'a', 'boolean': true }");
|
||||
v = validate_test_init(data,
|
||||
"{ 'enum1': 'value1', "
|
||||
"'string': 'str', "
|
||||
"'boolean': true }");
|
||||
/* TODO when generator bug is fixed, add 'integer': 41 */
|
||||
|
||||
visit_type_UserDefFlatUnion(v, &tmp, NULL, &errp);
|
||||
|
@@ -310,14 +310,18 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
|
||||
Error *err = NULL;
|
||||
UserDefFlatUnion *tmp;
|
||||
|
||||
v = visitor_input_test_init(data, "{ 'string': 'a', 'boolean': true }");
|
||||
v = visitor_input_test_init(data,
|
||||
"{ 'enum1': 'value1', "
|
||||
"'string': 'str', "
|
||||
"'boolean': true }");
|
||||
/* TODO when generator bug is fixed, add 'integer': 41 */
|
||||
|
||||
visit_type_UserDefFlatUnion(v, &tmp, NULL, &err);
|
||||
g_assert(err == NULL);
|
||||
g_assert_cmpint(tmp->kind, ==, USER_DEF_UNION_KIND_A);
|
||||
g_assert_cmpint(tmp->kind, ==, ENUM_ONE_VALUE1);
|
||||
g_assert_cmpstr(tmp->string, ==, "str");
|
||||
/* TODO g_assert_cmpint(tmp->integer, ==, 41); */
|
||||
g_assert_cmpint(tmp->a->boolean, ==, true);
|
||||
g_assert_cmpint(tmp->value1->boolean, ==, true);
|
||||
qapi_free_UserDefFlatUnion(tmp);
|
||||
}
|
||||
|
||||
|
@@ -449,10 +449,11 @@ static void test_visitor_out_union_flat(TestOutputVisitorData *data,
|
||||
Error *err = NULL;
|
||||
|
||||
UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
|
||||
tmp->kind = USER_DEF_UNION_KIND_A;
|
||||
tmp->a = g_malloc0(sizeof(UserDefA));
|
||||
tmp->kind = ENUM_ONE_VALUE1;
|
||||
tmp->string = g_strdup("str");
|
||||
tmp->value1 = g_malloc0(sizeof(UserDefA));
|
||||
/* TODO when generator bug is fixed: tmp->integer = 41; */
|
||||
tmp->a->boolean = true;
|
||||
tmp->value1->boolean = true;
|
||||
|
||||
visit_type_UserDefFlatUnion(data->ov, &tmp, NULL, &err);
|
||||
g_assert(err == NULL);
|
||||
@@ -461,7 +462,8 @@ static void test_visitor_out_union_flat(TestOutputVisitorData *data,
|
||||
g_assert(qobject_type(arg) == QTYPE_QDICT);
|
||||
qdict = qobject_to_qdict(arg);
|
||||
|
||||
g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "a");
|
||||
g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
|
||||
g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
|
||||
/* TODO g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41); */
|
||||
g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
|
||||
|
||||
|
Reference in New Issue
Block a user