1be76823fSMatt Evans /* 2be76823fSMatt Evans * SPAPR definitions and declarations 3be76823fSMatt Evans * 4be76823fSMatt Evans * Borrowed heavily from QEMU's spapr.h, 5be76823fSMatt Evans * Copyright (c) 2010 David Gibson, IBM Corporation. 6be76823fSMatt Evans * 7be76823fSMatt Evans * Modifications by Matt Evans <matt@ozlabs.org>, IBM Corporation. 8be76823fSMatt Evans * 9be76823fSMatt Evans * This program is free software; you can redistribute it and/or modify it 10be76823fSMatt Evans * under the terms of the GNU General Public License version 2 as published 11be76823fSMatt Evans * by the Free Software Foundation. 12be76823fSMatt Evans */ 13be76823fSMatt Evans 14be76823fSMatt Evans #if !defined(__HW_SPAPR_H__) 15be76823fSMatt Evans #define __HW_SPAPR_H__ 16be76823fSMatt Evans 17be76823fSMatt Evans #include <inttypes.h> 18*62a15bd1SBalbir Singh #include <linux/byteorder.h> 19be76823fSMatt Evans 20be76823fSMatt Evans #include "kvm/kvm.h" 21be76823fSMatt Evans #include "kvm/kvm-cpu.h" 22be76823fSMatt Evans 23be76823fSMatt Evans typedef unsigned long target_ulong; 24be76823fSMatt Evans typedef uintptr_t target_phys_addr_t; 25be76823fSMatt Evans 26241f595fSMichael Ellerman #define H_SUCCESS 0 27241f595fSMichael Ellerman #define H_HARDWARE -1 /* Hardware error */ 28241f595fSMichael Ellerman #define H_FUNCTION -2 /* Function not supported */ 29241f595fSMichael Ellerman #define H_PARAMETER -4 /* Parameter invalid, out-of-range or conflicting */ 30241f595fSMichael Ellerman 31241f595fSMichael Ellerman #define H_SET_DABR 0x28 32241f595fSMichael Ellerman #define H_LOGICAL_CI_LOAD 0x3c 33241f595fSMichael Ellerman #define H_LOGICAL_CI_STORE 0x40 34241f595fSMichael Ellerman #define H_LOGICAL_CACHE_LOAD 0x44 35241f595fSMichael Ellerman #define H_LOGICAL_CACHE_STORE 0x48 36241f595fSMichael Ellerman #define H_LOGICAL_ICBI 0x4c 37241f595fSMichael Ellerman #define H_LOGICAL_DCBF 0x50 38241f595fSMichael Ellerman #define H_GET_TERM_CHAR 0x54 39241f595fSMichael Ellerman #define H_PUT_TERM_CHAR 0x58 40241f595fSMichael Ellerman #define H_CPPR 0x68 41241f595fSMichael Ellerman #define H_EOI 0x64 42241f595fSMichael Ellerman #define H_IPI 0x6c 43241f595fSMichael Ellerman #define H_XIRR 0x74 44241f595fSMichael Ellerman #define MAX_HCALL_OPCODE H_XIRR 45241f595fSMichael Ellerman 46be76823fSMatt Evans /* 47be76823fSMatt Evans * The hcalls above are standardized in PAPR and implemented by pHyp 48be76823fSMatt Evans * as well. 49be76823fSMatt Evans * 50be76823fSMatt Evans * We also need some hcalls which are specific to qemu / KVM-on-POWER. 51be76823fSMatt Evans * So far we just need one for H_RTAS, but in future we'll need more 52be76823fSMatt Evans * for extensions like virtio. We put those into the 0xf000-0xfffc 53be76823fSMatt Evans * range which is reserved by PAPR for "platform-specific" hcalls. 54be76823fSMatt Evans */ 55be76823fSMatt Evans #define KVMPPC_HCALL_BASE 0xf000 56be76823fSMatt Evans #define KVMPPC_H_RTAS (KVMPPC_HCALL_BASE + 0x0) 57be76823fSMatt Evans #define KVMPPC_HCALL_MAX KVMPPC_H_RTAS 58be76823fSMatt Evans 59be76823fSMatt Evans #define DEBUG_SPAPR_HCALLS 60be76823fSMatt Evans 61be76823fSMatt Evans #ifdef DEBUG_SPAPR_HCALLS 62be76823fSMatt Evans #define hcall_dprintf(fmt, ...) \ 63be76823fSMatt Evans do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) 64be76823fSMatt Evans #else 65be76823fSMatt Evans #define hcall_dprintf(fmt, ...) \ 66be76823fSMatt Evans do { } while (0) 67be76823fSMatt Evans #endif 68be76823fSMatt Evans 69be76823fSMatt Evans typedef target_ulong (*spapr_hcall_fn)(struct kvm_cpu *vcpu, 70be76823fSMatt Evans target_ulong opcode, 71be76823fSMatt Evans target_ulong *args); 72be76823fSMatt Evans 73be76823fSMatt Evans void hypercall_init(void); 74be76823fSMatt Evans void register_core_rtas(void); 75be76823fSMatt Evans 76be76823fSMatt Evans void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn); 77be76823fSMatt Evans target_ulong spapr_hypercall(struct kvm_cpu *vcpu, target_ulong opcode, 78be76823fSMatt Evans target_ulong *args); 79be76823fSMatt Evans 80be76823fSMatt Evans int spapr_rtas_fdt_setup(struct kvm *kvm, void *fdt); 81be76823fSMatt Evans 82be76823fSMatt Evans static inline uint32_t rtas_ld(struct kvm *kvm, target_ulong phys, int n) 83be76823fSMatt Evans { 84*62a15bd1SBalbir Singh return cpu_to_be32(*((uint32_t *)guest_flat_to_host(kvm, phys + 4*n))); 85be76823fSMatt Evans } 86be76823fSMatt Evans 87be76823fSMatt Evans static inline void rtas_st(struct kvm *kvm, target_ulong phys, int n, uint32_t val) 88be76823fSMatt Evans { 89*62a15bd1SBalbir Singh *((uint32_t *)guest_flat_to_host(kvm, phys + 4*n)) = cpu_to_be32(val); 90be76823fSMatt Evans } 91be76823fSMatt Evans 92be76823fSMatt Evans typedef void (*spapr_rtas_fn)(struct kvm_cpu *vcpu, uint32_t token, 93be76823fSMatt Evans uint32_t nargs, target_ulong args, 94be76823fSMatt Evans uint32_t nret, target_ulong rets); 95be76823fSMatt Evans void spapr_rtas_register(const char *name, spapr_rtas_fn fn); 96be76823fSMatt Evans target_ulong spapr_rtas_call(struct kvm_cpu *vcpu, 97be76823fSMatt Evans uint32_t token, uint32_t nargs, target_ulong args, 98be76823fSMatt Evans uint32_t nret, target_ulong rets); 99be76823fSMatt Evans 100c481cfd5SMatt Evans #define SPAPR_PCI_BUID 0x800000020000001ULL 101c481cfd5SMatt Evans #define SPAPR_PCI_MEM_WIN_ADDR (KVM_MMIO_START + 0xA0000000) 102c481cfd5SMatt Evans #define SPAPR_PCI_MEM_WIN_SIZE 0x20000000 103c481cfd5SMatt Evans #define SPAPR_PCI_IO_WIN_ADDR (SPAPR_PCI_MEM_WIN_ADDR + SPAPR_PCI_MEM_WIN_SIZE) 104c481cfd5SMatt Evans #define SPAPR_PCI_IO_WIN_SIZE 0x2000000 105c481cfd5SMatt Evans 106c481cfd5SMatt Evans #define SPAPR_PCI_WIN_START SPAPR_PCI_MEM_WIN_ADDR 107c481cfd5SMatt Evans #define SPAPR_PCI_WIN_END (SPAPR_PCI_IO_WIN_ADDR + SPAPR_PCI_IO_WIN_SIZE) 108c481cfd5SMatt Evans 109be76823fSMatt Evans #endif /* !defined (__HW_SPAPR_H__) */ 110