xref: /openbmc/qemu/target/ppc/internal.h (revision 9b4b4e510bcb8b1c3c4789615dce3b520aa1f1d3)
1  /*
2   *  PowerPC internal definitions for qemu.
3   *
4   * This library is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU Lesser General Public
6   * License as published by the Free Software Foundation; either
7   * version 2.1 of the License, or (at your option) any later version.
8   *
9   * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16   */
17  
18  #ifndef PPC_INTERNAL_H
19  #define PPC_INTERNAL_H
20  
21  #include "hw/registerfields.h"
22  
23  #define FUNC_MASK(name, ret_type, size, max_val)                  \
24  static inline ret_type name(uint##size##_t start,                 \
25                                uint##size##_t end)                 \
26  {                                                                 \
27      ret_type ret, max_bit = size - 1;                             \
28                                                                    \
29      if (likely(start == 0)) {                                     \
30          ret = max_val << (max_bit - end);                         \
31      } else if (likely(end == max_bit)) {                          \
32          ret = max_val >> start;                                   \
33      } else {                                                      \
34          ret = (((uint##size##_t)(-1ULL)) >> (start)) ^            \
35              (((uint##size##_t)(-1ULL) >> (end)) >> 1);            \
36          if (unlikely(start > end)) {                              \
37              return ~ret;                                          \
38          }                                                         \
39      }                                                             \
40                                                                    \
41      return ret;                                                   \
42  }
43  
44  #if defined(TARGET_PPC64)
45  FUNC_MASK(MASK, target_ulong, 64, UINT64_MAX);
46  #else
47  FUNC_MASK(MASK, target_ulong, 32, UINT32_MAX);
48  #endif
49  FUNC_MASK(mask_u32, uint32_t, 32, UINT32_MAX);
50  FUNC_MASK(mask_u64, uint64_t, 64, UINT64_MAX);
51  
52  /*****************************************************************************/
53  /***                           Instruction decoding                        ***/
54  #define EXTRACT_HELPER(name, shift, nb)                                       \
55  static inline uint32_t name(uint32_t opcode)                                  \
56  {                                                                             \
57      return extract32(opcode, shift, nb);                                      \
58  }
59  
60  #define EXTRACT_SHELPER(name, shift, nb)                                      \
61  static inline int32_t name(uint32_t opcode)                                   \
62  {                                                                             \
63      return sextract32(opcode, shift, nb);                                     \
64  }
65  
66  #define EXTRACT_HELPER_SPLIT(name, shift1, nb1, shift2, nb2)                  \
67  static inline uint32_t name(uint32_t opcode)                                  \
68  {                                                                             \
69      return extract32(opcode, shift1, nb1) << nb2 |                            \
70                 extract32(opcode, shift2, nb2);                                \
71  }
72  
73  #define EXTRACT_HELPER_SPLIT_3(name,                                          \
74                                d0_bits, shift_op_d0, shift_d0,                 \
75                                d1_bits, shift_op_d1, shift_d1,                 \
76                                d2_bits, shift_op_d2, shift_d2)                 \
77  static inline int16_t name(uint32_t opcode)                                   \
78  {                                                                             \
79      return                                                                    \
80          (((opcode >> (shift_op_d0)) & ((1 << (d0_bits)) - 1)) << (shift_d0)) | \
81          (((opcode >> (shift_op_d1)) & ((1 << (d1_bits)) - 1)) << (shift_d1)) | \
82          (((opcode >> (shift_op_d2)) & ((1 << (d2_bits)) - 1)) << (shift_d2));  \
83  }
84  
85  
86  /* Opcode part 1 */
87  EXTRACT_HELPER(opc1, 26, 6);
88  /* Opcode part 2 */
89  EXTRACT_HELPER(opc2, 1, 5);
90  /* Opcode part 3 */
91  EXTRACT_HELPER(opc3, 6, 5);
92  /* Opcode part 4 */
93  EXTRACT_HELPER(opc4, 16, 5);
94  /* Update Cr0 flags */
95  EXTRACT_HELPER(Rc, 0, 1);
96  /* Update Cr6 flags (Altivec) */
97  EXTRACT_HELPER(Rc21, 10, 1);
98  /* Destination */
99  EXTRACT_HELPER(rD, 21, 5);
100  /* Source */
101  EXTRACT_HELPER(rS, 21, 5);
102  /* First operand */
103  EXTRACT_HELPER(rA, 16, 5);
104  /* Second operand */
105  EXTRACT_HELPER(rB, 11, 5);
106  /* Third operand */
107  EXTRACT_HELPER(rC, 6, 5);
108  /***                               Get CRn                                 ***/
109  EXTRACT_HELPER(crfD, 23, 3);
110  EXTRACT_HELPER(BF, 23, 3);
111  EXTRACT_HELPER(crfS, 18, 3);
112  EXTRACT_HELPER(crbD, 21, 5);
113  EXTRACT_HELPER(crbA, 16, 5);
114  EXTRACT_HELPER(crbB, 11, 5);
115  /* SPR / TBL */
116  EXTRACT_HELPER(_SPR, 11, 10);
117  static inline uint32_t SPR(uint32_t opcode)
118  {
119      uint32_t sprn = _SPR(opcode);
120  
121      return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
122  }
123  /***                              Get constants                            ***/
124  /* 16 bits signed immediate value */
125  EXTRACT_SHELPER(SIMM, 0, 16);
126  /* 16 bits unsigned immediate value */
127  EXTRACT_HELPER(UIMM, 0, 16);
128  /* 5 bits signed immediate value */
129  EXTRACT_SHELPER(SIMM5, 16, 5);
130  /* 5 bits signed immediate value */
131  EXTRACT_HELPER(UIMM5, 16, 5);
132  /* 4 bits unsigned immediate value */
133  EXTRACT_HELPER(UIMM4, 16, 4);
134  /* Bit count */
135  EXTRACT_HELPER(NB, 11, 5);
136  /* Shift count */
137  EXTRACT_HELPER(SH, 11, 5);
138  /* lwat/stwat/ldat/lwat */
139  EXTRACT_HELPER(FC, 11, 5);
140  /* Vector shift count */
141  EXTRACT_HELPER(VSH, 6, 4);
142  /* Mask start */
143  EXTRACT_HELPER(MB, 6, 5);
144  /* Mask end */
145  EXTRACT_HELPER(ME, 1, 5);
146  /* Trap operand */
147  EXTRACT_HELPER(TO, 21, 5);
148  
149  EXTRACT_HELPER(CRM, 12, 8);
150  
151  #ifndef CONFIG_USER_ONLY
152  EXTRACT_HELPER(SR, 16, 4);
153  #endif
154  
155  /* mtfsf/mtfsfi */
156  EXTRACT_HELPER(FPBF, 23, 3);
157  EXTRACT_HELPER(FPIMM, 12, 4);
158  EXTRACT_HELPER(FPL, 25, 1);
159  EXTRACT_HELPER(FPFLM, 17, 8);
160  EXTRACT_HELPER(FPW, 16, 1);
161  
162  /* addpcis */
163  EXTRACT_HELPER_SPLIT_3(DX, 10, 6, 6, 5, 16, 1, 1, 0, 0)
164  #if defined(TARGET_PPC64)
165  /* darn */
166  EXTRACT_HELPER(L, 16, 2);
167  #endif
168  /* wait */
169  EXTRACT_HELPER(WC, 21, 2);
170  EXTRACT_HELPER(PL, 16, 2);
171  
172  /***                            Jump target decoding                       ***/
173  /* Immediate address */
174  static inline target_ulong LI(uint32_t opcode)
175  {
176      return (opcode >> 0) & 0x03FFFFFC;
177  }
178  
179  static inline uint32_t BD(uint32_t opcode)
180  {
181      return (opcode >> 0) & 0xFFFC;
182  }
183  
184  EXTRACT_HELPER(BO, 21, 5);
185  EXTRACT_HELPER(BI, 16, 5);
186  /* Absolute/relative address */
187  EXTRACT_HELPER(AA, 1, 1);
188  /* Link */
189  EXTRACT_HELPER(LK, 0, 1);
190  
191  /* DFP Z22-form */
192  EXTRACT_HELPER(DCM, 10, 6)
193  
194  /* DFP Z23-form */
195  EXTRACT_HELPER(RMC, 9, 2)
196  EXTRACT_HELPER(Rrm, 16, 1)
197  
198  EXTRACT_HELPER_SPLIT(DQxT, 3, 1, 21, 5);
199  EXTRACT_HELPER_SPLIT(xT, 0, 1, 21, 5);
200  EXTRACT_HELPER_SPLIT(xS, 0, 1, 21, 5);
201  EXTRACT_HELPER_SPLIT(xA, 2, 1, 16, 5);
202  EXTRACT_HELPER_SPLIT(xB, 1, 1, 11, 5);
203  EXTRACT_HELPER_SPLIT(xC, 3, 1,  6, 5);
204  EXTRACT_HELPER(DM, 8, 2);
205  EXTRACT_HELPER(UIM, 16, 2);
206  EXTRACT_HELPER(SHW, 8, 2);
207  EXTRACT_HELPER(SP, 19, 2);
208  EXTRACT_HELPER(IMM8, 11, 8);
209  EXTRACT_HELPER(DCMX, 16, 7);
210  EXTRACT_HELPER_SPLIT_3(DCMX_XV, 5, 16, 0, 1, 2, 5, 1, 6, 6);
211  
212  void helper_compute_fprf_float16(CPUPPCState *env, float16 arg);
213  void helper_compute_fprf_float32(CPUPPCState *env, float32 arg);
214  void helper_compute_fprf_float128(CPUPPCState *env, float128 arg);
215  
216  /* translate.c */
217  
218  int ppc_fixup_cpu(PowerPCCPU *cpu);
219  void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp);
220  void destroy_ppc_opcodes(PowerPCCPU *cpu);
221  
222  /* gdbstub.c */
223  void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
224  gchar *ppc_gdb_arch_name(CPUState *cs);
225  
226  /**
227   * prot_for_access_type:
228   * @access_type: Access type
229   *
230   * Return the protection bit required for the given access type.
231   */
232  static inline int prot_for_access_type(MMUAccessType access_type)
233  {
234      switch (access_type) {
235      case MMU_INST_FETCH:
236          return PAGE_EXEC;
237      case MMU_DATA_LOAD:
238          return PAGE_READ;
239      case MMU_DATA_STORE:
240          return PAGE_WRITE;
241      }
242      g_assert_not_reached();
243  }
244  
245  #ifndef CONFIG_USER_ONLY
246  
247  /* PowerPC MMU emulation */
248  
249  typedef struct mmu_ctx_t mmu_ctx_t;
250  
251  bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
252                        hwaddr *raddrp, int *psizep, int *protp,
253                        int mmu_idx, bool guest_visible);
254  int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
255                                       target_ulong eaddr,
256                                       MMUAccessType access_type, int type,
257                                       int mmu_idx);
258  /* Software driven TLB helpers */
259  int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
260                                      int way, int is_code);
261  /* Context used internally during MMU translations */
262  struct mmu_ctx_t {
263      hwaddr raddr;      /* Real address              */
264      hwaddr eaddr;      /* Effective address         */
265      int prot;                      /* Protection bits           */
266      hwaddr hash[2];    /* Pagetable hash values     */
267      target_ulong ptem;             /* Virtual segment ID | API  */
268      int key;                       /* Access key                */
269      int nx;                        /* Non-execute area          */
270  };
271  
272  #endif /* !CONFIG_USER_ONLY */
273  
274  /* Common routines used by software and hardware TLBs emulation */
275  static inline int pte_is_valid(target_ulong pte0)
276  {
277      return pte0 & 0x80000000 ? 1 : 0;
278  }
279  
280  static inline void pte_invalidate(target_ulong *pte0)
281  {
282      *pte0 &= ~0x80000000;
283  }
284  
285  #define PTE_PTEM_MASK 0x7FFFFFBF
286  #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
287  
288  #ifdef CONFIG_USER_ONLY
289  void ppc_cpu_record_sigsegv(CPUState *cs, vaddr addr,
290                              MMUAccessType access_type,
291                              bool maperr, uintptr_t ra);
292  #else
293  bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
294                        MMUAccessType access_type, int mmu_idx,
295                        bool probe, uintptr_t retaddr);
296  G_NORETURN void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
297                                              MMUAccessType access_type, int mmu_idx,
298                                              uintptr_t retaddr);
299  void ppc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
300                                     vaddr addr, unsigned size,
301                                     MMUAccessType access_type,
302                                     int mmu_idx, MemTxAttrs attrs,
303                                     MemTxResult response, uintptr_t retaddr);
304  void ppc_cpu_debug_excp_handler(CPUState *cs);
305  bool ppc_cpu_debug_check_breakpoint(CPUState *cs);
306  bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
307  #endif
308  
309  FIELD(GER_MSK, XMSK, 0, 4)
310  FIELD(GER_MSK, YMSK, 4, 4)
311  FIELD(GER_MSK, PMSK, 8, 8)
312  
313  static inline int ger_pack_masks(int pmsk, int ymsk, int xmsk)
314  {
315      int msk = 0;
316      msk = FIELD_DP32(msk, GER_MSK, XMSK, xmsk);
317      msk = FIELD_DP32(msk, GER_MSK, YMSK, ymsk);
318      msk = FIELD_DP32(msk, GER_MSK, PMSK, pmsk);
319      return msk;
320  }
321  
322  #endif /* PPC_INTERNAL_H */
323