iob.cc (4194:af4f6022394b) iob.cc (4216:c01745179a1f)
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;

--- 178 unchanged lines hidden (view full) ---

187 int index;
188 uint64_t data;
189
190 if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) {
191 index = (accessAddr - IntManAddr) >> 3;
192 data = pkt->get<uint64_t>();
193 intMan[index].cpu = bits(data,12,8);
194 intMan[index].vector = bits(data,5,0);
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;

--- 178 unchanged lines hidden (view full) ---

187 int index;
188 uint64_t data;
189
190 if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) {
191 index = (accessAddr - IntManAddr) >> 3;
192 data = pkt->get<uint64_t>();
193 intMan[index].cpu = bits(data,12,8);
194 intMan[index].vector = bits(data,5,0);
195 DPRINTF(Iob, "Wrote IntMan %d cpu %d, vec %d\n", index,
196 intMan[index].cpu, intMan[index].vector);
195 return;
196 }
197
198 if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
199 index = (accessAddr - IntManAddr) >> 3;
200 data = pkt->get<uint64_t>();
201 intCtl[index].mask = bits(data,2,2);
202 if (bits(data,1,1))
203 intCtl[index].pend = false;
197 return;
198 }
199
200 if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
201 index = (accessAddr - IntManAddr) >> 3;
202 data = pkt->get<uint64_t>();
203 intCtl[index].mask = bits(data,2,2);
204 if (bits(data,1,1))
205 intCtl[index].pend = false;
206 DPRINTF(Iob, "Wrote IntCtl %d pend %d cleared %d\n", index,
207 intCtl[index].pend, bits(data,2,2));
204 return;
205 }
206
207 if (accessAddr == JIntVecAddr) {
208 jIntVec = bits(pkt->get<uint64_t>(), 5,0);
208 return;
209 }
210
211 if (accessAddr == JIntVecAddr) {
212 jIntVec = bits(pkt->get<uint64_t>(), 5,0);
213 DPRINTF(Iob, "Wrote jIntVec %d\n", jIntVec);
209 return;
210 }
211
212 if (accessAddr >= IntVecDisAddr && accessAddr < IntVecDisAddr + IntVecDisSize) {
213 Type type;
214 int cpu_id;
215 int vector;
216 index = (accessAddr - IntManAddr) >> 3;

--- 15 unchanged lines hidden (view full) ---

232 int cpuid = pkt->req->getCpuNum();
233 int index;
234 uint64_t data;
235
236 if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
237 index = (accessAddr - JIntBusyAddr) >> 3;
238 data = pkt->get<uint64_t>();
239 jIntBusy[index].busy = bits(data,5,5);
214 return;
215 }
216
217 if (accessAddr >= IntVecDisAddr && accessAddr < IntVecDisAddr + IntVecDisSize) {
218 Type type;
219 int cpu_id;
220 int vector;
221 index = (accessAddr - IntManAddr) >> 3;

--- 15 unchanged lines hidden (view full) ---

237 int cpuid = pkt->req->getCpuNum();
238 int index;
239 uint64_t data;
240
241 if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
242 index = (accessAddr - JIntBusyAddr) >> 3;
243 data = pkt->get<uint64_t>();
244 jIntBusy[index].busy = bits(data,5,5);
245 DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", index,
246 jIntBusy[index].busy);
240 return;
241 }
242 if (accessAddr == JIntABusyAddr) {
243 data = pkt->get<uint64_t>();
244 jIntBusy[cpuid].busy = bits(data,5,5);
247 return;
248 }
249 if (accessAddr == JIntABusyAddr) {
250 data = pkt->get<uint64_t>();
251 jIntBusy[cpuid].busy = bits(data,5,5);
252 DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", cpuid,
253 jIntBusy[cpuid].busy);
245 return;
246 };
247
248 panic("Write to unknown JBus offset 0x%x\n", accessAddr);
249}
250
251void
252Iob::receiveDeviceInterrupt(DeviceId devid)
253{
254 assert(devid < NumDeviceIds);
255 if (intCtl[devid].mask)
256 return;
257 intCtl[devid].mask = true;
258 intCtl[devid].pend = true;
254 return;
255 };
256
257 panic("Write to unknown JBus offset 0x%x\n", accessAddr);
258}
259
260void
261Iob::receiveDeviceInterrupt(DeviceId devid)
262{
263 assert(devid < NumDeviceIds);
264 if (intCtl[devid].mask)
265 return;
266 intCtl[devid].mask = true;
267 intCtl[devid].pend = true;
268 DPRINTF(Iob, "Receiving Device interrupt: %d for cpu %d vec %d\n",
269 devid, intMan[devid].cpu, intMan[devid].vector);
259 ic->post(intMan[devid].cpu, SparcISA::IT_INT_VEC, intMan[devid].vector);
260}
261
262
263void
264Iob::generateIpi(Type type, int cpu_id, int vector)
265{
266 SparcISA::SparcFault<SparcISA::PowerOnReset> *por = new SparcISA::PowerOnReset();
267 if (cpu_id >= sys->getNumCPUs())
268 return;
269
270 switch (type) {
271 case 0: // interrupt
270 ic->post(intMan[devid].cpu, SparcISA::IT_INT_VEC, intMan[devid].vector);
271}
272
273
274void
275Iob::generateIpi(Type type, int cpu_id, int vector)
276{
277 SparcISA::SparcFault<SparcISA::PowerOnReset> *por = new SparcISA::PowerOnReset();
278 if (cpu_id >= sys->getNumCPUs())
279 return;
280
281 switch (type) {
282 case 0: // interrupt
283 DPRINTF(Iob, "Generating interrupt because of I/O write to cpu: %d vec %d\n",
284 cpu_id, vector);
272 ic->post(cpu_id, SparcISA::IT_INT_VEC, vector);
273 break;
274 case 1: // reset
275 warn("Sending reset to CPU: %d\n", cpu_id);
276 if (vector != por->trapType())
277 panic("Don't know how to set non-POR reset to cpu\n");
278 por->invoke(sys->threadContexts[cpu_id]);
279 sys->threadContexts[cpu_id]->activate();
280 break;
281 case 2: // idle -- this means stop executing and don't wake on interrupts
285 ic->post(cpu_id, SparcISA::IT_INT_VEC, vector);
286 break;
287 case 1: // reset
288 warn("Sending reset to CPU: %d\n", cpu_id);
289 if (vector != por->trapType())
290 panic("Don't know how to set non-POR reset to cpu\n");
291 por->invoke(sys->threadContexts[cpu_id]);
292 sys->threadContexts[cpu_id]->activate();
293 break;
294 case 2: // idle -- this means stop executing and don't wake on interrupts
295 DPRINTF(Iob, "Idling CPU because of I/O write cpu: %d\n", cpu_id);
282 sys->threadContexts[cpu_id]->halt();
283 break;
284 case 3: // resume
296 sys->threadContexts[cpu_id]->halt();
297 break;
298 case 3: // resume
299 DPRINTF(Iob, "Resuming CPU because of I/O write cpu: %d\n", cpu_id);
285 sys->threadContexts[cpu_id]->activate();
286 break;
287 default:
288 panic("Invalid type to generate ipi\n");
289 }
290}
291
292bool
293Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
294{
295 // If we are already dealing with an interrupt for that cpu we can't deal
296 // with another one right now... come back later
297 if (jIntBusy[cpu_id].busy)
298 return false;
299
300 sys->threadContexts[cpu_id]->activate();
301 break;
302 default:
303 panic("Invalid type to generate ipi\n");
304 }
305}
306
307bool
308Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
309{
310 // If we are already dealing with an interrupt for that cpu we can't deal
311 // with another one right now... come back later
312 if (jIntBusy[cpu_id].busy)
313 return false;
314
315 DPRINTF(Iob, "Receiving jBus interrupt: %d for cpu %d vec %d\n",
316 source, cpu_id, jIntVec);
317
300 jIntBusy[cpu_id].busy = true;
301 jIntBusy[cpu_id].source = source;
302 jBusData0[cpu_id] = d0;
303 jBusData1[cpu_id] = d1;
304
305 ic->post(cpu_id, SparcISA::IT_INT_VEC, jIntVec);
306 return true;
307}

--- 77 unchanged lines hidden ---
318 jIntBusy[cpu_id].busy = true;
319 jIntBusy[cpu_id].source = source;
320 jBusData0[cpu_id] = d0;
321 jBusData1[cpu_id] = d1;
322
323 ic->post(cpu_id, SparcISA::IT_INT_VEC, jIntVec);
324 return true;
325}

--- 77 unchanged lines hidden ---