ia64/xen-unstable

view xen/arch/x86/extable.c @ 18806:ed8524f4a044

x86: Re-initialise HPET on resume from S3

Signed-off-by: Guanqun Lu <guanqun.lu@intel.com>
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Nov 18 15:55:14 2008 +0000 (2008-11-18)
parents 759d924af6d8
children
line source
2 #include <xen/config.h>
3 #include <xen/init.h>
4 #include <xen/perfc.h>
5 #include <xen/spinlock.h>
6 #include <asm/uaccess.h>
8 extern struct exception_table_entry __start___ex_table[];
9 extern struct exception_table_entry __stop___ex_table[];
10 extern struct exception_table_entry __start___pre_ex_table[];
11 extern struct exception_table_entry __stop___pre_ex_table[];
13 static void __init sort_exception_table(struct exception_table_entry *start,
14 struct exception_table_entry *end)
15 {
16 struct exception_table_entry *p, *q, tmp;
18 for ( p = start; p < end; p++ )
19 {
20 for ( q = p-1; q > start; q-- )
21 if ( p->insn > q->insn )
22 break;
23 if ( ++q != p )
24 {
25 tmp = *p;
26 memmove(q+1, q, (p-q)*sizeof(*p));
27 *q = tmp;
28 }
29 }
30 }
32 void __init sort_exception_tables(void)
33 {
34 sort_exception_table(__start___ex_table, __stop___ex_table);
35 sort_exception_table(__start___pre_ex_table, __stop___pre_ex_table);
36 }
38 static inline unsigned long
39 search_one_table(const struct exception_table_entry *first,
40 const struct exception_table_entry *last,
41 unsigned long value)
42 {
43 const struct exception_table_entry *mid;
44 long diff;
46 while ( first <= last )
47 {
48 mid = (last - first) / 2 + first;
49 diff = mid->insn - value;
50 if (diff == 0)
51 return mid->fixup;
52 else if (diff < 0)
53 first = mid+1;
54 else
55 last = mid-1;
56 }
57 return 0;
58 }
60 unsigned long
61 search_exception_table(unsigned long addr)
62 {
63 return search_one_table(
64 __start___ex_table, __stop___ex_table-1, addr);
65 }
67 unsigned long
68 search_pre_exception_table(struct cpu_user_regs *regs)
69 {
70 unsigned long addr = (unsigned long)regs->eip;
71 unsigned long fixup = search_one_table(
72 __start___pre_ex_table, __stop___pre_ex_table-1, addr);
73 if ( fixup )
74 {
75 dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
76 perfc_incr(exception_fixed);
77 }
78 return fixup;
79 }