1 #include <linux/init.h>
2 #include <linux/module.h>
4 #include <linux/cdev.h>
5 #include <linux/kdev_t.h>
6 #include <linux/semaphore.h>
8 #include <linux/poll.h>
9 #include <linux/wait.h>
10 #include <linux/ioctl.h>
11 #include <linux/ioport.h>
13 #include <linux/interrupt.h>
14 #include <linux/pagemap.h>
15 #include <linux/pci.h>
16 #include <linux/firmware.h>
17 #include <linux/sched.h>
18 #include "rar_register.h"
20 /* The following defines are for the IPC process to retrieve RAR in */
22 /* === Lincroft Message Bus Interface === */
23 /* Message Control Register */
24 #define LNC_MCR_OFFSET 0xD0
26 /* Message Data Register */
27 #define LNC_MDR_OFFSET 0xD4
30 #define LNC_MESSAGE_READ_OPCODE 0xD0
31 #define LNC_MESSAGE_WRITE_OPCODE 0xE0
33 /* Message Write Byte Enables */
34 #define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF
37 #define LNC_BUNIT_PORT 0x3
39 /* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
40 #define LNC_BRAR0L 0x10
41 #define LNC_BRAR0H 0x11
42 #define LNC_BRAR1L 0x12
43 #define LNC_BRAR1H 0x13
45 /* Reserved for SeP */
46 #define LNC_BRAR2L 0x14
47 #define LNC_BRAR2H 0x15
50 /* This structure is only used during module initialization. */
52 int low; /* Register offset for low RAR physical address. */
53 int high; /* Register offset for high RAR physical address. */
56 struct pci_dev *rar_dev;
57 static uint32_t registered;
59 /* Moorestown supports three restricted access regions. */
60 #define MRST_NUM_RAR 3
62 struct RAR_address_struct rar_addr[MRST_NUM_RAR];
64 /* prototype for init */
65 static int __init rar_init_handler(void);
66 static void __exit rar_exit_handler(void);
69 function that is activated on the successfull probe of the RAR device
71 static int __devinit rar_probe(struct pci_dev *pdev,
72 const struct pci_device_id *ent);
74 static const struct pci_device_id rar_pci_id_tbl[] = {
75 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) },
79 MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
81 /* field for registering driver to PCI device */
82 static struct pci_driver rar_pci_driver = {
84 .id_table = rar_pci_id_tbl,
88 /* This function is used to retrieved RAR info using the IPC message
90 static int memrar_get_rar_addr(struct pci_dev *pdev,
95 * ======== The Lincroft Message Bus Interface ========
96 * Lincroft registers may be obtained from the PCI
97 * (the Host Bridge) using the Lincroft Message Bus
98 * Interface. That message bus interface is generally
99 * comprised of two registers: a control register (MCR, 0xDO)
100 * and a data register (MDR, 0xD4).
102 * The MCR (message control register) format is the following:
105 * 3. [15:8]: Register Offset
106 * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
110 * Read (0xD0) and write (0xE0) opcodes are written to the
111 * control register when reading and writing to Lincroft
112 * registers, respectively.
114 * We're interested in registers found in the Lincroft
115 * B-unit. The B-unit port is 0x3.
117 * The six B-unit RAR register offsets we use are listed
118 * earlier in this file.
120 * Lastly writing to the MCR register requires the "Byte
121 * enables" bits to be set to 1. This may be achieved by
122 * writing 0xF at bit 4.
124 * The MDR (message data register) format is the following:
125 * 1. [31:0]: Read/Write Data
127 * Data being read from this register is only available after
128 * writing the appropriate control message to the MCR
131 * Data being written to this register must be written before
132 * writing the appropriate control message to the MCR
136 int result = 0; /* result */
137 /* Construct control message */
139 (LNC_MESSAGE_READ_OPCODE << 24)
140 | (LNC_BUNIT_PORT << 16)
142 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
144 printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset);
149 /* Send the control message */
150 result = pci_write_config_dword(pdev,
154 printk(KERN_WARNING "rar- result from send ctl register is %x\n",
158 result = pci_read_config_dword(pdev,
162 printk(KERN_WARNING "rar- result from read data register is %x\n",
165 printk(KERN_WARNING "rar- value read from data register is %x\n",
174 static int memrar_set_rar_addr(struct pci_dev *pdev,
179 * ======== The Lincroft Message Bus Interface ========
180 * Lincroft registers may be obtained from the PCI
181 * (the Host Bridge) using the Lincroft Message Bus
182 * Interface. That message bus interface is generally
183 * comprised of two registers: a control register (MCR, 0xDO)
184 * and a data register (MDR, 0xD4).
186 * The MCR (message control register) format is the following:
189 * 3. [15:8]: Register Offset
190 * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
194 * Read (0xD0) and write (0xE0) opcodes are written to the
195 * control register when reading and writing to Lincroft
196 * registers, respectively.
198 * We're interested in registers found in the Lincroft
199 * B-unit. The B-unit port is 0x3.
201 * The six B-unit RAR register offsets we use are listed
202 * earlier in this file.
204 * Lastly writing to the MCR register requires the "Byte
205 * enables" bits to be set to 1. This may be achieved by
206 * writing 0xF at bit 4.
208 * The MDR (message data register) format is the following:
209 * 1. [31:0]: Read/Write Data
211 * Data being read from this register is only available after
212 * writing the appropriate control message to the MCR
215 * Data being written to this register must be written before
216 * writing the appropriate control message to the MCR
220 int result = 0; /* result */
222 /* Construct control message */
224 (LNC_MESSAGE_WRITE_OPCODE << 24)
225 | (LNC_BUNIT_PORT << 16)
227 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
229 printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset);
234 /* Send the control message */
235 result = pci_write_config_dword(pdev,
239 printk(KERN_WARNING "rar- result from send ctl register is %x\n",
243 result = pci_write_config_dword(pdev,
247 printk(KERN_WARNING "rar- result from write data register is %x\n",
250 printk(KERN_WARNING "rar- value read to data register is %x\n",
261 * Initialize RAR parameters, such as physical addresses, etc.
264 static int memrar_init_rar_params(struct pci_dev *pdev)
266 struct RAR_offsets const offsets[] = {
267 { LNC_BRAR0L, LNC_BRAR0H },
268 { LNC_BRAR1L, LNC_BRAR1H },
269 { LNC_BRAR2L, LNC_BRAR2H }
272 size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]);
273 struct RAR_offsets const *end = offsets + num_offsets;
274 struct RAR_offsets const *i;
278 /* Retrieve RAR start and end physical addresses. */
281 * Access the RAR registers through the Lincroft Message Bus
282 * Interface on PCI device: 00:00.0 Host bridge.
285 /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */
290 for (i = offsets; i != end; ++i, ++n) {
291 if (memrar_get_rar_addr(pdev,
293 &(rar_addr[n].low)) != 0
294 || memrar_get_rar_addr(pdev,
296 &(rar_addr[n].high)) != 0) {
302 /* Done accessing the device. */
303 /* pci_dev_put(pdev); */
308 for (z = 0; z != MRST_NUM_RAR; ++z) {
310 "rar - BRAR[%Zd] physical address low\n"
324 function that is activated on the successfull probe of the RAR device
326 static int __devinit rar_probe(struct pci_dev *pdev,
327 const struct pci_device_id *ent)
332 /*------------------------
334 ---------------------------*/
336 DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
337 "Rar pci probe starting\n");
340 /* enable the device */
341 error = pci_enable_device(pdev);
343 DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
344 "error enabling pci device\n");
351 /* Initialize the RAR parameters, which have to be retrieved */
352 /* via the message bus service */
353 error = memrar_init_rar_params(rar_dev);
356 DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
357 "error getting RAR addresses device\n");
368 this function registers the driver to
369 the device subsystem (either PCI, USB, etc)
371 static int __init rar_init_handler(void)
373 return pci_register_driver(&rar_pci_driver);
376 static void __exit rar_exit_handler(void)
378 pci_unregister_driver(&rar_pci_driver);
381 module_init(rar_init_handler);
382 module_exit(rar_exit_handler);
384 MODULE_LICENSE("GPL");
387 /* The get_rar_address function is used by other device drivers
388 * to obtain RAR address information on a RAR. It takes two
392 * The rar_index is an index to the rar for which you wish to retrieve
393 * the address information.
394 * Values can be 0,1, or 2.
396 * struct RAR_address_struct is a pointer to a place to which the function
397 * can return the address structure for the RAR.
399 * The function returns a 0 upon success or a -1 if there is no RAR
400 * facility on this system.
402 int get_rar_address(int rar_index, struct RAR_address_struct *addresses)
404 if (registered && (rar_index < 3) && (rar_index >= 0)) {
405 *addresses = rar_addr[rar_index];
406 /* strip off lock bit information */
407 addresses->low = addresses->low & 0xfffffff0;
408 addresses->high = addresses->high & 0xfffffff0;
413 EXPORT_SYMBOL(get_rar_address);
415 /* The lock_rar function is used by other device drivers to lock an RAR.
416 * once an RAR is locked, it stays locked until the next system reboot.
417 * The function takes one parameter:
420 * The rar_index is an index to the rar that you want to lock.
421 * Values can be 0,1, or 2.
423 * The function returns a 0 upon success or a -1 if there is no RAR
424 * facility on this system.
426 int lock_rar(int rar_index)
431 if (registered && (rar_index < 3) && (rar_index >= 0)) {
432 /* first make sure that lock bits are clear (this does lock) */
433 working_addr = rar_addr[rar_index].low & 0xfffffff0;
435 /* now send that value to the register using the IPC */
436 result = memrar_set_rar_addr(rar_dev, rar_index, working_addr);