Home | History | Annotate | Line # | Download | only in ppc
interrupts.h revision 1.5
      1 /*  This file is part of the program psim.
      2 
      3     Copyright (C) 1994-1995, Andrew Cagney <cagney (at) 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