ia64/xen-unstable

view xen/arch/ia64/xen/vhpt.c @ 9405:29dfadcc5029

[IA64] Followup to xen time cleanup

Clean up to xen time handler. Tristan #if 0 some code because it seems
redundant, which however is actually problematic logic as a reason for
an intermittent timer oops issue of dom0. So delete it now.

Also remove vcpu_wake, since wakeup current has nothing meaningful and
simply waste cpu cycle.

Signed-off-by: Kevin Tian <kevin.tian@intel.com>
author awilliam@xenbuild.aw
date Mon Mar 27 15:32:08 2006 -0700 (2006-03-27)
parents 0b0be946cf9c
children 6796157b5f8a
line source
1 /*
2 * Initialize VHPT support.
3 *
4 * Copyright (C) 2004 Hewlett-Packard Co
5 * Dan Magenheimer <dan.magenheimer@hp.com>
6 */
7 #include <linux/config.h>
8 #include <linux/kernel.h>
9 #include <linux/init.h>
11 #include <asm/processor.h>
12 #include <asm/system.h>
13 #include <asm/pgalloc.h>
14 #include <asm/page.h>
15 #include <asm/dma.h>
16 #include <asm/vhpt.h>
18 DEFINE_PER_CPU (unsigned long, vhpt_paddr);
19 DEFINE_PER_CPU (unsigned long, vhpt_pend);
21 void vhpt_flush(void)
22 {
23 struct vhpt_lf_entry *v = (void *)VHPT_ADDR;
24 int i;
25 #if 0
26 static int firsttime = 2;
28 if (firsttime) firsttime--;
29 else {
30 printf("vhpt_flush: *********************************************\n");
31 printf("vhpt_flush: *********************************************\n");
32 printf("vhpt_flush: *********************************************\n");
33 printf("vhpt_flush: flushing vhpt (seems to crash at rid wrap?)...\n");
34 printf("vhpt_flush: *********************************************\n");
35 printf("vhpt_flush: *********************************************\n");
36 printf("vhpt_flush: *********************************************\n");
37 }
38 #endif
39 for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++) {
40 v->itir = 0;
41 v->CChain = 0;
42 v->page_flags = 0;
43 v->ti_tag = INVALID_TI_TAG;
44 }
45 // initialize cache too???
46 }
48 #ifdef VHPT_GLOBAL
49 void vhpt_flush_address(unsigned long vadr, unsigned long addr_range)
50 {
51 struct vhpt_lf_entry *vlfe;
53 if ((vadr >> 61) == 7) {
54 // no vhpt for region 7 yet, see vcpu_itc_no_srlz
55 printf("vhpt_flush_address: region 7, spinning...\n");
56 while(1);
57 }
58 #if 0
59 // this only seems to occur at shutdown, but it does occur
60 if ((!addr_range) || addr_range & (addr_range - 1)) {
61 printf("vhpt_flush_address: weird range, spinning...\n");
62 while(1);
63 }
64 //printf("************** vhpt_flush_address(%p,%p)\n",vadr,addr_range);
65 #endif
66 while ((long)addr_range > 0) {
67 vlfe = (struct vhpt_lf_entry *)ia64_thash(vadr);
68 // FIXME: for now, just blow it away even if it belongs to
69 // another domain. Later, use ttag to check for match
70 //if (!(vlfe->ti_tag & INVALID_TI_TAG)) {
71 //printf("vhpt_flush_address: blowing away valid tag for vadr=%p\n",vadr);
72 //}
73 vlfe->ti_tag |= INVALID_TI_TAG;
74 addr_range -= PAGE_SIZE;
75 vadr += PAGE_SIZE;
76 }
77 }
78 #endif
80 static void vhpt_map(unsigned long pte)
81 {
82 unsigned long psr;
84 psr = ia64_clear_ic();
85 ia64_itr(0x2, IA64_TR_VHPT, VHPT_ADDR, pte, VHPT_SIZE_LOG2);
86 ia64_set_psr(psr);
87 ia64_srlz_i();
88 }
90 void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte, unsigned long logps)
91 {
92 unsigned long mask = (1L << logps) - 1;
93 extern long running_on_sim;
94 int i;
96 if (logps-PAGE_SHIFT > 10 && !running_on_sim) {
97 // if this happens, we may want to revisit this algorithm
98 printf("vhpt_multiple_insert:logps-PAGE_SHIFT>10,spinning..\n");
99 while(1);
100 }
101 if (logps-PAGE_SHIFT > 2) {
102 // FIXME: Should add counter here to see how often this
103 // happens (e.g. for 16MB pages!) and determine if it
104 // is a performance problem. On a quick look, it takes
105 // about 39000 instrs for a 16MB page and it seems to occur
106 // only a few times/second, so OK for now.
107 // An alternate solution would be to just insert the one
108 // 16KB in the vhpt (but with the full mapping)?
109 //printf("vhpt_multiple_insert: logps-PAGE_SHIFT==%d,"
110 //"va=%p, pa=%p, pa-masked=%p\n",
111 //logps-PAGE_SHIFT,vaddr,pte&_PFN_MASK,
112 //(pte&_PFN_MASK)&~mask);
113 }
114 vaddr &= ~mask;
115 pte = ((pte & _PFN_MASK) & ~mask) | (pte & ~_PFN_MASK);
116 for (i = 1L << (logps-PAGE_SHIFT); i > 0; i--) {
117 vhpt_insert(vaddr,pte,logps<<2);
118 vaddr += PAGE_SIZE;
119 }
120 }
122 void vhpt_init(void)
123 {
124 unsigned long vhpt_total_size, vhpt_alignment;
125 unsigned long paddr, pte;
126 struct page_info *page;
127 #if !VHPT_ENABLED
128 return;
129 #endif
130 // allocate a huge chunk of physical memory.... how???
131 vhpt_total_size = 1 << VHPT_SIZE_LOG2; // 4MB, 16MB, 64MB, or 256MB
132 vhpt_alignment = 1 << VHPT_SIZE_LOG2; // 4MB, 16MB, 64MB, or 256MB
133 printf("vhpt_init: vhpt size=0x%lx, align=0x%lx\n",
134 vhpt_total_size, vhpt_alignment);
135 /* This allocation only holds true if vhpt table is unique for
136 * all domains. Or else later new vhpt table should be allocated
137 * from domain heap when each domain is created. Assume xen buddy
138 * allocator can provide natural aligned page by order?
139 */
140 // vhpt_imva = alloc_xenheap_pages(VHPT_SIZE_LOG2 - PAGE_SHIFT);
141 page = alloc_domheap_pages(NULL, VHPT_SIZE_LOG2 - PAGE_SHIFT, 0);
142 if (!page) {
143 printf("vhpt_init: can't allocate VHPT!\n");
144 while(1);
145 }
146 paddr = page_to_maddr(page);
147 __get_cpu_var(vhpt_paddr) = paddr;
148 __get_cpu_var(vhpt_pend) = paddr + vhpt_total_size - 1;
149 printf("vhpt_init: vhpt paddr=0x%lx, end=0x%lx\n",
150 paddr, __get_cpu_var(vhpt_pend));
151 pte = pte_val(pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL));
152 vhpt_map(pte);
153 ia64_set_pta(VHPT_ADDR | (1 << 8) | (VHPT_SIZE_LOG2 << 2) |
154 VHPT_ENABLED);
155 vhpt_flush();
156 }
159 void zero_vhpt_stats(void)
160 {
161 return;
162 }
164 int dump_vhpt_stats(char *buf)
165 {
166 int i;
167 char *s = buf;
168 struct vhpt_lf_entry *v = (void *)VHPT_ADDR;
169 unsigned long vhpt_valid = 0, vhpt_chains = 0;
171 for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++) {
172 if (!(v->ti_tag & INVALID_TI_TAG)) vhpt_valid++;
173 if (v->CChain) vhpt_chains++;
174 }
175 s += sprintf(s,"VHPT usage: %ld/%ld (%ld collision chains)\n",
176 vhpt_valid, (unsigned long) VHPT_NUM_ENTRIES, vhpt_chains);
177 return s - buf;
178 }