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>
1862a15bd1SBalbir 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 */
30*015785d4SBalbir Singh #define H_P2 -55
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
44*015785d4SBalbir Singh #define H_SET_MODE 0x31C
45*015785d4SBalbir Singh #define MAX_HCALL_OPCODE H_SET_MODE
46*015785d4SBalbir Singh
47*015785d4SBalbir Singh /* Values for 2nd argument to H_SET_MODE */
48*015785d4SBalbir Singh #define H_SET_MODE_RESOURCE_SET_CIABR 1
49*015785d4SBalbir Singh #define H_SET_MODE_RESOURCE_SET_DAWR 2
50*015785d4SBalbir Singh #define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3
51*015785d4SBalbir Singh #define H_SET_MODE_RESOURCE_LE 4
52*015785d4SBalbir Singh
53*015785d4SBalbir Singh /* Flags for H_SET_MODE_RESOURCE_LE */
54*015785d4SBalbir Singh #define H_SET_MODE_ENDIAN_BIG 0
55*015785d4SBalbir Singh #define H_SET_MODE_ENDIAN_LITTLE 1
56241f595fSMichael Ellerman
57be76823fSMatt Evans /*
58be76823fSMatt Evans * The hcalls above are standardized in PAPR and implemented by pHyp
59be76823fSMatt Evans * as well.
60be76823fSMatt Evans *
61be76823fSMatt Evans * We also need some hcalls which are specific to qemu / KVM-on-POWER.
62be76823fSMatt Evans * So far we just need one for H_RTAS, but in future we'll need more
63be76823fSMatt Evans * for extensions like virtio. We put those into the 0xf000-0xfffc
64be76823fSMatt Evans * range which is reserved by PAPR for "platform-specific" hcalls.
65be76823fSMatt Evans */
66be76823fSMatt Evans #define KVMPPC_HCALL_BASE 0xf000
67be76823fSMatt Evans #define KVMPPC_H_RTAS (KVMPPC_HCALL_BASE + 0x0)
68be76823fSMatt Evans #define KVMPPC_HCALL_MAX KVMPPC_H_RTAS
69be76823fSMatt Evans
70be76823fSMatt Evans #define DEBUG_SPAPR_HCALLS
71be76823fSMatt Evans
72be76823fSMatt Evans #ifdef DEBUG_SPAPR_HCALLS
73be76823fSMatt Evans #define hcall_dprintf(fmt, ...) \
74be76823fSMatt Evans do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
75be76823fSMatt Evans #else
76be76823fSMatt Evans #define hcall_dprintf(fmt, ...) \
77be76823fSMatt Evans do { } while (0)
78be76823fSMatt Evans #endif
79be76823fSMatt Evans
80be76823fSMatt Evans typedef target_ulong (*spapr_hcall_fn)(struct kvm_cpu *vcpu,
81be76823fSMatt Evans target_ulong opcode,
82be76823fSMatt Evans target_ulong *args);
83be76823fSMatt Evans
84be76823fSMatt Evans void hypercall_init(void);
85be76823fSMatt Evans void register_core_rtas(void);
86be76823fSMatt Evans
87be76823fSMatt Evans void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn);
88be76823fSMatt Evans target_ulong spapr_hypercall(struct kvm_cpu *vcpu, target_ulong opcode,
89be76823fSMatt Evans target_ulong *args);
90be76823fSMatt Evans
91be76823fSMatt Evans int spapr_rtas_fdt_setup(struct kvm *kvm, void *fdt);
92be76823fSMatt Evans
rtas_ld(struct kvm * kvm,target_ulong phys,int n)93be76823fSMatt Evans static inline uint32_t rtas_ld(struct kvm *kvm, target_ulong phys, int n)
94be76823fSMatt Evans {
9562a15bd1SBalbir Singh return cpu_to_be32(*((uint32_t *)guest_flat_to_host(kvm, phys + 4*n)));
96be76823fSMatt Evans }
97be76823fSMatt Evans
rtas_st(struct kvm * kvm,target_ulong phys,int n,uint32_t val)98be76823fSMatt Evans static inline void rtas_st(struct kvm *kvm, target_ulong phys, int n, uint32_t val)
99be76823fSMatt Evans {
10062a15bd1SBalbir Singh *((uint32_t *)guest_flat_to_host(kvm, phys + 4*n)) = cpu_to_be32(val);
101be76823fSMatt Evans }
102be76823fSMatt Evans
103be76823fSMatt Evans typedef void (*spapr_rtas_fn)(struct kvm_cpu *vcpu, uint32_t token,
104be76823fSMatt Evans uint32_t nargs, target_ulong args,
105be76823fSMatt Evans uint32_t nret, target_ulong rets);
106be76823fSMatt Evans void spapr_rtas_register(const char *name, spapr_rtas_fn fn);
107be76823fSMatt Evans target_ulong spapr_rtas_call(struct kvm_cpu *vcpu,
108be76823fSMatt Evans uint32_t token, uint32_t nargs, target_ulong args,
109be76823fSMatt Evans uint32_t nret, target_ulong rets);
110be76823fSMatt Evans
111c481cfd5SMatt Evans #define SPAPR_PCI_BUID 0x800000020000001ULL
112c481cfd5SMatt Evans #define SPAPR_PCI_MEM_WIN_ADDR (KVM_MMIO_START + 0xA0000000)
113c481cfd5SMatt Evans #define SPAPR_PCI_MEM_WIN_SIZE 0x20000000
114c481cfd5SMatt Evans #define SPAPR_PCI_IO_WIN_ADDR (SPAPR_PCI_MEM_WIN_ADDR + SPAPR_PCI_MEM_WIN_SIZE)
115c481cfd5SMatt Evans #define SPAPR_PCI_IO_WIN_SIZE 0x2000000
116c481cfd5SMatt Evans
117c481cfd5SMatt Evans #define SPAPR_PCI_WIN_START SPAPR_PCI_MEM_WIN_ADDR
118c481cfd5SMatt Evans #define SPAPR_PCI_WIN_END (SPAPR_PCI_IO_WIN_ADDR + SPAPR_PCI_IO_WIN_SIZE)
119c481cfd5SMatt Evans
120be76823fSMatt Evans #endif /* !defined (__HW_SPAPR_H__) */
121