1 /* This file is part of the program psim. 2 3 Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, see <http://www.gnu.org/licenses/>. 17 18 */ 19 20 21 #ifndef _INTERRUPTS_H_ 22 #define _INTERRUPTS_H_ 23 24 /* Interrupts: 25 26 The code below handles two different types of interrupts. 27 Synchronous and Asynchronous. 28 29 Synchronous: 30 31 Interrupts that must immediately force either an abort or restart 32 of a current instruction are implemented by forcing an instruction 33 restart. (or to put it another way, long jump). In looking at the 34 code it may occure to you that, for some interrupts, they could 35 return instead of restarting the cpu (eg system_call). While true 36 (it once was like that) I've decided to make the behavour of all 37 interrupt routines roughly identical. 38 39 Because, a cpu's recorded state (ie what is in the cpu structure) 40 is allowed to lag behind the cpu's true current state (eg PC not 41 updated) sycnronous interrupt handers are parameterized with the 42 the cpu being interrupted so that, as part of moddeling the 43 interrupt, the cpu's state can be updated. 44 45 Asynchronous: 46 47 Interrupts such as reset or external exception are delivered using 48 more normal (returning) functions. It is assumed that these 49 functions are called out side of the normal processor execution 50 cycle. */ 51 52 53 /* Software generated interrupts. 54 55 The below are generated by software driven events. For instance, 56 an invalid instruction or access (virtual or physical) to an 57 invalid address */ 58 59 typedef enum { 60 direct_store_storage_interrupt, 61 hash_table_miss_storage_interrupt, 62 protection_violation_storage_interrupt, 63 earwax_violation_storage_interrupt, 64 segment_table_miss_storage_interrupt, 65 earwax_disabled_storage_interrupt, 66 vea_storage_interrupt, 67 } storage_interrupt_reasons; 68 69 70 INLINE_INTERRUPTS\ 71 (void) data_storage_interrupt 72 (cpu *processor, 73 unsigned_word cia, 74 unsigned_word ea, 75 storage_interrupt_reasons reason, 76 int is_store); 77 78 INLINE_INTERRUPTS\ 79 (void) instruction_storage_interrupt 80 (cpu *processor, 81 unsigned_word cia, 82 storage_interrupt_reasons reason); 83 84 INLINE_INTERRUPTS\ 85 (void) alignment_interrupt 86 (cpu *processor, 87 unsigned_word cia, 88 unsigned_word ra); 89 90 typedef enum { 91 floating_point_enabled_program_interrupt, 92 illegal_instruction_program_interrupt, 93 privileged_instruction_program_interrupt, 94 trap_program_interrupt, 95 optional_instruction_program_interrupt, /* subset of illegal instruction */ 96 mpc860c0_instruction_program_interrupt, /* fwd br, taken but not predicted, near EO page */ 97 nr_program_interrupt_reasons 98 } program_interrupt_reasons; 99 100 INLINE_INTERRUPTS\ 101 (void) program_interrupt 102 (cpu *processor, 103 unsigned_word cia, 104 program_interrupt_reasons reason); 105 106 INLINE_INTERRUPTS\ 107 (void) floating_point_unavailable_interrupt 108 (cpu *processor, 109 unsigned_word cia); 110 111 INLINE_INTERRUPTS\ 112 (void) system_call_interrupt 113 (cpu *processor, 114 unsigned_word cia); 115 116 INLINE_INTERRUPTS\ 117 (void) floating_point_assist_interrupt 118 (cpu *processor, 119 unsigned_word cia); 120 121 INLINE_INTERRUPTS\ 122 (void) machine_check_interrupt 123 (cpu *processor, 124 unsigned_word cia); 125 126 /* Hardware generated interrupts: 127 128 These asynchronous hardware generated interrupts may be called at 129 any time. It is the responsibility of this (the interrupts) module 130 to ensure that interrupts are delivered correctly (when possible). 131 The delivery of these interrupts is controlled by the MSR's 132 external interrupt enable bit. When ever the MSR's value is 133 changed, the processor must call the check_masked_interrupts() 134 function in case delivery has been made possible. 135 136 decrementer_interrupt is `edge' sensitive. Multiple edges arriving 137 before the first edge has been delivered result in only one 138 interrupt. 139 140 external_interrupt is `level' sensitive. An external interrupt 141 will only be delivered when the external interrupt port is 142 `asserted'. While interrupts are disabled, the external interrupt 143 can be asserted and then de-asserted without an interrupt 144 eventually being delivered. */ 145 146 enum { 147 external_interrupt_pending = 1, 148 decrementer_interrupt_pending = 2, 149 }; 150 151 typedef struct _interrupts { 152 event_entry_tag delivery_scheduled; 153 int pending_interrupts; 154 } interrupts; 155 156 INLINE_INTERRUPTS\ 157 (void) check_masked_interrupts 158 (cpu *processor); 159 160 INLINE_INTERRUPTS\ 161 (void) decrementer_interrupt 162 (cpu *processor); 163 164 INLINE_INTERRUPTS\ 165 (void) external_interrupt 166 (cpu *processor, 167 int is_asserted); 168 169 #endif /* _INTERRUPTS_H_ */ 170