blob: 52e76a77eb9bee217819095b045ad09188d26e05 [file] [log] [blame]
Eric Biederman8ca8d762003-04-22 19:02:15 +00001#include <console/console.h>
2#include <arch/pirq_routing.h>
3#include <string.h>
4
Greg Watson9f461322004-03-23 17:41:15 +00005#if (DEBUG==1 && HAVE_PIRQ_TABLE==1)
Eric Biederman8ca8d762003-04-22 19:02:15 +00006void check_pirq_routing_table(void)
7{
Eric Biederman8cd55d72003-04-24 06:56:37 +00008 const uint8_t *addr;
Eric Biederman8ca8d762003-04-22 19:02:15 +00009 const struct irq_routing_table *rt;
10 int i;
Eric Biederman8cd55d72003-04-24 06:56:37 +000011 uint8_t sum;
Eric Biederman8ca8d762003-04-22 19:02:15 +000012
13 printk_info("Checking IRQ routing tables...\n");
14
Eric Biederman8cd55d72003-04-24 06:56:37 +000015#if defined(IRQ_SLOT_COUNT)
Eric Biederman8ca8d762003-04-22 19:02:15 +000016 if (sizeof(intel_irq_routing_table) != intel_irq_routing_table.size) {
Stefan Reinauer40cba392003-10-28 17:02:10 +000017 printk_warning("Inconsistent IRQ routing table size (0x%x/0x%x)\n",
Li-Ta Lo8e79fc32004-04-15 17:33:21 +000018 sizeof(intel_irq_routing_table),
19 intel_irq_routing_table.size
20 );
Stefan Reinauer40cba392003-10-28 17:02:10 +000021 intel_irq_routing_table.size=sizeof(intel_irq_routing_table);
Eric Biederman8ca8d762003-04-22 19:02:15 +000022 }
23#endif
24
25 rt = &intel_irq_routing_table;
Eric Biederman8cd55d72003-04-24 06:56:37 +000026 addr = (uint8_t *)rt;
Eric Biederman8ca8d762003-04-22 19:02:15 +000027
28 sum = 0;
29 for (i = 0; i < rt->size; i++)
30 sum += addr[i];
31
32 printk_debug("%s:%6d:%s() - irq_routing_table located at: 0x%p\n",
Li-Ta Lo8e79fc32004-04-15 17:33:21 +000033 __FILE__, __LINE__, __FUNCTION__, addr);
Eric Biederman8ca8d762003-04-22 19:02:15 +000034
Eric Biedermaneb00fa52003-04-25 02:02:25 +000035
36 sum = rt->checksum - sum;
Eric Biederman8ca8d762003-04-22 19:02:15 +000037
38 if (sum != rt->checksum) {
39 printk_warning("%s:%6d:%s() - "
Li-Ta Lo8e79fc32004-04-15 17:33:21 +000040 "checksum is: 0x%02x but should be: 0x%02x\n",
41 __FILE__, __LINE__, __FUNCTION__, rt->checksum, sum);
Stefan Reinauer40cba392003-10-28 17:02:10 +000042 rt->checksum = sum;
Eric Biederman8ca8d762003-04-22 19:02:15 +000043 }
44
45 if (rt->signature != PIRQ_SIGNATURE || rt->version != PIRQ_VERSION ||
46 rt->size % 16 || rt->size < sizeof(struct irq_routing_table)) {
47 printk_warning("%s:%6d:%s() - "
Li-Ta Lo8e79fc32004-04-15 17:33:21 +000048 "Interrupt Routing Table not valid\n",
49 __FILE__, __LINE__, __FUNCTION__);
Eric Biederman8ca8d762003-04-22 19:02:15 +000050 return;
51 }
52
53 sum = 0;
54 for (i=0; i<rt->size; i++)
55 sum += addr[i];
56
57 if (sum) {
58 printk_warning("%s:%6d:%s() - "
Li-Ta Lo8e79fc32004-04-15 17:33:21 +000059 "checksum error in irq routing table\n",
60 __FILE__, __LINE__, __FUNCTION__);
Eric Biederman8ca8d762003-04-22 19:02:15 +000061 }
62
63 printk_info("done.\n");
64}
65
66int verify_copy_pirq_routing_table(unsigned long addr)
67{
68 int i;
Eric Biederman8cd55d72003-04-24 06:56:37 +000069 uint8_t *rt_orig, *rt_curr;
Eric Biederman8ca8d762003-04-22 19:02:15 +000070
Eric Biederman8cd55d72003-04-24 06:56:37 +000071 rt_curr = (uint8_t*)addr;
72 rt_orig = (uint8_t*)&intel_irq_routing_table;
Stefan Reinauerabf9fea2004-01-26 10:54:44 +000073 printk_info("Verifing copy of IRQ routing tables at 0x%x...", addr);
Eric Biederman8ca8d762003-04-22 19:02:15 +000074 for (i = 0; i < intel_irq_routing_table.size; i++) {
75 if (*(rt_curr + i) != *(rt_orig + i)) {
76 printk_info("failed\n");
77 return -1;
78 }
79 }
Stefan Reinauerabf9fea2004-01-26 10:54:44 +000080 printk_info("done\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +000081 return 0;
82}
83#else
84#define verify_copy_pirq_routing_table(addr)
85#endif
86
Greg Watson9f461322004-03-23 17:41:15 +000087#if HAVE_PIRQ_TABLE==1
Eric Biederman8ca8d762003-04-22 19:02:15 +000088unsigned long copy_pirq_routing_table(unsigned long addr)
89{
90 /* Align the table to be 16 byte aligned. */
91 addr += 15;
92 addr &= ~15;
93
94 /* This table must be betweeen 0xf0000 & 0x100000 */
95 printk_info("Copying IRQ routing tables to 0x%x...", addr);
96 memcpy((void *)addr, &intel_irq_routing_table, intel_irq_routing_table.size);
97 printk_info("done.\n");
98 verify_copy_pirq_routing_table(addr);
99 return addr + intel_irq_routing_table.size;
100}
Greg Watson9f461322004-03-23 17:41:15 +0000101#endif