cache.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: cache.c,v 1.4 2000/01/25 00:11:38 prumpf Exp $
  2.  *
  3.  * This file is subject to the terms and conditions of the GNU General Public
  4.  * License.  See the file "COPYING" in the main directory of this archive
  5.  * for more details.
  6.  *
  7.  * Copyright (C) 1999 Helge Deller (07-13-1999)
  8.  * Copyright (C) 1999 SuSE GmbH Nuernberg
  9.  * Copyright (C) 2000 Philipp Rumpf (prumpf@tux.org)
  10.  *
  11.  * Cache and TLB management
  12.  *
  13.  */
  14.  
  15. #include <linux/init.h>
  16. #include <linux/kernel.h>
  17. #include <linux/mm.h>
  18. #include <linux/seq_file.h>
  19. #include <asm/pdc.h>
  20. #include <asm/cache.h>
  21. #include <asm/system.h>
  22. #include <asm/page.h>
  23. #include <asm/pgalloc.h>
  24. #include <asm/processor.h>
  25. int split_tlb;
  26. int dcache_stride;
  27. int icache_stride;
  28. struct pdc_cache_info cache_info;
  29. #ifndef CONFIG_PA20
  30. static struct pdc_btlb_info btlb_info;
  31. #endif
  32. #ifdef CONFIG_SMP
  33. void
  34. flush_data_cache(void)
  35. {
  36. smp_call_function((void (*)(void *))flush_data_cache_local, NULL, 1, 1);
  37. flush_data_cache_local();
  38. }
  39. #endif
  40. void
  41. flush_cache_all_local(void)
  42. {
  43. flush_instruction_cache_local();
  44. flush_data_cache_local();
  45. }
  46. /* flushes EVERYTHING (tlb & cache) */
  47. void
  48. flush_all_caches(void)
  49. {
  50. flush_cache_all();
  51. flush_tlb_all();
  52. }
  53. void
  54. update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
  55. {
  56. struct page *page = pte_page(pte);
  57. if (VALID_PAGE(page) && page->mapping &&
  58.     test_bit(PG_dcache_dirty, &page->flags)) {
  59. flush_kernel_dcache_page(page_address(page));
  60. clear_bit(PG_dcache_dirty, &page->flags);
  61. }
  62. }
  63. void
  64. show_cache_info(struct seq_file *m)
  65. {
  66. seq_printf(m, "I-cachett: %ld KBn", 
  67. cache_info.ic_size/1024 );
  68. seq_printf(m, "D-cachett: %ld KB (%s)%sn", 
  69. cache_info.dc_size/1024,
  70. (cache_info.dc_conf.cc_wt ? "WT":"WB"),
  71. (cache_info.dc_conf.cc_sh ? " - shared I/D":"")
  72. );
  73. seq_printf(m, "ITLB entriest: %ldn" "DTLB entriest: %ld%sn",
  74. cache_info.it_size,
  75. cache_info.dt_size,
  76. cache_info.dt_conf.tc_sh ? " - shared with ITLB":""
  77. );
  78. #ifndef CONFIG_PA20
  79. /* BTLB - Block TLB */
  80. if (btlb_info.max_size==0) {
  81. seq_printf(m, "BTLBtt: not supportedn" );
  82. } else {
  83. seq_printf(m, 
  84. "BTLB fixedt: max. %d pages, pagesize=%d (%dMB)n"
  85. "BTLB fix-entr.t: %d instruction, %d data (%d combined)n"
  86. "BTLB var-entr.t: %d instruction, %d data (%d combined)n",
  87. btlb_info.max_size, (int)4096,
  88. btlb_info.max_size>>8,
  89. btlb_info.fixed_range_info.num_i,
  90. btlb_info.fixed_range_info.num_d,
  91. btlb_info.fixed_range_info.num_comb, 
  92. btlb_info.variable_range_info.num_i,
  93. btlb_info.variable_range_info.num_d,
  94. btlb_info.variable_range_info.num_comb
  95. );
  96. }
  97. #endif
  98. }
  99. void __init 
  100. cache_init(void)
  101. {
  102. if(pdc_cache_info(&cache_info)<0)
  103. panic("cache_init: pdc_cache_info failed");
  104. #if 0
  105. printk(KERN_DEBUG "ic_size %lx dc_size %lx it_size %lx pdc_cache_info %d*long pdc_cache_cf %dn",
  106.     cache_info.ic_size,
  107.     cache_info.dc_size,
  108.     cache_info.it_size,
  109.     sizeof (struct pdc_cache_info) / sizeof (long),
  110.     sizeof (struct pdc_cache_cf)
  111. );
  112. printk(KERN_DEBUG "dc base %x dc stride %x dc count %x dc loop %dn",
  113.     cache_info.dc_base,
  114.     cache_info.dc_stride,
  115.     cache_info.dc_count,
  116.     cache_info.dc_loop);
  117. printk(KERN_DEBUG "dc conf: alias %d block %d line %d wt %d sh %d cst %d assoc %dn",
  118.     cache_info.dc_conf.cc_alias,
  119.     cache_info.dc_conf.cc_block,
  120.     cache_info.dc_conf.cc_line,
  121.     cache_info.dc_conf.cc_wt,
  122.     cache_info.dc_conf.cc_sh,
  123.     cache_info.dc_conf.cc_cst,
  124.     cache_info.dc_conf.cc_assoc);
  125. printk(KERN_DEBUG "ic conf: alias %d block %d line %d wt %d sh %d cst %d assoc %dn",
  126.     cache_info.ic_conf.cc_alias,
  127.     cache_info.ic_conf.cc_block,
  128.     cache_info.ic_conf.cc_line,
  129.     cache_info.ic_conf.cc_wt,
  130.     cache_info.ic_conf.cc_sh,
  131.     cache_info.ic_conf.cc_cst,
  132.     cache_info.ic_conf.cc_assoc);
  133. printk(KERN_DEBUG "dt conf: sh %d page %d cst %d aid %d pad1 %d n",
  134.     cache_info.dt_conf.tc_sh,
  135.     cache_info.dt_conf.tc_page,
  136.     cache_info.dt_conf.tc_cst,
  137.     cache_info.dt_conf.tc_aid,
  138.     cache_info.dt_conf.tc_pad1);
  139. printk(KERN_DEBUG "it conf: sh %d page %d cst %d aid %d pad1 %d n",
  140.     cache_info.it_conf.tc_sh,
  141.     cache_info.it_conf.tc_page,
  142.     cache_info.it_conf.tc_cst,
  143.     cache_info.it_conf.tc_aid,
  144.     cache_info.it_conf.tc_pad1);
  145. #endif
  146. split_tlb = 0;
  147. if (cache_info.dt_conf.tc_sh == 0 || cache_info.dt_conf.tc_sh == 2) {
  148.     if (cache_info.dt_conf.tc_sh == 2)
  149. printk(KERN_WARNING "Unexpected TLB configuration. "
  150. "Will flush I/D separately (could be optimized).n");
  151.     split_tlb = 1;
  152. }
  153. dcache_stride = ( (1<<(cache_info.dc_conf.cc_block+3)) *
  154.  cache_info.dc_conf.cc_line );
  155. icache_stride = ( (1<<(cache_info.ic_conf.cc_block+3)) *
  156.  cache_info.ic_conf.cc_line );
  157. #ifndef CONFIG_PA20
  158. if(pdc_btlb_info(&btlb_info)<0) {
  159. memset(&btlb_info, 0, sizeof btlb_info);
  160. }
  161. #endif
  162. if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) == PDC_MODEL_NVA_UNSUPPORTED) {
  163. printk(KERN_WARNING "Only equivalent aliasing supportedn");
  164. #ifndef CONFIG_SMP
  165. panic("SMP kernel required to avoid non-equivalent aliasing");
  166. #endif
  167. }
  168. }
  169. void disable_sr_hashing(void)
  170. {
  171.     int srhash_type;
  172.     if (boot_cpu_data.cpu_type == pcxl2)
  173. return; /* pcxl2 doesn't support space register hashing */
  174.     switch (boot_cpu_data.cpu_type) {
  175.     case pcx:
  176. BUG(); /* We shouldn't get here. code in setup.c should prevent it */
  177. return;
  178.     case pcxs:
  179.     case pcxt:
  180.     case pcxt_:
  181. srhash_type = SRHASH_PCXST;
  182. break;
  183.     case pcxl:
  184. srhash_type = SRHASH_PCXL;
  185. break;
  186.     default: /* Currently all PA2.0 machines use the same ins. sequence */
  187. srhash_type = SRHASH_PA20;
  188. break;
  189.     }
  190.     disable_sr_hashing_asm(srhash_type);
  191. }