/* * SPAPR definitions and declarations * * Borrowed heavily from QEMU's spapr.h, * Copyright (c) 2010 David Gibson, IBM Corporation. * * Modifications by Matt Evans , IBM Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. */ #if !defined(__HW_SPAPR_H__) #define __HW_SPAPR_H__ #include #include #include "kvm/kvm.h" #include "kvm/kvm-cpu.h" typedef unsigned long target_ulong; typedef uintptr_t target_phys_addr_t; #define H_SUCCESS 0 #define H_HARDWARE -1 /* Hardware error */ #define H_FUNCTION -2 /* Function not supported */ #define H_PARAMETER -4 /* Parameter invalid, out-of-range or conflicting */ #define H_P2 -55 #define H_SET_DABR 0x28 #define H_LOGICAL_CI_LOAD 0x3c #define H_LOGICAL_CI_STORE 0x40 #define H_LOGICAL_CACHE_LOAD 0x44 #define H_LOGICAL_CACHE_STORE 0x48 #define H_LOGICAL_ICBI 0x4c #define H_LOGICAL_DCBF 0x50 #define H_GET_TERM_CHAR 0x54 #define H_PUT_TERM_CHAR 0x58 #define H_CPPR 0x68 #define H_EOI 0x64 #define H_IPI 0x6c #define H_XIRR 0x74 #define H_SET_MODE 0x31C #define MAX_HCALL_OPCODE H_SET_MODE /* Values for 2nd argument to H_SET_MODE */ #define H_SET_MODE_RESOURCE_SET_CIABR 1 #define H_SET_MODE_RESOURCE_SET_DAWR 2 #define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3 #define H_SET_MODE_RESOURCE_LE 4 /* Flags for H_SET_MODE_RESOURCE_LE */ #define H_SET_MODE_ENDIAN_BIG 0 #define H_SET_MODE_ENDIAN_LITTLE 1 /* * The hcalls above are standardized in PAPR and implemented by pHyp * as well. * * We also need some hcalls which are specific to qemu / KVM-on-POWER. * So far we just need one for H_RTAS, but in future we'll need more * for extensions like virtio. We put those into the 0xf000-0xfffc * range which is reserved by PAPR for "platform-specific" hcalls. */ #define KVMPPC_HCALL_BASE 0xf000 #define KVMPPC_H_RTAS (KVMPPC_HCALL_BASE + 0x0) #define KVMPPC_HCALL_MAX KVMPPC_H_RTAS #define DEBUG_SPAPR_HCALLS #ifdef DEBUG_SPAPR_HCALLS #define hcall_dprintf(fmt, ...) \ do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) #else #define hcall_dprintf(fmt, ...) \ do { } while (0) #endif typedef target_ulong (*spapr_hcall_fn)(struct kvm_cpu *vcpu, target_ulong opcode, target_ulong *args); void hypercall_init(void); void register_core_rtas(void); void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn); target_ulong spapr_hypercall(struct kvm_cpu *vcpu, target_ulong opcode, target_ulong *args); int spapr_rtas_fdt_setup(struct kvm *kvm, void *fdt); static inline uint32_t rtas_ld(struct kvm *kvm, target_ulong phys, int n) { return cpu_to_be32(*((uint32_t *)guest_flat_to_host(kvm, phys + 4*n))); } static inline void rtas_st(struct kvm *kvm, target_ulong phys, int n, uint32_t val) { *((uint32_t *)guest_flat_to_host(kvm, phys + 4*n)) = cpu_to_be32(val); } typedef void (*spapr_rtas_fn)(struct kvm_cpu *vcpu, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets); void spapr_rtas_register(const char *name, spapr_rtas_fn fn); target_ulong spapr_rtas_call(struct kvm_cpu *vcpu, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets); #define SPAPR_PCI_BUID 0x800000020000001ULL #define SPAPR_PCI_MEM_WIN_ADDR (KVM_MMIO_START + 0xA0000000) #define SPAPR_PCI_MEM_WIN_SIZE 0x20000000 #define SPAPR_PCI_IO_WIN_ADDR (SPAPR_PCI_MEM_WIN_ADDR + SPAPR_PCI_MEM_WIN_SIZE) #define SPAPR_PCI_IO_WIN_SIZE 0x2000000 #define SPAPR_PCI_WIN_START SPAPR_PCI_MEM_WIN_ADDR #define SPAPR_PCI_WIN_END (SPAPR_PCI_IO_WIN_ADDR + SPAPR_PCI_IO_WIN_SIZE) #endif /* !defined (__HW_SPAPR_H__) */