1 Index: linux-2.6.33/drivers/staging/Kconfig
2 ===================================================================
3 --- linux-2.6.33.orig/drivers/staging/Kconfig
4 +++ linux-2.6.33/drivers/staging/Kconfig
5 @@ -141,5 +141,7 @@ source "drivers/staging/netwave/Kconfig"
7 source "drivers/staging/sm7xx/Kconfig"
9 +source "drivers/staging/rar_register/Kconfig"
11 endif # !STAGING_EXCLUDE_BUILD
13 Index: linux-2.6.33/drivers/staging/Makefile
14 ===================================================================
15 --- linux-2.6.33.orig/drivers/staging/Makefile
16 +++ linux-2.6.33/drivers/staging/Makefile
17 @@ -38,7 +38,7 @@ obj-$(CONFIG_VT6656) += vt6656/
18 obj-$(CONFIG_FB_UDL) += udlfb/
19 obj-$(CONFIG_HYPERV) += hv/
20 obj-$(CONFIG_VME_BUS) += vme/
21 -obj-$(CONFIG_RAR_REGISTER) += rar/
22 +obj-$(CONFIG_RAR_DRIVER) += rar/
23 obj-$(CONFIG_DX_SEP) += sep/
24 obj-$(CONFIG_IIO) += iio/
25 obj-$(CONFIG_RAMZSWAP) += ramzswap/
26 @@ -52,3 +52,4 @@ obj-$(CONFIG_WAVELAN) += wavelan/
27 obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/
28 obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/
29 obj-$(CONFIG_FB_SM7XX) += sm7xx/
30 +obj-$(CONFIG_RAR_REGISTER) += rar_register/
31 Index: linux-2.6.33/drivers/staging/rar_register/Kconfig
32 ===================================================================
34 +++ linux-2.6.33/drivers/staging/rar_register/Kconfig
37 +# Serial device configuration
40 +menu "RAR Register Driver"
43 + tristate "Intel Restricted Access Region Register Driver"
46 + This driver allows other kernel drivers access to the
47 + contents of the restricted access region registers.
50 Index: linux-2.6.33/drivers/staging/rar_register/Makefile
51 ===================================================================
53 +++ linux-2.6.33/drivers/staging/rar_register/Makefile
55 +EXTRA_CFLAGS += -DLITTLE__ENDIAN
56 +obj-$(CONFIG_RAR_REGISTER) += rar_register.o
57 +rar_register_driver-objs := rar_register.o
58 Index: linux-2.6.33/drivers/staging/rar_register/rar_register.c
59 ===================================================================
61 +++ linux-2.6.33/drivers/staging/rar_register/rar_register.c
64 + * rar_register.c - An Intel Restricted Access Region register driver
66 + * Copyright(c) 2009 Intel Corporation. All rights reserved.
68 + * This program is free software; you can redistribute it and/or
69 + * modify it under the terms of the GNU General Public License as
70 + * published by the Free Software Foundation; either version 2 of the
71 + * License, or (at your option) any later version.
73 + * This program is distributed in the hope that it will be useful,
74 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
75 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
76 + * General Public License for more details.
78 + * You should have received a copy of the GNU General Public License
79 + * along with this program; if not, write to the Free Software
80 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
83 + * -------------------------------------------------------------------
85 + * 20090806 Ossama Othman <ossama.othman@intel.com>
86 + * Return zero high address if upper 22 bits is zero.
87 + * Cleaned up checkpatch errors.
88 + * Clarified that driver is dealing with bus addresses.
90 + * 20090702 Ossama Othman <ossama.othman@intel.com>
91 + * Removed unnecessary include directives
92 + * Cleaned up spinlocks.
93 + * Cleaned up logging.
94 + * Improved invalid parameter checks.
95 + * Fixed and simplified RAR address retrieval and RAR locking
98 + * 20090626 Mark Allyn <mark.a.allyn@intel.com>
102 +#include <linux/rar/rar_register.h>
103 +#include <linux/rar/memrar.h>
105 +#include <linux/module.h>
106 +#include <linux/pci.h>
107 +#include <linux/spinlock.h>
108 +#include <linux/device.h>
109 +#include <linux/kernel.h>
112 +/* PCI vendor id for controller */
113 +#define VENDOR_ID 0x8086
115 +/* PCI device id for controller */
116 +#define DEVICE_ID 0x4110
119 +/* === Lincroft Message Bus Interface === */
120 +/* Message Control Register */
121 +#define LNC_MCR_OFFSET 0xD0
123 +/* Message Data Register */
124 +#define LNC_MDR_OFFSET 0xD4
126 +/* Message Opcodes */
127 +#define LNC_MESSAGE_READ_OPCODE 0xD0
128 +#define LNC_MESSAGE_WRITE_OPCODE 0xE0
130 +/* Message Write Byte Enables */
131 +#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF
134 +#define LNC_BUNIT_PORT 0x3
136 +/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
137 +#define LNC_BRAR0L 0x10
138 +#define LNC_BRAR0H 0x11
139 +#define LNC_BRAR1L 0x12
140 +#define LNC_BRAR1H 0x13
142 +/* Reserved for SeP */
143 +#define LNC_BRAR2L 0x14
144 +#define LNC_BRAR2H 0x15
146 +/* Moorestown supports three restricted access regions. */
147 +#define MRST_NUM_RAR 3
150 +/* RAR Bus Address Range */
151 +struct RAR_address_range {
156 +/* Structure containing low and high RAR register offsets. */
157 +struct RAR_offsets {
158 + u32 low; /* Register offset for low RAR bus address. */
159 + u32 high; /* Register offset for high RAR bus address. */
163 + int (*client_callback)(void *client_data);
164 + void *customer_data;
168 +DEFINE_SPINLOCK(rar_spinlock_lock);
169 +DEFINE_SPINLOCK(lnc_reg_lock);
172 + unsigned long rar_flags;
173 + unsigned long lnc_reg_flags;
174 + struct RAR_offsets rar_offsets[MRST_NUM_RAR];
175 + struct RAR_address_range rar_addr[MRST_NUM_RAR];
176 + struct pci_dev *rar_dev;
180 +/* this platform has only one rar_device for 3 rar regions */
181 +struct RAR_device my_rar_device;
183 +/* flag to indicatew whether or not this driver is registered;
184 + * this is for the entire driver and not just a device */
185 +int driver_registered;
187 +/* this data is for handling requests from other drivers which arrive
188 + * prior to this driver initializing
191 +struct RAR_client clients[MRST_NUM_RAR];
194 +/* prototype for init */
195 +static int __init rar_init_handler(void);
196 +static void __exit rar_exit_handler(void);
198 +const struct pci_device_id rar_pci_id_tbl[] = {
199 + { PCI_DEVICE(VENDOR_ID, DEVICE_ID) },
203 +MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
206 + * Function that is activated on the succesful probe of the RAR
207 + * device (Moorestown host controller).
209 +static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id);
211 +/* field for registering driver to PCI device */
212 +static struct pci_driver rar_pci_driver = {
213 + .name = "rar_register",
214 + .id_table = rar_pci_id_tbl,
218 +const struct pci_device_id *my_id_table = rar_pci_id_tbl;
221 + * This function is used to retrieved RAR info using the Lincroft
222 + * message bus interface.
224 +static int memrar_get_rar_addr(struct pci_dev *pdev,
229 + * ======== The Lincroft Message Bus Interface ========
230 + * Lincroft registers may be obtained from the PCI
231 + * (the Host Bridge) using the Lincroft Message Bus
232 + * Interface. That message bus interface is generally
233 + * comprised of two registers: a control register (MCR, 0xDO)
234 + * and a data register (MDR, 0xD4).
236 + * The MCR (message control register) format is the following:
237 + * 1. [31:24]: Opcode
239 + * 3. [15:8]: Register Offset
240 + * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
242 + * 5. [3:0]: reserved
244 + * Read (0xD0) and write (0xE0) opcodes are written to the
245 + * control register when reading and writing to Lincroft
246 + * registers, respectively.
248 + * We're interested in registers found in the Lincroft
249 + * B-unit. The B-unit port is 0x3.
251 + * The six B-unit RAR register offsets we use are listed
252 + * earlier in this file.
254 + * Lastly writing to the MCR register requires the "Byte
255 + * enables" bits to be set to 1. This may be achieved by
256 + * writing 0xF at bit 4.
258 + * The MDR (message data register) format is the following:
259 + * 1. [31:0]: Read/Write Data
261 + * Data being read from this register is only available after
262 + * writing the appropriate control message to the MCR
265 + * Data being written to this register must be written before
266 + * writing the appropriate control message to the MCR
272 + /* Construct control message */
273 + u32 const message =
274 + (LNC_MESSAGE_READ_OPCODE << 24)
275 + | (LNC_BUNIT_PORT << 16)
277 + | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
279 + dev_dbg(&pdev->dev, "Offset for 'get' LNC MSG is %x\n", offset);
286 + spin_lock_irqsave(&lnc_reg_lock, my_rar_device.lnc_reg_flags);
288 + /* Send the control message */
289 + result = pci_write_config_dword(pdev,
293 + dev_dbg(&pdev->dev,
294 + "Result from send ctl register is %x\n",
298 + result = pci_read_config_dword(pdev,
302 + dev_dbg(&pdev->dev,
303 + "Result from read data register is %x\n",
306 + dev_dbg(&pdev->dev,
307 + "Value read from data register is %x\n",
311 + spin_unlock_irqrestore(&lnc_reg_lock, my_rar_device.lnc_reg_flags);
316 +static int memrar_set_rar_addr(struct pci_dev *pdev,
321 + * Data being written to this register must be written before
322 + * writing the appropriate control message to the MCR
325 + * @note See memrar_get_rar_addr() for a description of the
326 + * message bus interface being used here.
331 + /* Construct control message */
332 + u32 const message =
333 + (LNC_MESSAGE_WRITE_OPCODE << 24)
334 + | (LNC_BUNIT_PORT << 16)
336 + | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
343 + spin_lock_irqsave(&lnc_reg_lock, my_rar_device.lnc_reg_flags);
345 + dev_dbg(&pdev->dev,
346 + "Offset for 'set' LNC MSG is %x\n", offset);
348 + /* Send the control message */
349 + result = pci_write_config_dword(pdev,
353 + dev_dbg(&pdev->dev,
354 + "Result from write data register is %x\n",
358 + dev_dbg(&pdev->dev,
359 + "Value written to data register is %x\n",
362 + result = pci_write_config_dword(pdev,
366 + dev_dbg(&pdev->dev,
367 + "Result from send ctl register is %x\n",
371 + spin_unlock_irqrestore(&lnc_reg_lock, my_rar_device.lnc_reg_flags);
377 + * Initialize RAR parameters, such as bus addresses, etc.
379 +static int memrar_init_rar_params(struct pci_dev *pdev)
381 + struct RAR_offsets const *end = my_rar_device.rar_offsets
383 + struct RAR_offsets const *i;
384 + struct pci_dev *my_pdev;
385 + unsigned int n = 0;
388 + /* Retrieve RAR start and end bus addresses. */
391 + * Access the RAR registers through the Lincroft Message Bus
392 + * Interface on PCI device: 00:00.0 Host bridge.
395 + /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */
397 + my_pdev = pci_dev_get(pdev);
399 + if (my_pdev == NULL) {
404 + for (i = my_rar_device.rar_offsets; i != end; ++i, ++n) {
405 + if (memrar_get_rar_addr(my_pdev,
407 + &(my_rar_device.rar_addr[n].low)) != 0
408 + || memrar_get_rar_addr(my_pdev,
410 + &(my_rar_device.rar_addr[n].high))
417 + * Only the upper 22 bits of the RAR addresses are
418 + * stored in their corresponding RAR registers so we
419 + * must set the lower 10 bits accordingly.
421 + * The low address has its lower 10 bits cleared, and
422 + * the high address has all its lower 10 bits set,
426 + * high = 0x3fffffff
428 + * This is not arbitrary, and is actually how RAR
429 + * addressing/configuration works.
431 + my_rar_device.rar_addr[n].low &= 0xfffffc00u;
434 + * Set bits 9:0 if the 1 KiB aligned (the upper 22
435 + * bits) high address is non-zero.
437 + * Otherwise set all bits to zero since that indicates
438 + * no RAR address is configured.
440 + if ((my_rar_device.rar_addr[n].high & 0xfffffc00u) == 0)
441 + my_rar_device.rar_addr[n].high = 0;
443 + my_rar_device.rar_addr[n].high |= 0x3ffu;
446 + /* Done accessing the device. */
447 + /* pci_dev_put(pdev); */
451 + for (z = 0; z != MRST_NUM_RAR; ++z) {
453 + * "BRAR" refers to the RAR registers in the
456 + dev_info(&pdev->dev,
457 + "BRAR[%u] bus address range = "
458 + "[0x%08x, 0x%08x]\n",
460 + my_rar_device.rar_addr[z].low,
461 + my_rar_device.rar_addr[z].high);
469 + * This function registers the driver with the device subsystem (
470 + * either PCI, USB, etc).
472 +static int __init rar_init_handler(void)
474 + return pci_register_driver(&rar_pci_driver);
477 +static void __exit rar_exit_handler(void)
479 + pci_unregister_driver(&rar_pci_driver);
482 +module_init(rar_init_handler);
483 +module_exit(rar_exit_handler);
485 +MODULE_LICENSE("GPL");
486 +MODULE_DESCRIPTION("Intel Restricted Access Region Register Driver");
489 + * Function that is activaed on the succesful probe of the RAR device
490 + * (Moorestown host controller).
492 +int rar_probe(struct pci_dev *dev, const struct pci_device_id *id)
498 + "PCI probe starting\n");
500 + /* enable the device */
501 + error = pci_enable_device(dev);
504 + "Error enabling RAR register PCI device\n");
508 + /* we have only one device; fill in the rar_device structure */
509 + my_rar_device.rar_dev = dev;
510 + my_rar_device.rar_flags = 0;
511 + my_rar_device.lnc_reg_flags = 0;
512 + my_rar_device.rar_offsets[0].low = LNC_BRAR0L;
513 + my_rar_device.rar_offsets[0].high = LNC_BRAR0H;
514 + my_rar_device.rar_offsets[1].low = LNC_BRAR1L;
515 + my_rar_device.rar_offsets[1].high = LNC_BRAR1H;
516 + my_rar_device.rar_offsets[2].low = LNC_BRAR2L;
517 + my_rar_device.rar_offsets[2].high = LNC_BRAR2H;
518 + my_rar_device.registered = 1;
521 + * Initialize the RAR parameters, which have to be retrieved */
522 + /* via the message bus interface.
524 + error = memrar_init_rar_params(dev);
526 + pci_disable_device(dev);
529 + "Error retrieving RAR addresses\n");
534 + driver_registered = 1;
536 + /* now call anyone who has registered (using callbacks) */
537 + for (counter = 0; counter < num_clients; counter += 1) {
538 + if (!clients[counter].client_called) {
539 + error = (*clients[counter].client_callback)(
540 + clients[counter].customer_data);
541 + clients[counter].client_called = 1;
542 + dev_dbg(&my_rar_device.rar_dev->dev,
543 + "Callback called for %d\n",
555 + * The rar_get_address function is used by other device drivers
556 + * to obtain RAR address information on a RAR. It takes three
560 + * The rar_index is an index to the rar for which you wish to retrieve
561 + * the address information.
562 + * Values can be 0,1, or 2.
564 + * The function returns a 0 upon success or a -1 if there is no RAR
565 + * facility on this system.
567 +int rar_get_address(int rar_index,
568 + u32 *start_address,
571 + int result = -ENODEV;
573 + if (my_rar_device.registered) {
574 + if (start_address == 0
575 + || end_address == 0
576 + || rar_index >= MRST_NUM_RAR
577 + || rar_index < 0) {
580 + *start_address = my_rar_device.rar_addr[rar_index].low;
581 + *end_address = my_rar_device.rar_addr[rar_index].high;
588 +EXPORT_SYMBOL(rar_get_address);
591 + * The rar_lock function is ued by other device drivers to lock an RAR.
592 + * once an RAR is locked, it stays locked until the next system reboot.
593 + * The function takes one parameter:
596 + * The rar_index is an index to the rar that you want to lock.
597 + * Values can be 0,1, or 2.
599 + * The function returns a 0 upon success or a -1 if there is no RAR
600 + * facility on this system.
602 +int rar_lock(int rar_index)
604 + int result = -ENODEV;
606 + if (rar_index >= MRST_NUM_RAR || rar_index < 0) {
608 + goto exit_rar_lock;
611 + spin_lock_irqsave(&rar_spinlock_lock, my_rar_device.rar_flags);
613 + if (my_rar_device.registered) {
619 + * Clear bits 4:0 in low register to lock.
620 + * Clear bits 8,4:0 in high register to lock.
622 + * The rest of the lower 10 bits in both registers are
623 + * unused so we might as well clear them all.
625 + if (rar_index == RAR_TYPE_VIDEO) {
626 + low = my_rar_device.rar_addr[rar_index].low &
628 + high = my_rar_device.rar_addr[rar_index].high &
631 + high |= 0x00000015;
634 + else if (rar_index == RAR_TYPE_AUDIO) {
635 + low = my_rar_device.rar_addr[rar_index].low &
637 + high = my_rar_device.rar_addr[rar_index].high &
640 + high |= 0x00000018;
644 + low = my_rar_device.rar_addr[rar_index].low &
646 + high = my_rar_device.rar_addr[rar_index].high &
648 + high |= 0x00000018;
652 + * Now program the register using the Lincroft message
655 + result = memrar_set_rar_addr(my_rar_device.rar_dev,
656 + my_rar_device.rar_offsets[rar_index].low,
660 + result = memrar_set_rar_addr(
661 + my_rar_device.rar_dev,
662 + my_rar_device.rar_offsets[rar_index].high,
666 + spin_unlock_irqrestore(&rar_spinlock_lock, my_rar_device.rar_flags);
672 +EXPORT_SYMBOL(rar_lock);
674 +/* The register_rar function is to used by other device drivers
675 + * to ensure that this driver is ready. As we cannot be sure of
676 + * the compile/execute order of dirvers in ther kernel, it is
677 + * best to give this driver a callback function to call when
678 + * it is ready to give out addresses. The callback function
679 + * would have those steps that continue the initialization of
680 + * a driver that do require a valid RAR address. One of those
681 + * steps would be to call get_rar_address()
682 + * This function return 0 on success an -1 on failure.
684 +int register_rar(int (*callback)(void *yourparameter), void *yourparameter)
691 + if (driver_registered) {
693 + /* if the driver already registered, then we can simply
694 + call the callback right now */
696 + result = (*callback)(yourparameter);
698 + dev_dbg(&my_rar_device.rar_dev->dev,
699 + "Immediate Callback failed: %x\n",
702 + dev_dbg(&my_rar_device.rar_dev->dev,
703 + "Immediate Callback ran okay\n");
709 + else if (num_clients >= MRST_NUM_RAR) {
715 + clients[num_clients].client_callback = callback;
716 + clients[num_clients].customer_data = yourparameter;
717 + clients[num_clients].client_called = 0;
719 + dev_dbg(&my_rar_device.rar_dev->dev, "Callback registered\n");
725 +EXPORT_SYMBOL(register_rar);
729 + c-file-style: "linux"
732 Index: linux-2.6.33/include/linux/rar/memrar.h
733 ===================================================================
735 +++ linux-2.6.33/include/linux/rar/memrar.h
738 + * RAR Handler (/dev/memrar) internal driver API.
739 + * Copyright (C) 2009 Intel Corporation. All rights reserved.
741 + * This program is free software; you can redistribute it and/or
742 + * modify it under the terms of version 2 of the GNU General
743 + * Public License as published by the Free Software Foundation.
745 + * This program is distributed in the hope that it will be
746 + * useful, but WITHOUT ANY WARRANTY; without even the implied
747 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
748 + * PURPOSE. See the GNU General Public License for more details.
749 + * You should have received a copy of the GNU General Public
750 + * License along with this program; if not, write to the Free
751 + * Software Foundation, Inc., 59 Temple Place - Suite 330,
752 + * Boston, MA 02111-1307, USA.
753 + * The full GNU General Public License is included in this
754 + * distribution in the file called COPYING.
761 +#include <linux/ioctl.h>
762 +#include <linux/types.h>
766 + * Constants that specify different kinds of RAR regions that could be
769 +static __u32 const RAR_TYPE_VIDEO; /* 0 */
770 +static __u32 const RAR_TYPE_AUDIO = 1;
771 +static __u32 const RAR_TYPE_IMAGE = 2;
772 +static __u32 const RAR_TYPE_DATA = 3;
777 + * @brief This structure is used for @c RAR_HANDLER_STAT ioctl and for
778 + * @c RAR_get_stat() user space wrapper function.
781 + /* Type of RAR memory (e.g., audio vs. video) */
785 + * Total size of RAR memory region.
789 + /* Size of the largest reservable block. */
790 + __u32 largest_block_size;
795 + * @struct RAR_block_info
797 + * @brief The argument for the @c RAR_HANDLER_RESERVE @c ioctl.
800 +struct RAR_block_info {
801 + /* Type of RAR memory (e.g., audio vs. video) */
804 + /* Requested size of a block to be reserved in RAR. */
807 + /* Handle that can be used to refer to reserved block. */
812 + * @struct RAR_buffer
814 + * Structure that contains all information related to a given block of
815 + * memory in RAR. It is generally only used when retrieving bus
818 + * @note This structure is used only by RAR-enabled drivers, and is
819 + * not intended to be exposed to the user space.
822 + /* Structure containing base RAR buffer information */
823 + struct RAR_block_info info;
825 + /* Buffer bus address */
830 +#define RAR_IOCTL_BASE 0xE0
832 +/* Reserve RAR block. */
833 +#define RAR_HANDLER_RESERVE _IOWR(RAR_IOCTL_BASE, 0x00, struct RAR_block_info)
835 +/* Release previously reserved RAR block. */
836 +#define RAR_HANDLER_RELEASE _IOW(RAR_IOCTL_BASE, 0x01, __u32)
838 +/* Get RAR stats. */
839 +#define RAR_HANDLER_STAT _IOWR(RAR_IOCTL_BASE, 0x02, struct RAR_stat)
842 +/* -------------------------------------------------------------- */
843 +/* Kernel Side RAR Handler Interface */
844 +/* -------------------------------------------------------------- */
847 + * @function rar_reserve
849 + * @brief Reserve RAR buffers.
851 + * This function will reserve buffers in the restricted access regions
854 + * @return Number of successfully reserved buffers.
855 + * Successful buffer reservations will have the corresponding
856 + * @c bus_address field set to a non-zero value in the
857 + * given @a buffers vector.
859 +extern size_t rar_reserve(struct RAR_buffer *buffers,
863 + * @function rar_release
865 + * @brief Release RAR buffers retrieved through call to
866 + * @c rar_reserve() or @c rar_handle_to_bus().
868 + * This function will release RAR buffers that were retrieved through
869 + * a call to @c rar_reserve() or @c rar_handle_to_bus() by
870 + * decrementing the reference count. The RAR buffer will be reclaimed
871 + * when the reference count drops to zero.
873 + * @return Number of successfully released buffers.
874 + * Successful releases will have their handle field set to
875 + * zero in the given @a buffers vector.
877 +extern size_t rar_release(struct RAR_buffer *buffers,
881 + * @function rar_handle_to_bus
883 + * @brief Convert a vector of RAR handles to bus addresses.
885 + * This function will retrieve the RAR buffer bus addresses, type and
886 + * size corresponding to the RAR handles provided in the @a buffers
889 + * @return Number of successfully converted buffers.
890 + * The bus address will be set to @c 0 for unrecognized
893 + * @note The reference count for each corresponding buffer in RAR will
894 + * be incremented. Call @c rar_release() when done with the
897 +extern size_t rar_handle_to_bus(struct RAR_buffer *buffers,
901 +#endif /* _MEMRAR_H */
906 + c-file-style: "linux"
909 Index: linux-2.6.33/include/linux/rar/rar_register.h
910 ===================================================================
912 +++ linux-2.6.33/include/linux/rar/rar_register.h
915 + * Copyright (C) 2008, 2009 Intel Corporation. All rights reserved.
917 + * This program is free software; you can redistribute it and/or
918 + * modify it under the terms of version 2 of the GNU General
919 + * Public License as published by the Free Software Foundation.
921 + * This program is distributed in the hope that it will be
922 + * useful, but WITHOUT ANY WARRANTY; without even the implied
923 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
924 + * PURPOSE. See the GNU General Public License for more details.
925 + * You should have received a copy of the GNU General Public
926 + * License along with this program; if not, write to the Free
927 + * Software Foundation, Inc., 59 Temple Place - Suite 330,
928 + * Boston, MA 02111-1307, USA.
929 + * The full GNU General Public License is included in this
930 + * distribution in the file called COPYING.
934 +#ifndef _RAR_REGISTER_H
935 +#define _RAR_REGISTER_H
937 +# include <linux/types.h>
939 +/* The register_rar function is to used by other device drivers
940 + * to ensure that this driver is ready. As we cannot be sure of
941 + * the compile/execute order of dirvers in ther kernel, it is
942 + * best to give this driver a callback function to call when
943 + * it is ready to give out addresses. The callback function
944 + * would have those steps that continue the initialization of
945 + * a driver that do require a valid RAR address. One of those
946 + * steps would be to call get_rar_address()
947 + * This function return 0 on success an -1 on failure.
949 +int register_rar(int (*callback)(void *yourparameter), void *yourparameter);
951 +/* The get_rar_address function is used by other device drivers
952 + * to obtain RAR address information on a RAR. It takes two
956 + * The rar_index is an index to the rar for which you wish to retrieve
957 + * the address information.
958 + * Values can be 0,1, or 2.
960 + * struct RAR_address_struct is a pointer to a place to which the function
961 + * can return the address structure for the RAR.
963 + * The function returns a 0 upon success or a -1 if there is no RAR
964 + * facility on this system.
966 +int rar_get_address(int rar_index,
967 + u32 *start_address,
971 +/* The lock_rar function is ued by other device drivers to lock an RAR.
972 + * once an RAR is locked, it stays locked until the next system reboot.
973 + * The function takes one parameter:
976 + * The rar_index is an index to the rar that you want to lock.
977 + * Values can be 0,1, or 2.
979 + * The function returns a 0 upon success or a -1 if there is no RAR
980 + * facility on this system.
982 +int rar_lock(int rar_index);
985 +#endif /* _RAR_REGISTER_H */
990 + c-file-style: "linux"
993 Index: linux-2.6.33/drivers/misc/Kconfig
994 ===================================================================
995 --- linux-2.6.33.orig/drivers/misc/Kconfig
996 +++ linux-2.6.33/drivers/misc/Kconfig
997 @@ -249,6 +249,17 @@ config SGI_GRU_DEBUG
998 This option enables addition debugging code for the SGI GRU driver. If
999 you are unsure, say N.
1001 +config MRST_RAR_HANDLER
1002 + tristate "RAR handler driver for Intel Moorestown platform"
1004 + select RAR_REGISTER
1006 + This driver provides a memory management interface to
1007 + restricted access regions available in the Intel Moorestown
1013 tristate "vibrator driver for Intel Moorestown platform"
1015 Index: linux-2.6.33/drivers/misc/Makefile
1016 ===================================================================
1017 --- linux-2.6.33.orig/drivers/misc/Makefile
1018 +++ linux-2.6.33/drivers/misc/Makefile
1019 @@ -22,6 +22,8 @@ obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfg
1020 obj-$(CONFIG_HP_ILO) += hpilo.o
1021 obj-$(CONFIG_MRST) += intel_mrst.o
1022 obj-$(CONFIG_ISL29003) += isl29003.o
1023 +obj-$(CONFIG_MRST_RAR_HANDLER) += memrar.o
1024 +memrar-y := memrar_allocator.o memrar_handler.o
1025 obj-$(CONFIG_MRST_VIB) += mrst_vib.o
1026 obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o
1027 obj-$(CONFIG_DS1682) += ds1682.o
1028 Index: linux-2.6.33/drivers/misc/memrar_allocator.c
1029 ===================================================================
1031 +++ linux-2.6.33/drivers/misc/memrar_allocator.c
1034 + * memrar_allocator 0.2: An allocator for Intel RAR.
1036 + * Copyright (C) 2009 Intel Corporation. All rights reserved.
1038 + * This program is free software; you can redistribute it and/or
1039 + * modify it under the terms of version 2 of the GNU General
1040 + * Public License as published by the Free Software Foundation.
1042 + * This program is distributed in the hope that it will be
1043 + * useful, but WITHOUT ANY WARRANTY; without even the implied
1044 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
1045 + * PURPOSE. See the GNU General Public License for more details.
1046 + * You should have received a copy of the GNU General Public
1047 + * License along with this program; if not, write to the Free
1048 + * Software Foundation, Inc., 59 Temple Place - Suite 330,
1049 + * Boston, MA 02111-1307, USA.
1050 + * The full GNU General Public License is included in this
1051 + * distribution in the file called COPYING.
1054 + * ------------------------------------------------------------------
1056 + * This simple allocator implementation provides a
1057 + * malloc()/free()-like interface for reserving space within a
1058 + * previously reserved block of memory. It is not specific to
1059 + * any hardware, nor is it coupled with the lower level paging
1062 + * The primary goal of this implementation is to provide a means
1063 + * to partition an arbitrary block of memory without actually
1064 + * accessing the memory or incurring any hardware side-effects
1065 + * (e.g. paging). It is, in effect, a bookkeeping mechanism for
1070 +#include "memrar_allocator.h"
1071 +#include <linux/slab.h>
1072 +#include <linux/bug.h>
1073 +#include <linux/kernel.h>
1076 +struct memrar_allocator *memrar_create_allocator(unsigned long base,
1078 + size_t block_size)
1080 + struct memrar_allocator *allocator = NULL;
1081 + struct memrar_free_list *first_node = NULL;
1084 + * Make sure the base address is aligned on a block_size
1087 + * @todo Is this necessary?
1089 + /* base = ALIGN(base, block_size); */
1091 + /* Validate parameters.
1093 + * Make sure we can allocate the entire memory allocator
1094 + * space. Zero capacity or block size are obviously invalid.
1098 + || block_size == 0
1099 + || ULONG_MAX - capacity < base
1100 + || capacity < block_size)
1104 + * There isn't much point in creating a memory allocator that
1105 + * is only capable of holding one block but we'll allow it,
1106 + * and issue a diagnostic.
1108 + WARN(capacity < block_size * 2,
1109 + "memrar: Only one block available to allocator.\n");
1111 + allocator = kmalloc(sizeof(*allocator), GFP_KERNEL);
1113 + if (allocator == NULL)
1116 + mutex_init(&allocator->lock);
1117 + allocator->base = base;
1119 + /* Round the capacity down to a multiple of block_size. */
1120 + allocator->capacity = (capacity / block_size) * block_size;
1122 + allocator->block_size = block_size;
1124 + allocator->largest_free_area = allocator->capacity;
1126 + /* Initialize the handle and free lists. */
1127 + INIT_LIST_HEAD(&allocator->handle_list.list);
1128 + INIT_LIST_HEAD(&allocator->free_list.list);
1130 + first_node = kmalloc(sizeof(*first_node), GFP_KERNEL);
1131 + if (first_node == NULL) {
1135 + /* Full range of blocks is available. */
1136 + first_node->begin = base;
1137 + first_node->end = base + allocator->capacity;
1138 + list_add(&first_node->list,
1139 + &allocator->free_list.list);
1145 +void memrar_destroy_allocator(struct memrar_allocator *allocator)
1148 + * Assume that the memory allocator lock isn't held at this
1149 + * point in time. Caller must ensure that.
1152 + struct memrar_free_list *pos;
1153 + struct memrar_free_list *n;
1155 + if (allocator == NULL)
1158 + mutex_lock(&allocator->lock);
1160 + /* Reclaim free list resources. */
1161 + list_for_each_entry_safe(pos,
1163 + &allocator->free_list.list,
1165 + list_del(&pos->list);
1169 + mutex_unlock(&allocator->lock);
1174 +unsigned long memrar_allocator_alloc(struct memrar_allocator *allocator,
1177 + struct memrar_free_list *pos = NULL;
1179 + size_t num_blocks;
1180 + unsigned long reserved_bytes;
1183 + * Address of allocated buffer. We assume that zero is not a
1186 + unsigned long addr = 0;
1188 + if (allocator == NULL || size == 0)
1191 + /* Reserve enough blocks to hold the amount of bytes requested. */
1192 + num_blocks = DIV_ROUND_UP(size, allocator->block_size);
1194 + reserved_bytes = num_blocks * allocator->block_size;
1196 + mutex_lock(&allocator->lock);
1198 + if (reserved_bytes > allocator->largest_free_area) {
1199 + mutex_unlock(&allocator->lock);
1204 + * Iterate through the free list to find a suitably sized
1205 + * range of free contiguous memory blocks.
1207 + list_for_each_entry(pos, &allocator->free_list.list, list) {
1208 + size_t const curr_size = pos->end - pos->begin;
1210 + if (curr_size >= reserved_bytes) {
1211 + struct memrar_handle *handle = NULL;
1212 + struct memrar_handle_list * const new_node =
1213 + kmalloc(sizeof(*new_node), GFP_KERNEL);
1215 + if (new_node == NULL)
1218 + list_add(&new_node->list,
1219 + &allocator->handle_list.list);
1221 + handle = &new_node->handle;
1222 + handle->end = pos->end;
1223 + pos->end -= reserved_bytes;
1224 + handle->begin = pos->end;
1225 + addr = handle->begin;
1227 + if (curr_size == allocator->largest_free_area)
1228 + allocator->largest_free_area -=
1235 + mutex_unlock(&allocator->lock);
1240 +long memrar_allocator_free(struct memrar_allocator *allocator,
1241 + unsigned long addr)
1243 + struct list_head *pos = NULL;
1244 + struct list_head *tmp = NULL;
1245 + struct memrar_handle_list *handles = NULL;
1246 + struct memrar_handle *handle = NULL;
1247 + struct memrar_free_list *new_node = NULL;
1248 + int result = -ENOMEM;
1250 + if (allocator == NULL)
1254 + return 0; /* Ignore free(0). */
1256 + mutex_lock(&allocator->lock);
1258 + /* Find the corresponding handle. */
1259 + list_for_each_entry(handles,
1260 + &allocator->handle_list.list,
1262 + if (handles->handle.begin == addr) {
1263 + handle = &handles->handle;
1268 + /* No such buffer created by this allocator. */
1269 + if (handle == NULL) {
1270 + mutex_unlock(&allocator->lock);
1275 + * Coalesce adjacent chunks of memory if possible.
1277 + * @note This isn't full blown coalescing since we're only
1278 + * coalescing at most three chunks of memory.
1280 + list_for_each_safe(pos, tmp, &allocator->free_list.list) {
1281 + /* @todo O(n) performance. Optimize. */
1283 + struct memrar_free_list * const chunk =
1285 + struct memrar_free_list,
1288 + struct memrar_free_list * const next =
1289 + list_entry(pos->next,
1290 + struct memrar_free_list,
1293 + /* Extend size of existing free adjacent chunk. */
1294 + if (chunk->end == handle->begin) {
1296 + * Chunk "less than" than the one we're
1297 + * freeing is adjacent.
1300 + unsigned long new_chunk_size;
1302 + chunk->end = handle->end;
1305 + * Now check if next free chunk is adjacent to
1306 + * the current extended free chunk.
1308 + if (pos != pos->next
1309 + && chunk->end == next->begin) {
1310 + chunk->end = next->end;
1311 + list_del(pos->next);
1315 + new_chunk_size = chunk->end - chunk->begin;
1317 + if (new_chunk_size > allocator->largest_free_area)
1318 + allocator->largest_free_area =
1322 + goto exit_memrar_free;
1323 + } else if (chunk->begin == handle->end) {
1325 + * Chunk "greater than" than the one we're
1326 + * freeing is adjacent.
1329 + unsigned long new_chunk_size;
1331 + chunk->begin = handle->begin;
1334 + * Now check if next free chunk is adjacent to
1335 + * the current extended free chunk.
1337 + if (pos != pos->next
1338 + && chunk->begin == next->end) {
1339 + chunk->begin = next->begin;
1340 + list_del(pos->next);
1344 + new_chunk_size = chunk->end - chunk->begin;
1346 + if (new_chunk_size > allocator->largest_free_area)
1347 + allocator->largest_free_area =
1351 + goto exit_memrar_free;
1356 + * Memory being freed is not adjacent to existing free areas
1357 + * of memory in the allocator. Add a new item to the free list.
1359 + * @todo Allocate this free_list node when the buffer itself
1360 + * is allocated to avoid a potential problem where a new
1361 + * node cannot be allocated due to lack of available
1362 + * kernel memory. We can then free this node in the
1363 + * above coalescing code node if it isn't needed.
1365 + * @todo While making this change would address potential
1366 + * memory allocation failure, it would also
1367 + * unfortunately reduce performance of buffer allocation
1368 + * provided by this allocator.
1370 + new_node = kmalloc(sizeof(*new_node), GFP_KERNEL);
1371 + if (new_node != NULL) {
1372 + unsigned long new_chunk_size;
1374 + new_node->begin = handle->begin;
1375 + new_node->end = handle->end;
1376 + list_add(&new_node->list,
1377 + &allocator->free_list.list);
1379 + new_chunk_size = handle->end - handle->begin;
1381 + if (new_chunk_size > allocator->largest_free_area)
1382 + allocator->largest_free_area =
1391 + list_del(&handles->list);
1393 + mutex_unlock(&allocator->lock);
1404 + c-file-style: "linux"
1407 Index: linux-2.6.33/drivers/misc/memrar_allocator.h
1408 ===================================================================
1410 +++ linux-2.6.33/drivers/misc/memrar_allocator.h
1413 + * Copyright (C) 2009 Intel Corporation. All rights reserved.
1415 + * This program is free software; you can redistribute it and/or
1416 + * modify it under the terms of version 2 of the GNU General
1417 + * Public License as published by the Free Software Foundation.
1419 + * This program is distributed in the hope that it will be
1420 + * useful, but WITHOUT ANY WARRANTY; without even the implied
1421 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
1422 + * PURPOSE. See the GNU General Public License for more details.
1423 + * You should have received a copy of the GNU General Public
1424 + * License along with this program; if not, write to the Free
1425 + * Software Foundation, Inc., 59 Temple Place - Suite 330,
1426 + * Boston, MA 02111-1307, USA.
1427 + * The full GNU General Public License is included in this
1428 + * distribution in the file called COPYING.
1431 +#ifndef MEMRAR_ALLOCATOR_H
1432 +#define MEMRAR_ALLOCATOR_H
1435 +#include <linux/mutex.h>
1436 +#include <linux/list.h>
1437 +#include <linux/types.h>
1438 +#include <linux/kernel.h>
1441 + * @struct memrar_free_list
1443 + * @brief List of available areas of memory.
1445 +struct memrar_free_list {
1446 + /* Linked list of free memory allocator blocks. */
1447 + struct list_head list;
1449 + /* Beginning of available address range. */
1450 + unsigned long begin;
1453 + * End of available address range, one past the end,
1454 + * i.e. [begin, end).
1456 + unsigned long end;
1459 +struct memrar_allocator;
1461 +/* Structure that describes a chunk memory reserved by the allocator. */
1462 +struct memrar_handle {
1463 + /* Beginning of available address range. */
1464 + unsigned long begin;
1467 + * End of available address range, one past the end,
1468 + * i.e. [begin, end).
1470 + unsigned long end;
1474 + * @struct memrar_handle_list
1476 + * @brief List of handles corresponding to allocated blocks of memory.
1478 +struct memrar_handle_list {
1479 + /* Linked list of handles corresponding to allocated blocks. */
1480 + struct list_head list;
1482 + /* Handle for the allocated block of memory. */
1483 + struct memrar_handle handle;
1487 + * @struct memrar_allocator
1489 + * @brief Encapsulation of the memory allocator state.
1491 + * This structure contains all memory allocator state, including the
1492 + * base address, capacity, free list, lock, etc.
1494 +struct memrar_allocator {
1496 + * Lock used to synchronize access to the memory allocator
1499 + struct mutex lock;
1501 + /* Base (start) address of the memory allocator. */
1502 + unsigned long base;
1504 + /* Size of the memory allocator in bytes. */
1508 + * The size in bytes of individual blocks within the memory
1511 + size_t block_size;
1513 + /* Largest free area of memory in the allocator in bytes. */
1514 + size_t largest_free_area;
1516 + /* List of handles for allocated blocks of memory. */
1517 + struct memrar_handle_list handle_list;
1519 + /* List of free address ranges. */
1520 + struct memrar_free_list free_list;
1524 + * @function memrar_create_allocator
1526 + * @brief Create a memory allocator.
1528 + * Create a memory allocator with the given capacity and block size.
1529 + * The capacity will be reduced to be a multiple of the block size, if
1532 + * @param base Address at which the memory allocator begins.
1533 + * @param capacity Desired size of the memory allocator. This value
1534 + * must be larger than the block_size, ideally more
1535 + * than twice as large since there wouldn't be much
1536 + * point in using a memory allocator otherwise.
1537 + * @param block_size The size of individual blocks within the memory
1538 + * allocator. This value must smaller than the
1540 + * @return An instance of the memory allocator, if creation succeeds.
1541 + * @return Zero if creation fails. Failure may occur if not enough
1542 + * kernel memory exists to create the memrar_allocator
1543 + * instance itself, or if the capacity and block_size
1544 + * arguments are not compatible or make sense.
1546 +struct memrar_allocator *memrar_create_allocator(unsigned long base,
1548 + size_t block_size);
1551 + * Reclaim resources held by the memory allocator. The caller must
1552 + * explicitly free all memory reserved by memrar_allocator_alloc()
1553 + * prior to calling this function. Otherwise leaks will occur.
1555 +void memrar_destroy_allocator(struct memrar_allocator *allocator);
1558 + * Reserve chunk of memory of given size in the memory allocator.
1560 +unsigned long memrar_allocator_alloc(struct memrar_allocator *allocator,
1564 + * Reserve chunk of memory of given size in the memory allocator.
1566 +long memrar_allocator_free(struct memrar_allocator *allocator,
1567 + unsigned long handle);
1569 +#endif /* MEMRAR_ALLOCATOR_H */
1574 + c-file-style: "linux"
1577 Index: linux-2.6.33/drivers/misc/memrar_handler.c
1578 ===================================================================
1580 +++ linux-2.6.33/drivers/misc/memrar_handler.c
1583 + * memrar_handler 1.0: An Intel restricted access region handler device
1585 + * Copyright (C) 2009 Intel Corporation. All rights reserved.
1587 + * This program is free software; you can redistribute it and/or
1588 + * modify it under the terms of version 2 of the GNU General
1589 + * Public License as published by the Free Software Foundation.
1591 + * This program is distributed in the hope that it will be
1592 + * useful, but WITHOUT ANY WARRANTY; without even the implied
1593 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
1594 + * PURPOSE. See the GNU General Public License for more details.
1595 + * You should have received a copy of the GNU General Public
1596 + * License along with this program; if not, write to the Free
1597 + * Software Foundation, Inc., 59 Temple Place - Suite 330,
1598 + * Boston, MA 02111-1307, USA.
1599 + * The full GNU General Public License is included in this
1600 + * distribution in the file called COPYING.
1602 + * -------------------------------------------------------------------
1604 + * Moorestown restricted access regions (RAR) provide isolated
1605 + * areas of main memory that are only acceessible by authorized
1608 + * The Intel Moorestown RAR handler module exposes a kernel space
1609 + * RAR memory management mechanism. It is essentially a
1610 + * RAR-specific allocator.
1612 + * Besides providing RAR buffer management, the RAR handler also
1613 + * behaves in many ways like an OS virtual memory manager. For
1614 + * example, the RAR "handles" created by the RAR handler are
1615 + * analogous to user space virtual addresses.
1617 + * RAR memory itself is never accessed directly by the RAR
1620 + * -------------------------------------------------------------------
1624 + * 1. Split user space interface from core/kernel code, e.g.:
1625 + * memrar_handler.c -> memrar_core.c, memrar_user.c
1627 + * 2. Convert API documentation to Kerneldoc.
1629 + * 3. Move memrar_allocator.* to kernel lib' directory since it
1631 + * a. Alternatively, use lib/genalloc.c instead.
1632 + * b. A kernel port of Doug Lea's malloc() implementation may
1633 + * also be an option.
1636 +#include <linux/miscdevice.h>
1637 +#include <linux/fs.h>
1638 +#include <linux/slab.h>
1639 +#include <linux/kref.h>
1640 +#include <linux/mutex.h>
1641 +#include <linux/kernel.h>
1642 +#include <linux/uaccess.h>
1643 +#include <linux/mm.h>
1644 +#include <linux/ioport.h>
1645 +#include <linux/io.h>
1647 +#include <linux/rar/rar_register.h>
1648 +#include <linux/rar/memrar.h>
1650 +#include "memrar_allocator.h"
1653 +#define MEMRAR_VER "1.0"
1656 + * Moorestown supports three restricted access regions.
1658 + * We only care about the first two, video and audio. The third,
1659 + * reserved for Chaabi and the P-unit, will be handled by their
1660 + * respective drivers.
1662 +#define MRST_NUM_RAR 2
1664 +/* ---------------- -------------------- ------------------- */
1667 + * List structure that keeps track of all RAR buffers.
1669 +struct memrar_buffer_info {
1670 + /* Linked list of memrar_buffer_info objects. */
1671 + struct list_head list;
1673 + /* Core RAR buffer information. */
1674 + struct RAR_buffer buffer;
1676 + /* Reference count */
1677 + struct kref refcount;
1680 + * File handle corresponding to process that reserved the
1681 + * block of memory in RAR. This will be zero for buffers
1682 + * allocated by other drivers instead of by a user space
1685 + struct file *owner;
1689 + * Structure that describes that characteristics of a given RAR.
1691 +struct memrar_rar_info {
1692 + /* Base bus address of the RAR. */
1693 + unsigned long base;
1695 + /* Length of the RAR. */
1696 + unsigned long length;
1698 + /* Virtual address of RAR mapped into kernel. */
1699 + void __iomem *iobase;
1702 + * Allocator associated with the RAR.
1704 + * @note The allocator "capacity" may be smaller than the RAR
1705 + * length if the length is not a multiple of the
1706 + * configured allocator block size.
1708 + struct memrar_allocator *allocator;
1711 + * Table that keeps track of all reserved RAR buffers.
1713 + struct memrar_buffer_info buffers;
1716 + * Lock used to synchronize access to RAR-specific data
1719 + struct mutex lock;
1723 + * Array of RAR characteristics.
1725 +static struct memrar_rar_info memrars[MRST_NUM_RAR];
1728 +/* ---------------- -------------------- ------------------- */
1730 +/* Validate RAR type. */
1731 +static inline int memrar_is_valid_rar_type(u32 type)
1733 + return type == RAR_TYPE_VIDEO || type == RAR_TYPE_AUDIO;
1736 +/* Check if an address/handle falls with the given RAR memory range. */
1737 +static inline int memrar_handle_in_range(struct memrar_rar_info *rar,
1740 + unsigned long const iobase = (unsigned long) (rar->iobase);
1741 + return (vaddr >= iobase && vaddr < iobase + rar->length);
1744 +/* Retrieve RAR information associated with the given handle. */
1745 +static struct memrar_rar_info *memrar_get_rar_info(u32 vaddr)
1748 + for (i = 0; i < MRST_NUM_RAR; ++i) {
1749 + struct memrar_rar_info * const rar = &memrars[i];
1750 + if (memrar_handle_in_range(rar, vaddr))
1758 + * Retrieve bus address from given handle.
1760 + * @return Address corresponding to given handle. Zero if handle
1763 +static unsigned long memrar_get_bus_address(
1764 + struct memrar_rar_info *rar,
1767 + unsigned long const iobase = (unsigned long) (rar->iobase);
1769 + if (!memrar_handle_in_range(rar, vaddr))
1773 + * An assumption is made that the virtual address offset is
1774 + * the same as the bus address offset, at least based on the
1775 + * way this driver is implemented. For example, vaddr + 2 ==
1778 + * @todo Is that a valid assumption?
1780 + return rar->base + (vaddr - iobase);
1784 + * Retrieve physical address from given handle.
1786 + * @return Address corresponding to given handle. Zero if handle
1789 +static unsigned long memrar_get_physical_address(
1790 + struct memrar_rar_info *rar,
1794 + * @todo This assumes that the bus address and physical
1795 + * address are the same. That is true for Moorestown
1796 + * but not necessarily on other platforms. This
1797 + * deficiency should be addressed at some point.
1799 + return memrar_get_bus_address(rar, vaddr);
1803 + * Core block release code.
1805 + * @note This code removes the node from a list. Make sure any list
1806 + * iteration is performed using list_for_each_safe().
1808 +static void memrar_release_block_i(struct kref *ref)
1811 + * Last reference is being released. Remove from the table,
1812 + * and reclaim resources.
1815 + struct memrar_buffer_info * const node =
1816 + container_of(ref, struct memrar_buffer_info, refcount);
1818 + struct RAR_block_info * const user_info =
1819 + &node->buffer.info;
1821 + struct memrar_allocator * const allocator =
1822 + memrars[user_info->type].allocator;
1824 + list_del(&node->list);
1826 + memrar_allocator_free(allocator, user_info->handle);
1832 + * Initialize RAR parameters, such as bus addresses, etc.
1834 +static int memrar_init_rar_resources(char const *devname)
1836 + /* ---- Sanity Checks ----
1837 + * 1. RAR bus addresses in both Lincroft and Langwell RAR
1838 + * registers should be the same.
1839 + * 2. Secure device ID in Langwell RAR registers should be set
1840 + * appropriately, i.e. only LPE DMA for the audio RAR, and
1841 + * security for the other Langwell based RAR register. The
1842 + * video RAR is not accessed from the Langwell side,
1843 + * meaning its corresponding Langwell RAR should only be
1844 + * accessible by the security engine.
1845 + * 3. Audio and video RAR register and RAR access should be
1846 + * locked. If not, lock them. Except for debugging
1847 + * purposes, there is no reason for them to be unlocked.
1849 + * @todo Should the RAR handler driver even be aware of audio
1850 + * and video RAR settings?
1854 + * RAR buffer block size.
1856 + * We choose it to be the size of a page to simplify the
1857 + * /dev/memrar mmap() implementation and usage. Otherwise
1858 + * paging is not involved once an RAR is locked down.
1860 + static size_t const RAR_BLOCK_SIZE = PAGE_SIZE;
1863 + int found_rar = 0;
1865 + BUG_ON(MRST_NUM_RAR != ARRAY_SIZE(memrars));
1867 + for (z = 0; z != MRST_NUM_RAR; ++z) {
1869 + struct memrar_rar_info * const rar = &memrars[z];
1871 + BUG_ON(!memrar_is_valid_rar_type(z));
1873 + mutex_init(&rar->lock);
1876 + * Initialize the process table before we reach any
1877 + * code that exit on failure since the finalization
1878 + * code requires an initialized list.
1880 + INIT_LIST_HEAD(&rar->buffers.list);
1882 + if (rar_get_address(z, &low, &high) != 0) {
1883 + /* No RAR is available. */
1885 + } else if (low == 0 || high == 0) {
1887 + * We don't immediately break out of the loop
1888 + * since the next type of RAR may be enabled.
1892 + rar->iobase = NULL;
1893 + rar->allocator = NULL;
1898 + * @todo Verify that LNC and LNW RAR register contents
1899 + * addresses, security, etc are compatible and
1903 + rar->length = high - low + 1;
1905 + /* Claim RAR memory as our own. */
1906 + if (request_mem_region(low, rar->length, devname) == NULL) {
1909 + pr_err("%s: Unable to claim RAR[%d] memory.\n",
1912 + pr_err("%s: RAR[%d] disabled.\n", devname, z);
1915 + * Rather than break out of the loop by
1916 + * returning -EBUSY, for example, we may be
1917 + * able to claim memory of the next RAR region
1926 + * Now map it into the kernel address space.
1928 + * Note that the RAR memory may only be accessed by IA
1929 + * when debugging. Otherwise attempts to access the
1930 + * RAR memory when it is locked down will result in
1931 + * behavior similar to writing to /dev/null and
1932 + * reading from /dev/zero. This behavior is enforced
1933 + * by the hardware. Even if we don't access the
1934 + * memory, mapping it into the kernel provides us with
1935 + * a convenient RAR handle to physical address mapping.
1937 + rar->iobase = ioremap_nocache(rar->base, rar->length);
1938 + if (rar->iobase == NULL) {
1939 + pr_err("%s: Unable to map RAR memory.\n",
1944 + /* Initialize corresponding memory allocator. */
1945 + rar->allocator = memrar_create_allocator(
1946 + (unsigned long) rar->iobase,
1949 + if (rar->allocator == NULL)
1953 + * -------------------------------------------------
1954 + * Make sure all RARs handled by us are locked down.
1955 + * -------------------------------------------------
1958 + /* Enable RAR protection on the Lincroft side. */
1960 + /* @todo Enable once LNW A2 is widely available. */
1963 + pr_warning("%s: LNC RAR[%d] no lock sanity check.\n",
1968 + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
1969 + /* |||||||||||||||||||||||||||||||||||||||||||||||||| */
1972 + * Enable RAR protection on the Langwell side.
1974 + * Ideally Langwell side RAR protection should already
1975 + * have been enabled by the OEM in the SMIP header but
1976 + * we perform a sanity check, just in case.
1978 + * @todo Set appropriate "lock"/"valid" bits in LNW
1979 + * {LOW,UP}RAR[12] SCCB registers **and** LNW
1980 + * {LOW,UP}RAR[01] cDMI registers only if a
1981 + * suitable SDID (i.e. for security or LPE DMA)
1984 + pr_warning("%s: LNW RAR[%d] no lock sanity check.\n",
1989 + pr_info("%s: BRAR[%d]\n"
1990 + "\tlow address: 0x%x\n"
1991 + "\thigh address: 0x%x\n"
1992 + "\tsize : %u KiB\n",
1997 + rar->allocator->capacity / 1024);
2004 + * No RAR support. Don't bother continuing.
2006 + * Note that this is not a failure.
2008 + pr_info("%s: No Moorestown RAR support available.\n",
2017 + * Finalize RAR resources.
2019 +static void memrar_fini_rar_resources(void)
2022 + struct memrar_buffer_info *pos;
2023 + struct memrar_buffer_info *tmp;
2026 + * @todo Do we need to hold a lock at this point in time?
2027 + * (module initialization failure or exit?)
2030 + for (z = MRST_NUM_RAR; z-- != 0; ) {
2031 + struct memrar_rar_info * const rar = &memrars[z];
2033 + /* Clean up remaining resources. */
2035 + list_for_each_entry_safe(pos,
2037 + &rar->buffers.list,
2039 + kref_put(&pos->refcount, memrar_release_block_i);
2042 + memrar_destroy_allocator(rar->allocator);
2043 + rar->allocator = NULL;
2045 + iounmap(rar->iobase);
2046 + rar->iobase = NULL;
2048 + release_mem_region(rar->base, rar->length);
2055 +static long memrar_reserve_block(struct RAR_buffer *request,
2056 + struct file *filp)
2058 + struct RAR_block_info * const rinfo = &request->info;
2059 + struct RAR_buffer *buffer;
2060 + struct memrar_buffer_info *buffer_info;
2062 + struct memrar_rar_info *rar = NULL;
2064 + /* Prevent array overflow. */
2065 + if (!memrar_is_valid_rar_type(rinfo->type))
2068 + rar = &memrars[rinfo->type];
2070 + /* Reserve memory in RAR. */
2071 + handle = memrar_allocator_alloc(rar->allocator, rinfo->size);
2075 + buffer_info = kmalloc(sizeof(*buffer_info), GFP_KERNEL);
2077 + if (buffer_info == NULL) {
2078 + memrar_allocator_free(rar->allocator, handle);
2082 + buffer = &buffer_info->buffer;
2083 + buffer->info.type = rinfo->type;
2084 + buffer->info.size = rinfo->size;
2086 + /* Memory handle corresponding to the bus address. */
2087 + buffer->info.handle = handle;
2088 + buffer->bus_address = memrar_get_bus_address(rar, handle);
2091 + * Keep track of owner so that we can later cleanup if
2094 + buffer_info->owner = filp;
2096 + kref_init(&buffer_info->refcount);
2098 + mutex_lock(&rar->lock);
2099 + list_add(&buffer_info->list, &rar->buffers.list);
2100 + mutex_unlock(&rar->lock);
2102 + rinfo->handle = buffer->info.handle;
2103 + request->bus_address = buffer->bus_address;
2108 +static long memrar_release_block(u32 addr)
2110 + struct memrar_buffer_info *pos;
2111 + struct memrar_buffer_info *tmp;
2112 + struct memrar_rar_info * const rar = memrar_get_rar_info(addr);
2113 + long result = -EINVAL;
2118 + mutex_lock(&rar->lock);
2121 + * Iterate through the buffer list to find the corresponding
2122 + * buffer to be released.
2124 + list_for_each_entry_safe(pos,
2126 + &rar->buffers.list,
2128 + if (addr == pos->buffer.info.handle
2129 + && memrar_is_valid_rar_type(pos->buffer.info.type)) {
2130 + kref_put(&pos->refcount, memrar_release_block_i);
2136 + mutex_unlock(&rar->lock);
2141 +static long memrar_get_stat(struct RAR_stat *r)
2143 + long result = -EINVAL;
2145 + if (likely(r != NULL) && memrar_is_valid_rar_type(r->type)) {
2146 + struct memrar_allocator * const allocator =
2147 + memrars[r->type].allocator;
2149 + BUG_ON(allocator == NULL);
2152 + * Allocator capacity doesn't change over time. No
2153 + * need to synchronize.
2155 + r->capacity = allocator->capacity;
2157 + mutex_lock(&allocator->lock);
2159 + r->largest_block_size = allocator->largest_free_area;
2161 + mutex_unlock(&allocator->lock);
2169 +static long memrar_ioctl(struct file *filp,
2171 + unsigned long arg)
2173 + void __user *argp = (void __user *)arg;
2176 + struct RAR_buffer buffer;
2177 + struct RAR_block_info * const request = &buffer.info;
2178 + struct RAR_stat rar_info;
2182 + case RAR_HANDLER_RESERVE:
2183 + if (copy_from_user(request,
2185 + sizeof(*request)))
2188 + result = memrar_reserve_block(&buffer, filp);
2192 + return copy_to_user(argp, request, sizeof(*request));
2194 + case RAR_HANDLER_RELEASE:
2195 + if (copy_from_user(&rar_handle,
2197 + sizeof(rar_handle)))
2200 + return memrar_release_block(rar_handle);
2202 + case RAR_HANDLER_STAT:
2203 + if (copy_from_user(&rar_info,
2205 + sizeof(rar_info)))
2209 + * Populate the RAR_stat structure based on the RAR
2210 + * type given by the user
2212 + if (memrar_get_stat(&rar_info) != 0)
2216 + * @todo Do we need to verify destination pointer
2217 + * "argp" is non-zero? Is that already done by
2220 + return copy_to_user(argp,
2222 + sizeof(rar_info)) ? -EFAULT : 0;
2231 +static int memrar_mmap(struct file *filp, struct vm_area_struct *vma)
2233 + size_t const size = vma->vm_end - vma->vm_start;
2235 + /* Users pass the RAR handle as the mmap() offset parameter. */
2236 + unsigned long const handle = vma->vm_pgoff << PAGE_SHIFT;
2238 + struct memrar_rar_info * const rar = memrar_get_rar_info(handle);
2240 + unsigned long pfn;
2242 + /* Invalid RAR handle or size passed to mmap(). */
2245 + || size > (handle - (unsigned long) rar->iobase))
2249 + * Retrieve physical address corresponding to the RAR handle,
2250 + * and convert it to a page frame.
2252 + pfn = memrar_get_physical_address(rar, handle) >> PAGE_SHIFT;
2255 + pr_debug("memrar: mapping RAR range [0x%lx, 0x%lx) into user space.\n",
2260 + * Map RAR memory into user space. This is really only useful
2261 + * for debugging purposes since the memory won't be
2262 + * accesssible, i.e. reads return zero and writes are ignired,
2263 + * when it is locked down.
2265 + if (remap_pfn_range(vma,
2269 + vma->vm_page_prot))
2272 + /* vma->vm_ops = &memrar_mem_ops; */
2277 +static int memrar_open(struct inode *inode, struct file *filp)
2279 + /* Nothing to do yet. */
2284 +static int memrar_release(struct inode *inode, struct file *filp)
2286 + /* Free all regions associated with the given file handle. */
2288 + struct memrar_buffer_info *pos;
2289 + struct memrar_buffer_info *tmp;
2292 + for (z = 0; z != MRST_NUM_RAR; ++z) {
2293 + struct memrar_rar_info * const rar = &memrars[z];
2295 + mutex_lock(&rar->lock);
2297 + list_for_each_entry_safe(pos,
2299 + &rar->buffers.list,
2301 + if (filp == pos->owner)
2302 + kref_put(&pos->refcount,
2303 + memrar_release_block_i);
2306 + mutex_unlock(&rar->lock);
2313 + * @note This function is part of the kernel space memrar driver API.
2315 +size_t rar_reserve(struct RAR_buffer *buffers, size_t count)
2317 + struct RAR_buffer * const end =
2318 + (buffers == NULL ? buffers : buffers + count);
2319 + struct RAR_buffer *i;
2321 + size_t reserve_count = 0;
2323 + for (i = buffers; i != end; ++i) {
2324 + if (memrar_reserve_block(i, NULL) == 0)
2327 + i->bus_address = 0;
2330 + return reserve_count;
2332 +EXPORT_SYMBOL(rar_reserve);
2335 + * @note This function is part of the kernel space memrar driver API.
2337 +size_t rar_release(struct RAR_buffer *buffers, size_t count)
2339 + struct RAR_buffer * const end =
2340 + (buffers == NULL ? buffers : buffers + count);
2341 + struct RAR_buffer *i;
2343 + size_t release_count = 0;
2345 + for (i = buffers; i != end; ++i) {
2346 + u32 * const handle = &i->info.handle;
2347 + if (memrar_release_block(*handle) == 0) {
2349 + * @todo We assume we should do this each time
2350 + * the ref count is decremented. Should
2351 + * we instead only do this when the ref
2352 + * count has dropped to zero, and the
2353 + * buffer has been completely
2354 + * released/unmapped?
2361 + return release_count;
2363 +EXPORT_SYMBOL(rar_release);
2366 + * @note This function is part of the kernel space driver API.
2368 +size_t rar_handle_to_bus(struct RAR_buffer *buffers, size_t count)
2370 + struct RAR_buffer * const end =
2371 + (buffers == NULL ? buffers : buffers + count);
2372 + struct RAR_buffer *i;
2373 + struct memrar_buffer_info *pos;
2375 + size_t conversion_count = 0;
2378 + * Find all bus addresses corresponding to the given handles.
2380 + * @todo Not liking this nested loop. Optimize.
2382 + for (i = buffers; i != end; ++i) {
2383 + struct memrar_rar_info * const rar =
2384 + memrar_get_rar_info(i->info.handle);
2387 + * Check if we have a bogus handle, and then continue
2388 + * with remaining buffers.
2390 + if (rar == NULL) {
2391 + i->bus_address = 0;
2395 + mutex_lock(&rar->lock);
2397 + list_for_each_entry(pos, &rar->buffers.list, list) {
2398 + struct RAR_block_info * const user_info =
2399 + &pos->buffer.info;
2401 + if (i->info.handle >= user_info->handle
2402 + && i->info.handle < (user_info->handle
2403 + + user_info->size)) {
2404 + u32 const offset =
2405 + i->info.handle - user_info->handle;
2407 + i->info.type = user_info->type;
2408 + i->info.size = user_info->size - offset;
2410 + pos->buffer.bus_address
2413 + /* Increment the reference count. */
2414 + kref_get(&pos->refcount);
2416 + ++conversion_count;
2419 + i->bus_address = 0;
2423 + mutex_unlock(&rar->lock);
2426 + return conversion_count;
2428 +EXPORT_SYMBOL(rar_handle_to_bus);
2430 +static const struct file_operations memrar_fops = {
2431 + .owner = THIS_MODULE,
2432 + .unlocked_ioctl = memrar_ioctl,
2433 + .mmap = memrar_mmap,
2434 + .open = memrar_open,
2435 + .release = memrar_release,
2438 +static struct miscdevice memrar_miscdev = {
2439 + .minor = MISC_DYNAMIC_MINOR, /* dynamic allocation */
2440 + .name = "memrar", /* /dev/memrar */
2441 + .fops = &memrar_fops
2444 +static char const banner[] __initdata =
2446 + "Intel RAR Handler: " MEMRAR_VER " initialized.\n";
2448 +static int __init memrar_init(void)
2455 + * We initialize the RAR parameters early on so that we can
2456 + * discontinue memrar device initialization and registration
2457 + * if suitably configured RARs are not available.
2459 + result = memrar_init_rar_resources(memrar_miscdev.name);
2464 + result = misc_register(&memrar_miscdev);
2466 + if (result != 0) {
2467 + pr_err("%s: misc_register() failed.\n",
2468 + memrar_miscdev.name);
2470 + /* Clean up resources previously reserved. */
2471 + memrar_fini_rar_resources();
2477 +static void __exit memrar_exit(void)
2479 + memrar_fini_rar_resources();
2481 + misc_deregister(&memrar_miscdev);
2486 + * The RAR handler must be initialized after the RAR register driver.
2487 + * Otherwise the RAR handler will always assume no RAR support
2490 +late_initcall_sync(memrar_init);
2492 +module_init(memrar_init);
2493 +#endif /* MODULE */
2495 +module_exit(memrar_exit);
2498 +MODULE_AUTHOR("Ossama Othman <ossama.othman@intel.com>");
2499 +MODULE_DESCRIPTION("Intel Restricted Access Region Handler");
2500 +MODULE_LICENSE("GPL");
2501 +MODULE_ALIAS_MISCDEV(MISC_DYNAMIC_MINOR);
2502 +MODULE_VERSION(MEMRAR_VER);
2508 + c-file-style: "linux"
2511 Index: linux-2.6.33/drivers/staging/rar/Kconfig
2512 ===================================================================
2513 --- linux-2.6.33.orig/drivers/staging/rar/Kconfig
2514 +++ linux-2.6.33/drivers/staging/rar/Kconfig
2515 @@ -6,7 +6,7 @@ menu "RAR Register Driver"
2517 # Restricted Access Register Manager
2519 -config RAR_REGISTER
2521 tristate "Restricted Access Region Register Driver"
2524 Index: linux-2.6.33/drivers/staging/rar/Makefile
2525 ===================================================================
2526 --- linux-2.6.33.orig/drivers/staging/rar/Makefile
2527 +++ linux-2.6.33/drivers/staging/rar/Makefile
2529 EXTRA_CFLAGS += -DLITTLE__ENDIAN
2530 -obj-$(CONFIG_RAR_REGISTER) += rar_driver.o
2531 +obj-$(CONFIG_RAR_DRIVER) += rar_driver.o