fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 237 lines 7.6 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/cpu/ppc405/internal.h * 7 * Created: 2003-11-07 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2003-2018 Hampa Hug <hampa@hampa.ch> * 9 * Copyright: (C) 2003-2006 Lukas Ruf <ruf@lpr.ch> * 10 *****************************************************************************/ 11 12/***************************************************************************** 13 * This program is free software. You can redistribute it and / or modify it * 14 * under the terms of the GNU General Public License version 2 as published * 15 * by the Free Software Foundation. * 16 * * 17 * This program is distributed in the hope that it will be useful, but * 18 * WITHOUT ANY WARRANTY, without even the implied warranty of * 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 20 * Public License for more details. * 21 *****************************************************************************/ 22 23/***************************************************************************** 24 * This software was developed at the Computer Engineering and Networks * 25 * Laboratory (TIK), Swiss Federal Institute of Technology (ETH) Zurich. * 26 *****************************************************************************/ 27 28 29#ifndef PPC405_INTERNAL_H 30#define PPC405_INTERNAL_H 31 32 33#include <stdlib.h> 34#include <stdio.h> 35 36 37/***************************************************************************** 38 * MMU 39 *****************************************************************************/ 40 41void p405_tlb_init (p405_tlb_t *tlb); 42 43void p405_tbuf_clear (p405_t *c); 44 45void p405_set_tlb_entry_hi (p405_t *c, unsigned idx, uint32_t tlbhi, uint8_t pid); 46void p405_set_tlb_entry_lo (p405_t *c, unsigned idx, uint32_t tlblo); 47 48uint32_t p405_get_tlb_entry_hi (p405_t *c, unsigned idx); 49uint32_t p405_get_tlb_entry_lo (p405_t *c, unsigned idx); 50uint32_t p405_get_tlb_entry_tid (p405_t *c, unsigned idx); 51 52void p405_tlb_invalidate_all (p405_t *c); 53 54int p405_ifetch (p405_t *c, uint32_t addr, uint32_t *val); 55 56int p405_dload8 (p405_t *c, uint32_t addr, uint8_t *val); 57int p405_dload16 (p405_t *c, uint32_t addr, uint16_t *val); 58int p405_dload32 (p405_t *c, uint32_t addr, uint32_t *val); 59 60int p405_dstore8 (p405_t *c, uint32_t addr, uint8_t val); 61int p405_dstore16 (p405_t *c, uint32_t addr, uint16_t val); 62int p405_dstore32 (p405_t *c, uint32_t addr, uint32_t val); 63 64 65/***************************************************************************** 66 * PPC 67 *****************************************************************************/ 68 69#define P405_PVR_405GP 0x40110000 70#define P405_PVR_405GP_A 0x40110000 71#define P405_PVR_405GP_B 0x40110040 72#define P405_PVR_405GP_C 0x40110082 73#define P405_PVR_405GP_D 0x401100c4 74#define P405_PVR_NPE405H 0x41410140UL 75#define P405_PVR_NPE405L 0x416100c0UL 76 77#define P405_CACHE_LINE_SIZE 32 78 79#define P405_IR_OE 0x0400 80#define P405_IR_RC 0x0001 81#define P405_IR_LK 0x0001 82#define P405_IR_AA 0x0002 83 84#define P405_INT_EXT 1 85#define P405_INT_PIT 2 86#define P405_INT_FIT 4 87 88#define P405_EXCPT_MSR (P405_MSR_AP | P405_MSR_APE | P405_MSR_WE | P405_MSR_EE |\ 89 P405_MSR_PR | P405_MSR_FP | P405_MSR_FE0 | P405_MSR_DWE | P405_MSR_FE1 |\ 90 P405_MSR_IR | P405_MSR_DR) 91 92#define p405_sext(x, n) ( \ 93 ((x) & (1UL << ((n) - 1))) ? \ 94 (((x) | ~((1UL << (n)) - 1)) & 0xffffffffUL) : \ 95 ((x) & ((1UL << (n)) - 1)) \ 96 ) 97 98#define p405_uext(x, n) ((x) & ((1 << (n)) - 1)) 99 100#define p405_bits(val, i, n) (((val) >> (32 - (i) - (n))) & ((1UL << (n)) - 1)) 101 102#define p405_get_ir_rc(ir) (((ir) & P405_IR_RC) != 0) 103#define p405_get_ir_oe(ir) (((ir) & P405_IR_OE) != 0) 104#define p405_get_ir_lk(ir) (((ir) & P405_IR_LK) != 0) 105#define p405_get_ir_aa(ir) (((ir) & P405_IR_AA) != 0) 106 107#define p405_get_ir_ra(ir) (((ir) >> 16) & 0x1f) 108#define p405_get_ir_rb(ir) (((ir) >> 11) & 0x1f) 109#define p405_get_ir_rs(ir) (((ir) >> 21) & 0x1f) 110#define p405_get_ir_rt(ir) (((ir) >> 21) & 0x1f) 111 112#define p405_get_ra(c, ir) ((c)->gpr[p405_get_ir_ra (ir)]) 113#define p405_get_rb(c, ir) ((c)->gpr[p405_get_ir_rb (ir)]) 114#define p405_get_rs(c, ir) ((c)->gpr[p405_get_ir_rs (ir)]) 115#define p405_get_rt(c, ir) ((c)->gpr[p405_get_ir_rt (ir)]) 116#define p405_get_ra0(c, ir) (((ir) & 0x1f0000) ? p405_get_ra (c, ir) : 0) 117 118#define p405_set_ra(c, ir, val) do { (c)->gpr[p405_get_ir_ra (ir)] = (val); } while (0) 119#define p405_set_rb(c, ir, val) do { (c)->gpr[p405_get_ir_rb (ir)] = (val); } while (0) 120#define p405_set_rs(c, ir, val) do { (c)->gpr[p405_get_ir_rs (ir)] = (val); } while (0) 121#define p405_set_rt(c, ir, val) do { (c)->gpr[p405_get_ir_rt (ir)] = (val); } while (0) 122 123#define p405_get_simm16(ir) (((ir) & 0x8000) ? ((ir) | 0xffff0000) : ((ir) & 0xffff)) 124#define p405_get_uimm16(ir) ((ir) & 0xffff) 125 126#define p405_set_clk(c, dpc, clk) do { (c)->pc += (dpc); (c)->delay += (clk); } while (0) 127 128 129typedef struct { 130 unsigned op; 131 p405_opcode_f fct; 132} p405_opcode_list_t; 133 134 135uint64_t p405_mul (uint32_t s1, uint32_t s2); 136uint16_t p405_br16 (uint16_t x); 137uint32_t p405_br32 (uint32_t x); 138 139void p405_op_branch (p405_t *c, uint32_t dst, unsigned bo, unsigned bi, int aa, int lk); 140void p405_op_crop (p405_t *c, unsigned bt, unsigned ba, unsigned bb, unsigned booltab); 141void p405_op_lsw (p405_t *c, unsigned rt, unsigned ra, unsigned rb, uint32_t ea, unsigned cnt); 142void p405_op_stsw (p405_t *c, unsigned rs, uint32_t ea, unsigned cnt); 143void p405_op_undefined (p405_t *c); 144 145void p405_exception_data_store (p405_t *c, uint32_t ea, int store, int zone); 146void p405_exception_instr_store (p405_t *c, int zone); 147void p405_exception_external (p405_t *c); 148void p405_exception_program (p405_t *c, uint32_t esr); 149void p405_exception_program_fpu (p405_t *c); 150void p405_exception_syscall (p405_t *c); 151void p405_exception_pit (p405_t *c); 152void p405_exception_fit (p405_t *c); 153void p405_exception_tlb_miss_data (p405_t *c, uint32_t ea, int store); 154void p405_exception_tlb_miss_instr (p405_t *c); 155 156void p405_set_opcode13 (p405_t *c); 157void p405_set_opcode1f (p405_t *c); 158void p405_set_opcodes (p405_t *c); 159 160 161static inline 162int p405_check_reserved (p405_t *c, uint32_t res) 163{ 164 if (c->ir & res) { 165 p405_op_undefined (c); 166 return (1); 167 } 168 169 return (0); 170} 171 172static inline 173int p405_check_privilege (p405_t *c) 174{ 175 if (p405_get_msr_pr (c)) { 176 p405_exception_program (c, P405_ESR_PPR); 177 return (1); 178 } 179 180 return (0); 181} 182 183static inline 184void p405_set_xer_oflow (p405_t *c, int of) 185{ 186 if (of) { 187 c->xer |= (P405_XER_SO | P405_XER_OV); 188 } 189 else { 190 c->xer &= ~P405_XER_OV; 191 } 192} 193 194static inline 195void p405_set_cr0 (p405_t *c, uint32_t r) 196{ 197 c->cr &= 0x0fffffff; 198 199 if (r & 0x80000000) { 200 c->cr |= P405_CR0_LT; 201 } 202 else if (r & 0x7fffffff) { 203 c->cr |= P405_CR0_GT; 204 } 205 else { 206 c->cr |= P405_CR0_EQ; 207 } 208 209 if (c->xer & P405_XER_SO) { 210 c->cr |= P405_CR0_SO; 211 } 212} 213 214static inline 215int p405_get_ea (p405_t *c, uint32_t *val, int idx, int upd) 216{ 217 if (upd) { 218 if (p405_get_ir_ra (c->ir) == 0) { 219 p405_op_undefined (c); 220 return (1); 221 } 222 } 223 224 if (idx) { 225 *val = p405_get_ra0 (c, c->ir) + p405_get_rb (c, c->ir); 226 } 227 else { 228 *val = p405_get_ra0 (c, c->ir) + p405_get_simm16 (c->ir); 229 } 230 231 *val &= 0xffffffff; 232 233 return (0); 234} 235 236 237#endif