| 1 | #ifndef HW_PPC_H |
| 2 | #define HW_PPC_H |
| 3 | |
| 4 | #include "target/ppc/cpu.h" |
| 5 | |
| 6 | void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level); |
| 7 | PowerPCCPU *ppc_get_vcpu_by_pir(int pir); |
| 8 | int ppc_cpu_pir(PowerPCCPU *cpu); |
| 9 | int ppc_cpu_tir(PowerPCCPU *cpu); |
| 10 | |
| 11 | /* PowerPC hardware exceptions management helpers */ |
| 12 | typedef void (*clk_setup_cb)(void *opaque, uint32_t freq); |
| 13 | typedef struct clk_setup_t clk_setup_t; |
| 14 | struct clk_setup_t { |
| 15 | clk_setup_cb cb; |
| 16 | void *opaque; |
| 17 | }; |
| 18 | static inline void clk_setup (clk_setup_t *clk, uint32_t freq) |
| 19 | { |
| 20 | if (clk->cb != NULL) |
| 21 | (*clk->cb)(clk->opaque, freq); |
| 22 | } |
| 23 | |
| 24 | struct ppc_tb_t { |
| 25 | /* Time base management */ |
| 26 | int64_t tb_offset; /* Compensation */ |
| 27 | int64_t atb_offset; /* Compensation */ |
| 28 | int64_t vtb_offset; |
| 29 | uint32_t tb_freq; /* TB frequency */ |
| 30 | /* Decrementer management */ |
| 31 | uint64_t decr_next; /* Tick for next decr interrupt */ |
| 32 | uint32_t decr_freq; /* decrementer frequency */ |
| 33 | QEMUTimer *decr_timer; |
| 34 | /* Hypervisor decrementer management */ |
| 35 | uint64_t hdecr_next; /* Tick for next hdecr interrupt */ |
| 36 | QEMUTimer *hdecr_timer; |
| 37 | int64_t purr_offset; |
| 38 | void *opaque; |
| 39 | uint32_t flags; |
| 40 | }; |
| 41 | |
| 42 | /* PPC Timers flags */ |
| 43 | #define PPC_TIMER_BOOKE (1 << 0) /* Enable Booke support */ |
| 44 | #define PPC_TIMER_E500 (1 << 1) /* Enable e500 support */ |
| 45 | #define PPC_DECR_UNDERFLOW_TRIGGERED (1 << 2) /* Decr interrupt triggered when |
| 46 | * the most significant bit |
| 47 | * changes from 0 to 1. |
| 48 | */ |
| 49 | #define PPC_DECR_ZERO_TRIGGERED (1 << 3) /* Decr interrupt triggered when |
| 50 | * the decrementer reaches zero. |
| 51 | */ |
| 52 | #define PPC_DECR_UNDERFLOW_LEVEL (1 << 4) /* Decr interrupt active when |
| 53 | * the most significant bit is 1. |
| 54 | */ |
| 55 | #define PPC_TIMER_PPE (1 << 5) /* Enable PPE support */ |
| 56 | |
| 57 | uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset); |
| 58 | void cpu_ppc_tb_init(CPUPPCState *env, uint32_t freq); |
| 59 | void cpu_ppc_tb_reset(CPUPPCState *env); |
| 60 | void cpu_ppc_tb_free(CPUPPCState *env); |
| 61 | void cpu_ppc_hdecr_init(CPUPPCState *env); |
| 62 | void cpu_ppc_hdecr_exit(CPUPPCState *env); |
| 63 | |
| 64 | /* Embedded PowerPC DCR management */ |
| 65 | typedef uint32_t (*dcr_read_cb)(void *opaque, int dcrn); |
| 66 | typedef void (*dcr_write_cb)(void *opaque, int dcrn, uint32_t val); |
| 67 | int ppc_dcr_init (CPUPPCState *env, int (*dcr_read_error)(int dcrn), |
| 68 | int (*dcr_write_error)(int dcrn)); |
| 69 | int ppc_dcr_register (CPUPPCState *env, int dcrn, void *opaque, |
| 70 | dcr_read_cb drc_read, dcr_write_cb dcr_write); |
| 71 | clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq, |
| 72 | unsigned int decr_excp); |
| 73 | |
| 74 | /* Embedded PowerPC reset */ |
| 75 | void ppc40x_core_reset(PowerPCCPU *cpu); |
| 76 | void ppc40x_chip_reset(PowerPCCPU *cpu); |
| 77 | void ppc40x_system_reset(PowerPCCPU *cpu); |
| 78 | |
| 79 | #if defined(CONFIG_USER_ONLY) |
| 80 | static inline void ppc40x_irq_init(PowerPCCPU *cpu) {} |
| 81 | static inline void ppc6xx_irq_init(PowerPCCPU *cpu) {} |
| 82 | static inline void ppc970_irq_init(PowerPCCPU *cpu) {} |
| 83 | static inline void ppcPOWER7_irq_init(PowerPCCPU *cpu) {} |
| 84 | static inline void ppcPOWER9_irq_init(PowerPCCPU *cpu) {} |
| 85 | static inline void ppce500_irq_init(PowerPCCPU *cpu) {} |
| 86 | static inline void ppc_irq_reset(PowerPCCPU *cpu) {} |
| 87 | #else |
| 88 | void ppc40x_irq_init(PowerPCCPU *cpu); |
| 89 | void ppce500_irq_init(PowerPCCPU *cpu); |
| 90 | void ppc6xx_irq_init(PowerPCCPU *cpu); |
| 91 | void ppc970_irq_init(PowerPCCPU *cpu); |
| 92 | void ppcPOWER7_irq_init(PowerPCCPU *cpu); |
| 93 | void ppcPOWER9_irq_init(PowerPCCPU *cpu); |
| 94 | void ppc_irq_reset(PowerPCCPU *cpu); |
| 95 | #endif |
| 96 | |
| 97 | /* PPC machines for OpenBIOS */ |
| 98 | enum { |
| 99 | ARCH_PREP = 0, |
| 100 | ARCH_MAC99, |
| 101 | ARCH_HEATHROW, |
| 102 | ARCH_MAC99_U3, |
| 103 | }; |
| 104 | |
| 105 | #define FW_CFG_PPC_WIDTH (FW_CFG_ARCH_LOCAL + 0x00) |
| 106 | #define FW_CFG_PPC_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01) |
| 107 | #define FW_CFG_PPC_DEPTH (FW_CFG_ARCH_LOCAL + 0x02) |
| 108 | #define FW_CFG_PPC_TBFREQ (FW_CFG_ARCH_LOCAL + 0x03) |
| 109 | #define FW_CFG_PPC_CLOCKFREQ (FW_CFG_ARCH_LOCAL + 0x04) |
| 110 | #define FW_CFG_PPC_IS_KVM (FW_CFG_ARCH_LOCAL + 0x05) |
| 111 | #define FW_CFG_PPC_KVM_HC (FW_CFG_ARCH_LOCAL + 0x06) |
| 112 | #define FW_CFG_PPC_KVM_PID (FW_CFG_ARCH_LOCAL + 0x07) |
| 113 | #define FW_CFG_PPC_NVRAM_ADDR (FW_CFG_ARCH_LOCAL + 0x08) |
| 114 | #define FW_CFG_PPC_BUSFREQ (FW_CFG_ARCH_LOCAL + 0x09) |
| 115 | #define FW_CFG_PPC_NVRAM_FLAT (FW_CFG_ARCH_LOCAL + 0x0a) |
| 116 | #define FW_CFG_PPC_VIACONFIG (FW_CFG_ARCH_LOCAL + 0x0b) |
| 117 | |
| 118 | #define PPC_SERIAL_MM_BAUDBASE 399193 |
| 119 | |
| 120 | #ifndef CONFIG_USER_ONLY |
| 121 | void booke206_set_tlb(ppcmas_tlb_t *tlb, target_ulong va, hwaddr pa, |
| 122 | hwaddr len); |
| 123 | void booke_set_tlb(ppcemb_tlb_t *tlb, target_ulong va, hwaddr pa, |
| 124 | target_ulong size); |
| 125 | #endif |
| 126 | |
| 127 | /* ppc_booke.c */ |
| 128 | void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags); |
| 129 | #endif |