aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru/grumain.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/sgi-gru/grumain.c')
-rw-r--r--drivers/misc/sgi-gru/grumain.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
index 0eeb8dddd2f5..e11e1ac50900 100644
--- a/drivers/misc/sgi-gru/grumain.c
+++ b/drivers/misc/sgi-gru/grumain.c
@@ -432,29 +432,35 @@ static inline long gru_copy_handle(void *d, void *s)
432 return GRU_HANDLE_BYTES; 432 return GRU_HANDLE_BYTES;
433} 433}
434 434
435/* rewrite in assembly & use lots of prefetch */ 435static void gru_prefetch_context(void *gseg, void *cb, void *cbe, unsigned long cbrmap,
436static void gru_load_context_data(void *save, void *grubase, int ctxnum, 436 unsigned long length)
437 unsigned long cbrmap, unsigned long dsrmap)
438{ 437{
439 void *gseg, *cb, *cbe;
440 unsigned long length;
441 int i, scr; 438 int i, scr;
442 439
443 gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
444 length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
445 prefetch_data(gseg + GRU_DS_BASE, length / GRU_CACHE_LINE_BYTES, 440 prefetch_data(gseg + GRU_DS_BASE, length / GRU_CACHE_LINE_BYTES,
446 GRU_CACHE_LINE_BYTES); 441 GRU_CACHE_LINE_BYTES);
447 442
448 cb = gseg + GRU_CB_BASE;
449 cbe = grubase + GRU_CBE_BASE;
450 for_each_cbr_in_allocation_map(i, &cbrmap, scr) { 443 for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
451 prefetch_data(cb, 1, GRU_CACHE_LINE_BYTES); 444 prefetch_data(cb, 1, GRU_CACHE_LINE_BYTES);
452 prefetch_data(cbe + i * GRU_HANDLE_STRIDE, 1, 445 prefetch_data(cbe + i * GRU_HANDLE_STRIDE, 1,
453 GRU_CACHE_LINE_BYTES); 446 GRU_CACHE_LINE_BYTES);
454 cb += GRU_HANDLE_STRIDE; 447 cb += GRU_HANDLE_STRIDE;
455 } 448 }
449}
450
451static void gru_load_context_data(void *save, void *grubase, int ctxnum,
452 unsigned long cbrmap, unsigned long dsrmap)
453{
454 void *gseg, *cb, *cbe;
455 unsigned long length;
456 int i, scr;
456 457
458 gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
457 cb = gseg + GRU_CB_BASE; 459 cb = gseg + GRU_CB_BASE;
460 cbe = grubase + GRU_CBE_BASE;
461 length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
462 gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
463
458 for_each_cbr_in_allocation_map(i, &cbrmap, scr) { 464 for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
459 save += gru_copy_handle(cb, save); 465 save += gru_copy_handle(cb, save);
460 save += gru_copy_handle(cbe + i * GRU_HANDLE_STRIDE, save); 466 save += gru_copy_handle(cbe + i * GRU_HANDLE_STRIDE, save);
@@ -472,15 +478,16 @@ static void gru_unload_context_data(void *save, void *grubase, int ctxnum,
472 int i, scr; 478 int i, scr;
473 479
474 gseg = grubase + ctxnum * GRU_GSEG_STRIDE; 480 gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
475
476 cb = gseg + GRU_CB_BASE; 481 cb = gseg + GRU_CB_BASE;
477 cbe = grubase + GRU_CBE_BASE; 482 cbe = grubase + GRU_CBE_BASE;
483 length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
484 gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
485
478 for_each_cbr_in_allocation_map(i, &cbrmap, scr) { 486 for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
479 save += gru_copy_handle(save, cb); 487 save += gru_copy_handle(save, cb);
480 save += gru_copy_handle(save, cbe + i * GRU_HANDLE_STRIDE); 488 save += gru_copy_handle(save, cbe + i * GRU_HANDLE_STRIDE);
481 cb += GRU_HANDLE_STRIDE; 489 cb += GRU_HANDLE_STRIDE;
482 } 490 }
483 length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
484 memcpy(save, gseg + GRU_DS_BASE, length); 491 memcpy(save, gseg + GRU_DS_BASE, length);
485} 492}
486 493