interrupts.hh revision 3894
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Gabe Black
29 */
30
31#ifndef __ARCH_SPARC_INTERRUPT_HH__
32#define __ARCH_SPARC_INTERRUPT_HH__
33
34#include "arch/sparc/faults.hh"
35#include "cpu/thread_context.hh"
36
37namespace SparcISA
38{
39
40enum interrupts_t {
41    trap_level_zero,
42    hstick_match,
43    interrupt_vector,
44    cpu_mondo,
45    dev_mondo,
46    resumable_error,
47    soft_interrupt,
48    num_interrupt_types
49};
50
51    class Interrupts
52    {
53
54      private:
55
56        bool interrupts[num_interrupt_types];
57        int numPosted;
58
59      public:
60        Interrupts()
61        {
62            for (int i = 0; i < num_interrupt_types; ++i) {
63                interrupts[i] = false;
64            }
65            numPosted = 0;
66        }
67
68        void post(int int_type)
69        {
70            if (int_type < 0 || int_type >= num_interrupt_types)
71                panic("posting unknown interrupt!\n");
72            interrupts[int_type] = true;
73            ++numPosted;
74        }
75
76        void post(int int_num, int index)
77        {
78
79        }
80
81        void clear(int int_num, int index)
82        {
83
84        }
85
86        void clear_all()
87        {
88
89        }
90
91        bool check_interrupts(ThreadContext * tc) const
92        {
93            if (numPosted)
94                return true;
95            else
96                return false;
97        }
98
99        Fault getInterrupt(ThreadContext * tc)
100        {
101            int hpstate = tc->readMiscReg(MISCREG_HPSTATE);
102            int pstate = tc->readMiscReg(MISCREG_PSTATE);
103            bool ie = pstate & PSTATE::ie;
104
105            // THESE ARE IN ORDER OF PRIORITY
106            // since there are early returns, and the highest
107            // priority interrupts should get serviced,
108            // it is v. important that new interrupts are inserted
109            // in the right order of processing
110            if (hpstate & HPSTATE::hpriv) {
111                if (ie) {
112                    if (interrupts[hstick_match]) {
113                        interrupts[hstick_match] = false;
114                        --numPosted;
115                        return new HstickMatch;
116                    }
117                    if (interrupts[interrupt_vector]) {
118                        interrupts[interrupt_vector] = false;
119                        --numPosted;
120                        //HAVEN'T IMPLed THIS YET
121                        return NoFault;
122                    }
123                }
124            } else {
125
126                if (interrupts[trap_level_zero]) {
127                    //HAVEN'T IMPLed YET
128                    if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) {
129                        interrupts[trap_level_zero] = false;
130                        --numPosted;
131                        return NoFault;
132                    }
133                }
134                if (interrupts[hstick_match]) {
135                    interrupts[hstick_match] = false;
136                    --numPosted;
137                    return new HstickMatch;
138                }
139                if (ie) {
140                    if (interrupts[cpu_mondo]) {
141                        interrupts[cpu_mondo] = false;
142                        --numPosted;
143                        return new CpuMondo;
144                    }
145                    if (interrupts[dev_mondo]) {
146                        interrupts[dev_mondo] = false;
147                        --numPosted;
148                        return new DevMondo;
149                    }
150                    if (interrupts[soft_interrupt]) {
151                        int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
152                        // it seems that interrupt vectors are right in
153                        // the middle of interrupt levels with regard to
154                        // priority, so have to check
155                        if ((il < 6) &&
156                            interrupts[interrupt_vector]) {
157                                // may require more details here since there
158                                // may be lots of interrupts embedded in an
159                                // platform interrupt vector
160                                interrupts[interrupt_vector] = false;
161                                --numPosted;
162                                //HAVEN'T IMPLed YET
163                                return NoFault;
164                        } else {
165                            if (il > tc->readMiscReg(MISCREG_PIL)) {
166                                uint64_t si = tc->readMiscReg(MISCREG_SOFTINT);
167                                uint64_t more = si & ~(1 << (il + 1));
168                                if (!InterruptLevel(more)) {
169                                    interrupts[soft_interrupt] = false;
170                                    --numPosted;
171                                }
172                                return new InterruptLevelN(il);
173                            }
174                        }
175                    }
176                    if (interrupts[resumable_error]) {
177                        interrupts[resumable_error] = false;
178                        --numPosted;
179                        return new ResumableError;
180                    }
181                }
182            }
183            return NoFault;
184
185
186            // conditioning the softint interrups
187            if (tc->readMiscReg(MISCREG_HPSTATE) & HPSTATE::hpriv) {
188                // if running in privileged mode, then pend the interrupt
189                return NoFault;
190            } else {
191                int int_level = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
192                if ((int_level <= tc->readMiscReg(MISCREG_PIL)) ||
193                    !(tc->readMiscReg(MISCREG_PSTATE) & PSTATE::ie)) {
194                    // if PIL or no interrupt enabled, then pend the interrupt
195                    return NoFault;
196                } else {
197                    return new InterruptLevelN(int_level);
198                }
199            }
200        }
201
202        void updateIntrInfo(ThreadContext * tc)
203        {
204
205        }
206
207        void serialize(std::ostream &os)
208        {
209        }
210
211        void unserialize(Checkpoint *cp, const std::string &section)
212        {
213        }
214    };
215}
216
217#endif // __ARCH_SPARC_INTERRUPT_HH__
218