1 /* getpir.c : This software is released under GPL
2 * For coreboot use only
3 * Aug 26 2001 , Nikolai Vladychevski, <niko@isl.net.mx>
4 * 2007.04.09 Jeremy Jackson <jerj@coplanar.net>
5 * updated for amd64 and general 64 bit portability
6 * 2010.04.24 Marc Bertens <mbertens@xs4all.nl>
7 * Added functionality to read a image file for checking the checksum of the PIR
16 #include <sys/types.h>
19 #include "pirq_routing.h"
23 #if defined (__sun) && (defined(__i386) || defined(__amd64))
24 # define MEM_DEV "/dev/xsvc"
26 # define MEM_DEV "/dev/mem"
30 * The probe_table() is now called with the pointer to the memory,
31 * this is to handle both the assessing memory and a file.
33 * This function now dumps the table found to the stdout, with
34 * descriptions, it is special handy when building a PIRQ table
35 * for a board to check the checksum.
37 static struct irq_routing_table
*probe_table(char* ptr
)
40 * Signature to search for $PIR<2-byte-version>
42 * this is to be sure that we find the correct table.
44 char signature
[] = "$PIR\x00\x01";
45 /** cast the pointer */
46 struct irq_routing_table
*rt
= (struct irq_routing_table
*)ptr
;
50 /** find the PIRQ table */
51 rt
= (struct irq_routing_table
*) memmem(ptr
+ size
, 16, signature
, 6);
53 /** found the table */
54 int i
, ts
= (rt
->size
- 32) / 16;
55 struct irq_info
*se_arr
;
56 se_arr
= (struct irq_info
*) ((char *) rt
+ 32);
57 /** Dump the table information to the stdout */
58 printf("Found PCI IRQ routing table signature at %p.\n", (void *) ((char *) rt
- ptr
+ 0xf0000));
59 printf("SIGNATURE = %s\n", (char*)&rt
->signature
);
60 printf("VERSION = %04x\n", rt
->version
);
61 printf("SIZE = %i\n", rt
->size
);
62 printf("MAX_DEVICES_ON_BUS = 32 + 16 * %d\n", ts
);
63 printf("INT_ROUTER_BUS = 0x%02x\n", rt
->rtr_bus
);
64 printf("INT_ROUTER DEVICE = (0x%02x << 3) | 0x%01x\n", rt
->rtr_devfn
>> 3, rt
->rtr_devfn
& 7);
65 printf("IRQ_DEVOTED_TO_PCI = %#x\n", rt
->exclusive_irqs
);
66 printf("VENDOR = %#x\n", rt
->rtr_vendor
);
67 printf("DEVICE = %#x\n", rt
->rtr_device
);
68 printf("MINIPORT = %#x\n", rt
->miniport_data
);
69 printf("CHECKSUM = %#x\n", rt
->checksum
);
70 printf("\tbus , dev | fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu\n");
71 for (i
= 0; i
< ts
; i
++) {
72 printf("\t0x%02x, (0x%02x << 3) | 0x%01x, {{0x%02x, 0x%04x}, {0x%02x, 0x%04x}, {0x%02x, 0x%04x}, {0x%02x, 0x%04x}}, 0x%x, 0x%x},\n",
73 (se_arr
+i
)->bus
, (se_arr
+i
)->devfn
>> 3,
74 (se_arr
+i
)->devfn
& 7, (se_arr
+i
)->irq
[0].link
,
75 (se_arr
+i
)->irq
[0].bitmap
, (se_arr
+i
)->irq
[1].link
,
76 (se_arr
+i
)->irq
[1].bitmap
, (se_arr
+i
)->irq
[2].link
,
77 (se_arr
+i
)->irq
[2].bitmap
, (se_arr
+i
)->irq
[3].link
,
78 (se_arr
+i
)->irq
[3].bitmap
, (se_arr
+i
)->slot
,
81 /** A table should not be over 0x400 bytes */
82 if (rt
->size
> 0x400) {
85 printf("Validating...\n");
86 /** Calculate the checksum value */
87 checksum_result
= calc_checksum(rt
);
88 /** Show the calculatedchecksum value */
89 printf("CHECKSUM = %#x\n", 0x100-((checksum_result
- rt
->checksum
) & 0xFF));
90 /** and the result of the calculation */
91 if (!checksum_result
) {
92 printf("checksum is ok.\n");
95 printf("checksum is wrong.\n");
99 } while (size
< 0xFFFF);
100 if (size
>= 0xFFFF) {
101 /** When the functions comes here there is no PIRQ table found. */
102 printf("No PCI IRQ routing table signature found.\n");
109 int main(int argc
, char* argv
[])
113 struct irq_routing_table
* rt
= NULL
;
114 void* bios_image
= NULL
;
117 /** there a paramater passed to the program, assume that it is a menory file */
118 printf("Opening memory image file '%s'\n", argv
[1]);
120 fd_mem
= open(argv
[1], O_RDONLY
);
122 /** get tyhe size of the file */
123 int file_size
= lseek(fd_mem
, 0, SEEK_END
);
124 printf("Memory image '%i'\n", file_size
);
125 /** get a memory block for it. */
126 bios_image
= malloc(file_size
);
128 /** Fill the created buffer */
129 lseek(fd_mem
, 0, SEEK_SET
);
130 read(fd_mem
, bios_image
, file_size
);
131 /** set the pointer for the probe function */
132 ptr
= (char*)bios_image
;
134 /* no memory available ? */
135 perror("Failed to open imagefile\n");
139 /** An error occourd, just exit with a message */
140 perror("Failed to open imagefile");
144 /** No paramaters means that the program will access the system memory */
145 printf("Accessing memory\n");
147 /** i'm not root message !!!! */
148 fprintf(stderr
, "Run me as root, I need access to " MEM_DEV
".\n");
150 /** open the system memory */
151 fd_mem
= open(MEM_DEV
, O_RDONLY
);
153 /** could not open the system memory, exit with a message */
154 perror("Could not open " MEM_DEV
":");
157 printf("Probing PIRQ table in memory.\n");
158 ptr
= mmap(0, 0x10000, PROT_READ
, MAP_SHARED
, fd_mem
, (off_t
)0xf0000);
159 if (ptr
== MAP_FAILED
) {
160 /** could not map the system memory, exit with a message */
161 perror("Mapping system memory failed: ");
167 /** now do the actual probe function */
168 rt
= probe_table(ptr
);
169 if (rt
!= NULL
&& bios_image
== NULL
) {
170 /** when probing system memory we write the 'irq_tables.c' code file */
171 printf("Creating irq_tables.c ...\n");
172 code_gen("irq_tables.c", rt
);
173 printf("Done, you can move the file to the coreboot tree now.\n");
176 printf("invalid memory pointer\n");
179 /** when we are reading from a file the memory must be released */
182 /** when reading from the system memory, it must be unmapped */
183 munmap(ptr
, 0x10000);
185 /** Close the file handle */
187 /** return 0 as OK ) */