mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/agraf/tags/signed-ppc-for-upstream' into staging
Patch queue for ppc - 2014-06-16 This pull request brings a lot of fun things. Among others we have - e500: u-boot firmware support - sPAPR: magic page enablement - sPAPR: add "compat" CPU option to support older guests - sPAPR: refactorings in preparation for VFIO - POWER8 live migration - mac99: expose bus frequency - little endian core dump, gdb and disas support - new ppc64le-linux-user target - DFP emulation - bug fixes # gpg: Signature made Mon 16 Jun 2014 12:28:32 BST using RSA key ID 03FEDC60 # gpg: Can't check signature: public key not found * remotes/agraf/tags/signed-ppc-for-upstream: (156 commits) spapr_pci: Advertise MSI quota PPC: KVM: Make pv hcall endian agnostic powerpc: use float64 for frsqrte spapr: Add kvm-type property spapr: Create SPAPRMachine struct linux-user: Tell guest about big host page sizes spapr_hcall: Add address-translation-mode-on-interrupt resource in H_SET_MODE spapr_hcall: Split h_set_mode() target-ppc: Enable DABRX SPR and limit it to <=POWER7 target-ppc: Enable PPR and VRSAVE SPRs migration target-ppc: Add POWER8's Event Based Branch (EBB) control SPRs KVM: target-ppc: Enable TM state migration target-ppc: Add POWER8's TM SPRs target-ppc: Add POWER8's MMCR2/MMCRS SPRs target-ppc: Enable FSCR facility check for TAR target-ppc: Add POWER8's FSCR SPR target-ppc: Add POWER8's TIR SPR target-ppc: Refactor class init for POWER7/8 target-ppc: Switch POWER7/8 classes to use correct PMU SPRs target-ppc: Make use of gen_spr_power5p_lpar() for POWER7/8 ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -28,3 +28,6 @@
|
||||
[submodule "dtc"]
|
||||
path = dtc
|
||||
url = git://git.qemu-project.org/dtc.git
|
||||
[submodule "roms/u-boot"]
|
||||
path = roms/u-boot
|
||||
url = git://git.qemu-project.org/u-boot.git
|
||||
|
||||
@@ -85,6 +85,12 @@ obj-y += disas.o
|
||||
obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
|
||||
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
|
||||
|
||||
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/decContext.o
|
||||
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/decNumber.o
|
||||
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal32.o
|
||||
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal64.o
|
||||
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal128.o
|
||||
|
||||
#########################################################
|
||||
# Linux user emulator target
|
||||
|
||||
|
||||
@@ -4955,6 +4955,12 @@ case "$target_name" in
|
||||
TARGET_ABI_DIR=ppc
|
||||
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
|
||||
;;
|
||||
ppc64le)
|
||||
TARGET_ARCH=ppc64
|
||||
TARGET_BASE_ARCH=ppc
|
||||
TARGET_ABI_DIR=ppc
|
||||
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
|
||||
;;
|
||||
ppc64abi32)
|
||||
TARGET_ARCH=ppc64
|
||||
TARGET_BASE_ARCH=ppc
|
||||
@@ -5222,6 +5228,7 @@ for bios_file in \
|
||||
$source_path/pc-bios/*.dtb \
|
||||
$source_path/pc-bios/*.img \
|
||||
$source_path/pc-bios/openbios-* \
|
||||
$source_path/pc-bios/u-boot.* \
|
||||
$source_path/pc-bios/palcode-*
|
||||
do
|
||||
FILES="$FILES pc-bios/`basename $bios_file`"
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
# Default configuration for ppc-linux-user
|
||||
CONFIG_LIBDECNUMBER=y
|
||||
|
||||
@@ -49,3 +49,4 @@ CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
|
||||
CONFIG_MC146818RTC=y
|
||||
CONFIG_ETSEC=y
|
||||
CONFIG_ISA_TESTDEV=y
|
||||
CONFIG_LIBDECNUMBER=y
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
# Default configuration for ppc64-linux-user
|
||||
CONFIG_LIBDECNUMBER=y
|
||||
|
||||
@@ -58,3 +58,4 @@ CONFIG_I82374=y
|
||||
CONFIG_I8257=y
|
||||
CONFIG_MC146818RTC=y
|
||||
CONFIG_ISA_TESTDEV=y
|
||||
CONFIG_LIBDECNUMBER=y
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
# Default configuration for ppc64abi32-linux-user
|
||||
CONFIG_LIBDECNUMBER=y
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Default configuration for ppc64le-linux-user
|
||||
CONFIG_LIBDECNUMBER=y
|
||||
@@ -16,3 +16,4 @@ CONFIG_I8259=y
|
||||
CONFIG_XILINX=y
|
||||
CONFIG_XILINX_ETHLITE=y
|
||||
CONFIG_OPENPIC=y
|
||||
CONFIG_LIBDECNUMBER=y
|
||||
|
||||
@@ -191,7 +191,8 @@ static int print_insn_od_target(bfd_vma pc, disassemble_info *info)
|
||||
values:
|
||||
i386 - 1 means 16 bit code, 2 means 64 bit code
|
||||
arm - bit 0 = thumb, bit 1 = reverse endian, bit 2 = A64
|
||||
ppc - nonzero means little endian
|
||||
ppc - bits 0:15 specify (optionally) the machine instruction set;
|
||||
bit 16 indicates little endian.
|
||||
other targets - unused
|
||||
*/
|
||||
void target_disas(FILE *out, CPUArchState *env, target_ulong code,
|
||||
@@ -251,11 +252,11 @@ void target_disas(FILE *out, CPUArchState *env, target_ulong code,
|
||||
s.info.mach = bfd_mach_sparc_v9b;
|
||||
#endif
|
||||
#elif defined(TARGET_PPC)
|
||||
if (flags >> 16) {
|
||||
if ((flags >> 16) & 1) {
|
||||
s.info.endian = BFD_ENDIAN_LITTLE;
|
||||
}
|
||||
if (flags & 0xFFFF) {
|
||||
/* If we have a precise definitions of the instructions set, use it */
|
||||
/* If we have a precise definition of the instruction set, use it. */
|
||||
s.info.mach = flags & 0xFFFF;
|
||||
} else {
|
||||
#ifdef TARGET_PPC64
|
||||
@@ -444,6 +445,8 @@ monitor_fprintf(FILE *stream, const char *fmt, ...)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Disassembler for the monitor.
|
||||
See target_disas for a description of flags. */
|
||||
void monitor_disas(Monitor *mon, CPUArchState *env,
|
||||
target_ulong pc, int nb_insn, int is_physical, int flags)
|
||||
{
|
||||
@@ -484,11 +487,19 @@ void monitor_disas(Monitor *mon, CPUArchState *env,
|
||||
s.info.mach = bfd_mach_sparc_v9b;
|
||||
#endif
|
||||
#elif defined(TARGET_PPC)
|
||||
if (flags & 0xFFFF) {
|
||||
/* If we have a precise definition of the instruction set, use it. */
|
||||
s.info.mach = flags & 0xFFFF;
|
||||
} else {
|
||||
#ifdef TARGET_PPC64
|
||||
s.info.mach = bfd_mach_ppc64;
|
||||
s.info.mach = bfd_mach_ppc64;
|
||||
#else
|
||||
s.info.mach = bfd_mach_ppc;
|
||||
s.info.mach = bfd_mach_ppc;
|
||||
#endif
|
||||
}
|
||||
if ((flags >> 16) & 1) {
|
||||
s.info.endian = BFD_ENDIAN_LITTLE;
|
||||
}
|
||||
print_insn = print_insn_ppc;
|
||||
#elif defined(TARGET_M68K)
|
||||
print_insn = print_insn_m68k;
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
#define ELF_MACHINE_UNAME "Unknown"
|
||||
#endif
|
||||
|
||||
static uint16_t cpu_convert_to_target16(uint16_t val, int endian)
|
||||
uint16_t cpu_to_dump16(DumpState *s, uint16_t val)
|
||||
{
|
||||
if (endian == ELFDATA2LSB) {
|
||||
if (s->dump_info.d_endian == ELFDATA2LSB) {
|
||||
val = cpu_to_le16(val);
|
||||
} else {
|
||||
val = cpu_to_be16(val);
|
||||
@@ -47,9 +47,9 @@ static uint16_t cpu_convert_to_target16(uint16_t val, int endian)
|
||||
return val;
|
||||
}
|
||||
|
||||
static uint32_t cpu_convert_to_target32(uint32_t val, int endian)
|
||||
uint32_t cpu_to_dump32(DumpState *s, uint32_t val)
|
||||
{
|
||||
if (endian == ELFDATA2LSB) {
|
||||
if (s->dump_info.d_endian == ELFDATA2LSB) {
|
||||
val = cpu_to_le32(val);
|
||||
} else {
|
||||
val = cpu_to_be32(val);
|
||||
@@ -58,9 +58,9 @@ static uint32_t cpu_convert_to_target32(uint32_t val, int endian)
|
||||
return val;
|
||||
}
|
||||
|
||||
static uint64_t cpu_convert_to_target64(uint64_t val, int endian)
|
||||
uint64_t cpu_to_dump64(DumpState *s, uint64_t val)
|
||||
{
|
||||
if (endian == ELFDATA2LSB) {
|
||||
if (s->dump_info.d_endian == ELFDATA2LSB) {
|
||||
val = cpu_to_le64(val);
|
||||
} else {
|
||||
val = cpu_to_be64(val);
|
||||
@@ -69,36 +69,6 @@ static uint64_t cpu_convert_to_target64(uint64_t val, int endian)
|
||||
return val;
|
||||
}
|
||||
|
||||
typedef struct DumpState {
|
||||
GuestPhysBlockList guest_phys_blocks;
|
||||
ArchDumpInfo dump_info;
|
||||
MemoryMappingList list;
|
||||
uint16_t phdr_num;
|
||||
uint32_t sh_info;
|
||||
bool have_section;
|
||||
bool resume;
|
||||
ssize_t note_size;
|
||||
hwaddr memory_offset;
|
||||
int fd;
|
||||
|
||||
GuestPhysBlock *next_block;
|
||||
ram_addr_t start;
|
||||
bool has_filter;
|
||||
int64_t begin;
|
||||
int64_t length;
|
||||
|
||||
uint8_t *note_buf; /* buffer for notes */
|
||||
size_t note_buf_offset; /* the writing place in note_buf */
|
||||
uint32_t nr_cpus; /* number of guest's cpu */
|
||||
uint64_t max_mapnr; /* the biggest guest's phys-mem's number */
|
||||
size_t len_dump_bitmap; /* the size of the place used to store
|
||||
dump_bitmap in vmcore */
|
||||
off_t offset_dump_bitmap; /* offset of dump_bitmap part in vmcore */
|
||||
off_t offset_page; /* offset of page part in vmcore */
|
||||
size_t num_dumpable; /* number of page that can be dumped */
|
||||
uint32_t flag_compress; /* indicate the compression format */
|
||||
} DumpState;
|
||||
|
||||
static int dump_cleanup(DumpState *s)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -137,29 +107,25 @@ static int write_elf64_header(DumpState *s)
|
||||
{
|
||||
Elf64_Ehdr elf_header;
|
||||
int ret;
|
||||
int endian = s->dump_info.d_endian;
|
||||
|
||||
memset(&elf_header, 0, sizeof(Elf64_Ehdr));
|
||||
memcpy(&elf_header, ELFMAG, SELFMAG);
|
||||
elf_header.e_ident[EI_CLASS] = ELFCLASS64;
|
||||
elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
|
||||
elf_header.e_ident[EI_VERSION] = EV_CURRENT;
|
||||
elf_header.e_type = cpu_convert_to_target16(ET_CORE, endian);
|
||||
elf_header.e_machine = cpu_convert_to_target16(s->dump_info.d_machine,
|
||||
endian);
|
||||
elf_header.e_version = cpu_convert_to_target32(EV_CURRENT, endian);
|
||||
elf_header.e_ehsize = cpu_convert_to_target16(sizeof(elf_header), endian);
|
||||
elf_header.e_phoff = cpu_convert_to_target64(sizeof(Elf64_Ehdr), endian);
|
||||
elf_header.e_phentsize = cpu_convert_to_target16(sizeof(Elf64_Phdr),
|
||||
endian);
|
||||
elf_header.e_phnum = cpu_convert_to_target16(s->phdr_num, endian);
|
||||
elf_header.e_type = cpu_to_dump16(s, ET_CORE);
|
||||
elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
|
||||
elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
|
||||
elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
|
||||
elf_header.e_phoff = cpu_to_dump64(s, sizeof(Elf64_Ehdr));
|
||||
elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr));
|
||||
elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
|
||||
if (s->have_section) {
|
||||
uint64_t shoff = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * s->sh_info;
|
||||
|
||||
elf_header.e_shoff = cpu_convert_to_target64(shoff, endian);
|
||||
elf_header.e_shentsize = cpu_convert_to_target16(sizeof(Elf64_Shdr),
|
||||
endian);
|
||||
elf_header.e_shnum = cpu_convert_to_target16(1, endian);
|
||||
elf_header.e_shoff = cpu_to_dump64(s, shoff);
|
||||
elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr));
|
||||
elf_header.e_shnum = cpu_to_dump16(s, 1);
|
||||
}
|
||||
|
||||
ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
|
||||
@@ -175,29 +141,25 @@ static int write_elf32_header(DumpState *s)
|
||||
{
|
||||
Elf32_Ehdr elf_header;
|
||||
int ret;
|
||||
int endian = s->dump_info.d_endian;
|
||||
|
||||
memset(&elf_header, 0, sizeof(Elf32_Ehdr));
|
||||
memcpy(&elf_header, ELFMAG, SELFMAG);
|
||||
elf_header.e_ident[EI_CLASS] = ELFCLASS32;
|
||||
elf_header.e_ident[EI_DATA] = endian;
|
||||
elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
|
||||
elf_header.e_ident[EI_VERSION] = EV_CURRENT;
|
||||
elf_header.e_type = cpu_convert_to_target16(ET_CORE, endian);
|
||||
elf_header.e_machine = cpu_convert_to_target16(s->dump_info.d_machine,
|
||||
endian);
|
||||
elf_header.e_version = cpu_convert_to_target32(EV_CURRENT, endian);
|
||||
elf_header.e_ehsize = cpu_convert_to_target16(sizeof(elf_header), endian);
|
||||
elf_header.e_phoff = cpu_convert_to_target32(sizeof(Elf32_Ehdr), endian);
|
||||
elf_header.e_phentsize = cpu_convert_to_target16(sizeof(Elf32_Phdr),
|
||||
endian);
|
||||
elf_header.e_phnum = cpu_convert_to_target16(s->phdr_num, endian);
|
||||
elf_header.e_type = cpu_to_dump16(s, ET_CORE);
|
||||
elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
|
||||
elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
|
||||
elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
|
||||
elf_header.e_phoff = cpu_to_dump32(s, sizeof(Elf32_Ehdr));
|
||||
elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr));
|
||||
elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
|
||||
if (s->have_section) {
|
||||
uint32_t shoff = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * s->sh_info;
|
||||
|
||||
elf_header.e_shoff = cpu_convert_to_target32(shoff, endian);
|
||||
elf_header.e_shentsize = cpu_convert_to_target16(sizeof(Elf32_Shdr),
|
||||
endian);
|
||||
elf_header.e_shnum = cpu_convert_to_target16(1, endian);
|
||||
elf_header.e_shoff = cpu_to_dump32(s, shoff);
|
||||
elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr));
|
||||
elf_header.e_shnum = cpu_to_dump16(s, 1);
|
||||
}
|
||||
|
||||
ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
|
||||
@@ -215,15 +177,14 @@ static int write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
|
||||
{
|
||||
Elf64_Phdr phdr;
|
||||
int ret;
|
||||
int endian = s->dump_info.d_endian;
|
||||
|
||||
memset(&phdr, 0, sizeof(Elf64_Phdr));
|
||||
phdr.p_type = cpu_convert_to_target32(PT_LOAD, endian);
|
||||
phdr.p_offset = cpu_convert_to_target64(offset, endian);
|
||||
phdr.p_paddr = cpu_convert_to_target64(memory_mapping->phys_addr, endian);
|
||||
phdr.p_filesz = cpu_convert_to_target64(filesz, endian);
|
||||
phdr.p_memsz = cpu_convert_to_target64(memory_mapping->length, endian);
|
||||
phdr.p_vaddr = cpu_convert_to_target64(memory_mapping->virt_addr, endian);
|
||||
phdr.p_type = cpu_to_dump32(s, PT_LOAD);
|
||||
phdr.p_offset = cpu_to_dump64(s, offset);
|
||||
phdr.p_paddr = cpu_to_dump64(s, memory_mapping->phys_addr);
|
||||
phdr.p_filesz = cpu_to_dump64(s, filesz);
|
||||
phdr.p_memsz = cpu_to_dump64(s, memory_mapping->length);
|
||||
phdr.p_vaddr = cpu_to_dump64(s, memory_mapping->virt_addr);
|
||||
|
||||
assert(memory_mapping->length >= filesz);
|
||||
|
||||
@@ -242,15 +203,14 @@ static int write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
|
||||
{
|
||||
Elf32_Phdr phdr;
|
||||
int ret;
|
||||
int endian = s->dump_info.d_endian;
|
||||
|
||||
memset(&phdr, 0, sizeof(Elf32_Phdr));
|
||||
phdr.p_type = cpu_convert_to_target32(PT_LOAD, endian);
|
||||
phdr.p_offset = cpu_convert_to_target32(offset, endian);
|
||||
phdr.p_paddr = cpu_convert_to_target32(memory_mapping->phys_addr, endian);
|
||||
phdr.p_filesz = cpu_convert_to_target32(filesz, endian);
|
||||
phdr.p_memsz = cpu_convert_to_target32(memory_mapping->length, endian);
|
||||
phdr.p_vaddr = cpu_convert_to_target32(memory_mapping->virt_addr, endian);
|
||||
phdr.p_type = cpu_to_dump32(s, PT_LOAD);
|
||||
phdr.p_offset = cpu_to_dump32(s, offset);
|
||||
phdr.p_paddr = cpu_to_dump32(s, memory_mapping->phys_addr);
|
||||
phdr.p_filesz = cpu_to_dump32(s, filesz);
|
||||
phdr.p_memsz = cpu_to_dump32(s, memory_mapping->length);
|
||||
phdr.p_vaddr = cpu_to_dump32(s, memory_mapping->virt_addr);
|
||||
|
||||
assert(memory_mapping->length >= filesz);
|
||||
|
||||
@@ -266,16 +226,15 @@ static int write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
|
||||
static int write_elf64_note(DumpState *s)
|
||||
{
|
||||
Elf64_Phdr phdr;
|
||||
int endian = s->dump_info.d_endian;
|
||||
hwaddr begin = s->memory_offset - s->note_size;
|
||||
int ret;
|
||||
|
||||
memset(&phdr, 0, sizeof(Elf64_Phdr));
|
||||
phdr.p_type = cpu_convert_to_target32(PT_NOTE, endian);
|
||||
phdr.p_offset = cpu_convert_to_target64(begin, endian);
|
||||
phdr.p_type = cpu_to_dump32(s, PT_NOTE);
|
||||
phdr.p_offset = cpu_to_dump64(s, begin);
|
||||
phdr.p_paddr = 0;
|
||||
phdr.p_filesz = cpu_convert_to_target64(s->note_size, endian);
|
||||
phdr.p_memsz = cpu_convert_to_target64(s->note_size, endian);
|
||||
phdr.p_filesz = cpu_to_dump64(s, s->note_size);
|
||||
phdr.p_memsz = cpu_to_dump64(s, s->note_size);
|
||||
phdr.p_vaddr = 0;
|
||||
|
||||
ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
|
||||
@@ -322,15 +281,14 @@ static int write_elf32_note(DumpState *s)
|
||||
{
|
||||
hwaddr begin = s->memory_offset - s->note_size;
|
||||
Elf32_Phdr phdr;
|
||||
int endian = s->dump_info.d_endian;
|
||||
int ret;
|
||||
|
||||
memset(&phdr, 0, sizeof(Elf32_Phdr));
|
||||
phdr.p_type = cpu_convert_to_target32(PT_NOTE, endian);
|
||||
phdr.p_offset = cpu_convert_to_target32(begin, endian);
|
||||
phdr.p_type = cpu_to_dump32(s, PT_NOTE);
|
||||
phdr.p_offset = cpu_to_dump32(s, begin);
|
||||
phdr.p_paddr = 0;
|
||||
phdr.p_filesz = cpu_convert_to_target32(s->note_size, endian);
|
||||
phdr.p_memsz = cpu_convert_to_target32(s->note_size, endian);
|
||||
phdr.p_filesz = cpu_to_dump32(s, s->note_size);
|
||||
phdr.p_memsz = cpu_to_dump32(s, s->note_size);
|
||||
phdr.p_vaddr = 0;
|
||||
|
||||
ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
|
||||
@@ -372,7 +330,6 @@ static int write_elf_section(DumpState *s, int type)
|
||||
{
|
||||
Elf32_Shdr shdr32;
|
||||
Elf64_Shdr shdr64;
|
||||
int endian = s->dump_info.d_endian;
|
||||
int shdr_size;
|
||||
void *shdr;
|
||||
int ret;
|
||||
@@ -380,12 +337,12 @@ static int write_elf_section(DumpState *s, int type)
|
||||
if (type == 0) {
|
||||
shdr_size = sizeof(Elf32_Shdr);
|
||||
memset(&shdr32, 0, shdr_size);
|
||||
shdr32.sh_info = cpu_convert_to_target32(s->sh_info, endian);
|
||||
shdr32.sh_info = cpu_to_dump32(s, s->sh_info);
|
||||
shdr = &shdr32;
|
||||
} else {
|
||||
shdr_size = sizeof(Elf64_Shdr);
|
||||
memset(&shdr64, 0, shdr_size);
|
||||
shdr64.sh_info = cpu_convert_to_target32(s->sh_info, endian);
|
||||
shdr64.sh_info = cpu_to_dump32(s, s->sh_info);
|
||||
shdr = &shdr64;
|
||||
}
|
||||
|
||||
@@ -791,7 +748,6 @@ static int create_header32(DumpState *s)
|
||||
DiskDumpHeader32 *dh = NULL;
|
||||
KdumpSubHeader32 *kh = NULL;
|
||||
size_t size;
|
||||
int endian = s->dump_info.d_endian;
|
||||
uint32_t block_size;
|
||||
uint32_t sub_hdr_size;
|
||||
uint32_t bitmap_blocks;
|
||||
@@ -803,18 +759,17 @@ static int create_header32(DumpState *s)
|
||||
dh = g_malloc0(size);
|
||||
|
||||
strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
|
||||
dh->header_version = cpu_convert_to_target32(6, endian);
|
||||
dh->header_version = cpu_to_dump32(s, 6);
|
||||
block_size = TARGET_PAGE_SIZE;
|
||||
dh->block_size = cpu_convert_to_target32(block_size, endian);
|
||||
dh->block_size = cpu_to_dump32(s, block_size);
|
||||
sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size;
|
||||
sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
|
||||
dh->sub_hdr_size = cpu_convert_to_target32(sub_hdr_size, endian);
|
||||
dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
|
||||
/* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
|
||||
dh->max_mapnr = cpu_convert_to_target32(MIN(s->max_mapnr, UINT_MAX),
|
||||
endian);
|
||||
dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
|
||||
dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
|
||||
dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
|
||||
bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
|
||||
dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
|
||||
dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
|
||||
strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
|
||||
|
||||
if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
|
||||
@@ -830,7 +785,7 @@ static int create_header32(DumpState *s)
|
||||
status |= DUMP_DH_COMPRESSED_SNAPPY;
|
||||
}
|
||||
#endif
|
||||
dh->status = cpu_convert_to_target32(status, endian);
|
||||
dh->status = cpu_to_dump32(s, status);
|
||||
|
||||
if (write_buffer(s->fd, 0, dh, size) < 0) {
|
||||
dump_error(s, "dump: failed to write disk dump header.\n");
|
||||
@@ -843,13 +798,13 @@ static int create_header32(DumpState *s)
|
||||
kh = g_malloc0(size);
|
||||
|
||||
/* 64bit max_mapnr_64 */
|
||||
kh->max_mapnr_64 = cpu_convert_to_target64(s->max_mapnr, endian);
|
||||
kh->phys_base = cpu_convert_to_target32(PHYS_BASE, endian);
|
||||
kh->dump_level = cpu_convert_to_target32(DUMP_LEVEL, endian);
|
||||
kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
|
||||
kh->phys_base = cpu_to_dump32(s, PHYS_BASE);
|
||||
kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
|
||||
|
||||
offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
|
||||
kh->offset_note = cpu_convert_to_target64(offset_note, endian);
|
||||
kh->note_size = cpu_convert_to_target32(s->note_size, endian);
|
||||
kh->offset_note = cpu_to_dump64(s, offset_note);
|
||||
kh->note_size = cpu_to_dump32(s, s->note_size);
|
||||
|
||||
if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
|
||||
block_size, kh, size) < 0) {
|
||||
@@ -898,7 +853,6 @@ static int create_header64(DumpState *s)
|
||||
DiskDumpHeader64 *dh = NULL;
|
||||
KdumpSubHeader64 *kh = NULL;
|
||||
size_t size;
|
||||
int endian = s->dump_info.d_endian;
|
||||
uint32_t block_size;
|
||||
uint32_t sub_hdr_size;
|
||||
uint32_t bitmap_blocks;
|
||||
@@ -910,18 +864,17 @@ static int create_header64(DumpState *s)
|
||||
dh = g_malloc0(size);
|
||||
|
||||
strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
|
||||
dh->header_version = cpu_convert_to_target32(6, endian);
|
||||
dh->header_version = cpu_to_dump32(s, 6);
|
||||
block_size = TARGET_PAGE_SIZE;
|
||||
dh->block_size = cpu_convert_to_target32(block_size, endian);
|
||||
dh->block_size = cpu_to_dump32(s, block_size);
|
||||
sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size;
|
||||
sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
|
||||
dh->sub_hdr_size = cpu_convert_to_target32(sub_hdr_size, endian);
|
||||
dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
|
||||
/* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
|
||||
dh->max_mapnr = cpu_convert_to_target32(MIN(s->max_mapnr, UINT_MAX),
|
||||
endian);
|
||||
dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
|
||||
dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
|
||||
dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
|
||||
bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
|
||||
dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
|
||||
dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
|
||||
strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
|
||||
|
||||
if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
|
||||
@@ -937,7 +890,7 @@ static int create_header64(DumpState *s)
|
||||
status |= DUMP_DH_COMPRESSED_SNAPPY;
|
||||
}
|
||||
#endif
|
||||
dh->status = cpu_convert_to_target32(status, endian);
|
||||
dh->status = cpu_to_dump32(s, status);
|
||||
|
||||
if (write_buffer(s->fd, 0, dh, size) < 0) {
|
||||
dump_error(s, "dump: failed to write disk dump header.\n");
|
||||
@@ -950,13 +903,13 @@ static int create_header64(DumpState *s)
|
||||
kh = g_malloc0(size);
|
||||
|
||||
/* 64bit max_mapnr_64 */
|
||||
kh->max_mapnr_64 = cpu_convert_to_target64(s->max_mapnr, endian);
|
||||
kh->phys_base = cpu_convert_to_target64(PHYS_BASE, endian);
|
||||
kh->dump_level = cpu_convert_to_target32(DUMP_LEVEL, endian);
|
||||
kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
|
||||
kh->phys_base = cpu_to_dump64(s, PHYS_BASE);
|
||||
kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
|
||||
|
||||
offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
|
||||
kh->offset_note = cpu_convert_to_target64(offset_note, endian);
|
||||
kh->note_size = cpu_convert_to_target64(s->note_size, endian);
|
||||
kh->offset_note = cpu_to_dump64(s, offset_note);
|
||||
kh->note_size = cpu_to_dump64(s, s->note_size);
|
||||
|
||||
if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
|
||||
block_size, kh, size) < 0) {
|
||||
@@ -1260,7 +1213,6 @@ static int write_dump_pages(DumpState *s)
|
||||
off_t offset_desc, offset_data;
|
||||
PageDescriptor pd, pd_zero;
|
||||
uint8_t *buf;
|
||||
int endian = s->dump_info.d_endian;
|
||||
GuestPhysBlock *block_iter = NULL;
|
||||
uint64_t pfn_iter;
|
||||
|
||||
@@ -1285,10 +1237,10 @@ static int write_dump_pages(DumpState *s)
|
||||
* init zero page's page_desc and page_data, because every zero page
|
||||
* uses the same page_data
|
||||
*/
|
||||
pd_zero.size = cpu_convert_to_target32(TARGET_PAGE_SIZE, endian);
|
||||
pd_zero.flags = cpu_convert_to_target32(0, endian);
|
||||
pd_zero.offset = cpu_convert_to_target64(offset_data, endian);
|
||||
pd_zero.page_flags = cpu_convert_to_target64(0, endian);
|
||||
pd_zero.size = cpu_to_dump32(s, TARGET_PAGE_SIZE);
|
||||
pd_zero.flags = cpu_to_dump32(s, 0);
|
||||
pd_zero.offset = cpu_to_dump64(s, offset_data);
|
||||
pd_zero.page_flags = cpu_to_dump64(s, 0);
|
||||
buf = g_malloc0(TARGET_PAGE_SIZE);
|
||||
ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false);
|
||||
g_free(buf);
|
||||
@@ -1326,12 +1278,11 @@ static int write_dump_pages(DumpState *s)
|
||||
*/
|
||||
size_out = len_buf_out;
|
||||
if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) &&
|
||||
(compress2(buf_out, (uLongf *)&size_out, buf,
|
||||
TARGET_PAGE_SIZE, Z_BEST_SPEED) == Z_OK) &&
|
||||
(size_out < TARGET_PAGE_SIZE)) {
|
||||
pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_ZLIB,
|
||||
endian);
|
||||
pd.size = cpu_convert_to_target32(size_out, endian);
|
||||
(compress2(buf_out, (uLongf *)&size_out, buf,
|
||||
TARGET_PAGE_SIZE, Z_BEST_SPEED) == Z_OK) &&
|
||||
(size_out < TARGET_PAGE_SIZE)) {
|
||||
pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_ZLIB);
|
||||
pd.size = cpu_to_dump32(s, size_out);
|
||||
|
||||
ret = write_cache(&page_data, buf_out, size_out, false);
|
||||
if (ret < 0) {
|
||||
@@ -1343,9 +1294,8 @@ static int write_dump_pages(DumpState *s)
|
||||
(lzo1x_1_compress(buf, TARGET_PAGE_SIZE, buf_out,
|
||||
(lzo_uint *)&size_out, wrkmem) == LZO_E_OK) &&
|
||||
(size_out < TARGET_PAGE_SIZE)) {
|
||||
pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_LZO,
|
||||
endian);
|
||||
pd.size = cpu_convert_to_target32(size_out, endian);
|
||||
pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_LZO);
|
||||
pd.size = cpu_to_dump32(s, size_out);
|
||||
|
||||
ret = write_cache(&page_data, buf_out, size_out, false);
|
||||
if (ret < 0) {
|
||||
@@ -1358,9 +1308,8 @@ static int write_dump_pages(DumpState *s)
|
||||
(snappy_compress((char *)buf, TARGET_PAGE_SIZE,
|
||||
(char *)buf_out, &size_out) == SNAPPY_OK) &&
|
||||
(size_out < TARGET_PAGE_SIZE)) {
|
||||
pd.flags = cpu_convert_to_target32(
|
||||
DUMP_DH_COMPRESSED_SNAPPY, endian);
|
||||
pd.size = cpu_convert_to_target32(size_out, endian);
|
||||
pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_SNAPPY);
|
||||
pd.size = cpu_to_dump32(s, size_out);
|
||||
|
||||
ret = write_cache(&page_data, buf_out, size_out, false);
|
||||
if (ret < 0) {
|
||||
@@ -1373,9 +1322,9 @@ static int write_dump_pages(DumpState *s)
|
||||
* fall back to save in plaintext, size_out should be
|
||||
* assigned TARGET_PAGE_SIZE
|
||||
*/
|
||||
pd.flags = cpu_convert_to_target32(0, endian);
|
||||
pd.flags = cpu_to_dump32(s, 0);
|
||||
size_out = TARGET_PAGE_SIZE;
|
||||
pd.size = cpu_convert_to_target32(size_out, endian);
|
||||
pd.size = cpu_to_dump32(s, size_out);
|
||||
|
||||
ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false);
|
||||
if (ret < 0) {
|
||||
@@ -1385,8 +1334,8 @@ static int write_dump_pages(DumpState *s)
|
||||
}
|
||||
|
||||
/* get and write page desc here */
|
||||
pd.page_flags = cpu_convert_to_target64(0, endian);
|
||||
pd.offset = cpu_convert_to_target64(offset_data, endian);
|
||||
pd.page_flags = cpu_to_dump64(s, 0);
|
||||
pd.offset = cpu_to_dump64(s, offset_data);
|
||||
offset_data += size_out;
|
||||
|
||||
ret = write_cache(&page_desc, &pd, sizeof(PageDescriptor), false);
|
||||
|
||||
+61
-10
@@ -193,6 +193,11 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (--io->requests) {
|
||||
/* More requests still in flight */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m->dma_active) {
|
||||
MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n",
|
||||
s->nsector, io->len, s->status);
|
||||
@@ -212,6 +217,13 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
|
||||
s->nsector -= n;
|
||||
}
|
||||
|
||||
if (io->finish_remain_read) {
|
||||
/* Finish a stale read from the last iteration */
|
||||
io->finish_remain_read = false;
|
||||
cpu_physical_memory_write(io->finish_addr, io->remainder,
|
||||
io->finish_len);
|
||||
}
|
||||
|
||||
MACIO_DPRINTF("remainder: %d io->len: %d nsector: %d "
|
||||
"sector_num: %" PRId64 "\n",
|
||||
io->remainder_len, io->len, s->nsector, sector_num);
|
||||
@@ -229,7 +241,6 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
|
||||
break;
|
||||
case IDE_DMA_WRITE:
|
||||
cpu_physical_memory_read(io->addr, p, remainder_len);
|
||||
bdrv_write(s->bs, sector_num - 1, io->remainder, 1);
|
||||
break;
|
||||
case IDE_DMA_TRIM:
|
||||
break;
|
||||
@@ -237,6 +248,15 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
|
||||
io->addr += remainder_len;
|
||||
io->len -= remainder_len;
|
||||
io->remainder_len -= remainder_len;
|
||||
|
||||
if (s->dma_cmd == IDE_DMA_WRITE && !io->remainder_len) {
|
||||
io->requests++;
|
||||
qemu_iovec_reset(&io->iov);
|
||||
qemu_iovec_add(&io->iov, io->remainder, 0x200);
|
||||
|
||||
m->aiocb = bdrv_aio_writev(s->bs, sector_num - 1, &io->iov, 1,
|
||||
pmac_ide_transfer_cb, io);
|
||||
}
|
||||
}
|
||||
|
||||
if (s->nsector == 0 && !io->remainder_len) {
|
||||
@@ -267,20 +287,25 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
|
||||
|
||||
switch (s->dma_cmd) {
|
||||
case IDE_DMA_READ:
|
||||
bdrv_read(s->bs, sector_num + nsector, io->remainder, 1);
|
||||
cpu_physical_memory_write(io->addr + io->len - unaligned,
|
||||
io->remainder, unaligned);
|
||||
io->requests++;
|
||||
io->finish_addr = io->addr + io->len - unaligned;
|
||||
io->finish_len = unaligned;
|
||||
io->finish_remain_read = true;
|
||||
qemu_iovec_reset(&io->iov);
|
||||
qemu_iovec_add(&io->iov, io->remainder, 0x200);
|
||||
|
||||
m->aiocb = bdrv_aio_readv(s->bs, sector_num + nsector, &io->iov, 1,
|
||||
pmac_ide_transfer_cb, io);
|
||||
break;
|
||||
case IDE_DMA_WRITE:
|
||||
/* cache the contents in our io struct */
|
||||
cpu_physical_memory_read(io->addr + io->len - unaligned,
|
||||
io->remainder, unaligned);
|
||||
io->remainder + io->remainder_len,
|
||||
unaligned);
|
||||
break;
|
||||
case IDE_DMA_TRIM:
|
||||
break;
|
||||
}
|
||||
|
||||
io->len -= unaligned;
|
||||
}
|
||||
|
||||
MACIO_DPRINTF("io->len = %#x\n", io->len);
|
||||
@@ -292,10 +317,12 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
|
||||
io->remainder_len = (0x200 - unaligned) & 0x1ff;
|
||||
MACIO_DPRINTF("set remainder to: %d\n", io->remainder_len);
|
||||
|
||||
/* We would read no data from the block layer, thus not get a callback.
|
||||
Just fake completion manually. */
|
||||
/* Only subsector reads happening */
|
||||
if (!io->len) {
|
||||
pmac_ide_transfer_cb(opaque, 0);
|
||||
if (!io->requests) {
|
||||
io->requests++;
|
||||
pmac_ide_transfer_cb(opaque, ret);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -319,6 +346,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
|
||||
DMA_DIRECTION_TO_DEVICE);
|
||||
break;
|
||||
}
|
||||
|
||||
io->requests++;
|
||||
return;
|
||||
|
||||
done:
|
||||
@@ -337,6 +366,27 @@ static void pmac_ide_transfer(DBDMA_io *io)
|
||||
|
||||
s->io_buffer_size = 0;
|
||||
if (s->drive_kind == IDE_CD) {
|
||||
|
||||
/* Handle non-block ATAPI DMA transfers */
|
||||
if (s->lba == -1) {
|
||||
s->io_buffer_size = MIN(io->len, s->packet_transfer_size);
|
||||
bdrv_acct_start(s->bs, &s->acct, s->io_buffer_size,
|
||||
BDRV_ACCT_READ);
|
||||
MACIO_DPRINTF("non-block ATAPI DMA transfer size: %d\n",
|
||||
s->io_buffer_size);
|
||||
|
||||
/* Copy ATAPI buffer directly to RAM and finish */
|
||||
cpu_physical_memory_write(io->addr, s->io_buffer,
|
||||
s->io_buffer_size);
|
||||
ide_atapi_cmd_ok(s);
|
||||
m->dma_active = false;
|
||||
|
||||
MACIO_DPRINTF("end of non-block ATAPI DMA transfer\n");
|
||||
bdrv_acct_done(s->bs, &s->acct);
|
||||
io->dma_end(io);
|
||||
return;
|
||||
}
|
||||
|
||||
bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
|
||||
pmac_ide_atapi_transfer_cb(io, 0);
|
||||
return;
|
||||
@@ -353,6 +403,7 @@ static void pmac_ide_transfer(DBDMA_io *io)
|
||||
break;
|
||||
}
|
||||
|
||||
io->requests++;
|
||||
pmac_ide_transfer_cb(io, 0);
|
||||
}
|
||||
|
||||
|
||||
+50
-49
@@ -192,6 +192,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
|
||||
int idx);
|
||||
static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
|
||||
uint32_t val, int idx);
|
||||
static void openpic_reset(DeviceState *d);
|
||||
|
||||
typedef enum IRQType {
|
||||
IRQ_TYPE_NORMAL = 0,
|
||||
@@ -529,55 +530,6 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level)
|
||||
}
|
||||
}
|
||||
|
||||
static void openpic_reset(DeviceState *d)
|
||||
{
|
||||
OpenPICState *opp = OPENPIC(d);
|
||||
int i;
|
||||
|
||||
opp->gcr = GCR_RESET;
|
||||
/* Initialise controller registers */
|
||||
opp->frr = ((opp->nb_irqs - 1) << FRR_NIRQ_SHIFT) |
|
||||
((opp->nb_cpus - 1) << FRR_NCPU_SHIFT) |
|
||||
(opp->vid << FRR_VID_SHIFT);
|
||||
|
||||
opp->pir = 0;
|
||||
opp->spve = -1 & opp->vector_mask;
|
||||
opp->tfrr = opp->tfrr_reset;
|
||||
/* Initialise IRQ sources */
|
||||
for (i = 0; i < opp->max_irq; i++) {
|
||||
opp->src[i].ivpr = opp->ivpr_reset;
|
||||
opp->src[i].idr = opp->idr_reset;
|
||||
|
||||
switch (opp->src[i].type) {
|
||||
case IRQ_TYPE_NORMAL:
|
||||
opp->src[i].level = !!(opp->ivpr_reset & IVPR_SENSE_MASK);
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_FSLINT:
|
||||
opp->src[i].ivpr |= IVPR_POLARITY_MASK;
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_FSLSPECIAL:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Initialise IRQ destinations */
|
||||
for (i = 0; i < MAX_CPU; i++) {
|
||||
opp->dst[i].ctpr = 15;
|
||||
memset(&opp->dst[i].raised, 0, sizeof(IRQQueue));
|
||||
opp->dst[i].raised.next = -1;
|
||||
memset(&opp->dst[i].servicing, 0, sizeof(IRQQueue));
|
||||
opp->dst[i].servicing.next = -1;
|
||||
}
|
||||
/* Initialise timers */
|
||||
for (i = 0; i < OPENPIC_MAX_TMR; i++) {
|
||||
opp->timers[i].tccr = 0;
|
||||
opp->timers[i].tbcr = TBCR_CI;
|
||||
}
|
||||
/* Go out of RESET state */
|
||||
opp->gcr = 0;
|
||||
}
|
||||
|
||||
static inline uint32_t read_IRQreg_idr(OpenPICState *opp, int n_IRQ)
|
||||
{
|
||||
return opp->src[n_IRQ].idr;
|
||||
@@ -1461,6 +1413,55 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void openpic_reset(DeviceState *d)
|
||||
{
|
||||
OpenPICState *opp = OPENPIC(d);
|
||||
int i;
|
||||
|
||||
opp->gcr = GCR_RESET;
|
||||
/* Initialise controller registers */
|
||||
opp->frr = ((opp->nb_irqs - 1) << FRR_NIRQ_SHIFT) |
|
||||
((opp->nb_cpus - 1) << FRR_NCPU_SHIFT) |
|
||||
(opp->vid << FRR_VID_SHIFT);
|
||||
|
||||
opp->pir = 0;
|
||||
opp->spve = -1 & opp->vector_mask;
|
||||
opp->tfrr = opp->tfrr_reset;
|
||||
/* Initialise IRQ sources */
|
||||
for (i = 0; i < opp->max_irq; i++) {
|
||||
opp->src[i].ivpr = opp->ivpr_reset;
|
||||
switch (opp->src[i].type) {
|
||||
case IRQ_TYPE_NORMAL:
|
||||
opp->src[i].level = !!(opp->ivpr_reset & IVPR_SENSE_MASK);
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_FSLINT:
|
||||
opp->src[i].ivpr |= IVPR_POLARITY_MASK;
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_FSLSPECIAL:
|
||||
break;
|
||||
}
|
||||
|
||||
write_IRQreg_idr(opp, i, opp->idr_reset);
|
||||
}
|
||||
/* Initialise IRQ destinations */
|
||||
for (i = 0; i < MAX_CPU; i++) {
|
||||
opp->dst[i].ctpr = 15;
|
||||
memset(&opp->dst[i].raised, 0, sizeof(IRQQueue));
|
||||
opp->dst[i].raised.next = -1;
|
||||
memset(&opp->dst[i].servicing, 0, sizeof(IRQQueue));
|
||||
opp->dst[i].servicing.next = -1;
|
||||
}
|
||||
/* Initialise timers */
|
||||
for (i = 0; i < OPENPIC_MAX_TMR; i++) {
|
||||
opp->timers[i].tccr = 0;
|
||||
opp->timers[i].tbcr = TBCR_CI;
|
||||
}
|
||||
/* Go out of RESET state */
|
||||
opp->gcr = 0;
|
||||
}
|
||||
|
||||
typedef struct MemReg {
|
||||
const char *name;
|
||||
MemoryRegionOps const *ops;
|
||||
|
||||
+10
-5
@@ -31,6 +31,8 @@
|
||||
#include "sysemu/kvm.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
#define GCR_RESET 0x80000000
|
||||
|
||||
#define KVM_OPENPIC(obj) \
|
||||
OBJECT_CHECK(KVMOpenPICState, (obj), TYPE_KVM_OPENPIC)
|
||||
|
||||
@@ -50,11 +52,6 @@ static void kvm_openpic_set_irq(void *opaque, int n_IRQ, int level)
|
||||
kvm_set_irq(kvm_state, n_IRQ, level);
|
||||
}
|
||||
|
||||
static void kvm_openpic_reset(DeviceState *d)
|
||||
{
|
||||
qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
|
||||
}
|
||||
|
||||
static void kvm_openpic_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned size)
|
||||
{
|
||||
@@ -74,6 +71,14 @@ static void kvm_openpic_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
}
|
||||
}
|
||||
|
||||
static void kvm_openpic_reset(DeviceState *d)
|
||||
{
|
||||
KVMOpenPICState *opp = KVM_OPENPIC(d);
|
||||
|
||||
/* Trigger the GCR.RESET bit to reset the PIC */
|
||||
kvm_openpic_write(opp, 0x1020, GCR_RESET, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
static uint64_t kvm_openpic_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
KVMOpenPICState *opp = opaque;
|
||||
|
||||
@@ -748,9 +748,15 @@ static void dbdma_reset(void *opaque)
|
||||
void* DBDMA_init (MemoryRegion **dbdma_mem)
|
||||
{
|
||||
DBDMAState *s;
|
||||
int i;
|
||||
|
||||
s = g_malloc0(sizeof(DBDMAState));
|
||||
|
||||
for (i = 0; i < DBDMA_CHANNELS; i++) {
|
||||
DBDMA_io *io = &s->channels[i].io;
|
||||
qemu_iovec_init(&io->iov, 1);
|
||||
}
|
||||
|
||||
memory_region_init_io(&s->mem, NULL, &dbdma_ops, s, "dbdma", 0x1000);
|
||||
*dbdma_mem = &s->mem;
|
||||
vmstate_register(NULL, -1, &vmstate_dbdma, s);
|
||||
|
||||
@@ -259,7 +259,7 @@ static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size)
|
||||
static const MemoryRegionOps timer_ops = {
|
||||
.read = timer_read,
|
||||
.write = timer_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static int macio_newworld_initfn(PCIDevice *d)
|
||||
|
||||
@@ -159,7 +159,7 @@ static void ievent_set(eTSEC *etsec,
|
||||
|
||||
if ((flags & IEVENT_RXB && etsec->regs[IMASK].value & IMASK_RXBEN)
|
||||
|| (flags & IEVENT_RXF && etsec->regs[IMASK].value & IMASK_RXFEN)) {
|
||||
qemu_irq_pulse(etsec->rx_irq);
|
||||
qemu_irq_raise(etsec->rx_irq);
|
||||
RING_DEBUG("%s Raise Rx IRQ\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ typedef struct sPAPRNVRAM {
|
||||
|
||||
#define MIN_NVRAM_SIZE 8192
|
||||
#define DEFAULT_NVRAM_SIZE 65536
|
||||
#define MAX_NVRAM_SIZE (UINT16_MAX * 16)
|
||||
#define MAX_NVRAM_SIZE 1048576
|
||||
|
||||
static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
|
||||
+31
-10
@@ -87,8 +87,10 @@ struct PPCE500PCIState {
|
||||
struct pci_outbound pob[PPCE500_PCI_NR_POBS];
|
||||
struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
|
||||
uint32_t gasket_time;
|
||||
qemu_irq irq[4];
|
||||
qemu_irq irq[PCI_NUM_PINS];
|
||||
uint32_t irq_num[PCI_NUM_PINS];
|
||||
uint32_t first_slot;
|
||||
uint32_t first_pin_irq;
|
||||
/* mmio maps */
|
||||
MemoryRegion container;
|
||||
MemoryRegion iomem;
|
||||
@@ -252,26 +254,39 @@ static const MemoryRegionOps e500_pci_reg_ops = {
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
};
|
||||
|
||||
static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
|
||||
static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int pin)
|
||||
{
|
||||
int devno = pci_dev->devfn >> 3;
|
||||
int ret;
|
||||
|
||||
ret = ppce500_pci_map_irq_slot(devno, irq_num);
|
||||
ret = ppce500_pci_map_irq_slot(devno, pin);
|
||||
|
||||
pci_debug("%s: devfn %x irq %d -> %d devno:%x\n", __func__,
|
||||
pci_dev->devfn, irq_num, ret, devno);
|
||||
pci_dev->devfn, pin, ret, devno);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mpc85xx_pci_set_irq(void *opaque, int irq_num, int level)
|
||||
static void mpc85xx_pci_set_irq(void *opaque, int pin, int level)
|
||||
{
|
||||
qemu_irq *pic = opaque;
|
||||
PPCE500PCIState *s = opaque;
|
||||
qemu_irq *pic = s->irq;
|
||||
|
||||
pci_debug("%s: PCI irq %d, level:%d\n", __func__, irq_num, level);
|
||||
pci_debug("%s: PCI irq %d, level:%d\n", __func__, pin , level);
|
||||
|
||||
qemu_set_irq(pic[irq_num], level);
|
||||
qemu_set_irq(pic[pin], level);
|
||||
}
|
||||
|
||||
static PCIINTxRoute e500_route_intx_pin_to_irq(void *opaque, int pin)
|
||||
{
|
||||
PCIINTxRoute route;
|
||||
PPCE500PCIState *s = opaque;
|
||||
|
||||
route.mode = PCI_INTX_ENABLED;
|
||||
route.irq = s->irq_num[pin];
|
||||
|
||||
pci_debug("%s: PCI irq-pin = %d, irq_num= %d\n", __func__, pin, route.irq);
|
||||
return route;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_pci_outbound = {
|
||||
@@ -308,7 +323,7 @@ static const VMStateDescription vmstate_ppce500_pci = {
|
||||
VMSTATE_STRUCT_ARRAY(pob, PPCE500PCIState, PPCE500_PCI_NR_POBS, 1,
|
||||
vmstate_pci_outbound, struct pci_outbound),
|
||||
VMSTATE_STRUCT_ARRAY(pib, PPCE500PCIState, PPCE500_PCI_NR_PIBS, 1,
|
||||
vmstate_pci_outbound, struct pci_inbound),
|
||||
vmstate_pci_inbound, struct pci_inbound),
|
||||
VMSTATE_UINT32(gasket_time, PPCE500PCIState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
@@ -349,10 +364,14 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
|
||||
sysbus_init_irq(dev, &s->irq[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < PCI_NUM_PINS; i++) {
|
||||
s->irq_num[i] = s->first_pin_irq + i;
|
||||
}
|
||||
|
||||
memory_region_init(&s->pio, OBJECT(s), "pci-pio", PCIE500_PCI_IOLEN);
|
||||
|
||||
b = pci_register_bus(DEVICE(dev), NULL, mpc85xx_pci_set_irq,
|
||||
mpc85xx_pci_map_irq, s->irq, address_space_mem,
|
||||
mpc85xx_pci_map_irq, s, address_space_mem,
|
||||
&s->pio, PCI_DEVFN(s->first_slot, 0), 4, TYPE_PCI_BUS);
|
||||
h->bus = b;
|
||||
|
||||
@@ -370,6 +389,7 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
|
||||
memory_region_add_subregion(&s->container, PCIE500_REG_BASE, &s->iomem);
|
||||
sysbus_init_mmio(dev, &s->container);
|
||||
sysbus_init_mmio(dev, &s->pio);
|
||||
pci_bus_set_route_irq_fn(b, e500_route_intx_pin_to_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -400,6 +420,7 @@ static const TypeInfo e500_host_bridge_info = {
|
||||
|
||||
static Property pcihost_properties[] = {
|
||||
DEFINE_PROP_UINT32("first_slot", PPCE500PCIState, first_slot, 0x11),
|
||||
DEFINE_PROP_UINT32("first_pin_irq", PPCE500PCIState, first_pin_irq, 0x1),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user