123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /* This file is part of the program psim.
- Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- */
- #ifndef _INTERRUPTS_H_
- #define _INTERRUPTS_H_
- /* Interrupts:
- The code below handles two different types of interrupts.
- Synchronous and Asynchronous.
- Synchronous:
- Interrupts that must immediately force either an abort or restart
- of a current instruction are implemented by forcing an instruction
- restart. (or to put it another way, long jump). In looking at the
- code it may occure to you that, for some interrupts, they could
- return instead of restarting the cpu (eg system_call). While true
- (it once was like that) I've decided to make the behavour of all
- interrupt routines roughly identical.
- Because, a cpu's recorded state (ie what is in the cpu structure)
- is allowed to lag behind the cpu's true current state (eg PC not
- updated) sycnronous interrupt handers are parameterized with the
- the cpu being interrupted so that, as part of moddeling the
- interrupt, the cpu's state can be updated.
- Asynchronous:
- Interrupts such as reset or external exception are delivered using
- more normal (returning) functions. It is assumed that these
- functions are called out side of the normal processor execution
- cycle. */
- /* Software generated interrupts.
- The below are generated by software driven events. For instance,
- an invalid instruction or access (virtual or physical) to an
- invalid address */
- typedef enum {
- direct_store_storage_interrupt,
- hash_table_miss_storage_interrupt,
- protection_violation_storage_interrupt,
- earwax_violation_storage_interrupt,
- segment_table_miss_storage_interrupt,
- earwax_disabled_storage_interrupt,
- vea_storage_interrupt,
- } storage_interrupt_reasons;
- INLINE_INTERRUPTS\
- (void) data_storage_interrupt
- (cpu *processor,
- unsigned_word cia,
- unsigned_word ea,
- storage_interrupt_reasons reason,
- int is_store);
- INLINE_INTERRUPTS\
- (void) instruction_storage_interrupt
- (cpu *processor,
- unsigned_word cia,
- storage_interrupt_reasons reason);
- INLINE_INTERRUPTS\
- (void) alignment_interrupt
- (cpu *processor,
- unsigned_word cia,
- unsigned_word ra);
- typedef enum {
- floating_point_enabled_program_interrupt,
- illegal_instruction_program_interrupt,
- privileged_instruction_program_interrupt,
- trap_program_interrupt,
- optional_instruction_program_interrupt, /* subset of illegal instruction */
- mpc860c0_instruction_program_interrupt, /* fwd br, taken but not predicted, near EO page */
- nr_program_interrupt_reasons
- } program_interrupt_reasons;
- INLINE_INTERRUPTS\
- (void) program_interrupt
- (cpu *processor,
- unsigned_word cia,
- program_interrupt_reasons reason);
- INLINE_INTERRUPTS\
- (void) floating_point_unavailable_interrupt
- (cpu *processor,
- unsigned_word cia);
- INLINE_INTERRUPTS\
- (void) system_call_interrupt
- (cpu *processor,
- unsigned_word cia);
- INLINE_INTERRUPTS\
- (void) floating_point_assist_interrupt
- (cpu *processor,
- unsigned_word cia);
- INLINE_INTERRUPTS\
- (void) machine_check_interrupt
- (cpu *processor,
- unsigned_word cia);
- /* Hardware generated interrupts:
- These asynchronous hardware generated interrupts may be called at
- any time. It is the responsibility of this (the interrupts) module
- to ensure that interrupts are delivered correctly (when possible).
- The delivery of these interrupts is controlled by the MSR's
- external interrupt enable bit. When ever the MSR's value is
- changed, the processor must call the check_masked_interrupts()
- function in case delivery has been made possible.
- decrementer_interrupt is `edge' sensitive. Multiple edges arriving
- before the first edge has been delivered result in only one
- interrupt.
- external_interrupt is `level' sensitive. An external interrupt
- will only be delivered when the external interrupt port is
- `asserted'. While interrupts are disabled, the external interrupt
- can be asserted and then de-asserted without an interrupt
- eventually being delivered. */
- enum {
- external_interrupt_pending = 1,
- decrementer_interrupt_pending = 2,
- };
- typedef struct _interrupts {
- event_entry_tag delivery_scheduled;
- int pending_interrupts;
- } interrupts;
- INLINE_INTERRUPTS\
- (void) check_masked_interrupts
- (cpu *processor);
- INLINE_INTERRUPTS\
- (void) decrementer_interrupt
- (cpu *processor);
- INLINE_INTERRUPTS\
- (void) external_interrupt
- (cpu *processor,
- int is_asserted);
- #endif /* _INTERRUPTS_H_ */
|