]>
Commit | Line | Data |
---|---|---|
2262cfee | 1 | /* |
dbf7115a GR |
2 | * (C) Copyright 2008-2011 |
3 | * Graeme Russ, <graeme.russ@gmail.com> | |
564a9984 | 4 | * |
2262cfee | 5 | * (C) Copyright 2002 |
fa82f871 | 6 | * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> |
2262cfee | 7 | * |
433ff2bd GR |
8 | * Portions of this file are derived from the Linux kernel source |
9 | * Copyright (C) 1991, 1992 Linus Torvalds | |
10 | * | |
1a459660 | 11 | * SPDX-License-Identifier: GPL-2.0+ |
2262cfee WD |
12 | */ |
13 | ||
14 | #include <common.h> | |
095593c0 SR |
15 | #include <asm/cache.h> |
16 | #include <asm/control_regs.h> | |
9933d609 | 17 | #include <asm/interrupt.h> |
ca56a4ce | 18 | #include <asm/io.h> |
0c24c9cc | 19 | #include <asm/processor-flags.h> |
717979fd | 20 | #include <linux/compiler.h> |
7c71034d VB |
21 | #include <asm/msr.h> |
22 | #include <asm/u-boot-x86.h> | |
2262cfee | 23 | |
7282d834 SG |
24 | DECLARE_GLOBAL_DATA_PTR; |
25 | ||
564a9984 GR |
26 | #define DECLARE_INTERRUPT(x) \ |
27 | ".globl irq_"#x"\n" \ | |
0fc1b49e GR |
28 | ".hidden irq_"#x"\n" \ |
29 | ".type irq_"#x", @function\n" \ | |
564a9984 | 30 | "irq_"#x":\n" \ |
564a9984 GR |
31 | "pushl $"#x"\n" \ |
32 | "jmp irq_common_entry\n" | |
2262cfee | 33 | |
7228efa3 | 34 | void dump_regs(struct irq_regs *regs) |
433ff2bd GR |
35 | { |
36 | unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; | |
37 | unsigned long d0, d1, d2, d3, d6, d7; | |
ca56a4ce | 38 | unsigned long sp; |
433ff2bd GR |
39 | |
40 | printf("EIP: %04x:[<%08lx>] EFLAGS: %08lx\n", | |
41 | (u16)regs->xcs, regs->eip, regs->eflags); | |
42 | ||
43 | printf("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", | |
44 | regs->eax, regs->ebx, regs->ecx, regs->edx); | |
45 | printf("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n", | |
46 | regs->esi, regs->edi, regs->ebp, regs->esp); | |
47 | printf(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n", | |
717979fd GR |
48 | (u16)regs->xds, (u16)regs->xes, (u16)regs->xfs, |
49 | (u16)regs->xgs, (u16)regs->xss); | |
433ff2bd GR |
50 | |
51 | cr0 = read_cr0(); | |
52 | cr2 = read_cr2(); | |
53 | cr3 = read_cr3(); | |
54 | cr4 = read_cr4(); | |
55 | ||
56 | printf("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", | |
57 | cr0, cr2, cr3, cr4); | |
58 | ||
59 | d0 = get_debugreg(0); | |
60 | d1 = get_debugreg(1); | |
61 | d2 = get_debugreg(2); | |
62 | d3 = get_debugreg(3); | |
63 | ||
64 | printf("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n", | |
65 | d0, d1, d2, d3); | |
66 | ||
67 | d6 = get_debugreg(6); | |
68 | d7 = get_debugreg(7); | |
69 | printf("DR6: %08lx DR7: %08lx\n", | |
70 | d6, d7); | |
ca56a4ce GR |
71 | |
72 | printf("Stack:\n"); | |
73 | sp = regs->esp; | |
74 | ||
75 | sp += 64; | |
76 | ||
77 | while (sp > (regs->esp - 16)) { | |
78 | if (sp == regs->esp) | |
79 | printf("--->"); | |
80 | else | |
81 | printf(" "); | |
82 | printf("0x%8.8lx : 0x%8.8lx\n", sp, (ulong)readl(sp)); | |
83 | sp -= 4; | |
84 | } | |
433ff2bd GR |
85 | } |
86 | ||
2262cfee WD |
87 | struct idt_entry { |
88 | u16 base_low; | |
89 | u16 selector; | |
90 | u8 res; | |
91 | u8 access; | |
92 | u16 base_high; | |
717979fd | 93 | } __packed; |
2262cfee | 94 | |
564a9984 GR |
95 | struct desc_ptr { |
96 | unsigned short size; | |
97 | unsigned long address; | |
98 | unsigned short segment; | |
717979fd | 99 | } __packed; |
2262cfee | 100 | |
58c7a675 | 101 | struct idt_entry idt[256] __aligned(16); |
2262cfee | 102 | |
564a9984 | 103 | struct desc_ptr idt_ptr; |
2262cfee | 104 | |
564a9984 GR |
105 | static inline void load_idt(const struct desc_ptr *dtr) |
106 | { | |
717979fd | 107 | asm volatile("cs lidt %0" : : "m" (*dtr)); |
564a9984 | 108 | } |
2262cfee | 109 | |
abf0cd3d | 110 | void set_vector(u8 intnum, void *routine) |
2262cfee | 111 | { |
1c409bc7 GR |
112 | idt[intnum].base_high = (u16)((u32)(routine) >> 16); |
113 | idt[intnum].base_low = (u16)((u32)(routine) & 0xffff); | |
2262cfee WD |
114 | } |
115 | ||
717979fd GR |
116 | /* |
117 | * Ideally these would be defined static to avoid a checkpatch warning, but | |
118 | * the compiler cannot see them in the inline asm and complains that they | |
119 | * aren't defined | |
120 | */ | |
564a9984 GR |
121 | void irq_0(void); |
122 | void irq_1(void); | |
2262cfee | 123 | |
abf0cd3d | 124 | int cpu_init_interrupts(void) |
2262cfee WD |
125 | { |
126 | int i; | |
8bde7f77 | 127 | |
564a9984 GR |
128 | int irq_entry_size = irq_1 - irq_0; |
129 | void *irq_entry = (void *)irq_0; | |
130 | ||
2262cfee WD |
131 | /* Just in case... */ |
132 | disable_interrupts(); | |
8bde7f77 | 133 | |
2262cfee | 134 | /* Setup the IDT */ |
717979fd | 135 | for (i = 0; i < 256; i++) { |
2262cfee | 136 | idt[i].access = 0x8e; |
8bde7f77 WD |
137 | idt[i].res = 0; |
138 | idt[i].selector = 0x10; | |
564a9984 GR |
139 | set_vector(i, irq_entry); |
140 | irq_entry += irq_entry_size; | |
8bde7f77 WD |
141 | } |
142 | ||
564a9984 GR |
143 | idt_ptr.size = 256 * 8; |
144 | idt_ptr.address = (unsigned long) idt; | |
145 | idt_ptr.segment = 0x18; | |
146 | ||
147 | load_idt(&idt_ptr); | |
8bde7f77 | 148 | |
2262cfee | 149 | /* It is now safe to enable interrupts */ |
8bde7f77 WD |
150 | enable_interrupts(); |
151 | ||
2262cfee WD |
152 | return 0; |
153 | } | |
154 | ||
564a9984 GR |
155 | void __do_irq(int irq) |
156 | { | |
157 | printf("Unhandled IRQ : %d\n", irq); | |
158 | } | |
159 | void do_irq(int irq) __attribute__((weak, alias("__do_irq"))); | |
160 | ||
2262cfee WD |
161 | void enable_interrupts(void) |
162 | { | |
163 | asm("sti\n"); | |
164 | } | |
165 | ||
166 | int disable_interrupts(void) | |
167 | { | |
168 | long flags; | |
8bde7f77 | 169 | |
2262cfee | 170 | asm volatile ("pushfl ; popl %0 ; cli\n" : "=g" (flags) : ); |
8bde7f77 | 171 | |
717979fd | 172 | return flags & X86_EFLAGS_IF; |
2262cfee | 173 | } |
564a9984 GR |
174 | |
175 | /* IRQ Low-Level Service Routine */ | |
7228efa3 | 176 | void irq_llsr(struct irq_regs *regs) |
564a9984 GR |
177 | { |
178 | /* | |
179 | * For detailed description of each exception, refer to: | |
fa82f871 | 180 | * Intel® 64 and IA-32 Architectures Software Developer's Manual |
564a9984 GR |
181 | * Volume 1: Basic Architecture |
182 | * Order Number: 253665-029US, November 2008 | |
183 | * Table 6-1. Exceptions and Interrupts | |
184 | */ | |
7228efa3 | 185 | switch (regs->irq_id) { |
564a9984 | 186 | case 0x00: |
433ff2bd GR |
187 | printf("Divide Error (Division by zero)\n"); |
188 | dump_regs(regs); | |
6d7404c4 | 189 | hang(); |
564a9984 GR |
190 | break; |
191 | case 0x01: | |
433ff2bd GR |
192 | printf("Debug Interrupt (Single step)\n"); |
193 | dump_regs(regs); | |
564a9984 GR |
194 | break; |
195 | case 0x02: | |
433ff2bd GR |
196 | printf("NMI Interrupt\n"); |
197 | dump_regs(regs); | |
564a9984 GR |
198 | break; |
199 | case 0x03: | |
433ff2bd GR |
200 | printf("Breakpoint\n"); |
201 | dump_regs(regs); | |
564a9984 GR |
202 | break; |
203 | case 0x04: | |
433ff2bd GR |
204 | printf("Overflow\n"); |
205 | dump_regs(regs); | |
6d7404c4 | 206 | hang(); |
564a9984 GR |
207 | break; |
208 | case 0x05: | |
433ff2bd GR |
209 | printf("BOUND Range Exceeded\n"); |
210 | dump_regs(regs); | |
6d7404c4 | 211 | hang(); |
564a9984 GR |
212 | break; |
213 | case 0x06: | |
433ff2bd GR |
214 | printf("Invalid Opcode (UnDefined Opcode)\n"); |
215 | dump_regs(regs); | |
6d7404c4 | 216 | hang(); |
564a9984 GR |
217 | break; |
218 | case 0x07: | |
433ff2bd GR |
219 | printf("Device Not Available (No Math Coprocessor)\n"); |
220 | dump_regs(regs); | |
6d7404c4 | 221 | hang(); |
564a9984 GR |
222 | break; |
223 | case 0x08: | |
433ff2bd GR |
224 | printf("Double fault\n"); |
225 | dump_regs(regs); | |
6d7404c4 | 226 | hang(); |
564a9984 GR |
227 | break; |
228 | case 0x09: | |
433ff2bd GR |
229 | printf("Co-processor segment overrun\n"); |
230 | dump_regs(regs); | |
6d7404c4 | 231 | hang(); |
564a9984 GR |
232 | break; |
233 | case 0x0a: | |
433ff2bd GR |
234 | printf("Invalid TSS\n"); |
235 | dump_regs(regs); | |
564a9984 GR |
236 | break; |
237 | case 0x0b: | |
433ff2bd GR |
238 | printf("Segment Not Present\n"); |
239 | dump_regs(regs); | |
6d7404c4 | 240 | hang(); |
564a9984 GR |
241 | break; |
242 | case 0x0c: | |
433ff2bd GR |
243 | printf("Stack Segment Fault\n"); |
244 | dump_regs(regs); | |
6d7404c4 | 245 | hang(); |
564a9984 GR |
246 | break; |
247 | case 0x0d: | |
433ff2bd GR |
248 | printf("General Protection\n"); |
249 | dump_regs(regs); | |
564a9984 GR |
250 | break; |
251 | case 0x0e: | |
433ff2bd GR |
252 | printf("Page fault\n"); |
253 | dump_regs(regs); | |
6d7404c4 | 254 | hang(); |
564a9984 GR |
255 | break; |
256 | case 0x0f: | |
433ff2bd GR |
257 | printf("Floating-Point Error (Math Fault)\n"); |
258 | dump_regs(regs); | |
564a9984 GR |
259 | break; |
260 | case 0x10: | |
433ff2bd GR |
261 | printf("Alignment check\n"); |
262 | dump_regs(regs); | |
564a9984 GR |
263 | break; |
264 | case 0x11: | |
433ff2bd GR |
265 | printf("Machine Check\n"); |
266 | dump_regs(regs); | |
564a9984 GR |
267 | break; |
268 | case 0x12: | |
433ff2bd GR |
269 | printf("SIMD Floating-Point Exception\n"); |
270 | dump_regs(regs); | |
564a9984 GR |
271 | break; |
272 | case 0x13: | |
273 | case 0x14: | |
274 | case 0x15: | |
275 | case 0x16: | |
276 | case 0x17: | |
277 | case 0x18: | |
278 | case 0x19: | |
279 | case 0x1a: | |
280 | case 0x1b: | |
281 | case 0x1c: | |
282 | case 0x1d: | |
283 | case 0x1e: | |
284 | case 0x1f: | |
433ff2bd GR |
285 | printf("Reserved Exception\n"); |
286 | dump_regs(regs); | |
564a9984 GR |
287 | break; |
288 | ||
289 | default: | |
290 | /* Hardware or User IRQ */ | |
7228efa3 | 291 | do_irq(regs->irq_id); |
564a9984 GR |
292 | } |
293 | } | |
294 | ||
295 | /* | |
296 | * OK - This looks really horrible, but it serves a purpose - It helps create | |
297 | * fully relocatable code. | |
298 | * - The call to irq_llsr will be a relative jump | |
299 | * - The IRQ entries will be guaranteed to be in order | |
433ff2bd GR |
300 | * Interrupt entries are now very small (a push and a jump) but they are |
301 | * now slower (all registers pushed on stack which provides complete | |
302 | * crash dumps in the low level handlers | |
7228efa3 GR |
303 | * |
304 | * Interrupt Entry Point: | |
305 | * - Interrupt has caused eflags, CS and EIP to be pushed | |
306 | * - Interrupt Vector Handler has pushed orig_eax | |
307 | * - pt_regs.esp needs to be adjusted by 40 bytes: | |
308 | * 12 bytes pushed by CPU (EFLAGSF, CS, EIP) | |
309 | * 4 bytes pushed by vector handler (irq_id) | |
310 | * 24 bytes pushed before SP (SS, GS, FS, ES, DS, EAX) | |
311 | * NOTE: Only longs are pushed on/popped off the stack! | |
564a9984 GR |
312 | */ |
313 | asm(".globl irq_common_entry\n" \ | |
0fc1b49e GR |
314 | ".hidden irq_common_entry\n" \ |
315 | ".type irq_common_entry, @function\n" \ | |
564a9984 | 316 | "irq_common_entry:\n" \ |
433ff2bd | 317 | "cld\n" \ |
7228efa3 | 318 | "pushl %ss\n" \ |
433ff2bd GR |
319 | "pushl %gs\n" \ |
320 | "pushl %fs\n" \ | |
321 | "pushl %es\n" \ | |
322 | "pushl %ds\n" \ | |
323 | "pushl %eax\n" \ | |
7228efa3 GR |
324 | "movl %esp, %eax\n" \ |
325 | "addl $40, %eax\n" \ | |
326 | "pushl %eax\n" \ | |
433ff2bd GR |
327 | "pushl %ebp\n" \ |
328 | "pushl %edi\n" \ | |
329 | "pushl %esi\n" \ | |
330 | "pushl %edx\n" \ | |
331 | "pushl %ecx\n" \ | |
332 | "pushl %ebx\n" \ | |
333 | "mov %esp, %eax\n" \ | |
564a9984 | 334 | "call irq_llsr\n" \ |
433ff2bd GR |
335 | "popl %ebx\n" \ |
336 | "popl %ecx\n" \ | |
337 | "popl %edx\n" \ | |
338 | "popl %esi\n" \ | |
339 | "popl %edi\n" \ | |
340 | "popl %ebp\n" \ | |
341 | "popl %eax\n" \ | |
7228efa3 | 342 | "popl %eax\n" \ |
433ff2bd GR |
343 | "popl %ds\n" \ |
344 | "popl %es\n" \ | |
345 | "popl %fs\n" \ | |
346 | "popl %gs\n" \ | |
7228efa3 | 347 | "popl %ss\n" \ |
433ff2bd | 348 | "add $4, %esp\n" \ |
564a9984 GR |
349 | "iret\n" \ |
350 | DECLARE_INTERRUPT(0) \ | |
351 | DECLARE_INTERRUPT(1) \ | |
352 | DECLARE_INTERRUPT(2) \ | |
353 | DECLARE_INTERRUPT(3) \ | |
354 | DECLARE_INTERRUPT(4) \ | |
355 | DECLARE_INTERRUPT(5) \ | |
356 | DECLARE_INTERRUPT(6) \ | |
357 | DECLARE_INTERRUPT(7) \ | |
358 | DECLARE_INTERRUPT(8) \ | |
359 | DECLARE_INTERRUPT(9) \ | |
360 | DECLARE_INTERRUPT(10) \ | |
361 | DECLARE_INTERRUPT(11) \ | |
362 | DECLARE_INTERRUPT(12) \ | |
363 | DECLARE_INTERRUPT(13) \ | |
364 | DECLARE_INTERRUPT(14) \ | |
365 | DECLARE_INTERRUPT(15) \ | |
366 | DECLARE_INTERRUPT(16) \ | |
367 | DECLARE_INTERRUPT(17) \ | |
368 | DECLARE_INTERRUPT(18) \ | |
369 | DECLARE_INTERRUPT(19) \ | |
370 | DECLARE_INTERRUPT(20) \ | |
371 | DECLARE_INTERRUPT(21) \ | |
372 | DECLARE_INTERRUPT(22) \ | |
373 | DECLARE_INTERRUPT(23) \ | |
374 | DECLARE_INTERRUPT(24) \ | |
375 | DECLARE_INTERRUPT(25) \ | |
376 | DECLARE_INTERRUPT(26) \ | |
377 | DECLARE_INTERRUPT(27) \ | |
378 | DECLARE_INTERRUPT(28) \ | |
379 | DECLARE_INTERRUPT(29) \ | |
380 | DECLARE_INTERRUPT(30) \ | |
381 | DECLARE_INTERRUPT(31) \ | |
382 | DECLARE_INTERRUPT(32) \ | |
383 | DECLARE_INTERRUPT(33) \ | |
384 | DECLARE_INTERRUPT(34) \ | |
385 | DECLARE_INTERRUPT(35) \ | |
386 | DECLARE_INTERRUPT(36) \ | |
387 | DECLARE_INTERRUPT(37) \ | |
388 | DECLARE_INTERRUPT(38) \ | |
389 | DECLARE_INTERRUPT(39) \ | |
390 | DECLARE_INTERRUPT(40) \ | |
391 | DECLARE_INTERRUPT(41) \ | |
392 | DECLARE_INTERRUPT(42) \ | |
393 | DECLARE_INTERRUPT(43) \ | |
394 | DECLARE_INTERRUPT(44) \ | |
395 | DECLARE_INTERRUPT(45) \ | |
396 | DECLARE_INTERRUPT(46) \ | |
397 | DECLARE_INTERRUPT(47) \ | |
398 | DECLARE_INTERRUPT(48) \ | |
399 | DECLARE_INTERRUPT(49) \ | |
400 | DECLARE_INTERRUPT(50) \ | |
401 | DECLARE_INTERRUPT(51) \ | |
402 | DECLARE_INTERRUPT(52) \ | |
403 | DECLARE_INTERRUPT(53) \ | |
404 | DECLARE_INTERRUPT(54) \ | |
405 | DECLARE_INTERRUPT(55) \ | |
406 | DECLARE_INTERRUPT(56) \ | |
407 | DECLARE_INTERRUPT(57) \ | |
408 | DECLARE_INTERRUPT(58) \ | |
409 | DECLARE_INTERRUPT(59) \ | |
410 | DECLARE_INTERRUPT(60) \ | |
411 | DECLARE_INTERRUPT(61) \ | |
412 | DECLARE_INTERRUPT(62) \ | |
413 | DECLARE_INTERRUPT(63) \ | |
414 | DECLARE_INTERRUPT(64) \ | |
415 | DECLARE_INTERRUPT(65) \ | |
416 | DECLARE_INTERRUPT(66) \ | |
417 | DECLARE_INTERRUPT(67) \ | |
418 | DECLARE_INTERRUPT(68) \ | |
419 | DECLARE_INTERRUPT(69) \ | |
420 | DECLARE_INTERRUPT(70) \ | |
421 | DECLARE_INTERRUPT(71) \ | |
422 | DECLARE_INTERRUPT(72) \ | |
423 | DECLARE_INTERRUPT(73) \ | |
424 | DECLARE_INTERRUPT(74) \ | |
425 | DECLARE_INTERRUPT(75) \ | |
426 | DECLARE_INTERRUPT(76) \ | |
427 | DECLARE_INTERRUPT(77) \ | |
428 | DECLARE_INTERRUPT(78) \ | |
429 | DECLARE_INTERRUPT(79) \ | |
430 | DECLARE_INTERRUPT(80) \ | |
431 | DECLARE_INTERRUPT(81) \ | |
432 | DECLARE_INTERRUPT(82) \ | |
433 | DECLARE_INTERRUPT(83) \ | |
434 | DECLARE_INTERRUPT(84) \ | |
435 | DECLARE_INTERRUPT(85) \ | |
436 | DECLARE_INTERRUPT(86) \ | |
437 | DECLARE_INTERRUPT(87) \ | |
438 | DECLARE_INTERRUPT(88) \ | |
439 | DECLARE_INTERRUPT(89) \ | |
440 | DECLARE_INTERRUPT(90) \ | |
441 | DECLARE_INTERRUPT(91) \ | |
442 | DECLARE_INTERRUPT(92) \ | |
443 | DECLARE_INTERRUPT(93) \ | |
444 | DECLARE_INTERRUPT(94) \ | |
445 | DECLARE_INTERRUPT(95) \ | |
446 | DECLARE_INTERRUPT(97) \ | |
447 | DECLARE_INTERRUPT(96) \ | |
448 | DECLARE_INTERRUPT(98) \ | |
449 | DECLARE_INTERRUPT(99) \ | |
450 | DECLARE_INTERRUPT(100) \ | |
451 | DECLARE_INTERRUPT(101) \ | |
452 | DECLARE_INTERRUPT(102) \ | |
453 | DECLARE_INTERRUPT(103) \ | |
454 | DECLARE_INTERRUPT(104) \ | |
455 | DECLARE_INTERRUPT(105) \ | |
456 | DECLARE_INTERRUPT(106) \ | |
457 | DECLARE_INTERRUPT(107) \ | |
458 | DECLARE_INTERRUPT(108) \ | |
459 | DECLARE_INTERRUPT(109) \ | |
460 | DECLARE_INTERRUPT(110) \ | |
461 | DECLARE_INTERRUPT(111) \ | |
462 | DECLARE_INTERRUPT(112) \ | |
463 | DECLARE_INTERRUPT(113) \ | |
464 | DECLARE_INTERRUPT(114) \ | |
465 | DECLARE_INTERRUPT(115) \ | |
466 | DECLARE_INTERRUPT(116) \ | |
467 | DECLARE_INTERRUPT(117) \ | |
468 | DECLARE_INTERRUPT(118) \ | |
469 | DECLARE_INTERRUPT(119) \ | |
470 | DECLARE_INTERRUPT(120) \ | |
471 | DECLARE_INTERRUPT(121) \ | |
472 | DECLARE_INTERRUPT(122) \ | |
473 | DECLARE_INTERRUPT(123) \ | |
474 | DECLARE_INTERRUPT(124) \ | |
475 | DECLARE_INTERRUPT(125) \ | |
476 | DECLARE_INTERRUPT(126) \ | |
477 | DECLARE_INTERRUPT(127) \ | |
478 | DECLARE_INTERRUPT(128) \ | |
479 | DECLARE_INTERRUPT(129) \ | |
480 | DECLARE_INTERRUPT(130) \ | |
481 | DECLARE_INTERRUPT(131) \ | |
482 | DECLARE_INTERRUPT(132) \ | |
483 | DECLARE_INTERRUPT(133) \ | |
484 | DECLARE_INTERRUPT(134) \ | |
485 | DECLARE_INTERRUPT(135) \ | |
486 | DECLARE_INTERRUPT(136) \ | |
487 | DECLARE_INTERRUPT(137) \ | |
488 | DECLARE_INTERRUPT(138) \ | |
489 | DECLARE_INTERRUPT(139) \ | |
490 | DECLARE_INTERRUPT(140) \ | |
491 | DECLARE_INTERRUPT(141) \ | |
492 | DECLARE_INTERRUPT(142) \ | |
493 | DECLARE_INTERRUPT(143) \ | |
494 | DECLARE_INTERRUPT(144) \ | |
495 | DECLARE_INTERRUPT(145) \ | |
496 | DECLARE_INTERRUPT(146) \ | |
497 | DECLARE_INTERRUPT(147) \ | |
498 | DECLARE_INTERRUPT(148) \ | |
499 | DECLARE_INTERRUPT(149) \ | |
500 | DECLARE_INTERRUPT(150) \ | |
501 | DECLARE_INTERRUPT(151) \ | |
502 | DECLARE_INTERRUPT(152) \ | |
503 | DECLARE_INTERRUPT(153) \ | |
504 | DECLARE_INTERRUPT(154) \ | |
505 | DECLARE_INTERRUPT(155) \ | |
506 | DECLARE_INTERRUPT(156) \ | |
507 | DECLARE_INTERRUPT(157) \ | |
508 | DECLARE_INTERRUPT(158) \ | |
509 | DECLARE_INTERRUPT(159) \ | |
510 | DECLARE_INTERRUPT(160) \ | |
511 | DECLARE_INTERRUPT(161) \ | |
512 | DECLARE_INTERRUPT(162) \ | |
513 | DECLARE_INTERRUPT(163) \ | |
514 | DECLARE_INTERRUPT(164) \ | |
515 | DECLARE_INTERRUPT(165) \ | |
516 | DECLARE_INTERRUPT(166) \ | |
517 | DECLARE_INTERRUPT(167) \ | |
518 | DECLARE_INTERRUPT(168) \ | |
519 | DECLARE_INTERRUPT(169) \ | |
520 | DECLARE_INTERRUPT(170) \ | |
521 | DECLARE_INTERRUPT(171) \ | |
522 | DECLARE_INTERRUPT(172) \ | |
523 | DECLARE_INTERRUPT(173) \ | |
524 | DECLARE_INTERRUPT(174) \ | |
525 | DECLARE_INTERRUPT(175) \ | |
526 | DECLARE_INTERRUPT(176) \ | |
527 | DECLARE_INTERRUPT(177) \ | |
528 | DECLARE_INTERRUPT(178) \ | |
529 | DECLARE_INTERRUPT(179) \ | |
530 | DECLARE_INTERRUPT(180) \ | |
531 | DECLARE_INTERRUPT(181) \ | |
532 | DECLARE_INTERRUPT(182) \ | |
533 | DECLARE_INTERRUPT(183) \ | |
534 | DECLARE_INTERRUPT(184) \ | |
535 | DECLARE_INTERRUPT(185) \ | |
536 | DECLARE_INTERRUPT(186) \ | |
537 | DECLARE_INTERRUPT(187) \ | |
538 | DECLARE_INTERRUPT(188) \ | |
539 | DECLARE_INTERRUPT(189) \ | |
540 | DECLARE_INTERRUPT(190) \ | |
541 | DECLARE_INTERRUPT(191) \ | |
542 | DECLARE_INTERRUPT(192) \ | |
543 | DECLARE_INTERRUPT(193) \ | |
544 | DECLARE_INTERRUPT(194) \ | |
545 | DECLARE_INTERRUPT(195) \ | |
546 | DECLARE_INTERRUPT(196) \ | |
547 | DECLARE_INTERRUPT(197) \ | |
548 | DECLARE_INTERRUPT(198) \ | |
549 | DECLARE_INTERRUPT(199) \ | |
550 | DECLARE_INTERRUPT(200) \ | |
551 | DECLARE_INTERRUPT(201) \ | |
552 | DECLARE_INTERRUPT(202) \ | |
553 | DECLARE_INTERRUPT(203) \ | |
554 | DECLARE_INTERRUPT(204) \ | |
555 | DECLARE_INTERRUPT(205) \ | |
556 | DECLARE_INTERRUPT(206) \ | |
557 | DECLARE_INTERRUPT(207) \ | |
558 | DECLARE_INTERRUPT(208) \ | |
559 | DECLARE_INTERRUPT(209) \ | |
560 | DECLARE_INTERRUPT(210) \ | |
561 | DECLARE_INTERRUPT(211) \ | |
562 | DECLARE_INTERRUPT(212) \ | |
563 | DECLARE_INTERRUPT(213) \ | |
564 | DECLARE_INTERRUPT(214) \ | |
565 | DECLARE_INTERRUPT(215) \ | |
566 | DECLARE_INTERRUPT(216) \ | |
567 | DECLARE_INTERRUPT(217) \ | |
568 | DECLARE_INTERRUPT(218) \ | |
569 | DECLARE_INTERRUPT(219) \ | |
570 | DECLARE_INTERRUPT(220) \ | |
571 | DECLARE_INTERRUPT(221) \ | |
572 | DECLARE_INTERRUPT(222) \ | |
573 | DECLARE_INTERRUPT(223) \ | |
574 | DECLARE_INTERRUPT(224) \ | |
575 | DECLARE_INTERRUPT(225) \ | |
576 | DECLARE_INTERRUPT(226) \ | |
577 | DECLARE_INTERRUPT(227) \ | |
578 | DECLARE_INTERRUPT(228) \ | |
579 | DECLARE_INTERRUPT(229) \ | |
580 | DECLARE_INTERRUPT(230) \ | |
581 | DECLARE_INTERRUPT(231) \ | |
582 | DECLARE_INTERRUPT(232) \ | |
583 | DECLARE_INTERRUPT(233) \ | |
584 | DECLARE_INTERRUPT(234) \ | |
585 | DECLARE_INTERRUPT(235) \ | |
586 | DECLARE_INTERRUPT(236) \ | |
587 | DECLARE_INTERRUPT(237) \ | |
588 | DECLARE_INTERRUPT(238) \ | |
589 | DECLARE_INTERRUPT(239) \ | |
590 | DECLARE_INTERRUPT(240) \ | |
591 | DECLARE_INTERRUPT(241) \ | |
592 | DECLARE_INTERRUPT(242) \ | |
593 | DECLARE_INTERRUPT(243) \ | |
594 | DECLARE_INTERRUPT(244) \ | |
595 | DECLARE_INTERRUPT(245) \ | |
596 | DECLARE_INTERRUPT(246) \ | |
597 | DECLARE_INTERRUPT(247) \ | |
598 | DECLARE_INTERRUPT(248) \ | |
599 | DECLARE_INTERRUPT(249) \ | |
600 | DECLARE_INTERRUPT(250) \ | |
601 | DECLARE_INTERRUPT(251) \ | |
602 | DECLARE_INTERRUPT(252) \ | |
603 | DECLARE_INTERRUPT(253) \ | |
604 | DECLARE_INTERRUPT(254) \ | |
605 | DECLARE_INTERRUPT(255)); | |
7c71034d VB |
606 | |
607 | #if defined(CONFIG_INTEL_CORE_ARCH) | |
608 | /* | |
609 | * Get the number of CPU time counter ticks since it was read first time after | |
610 | * restart. This yields a free running counter guaranteed to take almost 6 | |
611 | * years to wrap around even at 100GHz clock rate. | |
612 | */ | |
613 | u64 get_ticks(void) | |
614 | { | |
7c71034d VB |
615 | u64 now_tick = rdtsc(); |
616 | ||
bc2df1af SG |
617 | if (!gd->arch.tsc_base) |
618 | gd->arch.tsc_base = now_tick; | |
7c71034d | 619 | |
bc2df1af | 620 | return now_tick - gd->arch.tsc_base; |
7c71034d VB |
621 | } |
622 | ||
623 | #define PLATFORM_INFO_MSR 0xce | |
624 | ||
625 | unsigned long get_tbclk(void) | |
626 | { | |
627 | u32 ratio; | |
628 | u64 platform_info = native_read_msr(PLATFORM_INFO_MSR); | |
629 | ||
630 | ratio = (platform_info >> 8) & 0xff; | |
631 | return 100 * 1000 * 1000 * ratio; /* 100MHz times Max Non Turbo ratio */ | |
632 | } | |
633 | #endif |