RubyPort.cc (8505:442804117f95) RubyPort.cc (8532:8f27cf8971fe)
1/*
2 * Copyright (c) 2009 Advanced Micro Devices, Inc.
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;

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

295
296bool
297RubyPort::M5Port::doFunctionalRead(PacketPtr pkt)
298{
299 Address address(pkt->getAddr());
300 Address line_address(address);
301 line_address.makeLineAddress();
302
1/*
2 * Copyright (c) 2009 Advanced Micro Devices, Inc.
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;

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

295
296bool
297RubyPort::M5Port::doFunctionalRead(PacketPtr pkt)
298{
299 Address address(pkt->getAddr());
300 Address line_address(address);
301 line_address.makeLineAddress();
302
303 AccessPermission accessPerm = AccessPermission_NotPresent;
303 AccessPermission access_perm = AccessPermission_NotPresent;
304 int num_controllers = ruby_system->m_abs_cntrl_vec.size();
305
304 int num_controllers = ruby_system->m_abs_cntrl_vec.size();
305
306 // In this loop, we try to figure which controller has a read only or
307 // a read write copy of the given address. Any valid copy would suffice
308 // for a functional read.
309
310 DPRINTF(RubyPort, "Functional Read request for %s\n",address);
306 DPRINTF(RubyPort, "Functional Read request for %s\n",address);
311 for(int i = 0;i < num_controllers;++i)
312 {
313 accessPerm = ruby_system->m_abs_cntrl_vec[i]
314 ->getAccessPermission(line_address);
315 if(accessPerm == AccessPermission_Read_Only ||
316 accessPerm == AccessPermission_Read_Write)
317 {
318 unsigned startByte = address.getAddress() - line_address.getAddress();
319
307
320 uint8* data = pkt->getPtr<uint8_t>(true);
321 unsigned int size_in_bytes = pkt->getSize();
322 DataBlock& block = ruby_system->m_abs_cntrl_vec[i]
308 unsigned int num_ro = 0;
309 unsigned int num_rw = 0;
310 unsigned int num_busy = 0;
311 unsigned int num_backing_store = 0;
312 unsigned int num_invalid = 0;
313
314 // In this loop we count the number of controllers that have the given
315 // address in read only, read write and busy states.
316 for (int i = 0; i < num_controllers; ++i) {
317 access_perm = ruby_system->m_abs_cntrl_vec[i]->
318 getAccessPermission(line_address);
319 if (access_perm == AccessPermission_Read_Only)
320 num_ro++;
321 else if (access_perm == AccessPermission_Read_Write)
322 num_rw++;
323 else if (access_perm == AccessPermission_Busy)
324 num_busy++;
325 else if (access_perm == AccessPermission_Backing_Store)
326 // See RubySlicc_Exports.sm for details, but Backing_Store is meant
327 // to represent blocks in memory *for Broadcast/Snooping protocols*,
328 // where memory has no idea whether it has an exclusive copy of data
329 // or not.
330 num_backing_store++;
331 else if (access_perm == AccessPermission_Invalid ||
332 access_perm == AccessPermission_NotPresent)
333 num_invalid++;
334 }
335 assert(num_rw <= 1);
336
337 uint8* data = pkt->getPtr<uint8_t>(true);
338 unsigned int size_in_bytes = pkt->getSize();
339 unsigned startByte = address.getAddress() - line_address.getAddress();
340
341 // This if case is meant to capture what happens in a Broadcast/Snoop
342 // protocol where the block does not exist in the cache hierarchy. You
343 // only want to read from the Backing_Store memory if there is no copy in
344 // the cache hierarchy, otherwise you want to try to read the RO or RW
345 // copies existing in the cache hierarchy (covered by the else statement).
346 // The reason is because the Backing_Store memory could easily be stale, if
347 // there are copies floating around the cache hierarchy, so you want to read
348 // it only if it's not in the cache hierarchy at all.
349 if (num_invalid == (num_controllers - 1) &&
350 num_backing_store == 1)
351 {
352 DPRINTF(RubyPort, "only copy in Backing_Store memory, read from it\n");
353 for (int i = 0; i < num_controllers; ++i) {
354 access_perm = ruby_system->m_abs_cntrl_vec[i]
355 ->getAccessPermission(line_address);
356 if (access_perm == AccessPermission_Backing_Store) {
357 DataBlock& block = ruby_system->m_abs_cntrl_vec[i]
323 ->getDataBlock(line_address);
324
358 ->getDataBlock(line_address);
359
325 DPRINTF(RubyPort, "reading from %s block %s\n",
326 ruby_system->m_abs_cntrl_vec[i]->name(), block);
327 for (unsigned i = 0; i < size_in_bytes; ++i)
360 DPRINTF(RubyPort, "reading from %s block %s\n",
361 ruby_system->m_abs_cntrl_vec[i]->name(), block);
362 for (unsigned i = 0; i < size_in_bytes; ++i) {
363 data[i] = block.getByte(i + startByte);
364 }
365 return true;
366 }
367 }
368 } else {
369 // In Broadcast/Snoop protocols, this covers if you know the block
370 // exists somewhere in the caching hierarchy, then you want to read any
371 // valid RO or RW block. In directory protocols, same thing, you want
372 // to read any valid readable copy of the block.
373 DPRINTF(RubyPort, "num_busy = %d, num_ro = %d, num_rw = %d\n",
374 num_busy, num_ro, num_rw);
375 // In this loop, we try to figure which controller has a read only or
376 // a read write copy of the given address. Any valid copy would suffice
377 // for a functional read.
378 for(int i = 0;i < num_controllers;++i) {
379 access_perm = ruby_system->m_abs_cntrl_vec[i]
380 ->getAccessPermission(line_address);
381 if(access_perm == AccessPermission_Read_Only ||
382 access_perm == AccessPermission_Read_Write)
328 {
383 {
329 data[i] = block.getByte(i + startByte);
384 DataBlock& block = ruby_system->m_abs_cntrl_vec[i]
385 ->getDataBlock(line_address);
386
387 DPRINTF(RubyPort, "reading from %s block %s\n",
388 ruby_system->m_abs_cntrl_vec[i]->name(), block);
389 for (unsigned i = 0; i < size_in_bytes; ++i) {
390 data[i] = block.getByte(i + startByte);
391 }
392 return true;
330 }
393 }
331 return true;
332 }
333 }
334 return false;
335}
336
337bool
338RubyPort::M5Port::doFunctionalWrite(PacketPtr pkt)
339{
340 Address addr(pkt->getAddr());
341 Address line_addr = line_address(addr);
394 }
395 }
396 return false;
397}
398
399bool
400RubyPort::M5Port::doFunctionalWrite(PacketPtr pkt)
401{
402 Address addr(pkt->getAddr());
403 Address line_addr = line_address(addr);
342 AccessPermission accessPerm = AccessPermission_NotPresent;
404 AccessPermission access_perm = AccessPermission_NotPresent;
343 int num_controllers = ruby_system->m_abs_cntrl_vec.size();
344
345 DPRINTF(RubyPort, "Functional Write request for %s\n",addr);
346
347 unsigned int num_ro = 0;
348 unsigned int num_rw = 0;
349 unsigned int num_busy = 0;
405 int num_controllers = ruby_system->m_abs_cntrl_vec.size();
406
407 DPRINTF(RubyPort, "Functional Write request for %s\n",addr);
408
409 unsigned int num_ro = 0;
410 unsigned int num_rw = 0;
411 unsigned int num_busy = 0;
412 unsigned int num_backing_store = 0;
413 unsigned int num_invalid = 0;
350
351 // In this loop we count the number of controllers that have the given
352 // address in read only, read write and busy states.
414
415 // In this loop we count the number of controllers that have the given
416 // address in read only, read write and busy states.
353 for(int i = 0;i < num_controllers;++i)
354 {
355 accessPerm = ruby_system->m_abs_cntrl_vec[i]->
417 for(int i = 0;i < num_controllers;++i) {
418 access_perm = ruby_system->m_abs_cntrl_vec[i]->
356 getAccessPermission(line_addr);
419 getAccessPermission(line_addr);
357 if(accessPerm == AccessPermission_Read_Only) num_ro++;
358 else if(accessPerm == AccessPermission_Read_Write) num_rw++;
359 else if(accessPerm == AccessPermission_Busy) num_busy++;
420 if (access_perm == AccessPermission_Read_Only)
421 num_ro++;
422 else if (access_perm == AccessPermission_Read_Write)
423 num_rw++;
424 else if (access_perm == AccessPermission_Busy)
425 num_busy++;
426 else if (access_perm == AccessPermission_Backing_Store)
427 // See RubySlicc_Exports.sm for details, but Backing_Store is meant
428 // to represent blocks in memory *for Broadcast/Snooping protocols*,
429 // where memory has no idea whether it has an exclusive copy of data
430 // or not.
431 num_backing_store++;
432 else if (access_perm == AccessPermission_Invalid ||
433 access_perm == AccessPermission_NotPresent)
434 num_invalid++;
360 }
361
362 // If the number of read write copies is more than 1, then there is bug in
363 // coherence protocol. Otherwise, if all copies are in stable states, i.e.
364 // num_busy == 0, we update all the copies. If there is at least one copy
365 // in busy state, then we check if there is read write copy. If yes, then
435 }
436
437 // If the number of read write copies is more than 1, then there is bug in
438 // coherence protocol. Otherwise, if all copies are in stable states, i.e.
439 // num_busy == 0, we update all the copies. If there is at least one copy
440 // in busy state, then we check if there is read write copy. If yes, then
366 // also we let the access go through.
441 // also we let the access go through. Or, if there is no copy in the cache
442 // hierarchy at all, we still want to do the write to the memory
443 // (Backing_Store) instead of failing.
367
368 DPRINTF(RubyPort, "num_busy = %d, num_ro = %d, num_rw = %d\n",
369 num_busy, num_ro, num_rw);
370 assert(num_rw <= 1);
444
445 DPRINTF(RubyPort, "num_busy = %d, num_ro = %d, num_rw = %d\n",
446 num_busy, num_ro, num_rw);
447 assert(num_rw <= 1);
371 if((num_busy == 0 && num_ro > 0) || num_rw == 1)
372 {
373 uint8* data = pkt->getPtr<uint8_t>(true);
374 unsigned int size_in_bytes = pkt->getSize();
375 unsigned startByte = addr.getAddress() - line_addr.getAddress();
376
448
377 for(int i = 0; i < num_controllers;++i)
378 {
379 accessPerm = ruby_system->m_abs_cntrl_vec[i]->
449 uint8* data = pkt->getPtr<uint8_t>(true);
450 unsigned int size_in_bytes = pkt->getSize();
451 unsigned startByte = addr.getAddress() - line_addr.getAddress();
452
453 if ((num_busy == 0 && num_ro > 0) || num_rw == 1 ||
454 (num_invalid == (num_controllers - 1) && num_backing_store == 1))
455 {
456 for(int i = 0; i < num_controllers;++i) {
457 access_perm = ruby_system->m_abs_cntrl_vec[i]->
380 getAccessPermission(line_addr);
458 getAccessPermission(line_addr);
381 if(accessPerm == AccessPermission_Read_Only ||
382 accessPerm == AccessPermission_Read_Write||
383 accessPerm == AccessPermission_Maybe_Stale)
459 if(access_perm == AccessPermission_Read_Only ||
460 access_perm == AccessPermission_Read_Write||
461 access_perm == AccessPermission_Maybe_Stale ||
462 access_perm == AccessPermission_Backing_Store)
384 {
385 DataBlock& block = ruby_system->m_abs_cntrl_vec[i]
386 ->getDataBlock(line_addr);
387
388 DPRINTF(RubyPort, "%s\n",block);
463 {
464 DataBlock& block = ruby_system->m_abs_cntrl_vec[i]
465 ->getDataBlock(line_addr);
466
467 DPRINTF(RubyPort, "%s\n",block);
389 for (unsigned i = 0; i < size_in_bytes; ++i)
390 {
468 for (unsigned i = 0; i < size_in_bytes; ++i) {
391 block.setByte(i + startByte, data[i]);
392 }
393 DPRINTF(RubyPort, "%s\n",block);
394 }
395 }
396 return true;
397 }
398 return false;

--- 200 unchanged lines hidden ---
469 block.setByte(i + startByte, data[i]);
470 }
471 DPRINTF(RubyPort, "%s\n",block);
472 }
473 }
474 return true;
475 }
476 return false;

--- 200 unchanged lines hidden ---