Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / pli / src / SS_IrqSync.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: SS_IrqSync.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21
22#include <stdio.h>
23#include "SS_IrqSync.h"
24
25SS_IrqSync::SS_IrqSync( SS_Strand* s )/*{{{*/
26 :
27 strand(s),
28 cur_time(0),
29 head(0)
30{
31 // Plug this IrqSync into the Strand
32
33 strand->irq_sync = this;
34 strand->irq_store = &SS_IrqSync::store;
35}
36/*}}}*/
37void SS_IrqSync::store( void* _irq_sync, SS_Trap::Type irq_type, bool do_time_out ) /*{{{*/
38{
39 SS_IrqSync* irq_sync = (SS_IrqSync*)_irq_sync;
40
41 // Insert the new trap in the chain based on priority: highest priority is on the head,
42 // If there are traps with same priority but different type we stick the last one at
43 // the end: first come first serve.
44
45 if (irq_type == SS_Trap::TRAP_LEVEL_ZERO)
46 do_time_out = false;
47
48 uint_t priority = SS_Trap::table[irq_type].priority;
49
50 IrqInfo* here = irq_sync->head;
51
52 if (here == 0 || priority < here->priority)
53 {
54 irq_sync->head = new IrqInfo(irq_type,priority,do_time_out ? (irq_sync->cur_time + SS_IrqSync::TIME_OUT) : 0,here);
55 }
56 else
57 {
58 IrqInfo* next = here->next;
59
60 while (next && (priority >= next->priority))
61 {
62 // Allow the same interruppt to be stored more then once ...
63 // It makes life so much easier if we do this.
64 if (here->irq_type == irq_type)
65 return;
66
67 here = next;
68 next = here->next;
69 }
70
71 here->next = new IrqInfo(irq_type,priority,do_time_out ? (irq_sync->cur_time + SS_IrqSync::TIME_OUT) : 0,next);
72 }
73}
74/*}}}*/
75void SS_IrqSync::raise( SS_Trap::Type irq_type )/*{{{*/
76{
77 // The DUT sends us a INTP tid tt=0 right at the beginning.
78 // There is no point in that as when Vonk is created the
79 // cpu/core/strand state has already been through a reset.
80
81 if (irq_type == 0)
82 return;
83
84 for (IrqInfo* here = head; here; here = here->next)
85 {
86 if (here->irq_type == irq_type)
87 {
88 here->time_out = 0;
89 return;
90 }
91 }
92
93 // Don't complain about reset type traps.
94 if ((irq_type >= SS_Trap::STORE_ERROR) &&
95 (irq_type != SS_Trap::RESET_GEN_WMR))
96 fprintf(stdout,"IRQ_SYNC: Trap tt=0x%x is raised unexpectedly\n",irq_type);
97
98 store(this,irq_type,false);
99}
100/*}}}*/
101bool SS_IrqSync::check_list()/*{{{*/
102{
103 IrqInfo* prev = head;
104 IrqInfo* here = prev;
105
106 while (here)
107 {
108 if (here->time_out == 0)
109 {
110 if (strand->trap_launch_ok(here->irq_type))
111 {
112 (strand->trap)(strand->pc(),strand->npc(),strand,0,here->irq_type);
113 if (prev == here)
114 head = here->next;
115 else
116 prev->next = here->next;
117 delete here;
118 return true;
119 }
120 else
121 {
122 prev = here;
123 here = here->next;
124 }
125 }
126 else if (here->time_out < cur_time)
127 {
128 fprintf(stdout,"IRQ_SYNC: Trap tt=0x%x timed out.\n",here->irq_type);
129 if (prev == here)
130 {
131 head = here->next;
132 delete here;
133 prev = head;
134 here = prev;
135 }
136 else
137 {
138 prev->next = here->next;
139 delete here;
140 here = prev->next;
141 }
142 }
143 else
144 {
145 prev = here;
146 here = here->next;
147 }
148 }
149 return false;
150}
151/*}}}*/
152
153void SS_IrqSync::clear_list()/*{{{*/
154{
155 IrqInfo* here = head;
156 while (here)
157 {
158 IrqInfo* next = here->next;
159 fprintf(stdout, "IRQ_SYNC: Trap tt=0x%x removed.\n", here->irq_type);
160 delete here;
161 here = next;
162 }
163 head = 0;
164}
165/*}}}*/