Merge branch 'ppc-for-upstream' of git://github.com/agraf/qemu
* 'ppc-for-upstream' of git://github.com/agraf/qemu: (66 commits) pseries: Add compatible property to root of device tree target-ppc: Move CPU aliases out of translate_init.c target-ppc: Report CPU aliases for QMP target-ppc: List alias names alongside CPU models target-ppc: Make host CPU a subclass of the host's CPU model PPC: xnu kernel expects FLUSH to be cleared on STOP PPC: Fix dma interrupt target-ppc: Fix PPC_DUMP_SPR_ACCESS build target-ppc: Synchronize FPU state with KVM target-ppc: Add mechanism for synchronizing SPRs with KVM Save memory allocation in the elf loader pseries: Implement h_read hcall target-ppc: Change "POWER7" CPU alias target-ppc: Fix remaining microcontroller typos among models target-ppc: Split model definitions out of translate_init.c target-ppc: Update Coding Style for CPU models target-ppc: Turn descriptive CPU model comments into device descriptions target-ppc: Turn descriptive CPU family comments into device descriptions target-ppc: Set remaining fields on CPU family classes target-ppc: Register all types for TARGET_PPCEMB ...
This commit is contained in:
commit
62e1aeaee4
19
hw/elf_ops.h
19
hw/elf_ops.h
@ -197,7 +197,7 @@ static int glue(load_elf, SZ)(const char *name, int fd,
|
||||
struct elfhdr ehdr;
|
||||
struct elf_phdr *phdr = NULL, *ph;
|
||||
int size, i, total_size;
|
||||
elf_word mem_size;
|
||||
elf_word mem_size, file_size;
|
||||
uint64_t addr, low = (uint64_t)-1, high = 0;
|
||||
uint8_t *data = NULL;
|
||||
char label[128];
|
||||
@ -252,14 +252,16 @@ static int glue(load_elf, SZ)(const char *name, int fd,
|
||||
for(i = 0; i < ehdr.e_phnum; i++) {
|
||||
ph = &phdr[i];
|
||||
if (ph->p_type == PT_LOAD) {
|
||||
mem_size = ph->p_memsz;
|
||||
/* XXX: avoid allocating */
|
||||
data = g_malloc0(mem_size);
|
||||
mem_size = ph->p_memsz; /* Size of the ROM */
|
||||
file_size = ph->p_filesz; /* Size of the allocated data */
|
||||
data = g_malloc0(file_size);
|
||||
if (ph->p_filesz > 0) {
|
||||
if (lseek(fd, ph->p_offset, SEEK_SET) < 0)
|
||||
if (lseek(fd, ph->p_offset, SEEK_SET) < 0) {
|
||||
goto fail;
|
||||
if (read(fd, data, ph->p_filesz) != ph->p_filesz)
|
||||
}
|
||||
if (read(fd, data, file_size) != file_size) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
/* address_offset is hack for kernel images that are
|
||||
linked at the wrong physical address. */
|
||||
@ -281,7 +283,9 @@ static int glue(load_elf, SZ)(const char *name, int fd,
|
||||
}
|
||||
|
||||
snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
|
||||
rom_add_blob_fixed(label, data, mem_size, addr);
|
||||
|
||||
/* rom_add_elf_program() seize the ownership of 'data' */
|
||||
rom_add_elf_program(label, data, file_size, mem_size, addr);
|
||||
|
||||
total_size += mem_size;
|
||||
if (addr < low)
|
||||
@ -289,7 +293,6 @@ static int glue(load_elf, SZ)(const char *name, int fd,
|
||||
if ((addr + mem_size) > high)
|
||||
high = addr + mem_size;
|
||||
|
||||
g_free(data);
|
||||
data = NULL;
|
||||
}
|
||||
}
|
||||
|
75
hw/loader.c
75
hw/loader.c
@ -533,7 +533,14 @@ typedef struct Rom Rom;
|
||||
struct Rom {
|
||||
char *name;
|
||||
char *path;
|
||||
|
||||
/* datasize is the amount of memory allocated in "data". If datasize is less
|
||||
* than romsize, it means that the area from datasize to romsize is filled
|
||||
* with zeros.
|
||||
*/
|
||||
size_t romsize;
|
||||
size_t datasize;
|
||||
|
||||
uint8_t *data;
|
||||
int isrom;
|
||||
char *fw_dir;
|
||||
@ -589,14 +596,15 @@ int rom_add_file(const char *file, const char *fw_dir,
|
||||
rom->fw_dir = g_strdup(fw_dir);
|
||||
rom->fw_file = g_strdup(file);
|
||||
}
|
||||
rom->addr = addr;
|
||||
rom->romsize = lseek(fd, 0, SEEK_END);
|
||||
rom->data = g_malloc0(rom->romsize);
|
||||
rom->addr = addr;
|
||||
rom->romsize = lseek(fd, 0, SEEK_END);
|
||||
rom->datasize = rom->romsize;
|
||||
rom->data = g_malloc0(rom->datasize);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
rc = read(fd, rom->data, rom->romsize);
|
||||
if (rc != rom->romsize) {
|
||||
rc = read(fd, rom->data, rom->datasize);
|
||||
if (rc != rom->datasize) {
|
||||
fprintf(stderr, "rom: file %-20s: read error: rc=%d (expected %zd)\n",
|
||||
rom->name, rc, rom->romsize);
|
||||
rom->name, rc, rom->datasize);
|
||||
goto err;
|
||||
}
|
||||
close(fd);
|
||||
@ -637,16 +645,37 @@ int rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
{
|
||||
Rom *rom;
|
||||
|
||||
rom = g_malloc0(sizeof(*rom));
|
||||
rom->name = g_strdup(name);
|
||||
rom->addr = addr;
|
||||
rom->romsize = len;
|
||||
rom->data = g_malloc0(rom->romsize);
|
||||
rom = g_malloc0(sizeof(*rom));
|
||||
rom->name = g_strdup(name);
|
||||
rom->addr = addr;
|
||||
rom->romsize = len;
|
||||
rom->datasize = len;
|
||||
rom->data = g_malloc0(rom->datasize);
|
||||
memcpy(rom->data, blob, len);
|
||||
rom_insert(rom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function is specific for elf program because we don't need to allocate
|
||||
* all the rom. We just allocate the first part and the rest is just zeros. This
|
||||
* is why romsize and datasize are different. Also, this function seize the
|
||||
* memory ownership of "data", so we don't have to allocate and copy the buffer.
|
||||
*/
|
||||
int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
||||
size_t romsize, hwaddr addr)
|
||||
{
|
||||
Rom *rom;
|
||||
|
||||
rom = g_malloc0(sizeof(*rom));
|
||||
rom->name = g_strdup(name);
|
||||
rom->addr = addr;
|
||||
rom->datasize = datasize;
|
||||
rom->romsize = romsize;
|
||||
rom->data = data;
|
||||
rom_insert(rom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rom_add_vga(const char *file)
|
||||
{
|
||||
return rom_add_file(file, "vgaroms", 0, -1);
|
||||
@ -668,7 +697,7 @@ static void rom_reset(void *unused)
|
||||
if (rom->data == NULL) {
|
||||
continue;
|
||||
}
|
||||
cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize);
|
||||
cpu_physical_memory_write_rom(rom->addr, rom->data, rom->datasize);
|
||||
if (rom->isrom) {
|
||||
/* rom needs to be written only once */
|
||||
g_free(rom->data);
|
||||
@ -756,13 +785,33 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
|
||||
|
||||
d = dest + (rom->addr - addr);
|
||||
s = rom->data;
|
||||
l = rom->romsize;
|
||||
l = rom->datasize;
|
||||
|
||||
if ((d + l) > (dest + size)) {
|
||||
l = dest - d;
|
||||
}
|
||||
|
||||
memcpy(d, s, l);
|
||||
|
||||
if (rom->romsize > rom->datasize) {
|
||||
/* If datasize is less than romsize, it means that we didn't
|
||||
* allocate all the ROM because the trailing data are only zeros.
|
||||
*/
|
||||
|
||||
d += l;
|
||||
l = rom->romsize - rom->datasize;
|
||||
|
||||
if ((d + l) > (dest + size)) {
|
||||
/* Rom size doesn't fit in the destination area. Adjust to avoid
|
||||
* overflow.
|
||||
*/
|
||||
l = dest - d;
|
||||
}
|
||||
|
||||
if (l > 0) {
|
||||
memset(d, 0x0, l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (d + l) - dest;
|
||||
|
@ -27,6 +27,8 @@ int rom_add_file(const char *file, const char *fw_dir,
|
||||
hwaddr addr, int32_t bootindex);
|
||||
int rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
hwaddr addr);
|
||||
int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
||||
size_t romsize, hwaddr addr);
|
||||
int rom_load_all(void);
|
||||
void rom_set_fw(void *f);
|
||||
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
|
||||
|
@ -688,6 +688,10 @@ dbdma_control_write(DBDMA_channel *ch)
|
||||
if ((ch->regs[DBDMA_STATUS] & RUN) && !(status & RUN)) {
|
||||
/* RUN is cleared */
|
||||
status &= ~(ACTIVE|DEAD);
|
||||
if ((status & FLUSH) && ch->flush) {
|
||||
ch->flush(&ch->io);
|
||||
status &= ~FLUSH;
|
||||
}
|
||||
}
|
||||
|
||||
DBDMA_DPRINTF(" status 0x%08x\n", status);
|
||||
|
@ -370,7 +370,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
|
||||
qdev_connect_gpio_out(dev, 1, pic[0x0d]); /* IDE */
|
||||
qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE DMA */
|
||||
qdev_connect_gpio_out(dev, 3, pic[0x0e]); /* IDE */
|
||||
qdev_connect_gpio_out(dev, 4, pic[0x02]); /* IDE DMA */
|
||||
qdev_connect_gpio_out(dev, 4, pic[0x03]); /* IDE DMA */
|
||||
macio_init(macio, pic_mem, escc_bar);
|
||||
|
||||
/* We only emulate 2 out of 3 IDE controllers for now */
|
||||
|
@ -260,6 +260,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
|
||||
_FDT((fdt_begin_node(fdt, "")));
|
||||
_FDT((fdt_property_string(fdt, "device_type", "chrp")));
|
||||
_FDT((fdt_property_string(fdt, "model", "IBM pSeries (emulated by qemu)")));
|
||||
_FDT((fdt_property_string(fdt, "compatible", "qemu,pseries")));
|
||||
|
||||
_FDT((fdt_property_cell(fdt, "#address-cells", 0x2)));
|
||||
_FDT((fdt_property_cell(fdt, "#size-cells", 0x2)));
|
||||
|
@ -323,6 +323,36 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_read(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
target_ulong flags = args[0];
|
||||
target_ulong pte_index = args[1];
|
||||
uint8_t *hpte;
|
||||
int i, ridx, n_entries = 1;
|
||||
|
||||
if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
|
||||
return H_PARAMETER;
|
||||
}
|
||||
|
||||
if (flags & H_READ_4) {
|
||||
/* Clear the two low order bits */
|
||||
pte_index &= ~(3ULL);
|
||||
n_entries = 4;
|
||||
}
|
||||
|
||||
hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
|
||||
|
||||
for (i = 0, ridx = 0; i < n_entries; i++) {
|
||||
args[ridx++] = ldq_p(hpte);
|
||||
args[ridx++] = ldq_p(hpte + (HASH_PTE_SIZE_64/2));
|
||||
hpte += HASH_PTE_SIZE_64;
|
||||
}
|
||||
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
@ -710,6 +740,7 @@ static void hypercall_register_types(void)
|
||||
spapr_register_hypercall(H_ENTER, h_enter);
|
||||
spapr_register_hypercall(H_REMOVE, h_remove);
|
||||
spapr_register_hypercall(H_PROTECT, h_protect);
|
||||
spapr_register_hypercall(H_READ, h_read);
|
||||
|
||||
/* hcall-bulk */
|
||||
spapr_register_hypercall(H_BULK_REMOVE, h_bulk_remove);
|
||||
|
@ -175,11 +175,19 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
|
||||
return size;
|
||||
}
|
||||
|
||||
static void spapr_vlan_cleanup(NetClientState *nc)
|
||||
{
|
||||
VIOsPAPRVLANDevice *dev = qemu_get_nic_opaque(nc);
|
||||
|
||||
dev->nic = NULL;
|
||||
}
|
||||
|
||||
static NetClientInfo net_spapr_vlan_info = {
|
||||
.type = NET_CLIENT_OPTIONS_KIND_NIC,
|
||||
.size = sizeof(NICState),
|
||||
.can_receive = spapr_vlan_can_receive,
|
||||
.receive = spapr_vlan_receive,
|
||||
.cleanup = spapr_vlan_cleanup,
|
||||
};
|
||||
|
||||
static void spapr_vlan_reset(VIOsPAPRDevice *sdev)
|
||||
|
@ -1,3 +1,4 @@
|
||||
obj-y += cpu-models.o
|
||||
obj-y += translate.o
|
||||
obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o
|
||||
|
1419
target-ppc/cpu-models.c
Normal file
1419
target-ppc/cpu-models.c
Normal file
File diff suppressed because it is too large
Load Diff
741
target-ppc/cpu-models.h
Normal file
741
target-ppc/cpu-models.h
Normal file
@ -0,0 +1,741 @@
|
||||
/*
|
||||
* PowerPC CPU initialization for qemu.
|
||||
*
|
||||
* Copyright (c) 2003-2007 Jocelyn Mayer
|
||||
* Copyright 2011 Freescale Semiconductor, Inc.
|
||||
* Copyright 2013 SUSE LINUX Products GmbH
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
#ifndef TARGET_PPC_CPU_MODELS_H
|
||||
#define TARGET_PPC_CPU_MODELS_H
|
||||
|
||||
/**
|
||||
* PowerPCCPUAlias:
|
||||
* @alias: The alias name.
|
||||
* @model: The CPU model @alias refers to.
|
||||
*
|
||||
* A mapping entry from CPU @alias to CPU @model.
|
||||
*/
|
||||
typedef struct PowerPCCPUAlias {
|
||||
const char *alias;
|
||||
const char *model;
|
||||
} PowerPCCPUAlias;
|
||||
|
||||
extern const PowerPCCPUAlias ppc_cpu_aliases[];
|
||||
|
||||
/*****************************************************************************/
|
||||
/* PVR definitions for most known PowerPC */
|
||||
enum {
|
||||
/* PowerPC 401 family */
|
||||
/* Generic PowerPC 401 */
|
||||
#define CPU_POWERPC_401 CPU_POWERPC_401G2
|
||||
/* PowerPC 401 cores */
|
||||
CPU_POWERPC_401A1 = 0x00210000,
|
||||
CPU_POWERPC_401B2 = 0x00220000,
|
||||
#if 0
|
||||
CPU_POWERPC_401B3 = xxx,
|
||||
#endif
|
||||
CPU_POWERPC_401C2 = 0x00230000,
|
||||
CPU_POWERPC_401D2 = 0x00240000,
|
||||
CPU_POWERPC_401E2 = 0x00250000,
|
||||
CPU_POWERPC_401F2 = 0x00260000,
|
||||
CPU_POWERPC_401G2 = 0x00270000,
|
||||
/* PowerPC 401 microcontrolers */
|
||||
#if 0
|
||||
CPU_POWERPC_401GF = xxx,
|
||||
#endif
|
||||
#define CPU_POWERPC_IOP480 CPU_POWERPC_401B2
|
||||
/* IBM Processor for Network Resources */
|
||||
CPU_POWERPC_COBRA = 0x10100000, /* XXX: 405 ? */
|
||||
#if 0
|
||||
CPU_POWERPC_XIPCHIP = xxx,
|
||||
#endif
|
||||
/* PowerPC 403 family */
|
||||
/* PowerPC 403 microcontrollers */
|
||||
CPU_POWERPC_403GA = 0x00200011,
|
||||
CPU_POWERPC_403GB = 0x00200100,
|
||||
CPU_POWERPC_403GC = 0x00200200,
|
||||
CPU_POWERPC_403GCX = 0x00201400,
|
||||
#if 0
|
||||
CPU_POWERPC_403GP = xxx,
|
||||
#endif
|
||||
/* PowerPC 405 family */
|
||||
/* PowerPC 405 cores */
|
||||
#if 0
|
||||
CPU_POWERPC_405A3 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405A4 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405B3 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405B4 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405C3 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405C4 = xxx,
|
||||
#endif
|
||||
CPU_POWERPC_405D2 = 0x20010000,
|
||||
#if 0
|
||||
CPU_POWERPC_405D3 = xxx,
|
||||
#endif
|
||||
CPU_POWERPC_405D4 = 0x41810000,
|
||||
#if 0
|
||||
CPU_POWERPC_405D5 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405E4 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405F4 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405F5 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405F6 = xxx,
|
||||
#endif
|
||||
/* PowerPC 405 microcontrolers */
|
||||
/* XXX: missing 0x200108a0 */
|
||||
CPU_POWERPC_405CRa = 0x40110041,
|
||||
CPU_POWERPC_405CRb = 0x401100C5,
|
||||
CPU_POWERPC_405CRc = 0x40110145,
|
||||
CPU_POWERPC_405EP = 0x51210950,
|
||||
#if 0
|
||||
CPU_POWERPC_405EXr = xxx,
|
||||
#endif
|
||||
CPU_POWERPC_405EZ = 0x41511460, /* 0x51210950 ? */
|
||||
#if 0
|
||||
CPU_POWERPC_405FX = xxx,
|
||||
#endif
|
||||
CPU_POWERPC_405GPa = 0x40110000,
|
||||
CPU_POWERPC_405GPb = 0x40110040,
|
||||
CPU_POWERPC_405GPc = 0x40110082,
|
||||
CPU_POWERPC_405GPd = 0x401100C4,
|
||||
CPU_POWERPC_405GPR = 0x50910951,
|
||||
#if 0
|
||||
CPU_POWERPC_405H = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405L = xxx,
|
||||
#endif
|
||||
CPU_POWERPC_405LP = 0x41F10000,
|
||||
#if 0
|
||||
CPU_POWERPC_405PM = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405PS = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_405S = xxx,
|
||||
#endif
|
||||
/* IBM network processors */
|
||||
CPU_POWERPC_NPE405H = 0x414100C0,
|
||||
CPU_POWERPC_NPE405H2 = 0x41410140,
|
||||
CPU_POWERPC_NPE405L = 0x416100C0,
|
||||
CPU_POWERPC_NPE4GS3 = 0x40B10000,
|
||||
#if 0
|
||||
CPU_POWERPC_NPCxx1 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_NPR161 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_LC77700 = xxx,
|
||||
#endif
|
||||
/* IBM STBxxx (PowerPC 401/403/405 core based microcontrollers) */
|
||||
#if 0
|
||||
CPU_POWERPC_STB01000 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_STB01010 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_STB0210 = xxx, /* 401B3 */
|
||||
#endif
|
||||
CPU_POWERPC_STB03 = 0x40310000, /* 0x40130000 ? */
|
||||
#if 0
|
||||
CPU_POWERPC_STB043 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_STB045 = xxx,
|
||||
#endif
|
||||
CPU_POWERPC_STB04 = 0x41810000,
|
||||
CPU_POWERPC_STB25 = 0x51510950,
|
||||
#if 0
|
||||
CPU_POWERPC_STB130 = xxx,
|
||||
#endif
|
||||
/* Xilinx cores */
|
||||
CPU_POWERPC_X2VP4 = 0x20010820,
|
||||
CPU_POWERPC_X2VP20 = 0x20010860,
|
||||
#if 0
|
||||
CPU_POWERPC_ZL10310 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_ZL10311 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_ZL10320 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_ZL10321 = xxx,
|
||||
#endif
|
||||
/* PowerPC 440 family */
|
||||
/* Generic PowerPC 440 */
|
||||
#define CPU_POWERPC_440 CPU_POWERPC_440GXf
|
||||
/* PowerPC 440 cores */
|
||||
#if 0
|
||||
CPU_POWERPC_440A4 = xxx,
|
||||
#endif
|
||||
CPU_POWERPC_440_XILINX = 0x7ff21910,
|
||||
#if 0
|
||||
CPU_POWERPC_440A5 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_440B4 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_440F5 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_440G5 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_440H4 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_440H6 = xxx,
|
||||
#endif
|
||||
/* PowerPC 440 microcontrolers */
|
||||
CPU_POWERPC_440EPa = 0x42221850,
|
||||
CPU_POWERPC_440EPb = 0x422218D3,
|
||||
CPU_POWERPC_440GPb = 0x40120440,
|
||||
CPU_POWERPC_440GPc = 0x40120481,
|
||||
#define CPU_POWERPC_440GRa CPU_POWERPC_440EPb
|
||||
CPU_POWERPC_440GRX = 0x200008D0,
|
||||
#define CPU_POWERPC_440EPX CPU_POWERPC_440GRX
|
||||
CPU_POWERPC_440GXa = 0x51B21850,
|
||||
CPU_POWERPC_440GXb = 0x51B21851,
|
||||
CPU_POWERPC_440GXc = 0x51B21892,
|
||||
CPU_POWERPC_440GXf = 0x51B21894,
|
||||
#if 0
|
||||
CPU_POWERPC_440S = xxx,
|
||||
#endif
|
||||
CPU_POWERPC_440SP = 0x53221850,
|
||||
CPU_POWERPC_440SP2 = 0x53221891,
|
||||
CPU_POWERPC_440SPE = 0x53421890,
|
||||
/* PowerPC 460 family */
|
||||
#if 0
|
||||
/* Generic PowerPC 464 */
|
||||
#define CPU_POWERPC_464 CPU_POWERPC_464H90
|
||||
#endif
|
||||
/* PowerPC 464 microcontrolers */
|
||||
#if 0
|
||||
CPU_POWERPC_464H90 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_464H90FP = xxx,
|
||||
#endif
|
||||
/* Freescale embedded PowerPC cores */
|
||||
/* PowerPC MPC 5xx cores (aka RCPU) */
|
||||
CPU_POWERPC_MPC5xx = 0x00020020,
|
||||
/* PowerPC MPC 8xx cores (aka PowerQUICC) */
|
||||
CPU_POWERPC_MPC8xx = 0x00500000,
|
||||
/* G2 cores (aka PowerQUICC-II) */
|
||||
CPU_POWERPC_G2 = 0x00810011,
|
||||
CPU_POWERPC_G2H4 = 0x80811010,
|
||||
CPU_POWERPC_G2gp = 0x80821010,
|
||||
CPU_POWERPC_G2ls = 0x90810010,
|
||||
CPU_POWERPC_MPC603 = 0x00810100,
|
||||
CPU_POWERPC_G2_HIP3 = 0x00810101,
|
||||
CPU_POWERPC_G2_HIP4 = 0x80811014,
|
||||
/* G2_LE core (aka PowerQUICC-II) */
|
||||
CPU_POWERPC_G2LE = 0x80820010,
|
||||
CPU_POWERPC_G2LEgp = 0x80822010,
|
||||
CPU_POWERPC_G2LEls = 0xA0822010,
|
||||
CPU_POWERPC_G2LEgp1 = 0x80822011,
|
||||
CPU_POWERPC_G2LEgp3 = 0x80822013,
|
||||
/* MPC52xx microcontrollers */
|
||||
/* XXX: MPC 5121 ? */
|
||||
#define CPU_POWERPC_MPC5200_v10 CPU_POWERPC_G2LEgp1
|
||||
#define CPU_POWERPC_MPC5200_v11 CPU_POWERPC_G2LEgp1
|
||||
#define CPU_POWERPC_MPC5200_v12 CPU_POWERPC_G2LEgp1
|
||||
#define CPU_POWERPC_MPC5200B_v20 CPU_POWERPC_G2LEgp1
|
||||
#define CPU_POWERPC_MPC5200B_v21 CPU_POWERPC_G2LEgp1
|
||||
/* e200 family */
|
||||
/* e200 cores */
|
||||
#if 0
|
||||
CPU_POWERPC_e200z0 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWERPC_e200z1 = xxx,
|
||||
#endif
|
||||
#if 0 /* ? */
|
||||
CPU_POWERPC_e200z3 = 0x81120000,
|
||||
#endif
|
||||
CPU_POWERPC_e200z5 = 0x81000000,
|
||||
CPU_POWERPC_e200z6 = 0x81120000,
|
||||
/* MPC55xx microcontrollers */
|
||||
#define CPU_POWERPC_MPC55xx CPU_POWERPC_MPC5567
|
||||
#if 0
|
||||
#define CPU_POWERPC_MPC5514E CPU_POWERPC_MPC5514E_v1
|
||||
#define CPU_POWERPC_MPC5514E_v0 CPU_POWERPC_e200z0
|
||||
#define CPU_POWERPC_MPC5514E_v1 CPU_POWERPC_e200z1
|
||||
#define CPU_POWERPC_MPC5514G CPU_POWERPC_MPC5514G_v1
|
||||
#define CPU_POWERPC_MPC5514G_v0 CPU_POWERPC_e200z0
|
||||
#define CPU_POWERPC_MPC5514G_v1 CPU_POWERPC_e200z1
|
||||
#define CPU_POWERPC_MPC5515S CPU_POWERPC_e200z1
|
||||
#define CPU_POWERPC_MPC5516E CPU_POWERPC_MPC5516E_v1
|
||||
#define CPU_POWERPC_MPC5516E_v0 CPU_POWERPC_e200z0
|
||||
#define CPU_POWERPC_MPC5516E_v1 CPU_POWERPC_e200z1
|
||||
#define CPU_POWERPC_MPC5516G CPU_POWERPC_MPC5516G_v1
|
||||
#define CPU_POWERPC_MPC5516G_v0 CPU_POWERPC_e200z0
|
||||
#define CPU_POWERPC_MPC5516G_v1 CPU_POWERPC_e200z1
|
||||
#define CPU_POWERPC_MPC5516S CPU_POWERPC_e200z1
|
||||
#endif
|
||||
#if 0
|
||||
#define CPU_POWERPC_MPC5533 CPU_POWERPC_e200z3
|
||||
#define CPU_POWERPC_MPC5534 CPU_POWERPC_e200z3
|
||||
#endif
|
||||
#define CPU_POWERPC_MPC5553 CPU_POWERPC_e200z6
|
||||
#define CPU_POWERPC_MPC5554 CPU_POWERPC_e200z6
|
||||
#define CPU_POWERPC_MPC5561 CPU_POWERPC_e200z6
|
||||
#define CPU_POWERPC_MPC5565 CPU_POWERPC_e200z6
|
||||
#define CPU_POWERPC_MPC5566 CPU_POWERPC_e200z6
|
||||
#define CPU_POWERPC_MPC5567 CPU_POWERPC_e200z6
|
||||
/* e300 family */
|
||||
/* e300 cores */
|
||||
CPU_POWERPC_e300c1 = 0x00830010,
|
||||
CPU_POWERPC_e300c2 = 0x00840010,
|
||||
CPU_POWERPC_e300c3 = 0x00850010,
|
||||
CPU_POWERPC_e300c4 = 0x00860010,
|
||||
/* MPC83xx microcontrollers */
|
||||
#define CPU_POWERPC_MPC831x CPU_POWERPC_e300c3
|
||||
#define CPU_POWERPC_MPC832x CPU_POWERPC_e300c2
|
||||
#define CPU_POWERPC_MPC834x CPU_POWERPC_e300c1
|
||||
#define CPU_POWERPC_MPC835x CPU_POWERPC_e300c1
|
||||
#define CPU_POWERPC_MPC836x CPU_POWERPC_e300c1
|
||||
#define CPU_POWERPC_MPC837x CPU_POWERPC_e300c4
|
||||
/* e500 family */
|
||||
/* e500 cores */
|
||||
#define CPU_POWERPC_e500 CPU_POWERPC_e500v2_v22
|
||||
CPU_POWERPC_e500v1_v10 = 0x80200010,
|
||||
CPU_POWERPC_e500v1_v20 = 0x80200020,
|
||||
CPU_POWERPC_e500v2_v10 = 0x80210010,
|
||||
CPU_POWERPC_e500v2_v11 = 0x80210011,
|
||||
CPU_POWERPC_e500v2_v20 = 0x80210020,
|
||||
CPU_POWERPC_e500v2_v21 = 0x80210021,
|
||||
CPU_POWERPC_e500v2_v22 = 0x80210022,
|
||||
CPU_POWERPC_e500v2_v30 = 0x80210030,
|
||||
CPU_POWERPC_e500mc = 0x80230020,
|
||||
CPU_POWERPC_e5500 = 0x80240020,
|
||||
/* MPC85xx microcontrollers */
|
||||
#define CPU_POWERPC_MPC8533_v10 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8533_v11 CPU_POWERPC_e500v2_v22
|
||||
#define CPU_POWERPC_MPC8533E_v10 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8533E_v11 CPU_POWERPC_e500v2_v22
|
||||
#define CPU_POWERPC_MPC8540_v10 CPU_POWERPC_e500v1_v10
|
||||
#define CPU_POWERPC_MPC8540_v20 CPU_POWERPC_e500v1_v20
|
||||
#define CPU_POWERPC_MPC8540_v21 CPU_POWERPC_e500v1_v20
|
||||
#define CPU_POWERPC_MPC8541_v10 CPU_POWERPC_e500v1_v20
|
||||
#define CPU_POWERPC_MPC8541_v11 CPU_POWERPC_e500v1_v20
|
||||
#define CPU_POWERPC_MPC8541E_v10 CPU_POWERPC_e500v1_v20
|
||||
#define CPU_POWERPC_MPC8541E_v11 CPU_POWERPC_e500v1_v20
|
||||
#define CPU_POWERPC_MPC8543_v10 CPU_POWERPC_e500v2_v10
|
||||
#define CPU_POWERPC_MPC8543_v11 CPU_POWERPC_e500v2_v11
|
||||
#define CPU_POWERPC_MPC8543_v20 CPU_POWERPC_e500v2_v20
|
||||
#define CPU_POWERPC_MPC8543_v21 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8543E_v10 CPU_POWERPC_e500v2_v10
|
||||
#define CPU_POWERPC_MPC8543E_v11 CPU_POWERPC_e500v2_v11
|
||||
#define CPU_POWERPC_MPC8543E_v20 CPU_POWERPC_e500v2_v20
|
||||
#define CPU_POWERPC_MPC8543E_v21 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8544_v10 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8544_v11 CPU_POWERPC_e500v2_v22
|
||||
#define CPU_POWERPC_MPC8544E_v11 CPU_POWERPC_e500v2_v22
|
||||
#define CPU_POWERPC_MPC8544E_v10 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8545_v10 CPU_POWERPC_e500v2_v10
|
||||
#define CPU_POWERPC_MPC8545_v20 CPU_POWERPC_e500v2_v20
|
||||
#define CPU_POWERPC_MPC8545_v21 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8545E_v10 CPU_POWERPC_e500v2_v10
|
||||
#define CPU_POWERPC_MPC8545E_v20 CPU_POWERPC_e500v2_v20
|
||||
#define CPU_POWERPC_MPC8545E_v21 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8547E_v10 CPU_POWERPC_e500v2_v10
|
||||
#define CPU_POWERPC_MPC8547E_v20 CPU_POWERPC_e500v2_v20
|
||||
#define CPU_POWERPC_MPC8547E_v21 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8548_v10 CPU_POWERPC_e500v2_v10
|
||||
#define CPU_POWERPC_MPC8548_v11 CPU_POWERPC_e500v2_v11
|
||||
#define CPU_POWERPC_MPC8548_v20 CPU_POWERPC_e500v2_v20
|
||||
#define CPU_POWERPC_MPC8548_v21 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8548E_v10 CPU_POWERPC_e500v2_v10
|
||||
#define CPU_POWERPC_MPC8548E_v11 CPU_POWERPC_e500v2_v11
|
||||
#define CPU_POWERPC_MPC8548E_v20 CPU_POWERPC_e500v2_v20
|
||||
#define CPU_POWERPC_MPC8548E_v21 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8555_v10 CPU_POWERPC_e500v2_v10
|
||||
#define CPU_POWERPC_MPC8555_v11 CPU_POWERPC_e500v2_v11
|
||||
#define CPU_POWERPC_MPC8555E_v10 CPU_POWERPC_e500v2_v10
|
||||
#define CPU_POWERPC_MPC8555E_v11 CPU_POWERPC_e500v2_v11
|
||||
#define CPU_POWERPC_MPC8560_v10 CPU_POWERPC_e500v2_v10
|
||||
#define CPU_POWERPC_MPC8560_v20 CPU_POWERPC_e500v2_v20
|
||||
#define CPU_POWERPC_MPC8560_v21 CPU_POWERPC_e500v2_v21
|
||||
#define CPU_POWERPC_MPC8567 CPU_POWERPC_e500v2_v22
|
||||
#define CPU_POWERPC_MPC8567E CPU_POWERPC_e500v2_v22
|
||||
#define CPU_POWERPC_MPC8568 CPU_POWERPC_e500v2_v22
|
||||
#define CPU_POWERPC_MPC8568E CPU_POWERPC_e500v2_v22
|
||||
#define CPU_POWERPC_MPC8572 CPU_POWERPC_e500v2_v30
|
||||
#define CPU_POWERPC_MPC8572E CPU_POWERPC_e500v2_v30
|
||||
/* e600 family */
|
||||
/* e600 cores */
|
||||
CPU_POWERPC_e600 = 0x80040010,
|
||||
/* MPC86xx microcontrollers */
|
||||
#define CPU_POWERPC_MPC8610 CPU_POWERPC_e600
|
||||
#define CPU_POWERPC_MPC8641 CPU_POWERPC_e600
|
||||
#define CPU_POWERPC_MPC8641D CPU_POWERPC_e600
|
||||
/* PowerPC 6xx cores */
|
||||
CPU_POWERPC_601_v0 = 0x00010001,
|
||||
CPU_POWERPC_601_v1 = 0x00010001,
|
||||
CPU_POWERPC_601_v2 = 0x00010002,
|
||||
CPU_POWERPC_602 = 0x00050100,
|
||||
CPU_POWERPC_603 = 0x00030100,
|
||||
CPU_POWERPC_603E_v11 = 0x00060101,
|
||||
CPU_POWERPC_603E_v12 = 0x00060102,
|
||||
CPU_POWERPC_603E_v13 = 0x00060103,
|
||||
CPU_POWERPC_603E_v14 = 0x00060104,
|
||||
CPU_POWERPC_603E_v22 = 0x00060202,
|
||||
CPU_POWERPC_603E_v3 = 0x00060300,
|
||||
CPU_POWERPC_603E_v4 = 0x00060400,
|
||||
CPU_POWERPC_603E_v41 = 0x00060401,
|
||||
CPU_POWERPC_603E7t = 0x00071201,
|
||||
CPU_POWERPC_603E7v = 0x00070100,
|
||||
CPU_POWERPC_603E7v1 = 0x00070101,
|
||||
CPU_POWERPC_603E7v2 = 0x00070201,
|
||||
CPU_POWERPC_603E7 = 0x00070200,
|
||||
CPU_POWERPC_603P = 0x00070000,
|
||||
/* XXX: missing 0x00040303 (604) */
|
||||
CPU_POWERPC_604 = 0x00040103,
|
||||
/* XXX: missing 0x00091203 */
|
||||
/* XXX: missing 0x00092110 */
|
||||
/* XXX: missing 0x00092120 */
|
||||
CPU_POWERPC_604E_v10 = 0x00090100,
|
||||
CPU_POWERPC_604E_v22 = 0x00090202,
|
||||
CPU_POWERPC_604E_v24 = 0x00090204,
|
||||
/* XXX: missing 0x000a0100 */
|
||||
/* XXX: missing 0x00093102 */
|
||||
CPU_POWERPC_604R = 0x000a0101,
|
||||
#if 0
|
||||
CPU_POWERPC_604EV = xxx, /* XXX: same as 604R ? */
|
||||
#endif
|
||||
/* PowerPC 740/750 cores (aka G3) */
|
||||
/* XXX: missing 0x00084202 */
|
||||
CPU_POWERPC_7x0_v10 = 0x00080100,
|
||||
CPU_POWERPC_7x0_v20 = 0x00080200,
|
||||
CPU_POWERPC_7x0_v21 = 0x00080201,
|
||||
CPU_POWERPC_7x0_v22 = 0x00080202,
|
||||
CPU_POWERPC_7x0_v30 = 0x00080300,
|
||||
CPU_POWERPC_7x0_v31 = 0x00080301,
|
||||
CPU_POWERPC_740E = 0x00080100,
|
||||
CPU_POWERPC_750E = 0x00080200,
|
||||
CPU_POWERPC_7x0P = 0x10080000,
|
||||
/* XXX: missing 0x00087010 (CL ?) */
|
||||
CPU_POWERPC_750CL_v10 = 0x00087200,
|
||||
CPU_POWERPC_750CL_v20 = 0x00087210, /* aka rev E */
|
||||
CPU_POWERPC_750CX_v10 = 0x00082100,
|
||||
CPU_POWERPC_750CX_v20 = 0x00082200,
|
||||
CPU_POWERPC_750CX_v21 = 0x00082201,
|
||||
CPU_POWERPC_750CX_v22 = 0x00082202,
|
||||
CPU_POWERPC_750CXE_v21 = 0x00082211,
|
||||
CPU_POWERPC_750CXE_v22 = 0x00082212,
|
||||
CPU_POWERPC_750CXE_v23 = 0x00082213,
|
||||
CPU_POWERPC_750CXE_v24 = 0x00082214,
|
||||
CPU_POWERPC_750CXE_v24b = 0x00083214,
|
||||
CPU_POWERPC_750CXE_v30 = 0x00082310,
|
||||
CPU_POWERPC_750CXE_v31 = 0x00082311,
|
||||
CPU_POWERPC_750CXE_v31b = 0x00083311,
|
||||
CPU_POWERPC_750CXR = 0x00083410,
|
||||
CPU_POWERPC_750FL = 0x70000203,
|
||||
CPU_POWERPC_750FX_v10 = 0x70000100,
|
||||
CPU_POWERPC_750FX_v20 = 0x70000200,
|
||||
CPU_POWERPC_750FX_v21 = 0x70000201,
|
||||
CPU_POWERPC_750FX_v22 = 0x70000202,
|
||||
CPU_POWERPC_750FX_v23 = 0x70000203,
|
||||
CPU_POWERPC_750GL = 0x70020102,
|
||||
CPU_POWERPC_750GX_v10 = 0x70020100,
|
||||
CPU_POWERPC_750GX_v11 = 0x70020101,
|
||||
CPU_POWERPC_750GX_v12 = 0x70020102,
|
||||
CPU_POWERPC_750L_v20 = 0x00088200,
|
||||
CPU_POWERPC_750L_v21 = 0x00088201,
|
||||
CPU_POWERPC_750L_v22 = 0x00088202,
|
||||
CPU_POWERPC_750L_v30 = 0x00088300,
|
||||
CPU_POWERPC_750L_v32 = 0x00088302,
|
||||
/* PowerPC 745/755 cores */
|
||||
CPU_POWERPC_7x5_v10 = 0x00083100,
|
||||
CPU_POWERPC_7x5_v11 = 0x00083101,
|
||||
CPU_POWERPC_7x5_v20 = 0x00083200,
|
||||
CPU_POWERPC_7x5_v21 = 0x00083201,
|
||||
CPU_POWERPC_7x5_v22 = 0x00083202, /* aka D */
|
||||
CPU_POWERPC_7x5_v23 = 0x00083203, /* aka E */
|
||||
CPU_POWERPC_7x5_v24 = 0x00083204,
|
||||
CPU_POWERPC_7x5_v25 = 0x00083205,
|
||||
CPU_POWERPC_7x5_v26 = 0x00083206,
|
||||
CPU_POWERPC_7x5_v27 = 0x00083207,
|
||||
CPU_POWERPC_7x5_v28 = 0x00083208,
|
||||
#if 0
|
||||
CPU_POWERPC_7x5P = xxx,
|
||||
#endif
|
||||
/* PowerPC 74xx cores (aka G4) */
|
||||
/* XXX: missing 0x000C1101 */
|
||||
CPU_POWERPC_7400_v10 = 0x000C0100,
|
||||
CPU_POWERPC_7400_v11 = 0x000C0101,
|
||||
CPU_POWERPC_7400_v20 = 0x000C0200,
|
||||
CPU_POWERPC_7400_v21 = 0x000C0201,
|
||||
CPU_POWERPC_7400_v22 = 0x000C0202,
|
||||
CPU_POWERPC_7400_v26 = 0x000C0206,
|
||||
CPU_POWERPC_7400_v27 = 0x000C0207,
|
||||
CPU_POWERPC_7400_v28 = 0x000C0208,
|
||||
CPU_POWERPC_7400_v29 = 0x000C0209,
|
||||
CPU_POWERPC_7410_v10 = 0x800C1100,
|
||||
CPU_POWERPC_7410_v11 = 0x800C1101,
|
||||
CPU_POWERPC_7410_v12 = 0x800C1102, /* aka C */
|
||||
CPU_POWERPC_7410_v13 = 0x800C1103, /* aka D */
|
||||
CPU_POWERPC_7410_v14 = 0x800C1104, /* aka E */
|
||||
CPU_POWERPC_7448_v10 = 0x80040100,
|
||||
CPU_POWERPC_7448_v11 = 0x80040101,
|
||||
CPU_POWERPC_7448_v20 = 0x80040200,
|
||||
CPU_POWERPC_7448_v21 = 0x80040201,
|
||||
CPU_POWERPC_7450_v10 = 0x80000100,
|
||||
CPU_POWERPC_7450_v11 = 0x80000101,
|
||||
CPU_POWERPC_7450_v12 = 0x80000102,
|
||||
CPU_POWERPC_7450_v20 = 0x80000200, /* aka A, B, C, D: 2.04 */
|
||||
CPU_POWERPC_7450_v21 = 0x80000201, /* aka E */
|
||||
CPU_POWERPC_74x1_v23 = 0x80000203, /* aka G: 2.3 */
|
||||
/* XXX: this entry might be a bug in some documentation */
|
||||
CPU_POWERPC_74x1_v210 = 0x80000210, /* aka G: 2.3 ? */
|
||||
CPU_POWERPC_74x5_v10 = 0x80010100,
|
||||
/* XXX: missing 0x80010200 */
|
||||
CPU_POWERPC_74x5_v21 = 0x80010201, /* aka C: 2.1 */
|
||||
CPU_POWERPC_74x5_v32 = 0x80010302,
|
||||
CPU_POWERPC_74x5_v33 = 0x80010303, /* aka F: 3.3 */
|
||||
CPU_POWERPC_74x5_v34 = 0x80010304, /* aka G: 3.4 */
|
||||
CPU_POWERPC_74x7_v10 = 0x80020100, /* aka A: 1.0 */
|
||||
CPU_POWERPC_74x7_v11 = 0x80020101, /* aka B: 1.1 */
|
||||
CPU_POWERPC_74x7_v12 = 0x80020102, /* aka C: 1.2 */
|
||||
CPU_POWERPC_74x7A_v10 = 0x80030100, /* aka A: 1.0 */
|
||||
CPU_POWERPC_74x7A_v11 = 0x80030101, /* aka B: 1.1 */
|
||||
CPU_POWERPC_74x7A_v12 = 0x80030102, /* aka C: 1.2 */
|
||||
/* 64 bits PowerPC */
|
||||
#if defined(TARGET_PPC64)
|
||||
CPU_POWERPC_620 = 0x00140000,
|
||||
CPU_POWERPC_630 = 0x00400000,
|
||||
CPU_POWERPC_631 = 0x00410104,
|
||||
CPU_POWERPC_POWER4 = 0x00350000,
|
||||
CPU_POWERPC_POWER4P = 0x00380000,
|
||||
/* XXX: missing 0x003A0201 */
|
||||
CPU_POWERPC_POWER5 = 0x003A0203,
|
||||
#define CPU_POWERPC_POWER5GR CPU_POWERPC_POWER5
|
||||
CPU_POWERPC_POWER5P = 0x003B0000,
|
||||
#define CPU_POWERPC_POWER5GS CPU_POWERPC_POWER5P
|
||||
CPU_POWERPC_POWER6 = 0x003E0000,
|
||||
CPU_POWERPC_POWER6_5 = 0x0F000001, /* POWER6 in POWER5 mode */
|
||||
CPU_POWERPC_POWER6A = 0x0F000002,
|
||||
CPU_POWERPC_POWER7_v20 = 0x003F0200,
|
||||
CPU_POWERPC_POWER7_v21 = 0x003F0201,
|
||||
CPU_POWERPC_POWER7_v23 = 0x003F0203,
|
||||
CPU_POWERPC_970 = 0x00390202,
|
||||
CPU_POWERPC_970FX_v10 = 0x00391100,
|
||||
CPU_POWERPC_970FX_v20 = 0x003C0200,
|
||||
CPU_POWERPC_970FX_v21 = 0x003C0201,
|
||||
CPU_POWERPC_970FX_v30 = 0x003C0300,
|
||||
CPU_POWERPC_970FX_v31 = 0x003C0301,
|
||||
CPU_POWERPC_970GX = 0x00450000,
|
||||
CPU_POWERPC_970MP_v10 = 0x00440100,
|
||||
CPU_POWERPC_970MP_v11 = 0x00440101,
|
||||
#define CPU_POWERPC_CELL CPU_POWERPC_CELL_v32
|
||||
CPU_POWERPC_CELL_v10 = 0x00700100,
|
||||
CPU_POWERPC_CELL_v20 = 0x00700400,
|
||||
CPU_POWERPC_CELL_v30 = 0x00700500,
|
||||
CPU_POWERPC_CELL_v31 = 0x00700501,
|
||||
#define CPU_POWERPC_CELL_v32 CPU_POWERPC_CELL_v31
|
||||
CPU_POWERPC_RS64 = 0x00330000,
|
||||
CPU_POWERPC_RS64II = 0x00340000,
|
||||
CPU_POWERPC_RS64III = 0x00360000,
|
||||
CPU_POWERPC_RS64IV = 0x00370000,
|
||||
#endif /* defined(TARGET_PPC64) */
|
||||
/* Original POWER */
|
||||
/* XXX: should be POWER (RIOS), RSC3308, RSC4608,
|
||||
* POWER2 (RIOS2) & RSC2 (P2SC) here
|
||||
*/
|
||||
#if 0
|
||||
CPU_POWER = xxx, /* 0x20000 ? 0x30000 for RSC ? */
|
||||
#endif
|
||||
#if 0
|
||||
CPU_POWER2 = xxx, /* 0x40000 ? */
|
||||
#endif
|
||||
/* PA Semi core */
|
||||
CPU_POWERPC_PA6T = 0x00900000,
|
||||
};
|
||||
|
||||
/* System version register (used on MPC 8xxx) */
|
||||
enum {
|
||||
POWERPC_SVR_NONE = 0x00000000,
|
||||
POWERPC_SVR_5200_v10 = 0x80110010,
|
||||
POWERPC_SVR_5200_v11 = 0x80110011,
|
||||
POWERPC_SVR_5200_v12 = 0x80110012,
|
||||
POWERPC_SVR_5200B_v20 = 0x80110020,
|
||||
POWERPC_SVR_5200B_v21 = 0x80110021,
|
||||
#define POWERPC_SVR_55xx POWERPC_SVR_5567
|
||||
#if 0
|
||||
POWERPC_SVR_5533 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_5534 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_5553 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_5554 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_5561 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_5565 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_5566 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_5567 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_8313 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_8313E = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_8314 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_8314E = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_8315 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_8315E = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_8321 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_8321E = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_8323 = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_8323E = xxx,
|
||||
#endif
|
||||
POWERPC_SVR_8343 = 0x80570010,
|
||||
POWERPC_SVR_8343A = 0x80570030,
|
||||
POWERPC_SVR_8343E = 0x80560010,
|
||||
POWERPC_SVR_8343EA = 0x80560030,
|
||||
POWERPC_SVR_8347P = 0x80550010, /* PBGA package */
|
||||
POWERPC_SVR_8347T = 0x80530010, /* TBGA package */
|
||||
POWERPC_SVR_8347AP = 0x80550030, /* PBGA package */
|
||||
POWERPC_SVR_8347AT = 0x80530030, /* TBGA package */
|
||||
POWERPC_SVR_8347EP = 0x80540010, /* PBGA package */
|
||||
POWERPC_SVR_8347ET = 0x80520010, /* TBGA package */
|
||||
POWERPC_SVR_8347EAP = 0x80540030, /* PBGA package */
|
||||
POWERPC_SVR_8347EAT = 0x80520030, /* TBGA package */
|
||||
POWERPC_SVR_8349 = 0x80510010,
|
||||
POWERPC_SVR_8349A = 0x80510030,
|
||||
POWERPC_SVR_8349E = 0x80500010,
|
||||
POWERPC_SVR_8349EA = 0x80500030,
|
||||
#if 0
|
||||
POWERPC_SVR_8358E = xxx,
|
||||
#endif
|
||||
#if 0
|
||||
POWERPC_SVR_8360E = xxx,
|
||||
#endif
|
||||
#define POWERPC_SVR_E500 0x40000000
|
||||
POWERPC_SVR_8377 = 0x80C70010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8377E = 0x80C60010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8378 = 0x80C50010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8378E = 0x80C40010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8379 = 0x80C30010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8379E = 0x80C00010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8533_v10 = 0x80340010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8533_v11 = 0x80340011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8533E_v10 = 0x803C0010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8533E_v11 = 0x803C0011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8540_v10 = 0x80300010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8540_v20 = 0x80300020 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8540_v21 = 0x80300021 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8541_v10 = 0x80720010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8541_v11 = 0x80720011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8541E_v10 = 0x807A0010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8541E_v11 = 0x807A0011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8543_v10 = 0x80320010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8543_v11 = 0x80320011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8543_v20 = 0x80320020 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8543_v21 = 0x80320021 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8543E_v10 = 0x803A0010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8543E_v11 = 0x803A0011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8543E_v20 = 0x803A0020 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8543E_v21 = 0x803A0021 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8544_v10 = 0x80340110 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8544_v11 = 0x80340111 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8544E_v10 = 0x803C0110 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8544E_v11 = 0x803C0111 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8545_v20 = 0x80310220 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8545_v21 = 0x80310221 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8545E_v20 = 0x80390220 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8545E_v21 = 0x80390221 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8547E_v20 = 0x80390120 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8547E_v21 = 0x80390121 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8548_v10 = 0x80310010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8548_v11 = 0x80310011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8548_v20 = 0x80310020 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8548_v21 = 0x80310021 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8548E_v10 = 0x80390010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8548E_v11 = 0x80390011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8548E_v20 = 0x80390020 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8548E_v21 = 0x80390021 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8555_v10 = 0x80710010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8555_v11 = 0x80710011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8555E_v10 = 0x80790010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8555E_v11 = 0x80790011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8560_v10 = 0x80700010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8560_v20 = 0x80700020 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8560_v21 = 0x80700021 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8567 = 0x80750111 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8567E = 0x807D0111 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8568 = 0x80750011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8568E = 0x807D0011 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8572 = 0x80E00010 | POWERPC_SVR_E500,
|
||||
POWERPC_SVR_8572E = 0x80E80010 | POWERPC_SVR_E500,
|
||||
#if 0
|
||||
POWERPC_SVR_8610 = xxx,
|
||||
#endif
|
||||
POWERPC_SVR_8641 = 0x80900021,
|
||||
POWERPC_SVR_8641D = 0x80900121,
|
||||
};
|
||||
|
||||
#endif
|
@ -53,8 +53,21 @@ typedef struct PowerPCCPUClass {
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
|
||||
/* TODO inline fields here */
|
||||
ppc_def_t *info;
|
||||
uint32_t pvr;
|
||||
uint32_t svr;
|
||||
uint64_t insns_flags;
|
||||
uint64_t insns_flags2;
|
||||
uint64_t msr_mask;
|
||||
powerpc_mmu_t mmu_model;
|
||||
powerpc_excp_t excp_model;
|
||||
powerpc_input_t bus_model;
|
||||
uint32_t flags;
|
||||
int bfd_mach;
|
||||
#if defined(TARGET_PPC64)
|
||||
const struct ppc_segment_page_sizes *sps;
|
||||
#endif
|
||||
void (*init_proc)(CPUPPCState *env);
|
||||
int (*check_pow)(CPUPPCState *env);
|
||||
} PowerPCCPUClass;
|
||||
|
||||
/**
|
||||
|
@ -307,7 +307,6 @@ enum powerpc_input_t {
|
||||
#define PPC_INPUT(env) (env->bus_model)
|
||||
|
||||
/*****************************************************************************/
|
||||
typedef struct ppc_def_t ppc_def_t;
|
||||
typedef struct opc_handler_t opc_handler_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -330,6 +329,12 @@ struct ppc_spr_t {
|
||||
void (*hea_write)(void *opaque, int spr_num, int gpr_num);
|
||||
#endif
|
||||
const char *name;
|
||||
#ifdef CONFIG_KVM
|
||||
/* We (ab)use the fact that all the SPRs will have ids for the
|
||||
* ONE_REG interface will have KVM_REG_PPC to use 0 as meaning,
|
||||
* don't sync this */
|
||||
uint64_t one_reg_id;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Altivec registers (128 bits) */
|
||||
@ -902,25 +907,6 @@ struct ppc_segment_page_sizes {
|
||||
/* The whole PowerPC CPU context */
|
||||
#define NB_MMU_MODES 3
|
||||
|
||||
struct ppc_def_t {
|
||||
const char *name;
|
||||
uint32_t pvr;
|
||||
uint32_t svr;
|
||||
uint64_t insns_flags;
|
||||
uint64_t insns_flags2;
|
||||
uint64_t msr_mask;
|
||||
powerpc_mmu_t mmu_model;
|
||||
powerpc_excp_t excp_model;
|
||||
powerpc_input_t bus_model;
|
||||
uint32_t flags;
|
||||
int bfd_mach;
|
||||
#if defined(TARGET_PPC64)
|
||||
const struct ppc_segment_page_sizes *sps;
|
||||
#endif
|
||||
void (*init_proc)(CPUPPCState *env);
|
||||
int (*check_pow)(CPUPPCState *env);
|
||||
};
|
||||
|
||||
struct CPUPPCState {
|
||||
/* First are the most commonly used resources
|
||||
* during translated code execution
|
||||
|
311
target-ppc/kvm.c
311
target-ppc/kvm.c
@ -61,6 +61,7 @@ static int cap_ppc_smt;
|
||||
static int cap_ppc_rma;
|
||||
static int cap_spapr_tce;
|
||||
static int cap_hior;
|
||||
static int cap_one_reg;
|
||||
|
||||
/* XXX We have a race condition where we actually have a level triggered
|
||||
* interrupt, but the infrastructure can't expose that yet, so the guest
|
||||
@ -80,6 +81,8 @@ static void kvm_kick_cpu(void *opaque)
|
||||
qemu_cpu_kick(CPU(cpu));
|
||||
}
|
||||
|
||||
static int kvm_ppc_register_host_cpu_type(void);
|
||||
|
||||
int kvm_arch_init(KVMState *s)
|
||||
{
|
||||
cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ);
|
||||
@ -89,6 +92,7 @@ int kvm_arch_init(KVMState *s)
|
||||
cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
|
||||
cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
|
||||
cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
|
||||
cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG);
|
||||
cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR);
|
||||
|
||||
if (!cap_interrupt_level) {
|
||||
@ -96,6 +100,8 @@ int kvm_arch_init(KVMState *s)
|
||||
"VM to stall at times!\n");
|
||||
}
|
||||
|
||||
kvm_ppc_register_host_cpu_type();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -449,6 +455,202 @@ static void kvm_sw_tlb_put(PowerPCCPU *cpu)
|
||||
g_free(bitmap);
|
||||
}
|
||||
|
||||
static void kvm_get_one_spr(CPUState *cs, uint64_t id, int spr)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
union {
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
} val;
|
||||
struct kvm_one_reg reg = {
|
||||
.id = id,
|
||||
.addr = (uintptr_t) &val,
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Warning: Unable to retrieve SPR %d from KVM: %s\n",
|
||||
spr, strerror(errno));
|
||||
} else {
|
||||
switch (id & KVM_REG_SIZE_MASK) {
|
||||
case KVM_REG_SIZE_U32:
|
||||
env->spr[spr] = val.u32;
|
||||
break;
|
||||
|
||||
case KVM_REG_SIZE_U64:
|
||||
env->spr[spr] = val.u64;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Don't handle this size yet */
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void kvm_put_one_spr(CPUState *cs, uint64_t id, int spr)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
union {
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
} val;
|
||||
struct kvm_one_reg reg = {
|
||||
.id = id,
|
||||
.addr = (uintptr_t) &val,
|
||||
};
|
||||
int ret;
|
||||
|
||||
switch (id & KVM_REG_SIZE_MASK) {
|
||||
case KVM_REG_SIZE_U32:
|
||||
val.u32 = env->spr[spr];
|
||||
break;
|
||||
|
||||
case KVM_REG_SIZE_U64:
|
||||
val.u64 = env->spr[spr];
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Don't handle this size yet */
|
||||
abort();
|
||||
}
|
||||
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Warning: Unable to set SPR %d to KVM: %s\n",
|
||||
spr, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static int kvm_put_fp(CPUState *cs)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
struct kvm_one_reg reg;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (env->insns_flags & PPC_FLOAT) {
|
||||
uint64_t fpscr = env->fpscr;
|
||||
bool vsx = !!(env->insns_flags2 & PPC2_VSX);
|
||||
|
||||
reg.id = KVM_REG_PPC_FPSCR;
|
||||
reg.addr = (uintptr_t)&fpscr;
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
|
||||
if (ret < 0) {
|
||||
dprintf("Unable to set FPSCR to KVM: %s\n", strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
uint64_t vsr[2];
|
||||
|
||||
vsr[0] = float64_val(env->fpr[i]);
|
||||
vsr[1] = env->vsr[i];
|
||||
reg.addr = (uintptr_t) &vsr;
|
||||
reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
|
||||
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
|
||||
if (ret < 0) {
|
||||
dprintf("Unable to set %s%d to KVM: %s\n", vsx ? "VSR" : "FPR",
|
||||
i, strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (env->insns_flags & PPC_ALTIVEC) {
|
||||
reg.id = KVM_REG_PPC_VSCR;
|
||||
reg.addr = (uintptr_t)&env->vscr;
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
|
||||
if (ret < 0) {
|
||||
dprintf("Unable to set VSCR to KVM: %s\n", strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
reg.id = KVM_REG_PPC_VR(i);
|
||||
reg.addr = (uintptr_t)&env->avr[i];
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
|
||||
if (ret < 0) {
|
||||
dprintf("Unable to set VR%d to KVM: %s\n", i, strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvm_get_fp(CPUState *cs)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
struct kvm_one_reg reg;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (env->insns_flags & PPC_FLOAT) {
|
||||
uint64_t fpscr;
|
||||
bool vsx = !!(env->insns_flags2 & PPC2_VSX);
|
||||
|
||||
reg.id = KVM_REG_PPC_FPSCR;
|
||||
reg.addr = (uintptr_t)&fpscr;
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
|
||||
if (ret < 0) {
|
||||
dprintf("Unable to get FPSCR from KVM: %s\n", strerror(errno));
|
||||
return ret;
|
||||
} else {
|
||||
env->fpscr = fpscr;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
uint64_t vsr[2];
|
||||
|
||||
reg.addr = (uintptr_t) &vsr;
|
||||
reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
|
||||
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
|
||||
if (ret < 0) {
|
||||
dprintf("Unable to get %s%d from KVM: %s\n",
|
||||
vsx ? "VSR" : "FPR", i, strerror(errno));
|
||||
return ret;
|
||||
} else {
|
||||
env->fpr[i] = vsr[0];
|
||||
if (vsx) {
|
||||
env->vsr[i] = vsr[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (env->insns_flags & PPC_ALTIVEC) {
|
||||
reg.id = KVM_REG_PPC_VSCR;
|
||||
reg.addr = (uintptr_t)&env->vscr;
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
|
||||
if (ret < 0) {
|
||||
dprintf("Unable to get VSCR from KVM: %s\n", strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
reg.id = KVM_REG_PPC_VR(i);
|
||||
reg.addr = (uintptr_t)&env->avr[i];
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
|
||||
if (ret < 0) {
|
||||
dprintf("Unable to get VR%d from KVM: %s\n",
|
||||
i, strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_put_registers(CPUState *cs, int level)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
@ -489,6 +691,8 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
kvm_put_fp(cs);
|
||||
|
||||
if (env->tlb_dirty) {
|
||||
kvm_sw_tlb_put(cpu);
|
||||
env->tlb_dirty = false;
|
||||
@ -530,15 +734,22 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
||||
}
|
||||
|
||||
if (cap_hior && (level >= KVM_PUT_RESET_STATE)) {
|
||||
uint64_t hior = env->spr[SPR_HIOR];
|
||||
struct kvm_one_reg reg = {
|
||||
.id = KVM_REG_PPC_HIOR,
|
||||
.addr = (uintptr_t) &hior,
|
||||
};
|
||||
kvm_put_one_spr(cs, KVM_REG_PPC_HIOR, SPR_HIOR);
|
||||
}
|
||||
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
|
||||
if (ret) {
|
||||
return ret;
|
||||
if (cap_one_reg) {
|
||||
int i;
|
||||
|
||||
/* We deliberately ignore errors here, for kernels which have
|
||||
* the ONE_REG calls, but don't support the specific
|
||||
* registers, there's a reasonable chance things will still
|
||||
* work, at least until we try to migrate. */
|
||||
for (i = 0; i < 1024; i++) {
|
||||
uint64_t id = env->spr_cb[i].one_reg_id;
|
||||
|
||||
if (id != 0) {
|
||||
kvm_put_one_spr(cs, id, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -587,6 +798,8 @@ int kvm_arch_get_registers(CPUState *cs)
|
||||
for (i = 0;i < 32; i++)
|
||||
env->gpr[i] = regs.gpr[i];
|
||||
|
||||
kvm_get_fp(cs);
|
||||
|
||||
if (cap_booke_sregs) {
|
||||
ret = kvm_vcpu_ioctl(cs, KVM_GET_SREGS, &sregs);
|
||||
if (ret < 0) {
|
||||
@ -721,6 +934,26 @@ int kvm_arch_get_registers(CPUState *cs)
|
||||
}
|
||||
}
|
||||
|
||||
if (cap_hior) {
|
||||
kvm_get_one_spr(cs, KVM_REG_PPC_HIOR, SPR_HIOR);
|
||||
}
|
||||
|
||||
if (cap_one_reg) {
|
||||
int i;
|
||||
|
||||
/* We deliberately ignore errors here, for kernels which have
|
||||
* the ONE_REG calls, but don't support the specific
|
||||
* registers, there's a reasonable chance things will still
|
||||
* work, at least until we try to migrate. */
|
||||
for (i = 0; i < 1024; i++) {
|
||||
uint64_t id = env->spr_cb[i].one_reg_id;
|
||||
|
||||
if (id != 0) {
|
||||
kvm_get_one_spr(cs, id, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1259,46 +1492,25 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on)
|
||||
|
||||
static void kvmppc_host_cpu_initfn(Object *obj)
|
||||
{
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(obj);
|
||||
|
||||
assert(kvm_enabled());
|
||||
|
||||
if (pcc->info->pvr != mfpvr()) {
|
||||
fprintf(stderr, "Your host CPU is unsupported.\n"
|
||||
"Please choose a supported model instead, see -cpu ?.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
|
||||
uint32_t host_pvr = mfpvr();
|
||||
PowerPCCPUClass *pvr_pcc;
|
||||
ppc_def_t *spec;
|
||||
uint32_t vmx = kvmppc_get_vmx();
|
||||
uint32_t dfp = kvmppc_get_dfp();
|
||||
|
||||
spec = g_malloc0(sizeof(*spec));
|
||||
|
||||
pvr_pcc = ppc_cpu_class_by_pvr(host_pvr);
|
||||
if (pvr_pcc != NULL) {
|
||||
memcpy(spec, pvr_pcc->info, sizeof(*spec));
|
||||
}
|
||||
pcc->info = spec;
|
||||
/* Override the display name for -cpu ? and QMP */
|
||||
pcc->info->name = "host";
|
||||
|
||||
/* Now fix up the spec with information we can query from the host */
|
||||
/* Now fix up the class with information we can query from the host */
|
||||
|
||||
if (vmx != -1) {
|
||||
/* Only override when we know what the host supports */
|
||||
alter_insns(&spec->insns_flags, PPC_ALTIVEC, vmx > 0);
|
||||
alter_insns(&spec->insns_flags2, PPC2_VSX, vmx > 1);
|
||||
alter_insns(&pcc->insns_flags, PPC_ALTIVEC, vmx > 0);
|
||||
alter_insns(&pcc->insns_flags2, PPC2_VSX, vmx > 1);
|
||||
}
|
||||
if (dfp != -1) {
|
||||
/* Only override when we know what the host supports */
|
||||
alter_insns(&spec->insns_flags2, PPC2_DFP, dfp);
|
||||
alter_insns(&pcc->insns_flags2, PPC2_DFP, dfp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1315,6 +1527,25 @@ int kvmppc_fixup_cpu(PowerPCCPU *cpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvm_ppc_register_host_cpu_type(void)
|
||||
{
|
||||
TypeInfo type_info = {
|
||||
.name = TYPE_HOST_POWERPC_CPU,
|
||||
.instance_init = kvmppc_host_cpu_initfn,
|
||||
.class_init = kvmppc_host_cpu_class_init,
|
||||
};
|
||||
uint32_t host_pvr = mfpvr();
|
||||
PowerPCCPUClass *pvr_pcc;
|
||||
|
||||
pvr_pcc = ppc_cpu_class_by_pvr(host_pvr);
|
||||
if (pvr_pcc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
type_info.parent = object_class_get_name(OBJECT_CLASS(pvr_pcc));
|
||||
type_register(&type_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool kvm_arch_stop_on_emulation_error(CPUState *cpu)
|
||||
{
|
||||
@ -1330,17 +1561,3 @@ int kvm_arch_on_sigbus(int code, void *addr)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const TypeInfo kvm_host_cpu_type_info = {
|
||||
.name = TYPE_HOST_POWERPC_CPU,
|
||||
.parent = TYPE_POWERPC_CPU,
|
||||
.instance_init = kvmppc_host_cpu_initfn,
|
||||
.class_init = kvmppc_host_cpu_class_init,
|
||||
};
|
||||
|
||||
static void kvm_ppc_register_types(void)
|
||||
{
|
||||
type_register_static(&kvm_host_cpu_type_info);
|
||||
}
|
||||
|
||||
type_init(kvm_ppc_register_types)
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user