Skip to content

Commit

Permalink
drivers/staging: Gasket driver framework + Apex driver
Browse files Browse the repository at this point in the history
The Gasket (Google ASIC Software, Kernel Extensions, and Tools) kernel
framework is a generic, flexible system that supports thin kernel
drivers. Gasket kernel drivers are expected to handle opening and
closing devices, mmap'ing BAR space as requested, a small selection of
ioctls, and handling page table translation (covered below). Any other
functions should be handled by userspace code.

The Gasket common module is not enough to run a device. In order to
customize the Gasket code for a given piece of hardware, a device
specific module must be created. At a minimum, this module must define a
struct gasket_driver_desc containing the device-specific data for use by
the framework; in addition, the module must declare an __init function
that calls gasket_register_device with the module's gasket_driver_desc
struct. Finally, the driver must define an exit function that calls
gasket_unregister_device with the module's gasket_driver_desc struct.

One of the core assumptions of the Gasket framework is that precisely
one process is allowed to have an open write handle to the device node
at any given time. (That process may, once it has one write handle, open
any number of additional write handles.) This is accomplished by
tracking open and close data for each driver instance.

Signed-off-by: Rob Springer <rspringer@google.com>
Signed-off-by: John Joseph <jnjoseph@google.com>
Signed-off-by: Simon Que <sque@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Simon Que authored and Greg Kroah-Hartman committed Jul 2, 2018
1 parent ee55fe5 commit 9a69f50
Show file tree
Hide file tree
Showing 21 changed files with 8,083 additions and 0 deletions.
7 changes: 7 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -5928,6 +5928,13 @@ F: scripts/gcc-plugin.sh
F: scripts/Makefile.gcc-plugins
F: Documentation/gcc-plugins.txt

GASKET DRIVER FRAMEWORK
M: Rob Springer <rspringer@google.com>
M: John Joseph <jnjoseph@google.com>
M: Ben Chan <benchan@chromium.org>
S: Maintained
F: drivers/staging/gasket/

GCOV BASED KERNEL PROFILING
M: Peter Oberparleiter <oberpar@linux.ibm.com>
S: Maintained
Expand Down
2 changes: 2 additions & 0 deletions drivers/staging/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,6 @@ source "drivers/staging/mt7621-eth/Kconfig"

source "drivers/staging/mt7621-dts/Kconfig"

source "drivers/staging/gasket/Kconfig"

endif # STAGING
1 change: 1 addition & 0 deletions drivers/staging/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ obj-$(CONFIG_SOC_MT7621) += mt7621-dma/
obj-$(CONFIG_SOC_MT7621) += mt7621-mmc/
obj-$(CONFIG_SOC_MT7621) += mt7621-eth/
obj-$(CONFIG_SOC_MT7621) += mt7621-dts/
obj-$(CONFIG_STAGING_GASKET_FRAMEWORK) += gasket/
23 changes: 23 additions & 0 deletions drivers/staging/gasket/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
menu "Gasket devices"

config STAGING_GASKET_FRAMEWORK
tristate "Gasket framework"
depends on PCI && X86_64
help
This framework supports Gasket-compatible devices, such as Apex.
It is required for any of the following module(s).

To compile this driver as a module, choose M here. The module
will be called "gasket".

config STAGING_APEX_DRIVER
tristate "Apex Driver"
depends on STAGING_GASKET_FRAMEWORK
help
This driver supports the Apex device. Say Y if you want to
include this driver in the kernel.

To compile this driver as a module, choose M here. The module
will be called "apex".

endmenu
9 changes: 9 additions & 0 deletions drivers/staging/gasket/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#
# Makefile for Gasket framework and dependent drivers.
#

obj-$(CONFIG_STAGING_GASKET_FRAMEWORK) += gasket.o
obj-$(CONFIG_STAGING_APEX_DRIVER) += apex.o

gasket-objs := gasket_core.o gasket_ioctl.o gasket_interrupt.o gasket_page_table.o gasket_sysfs.o
apex-objs := apex_driver.o
17 changes: 17 additions & 0 deletions drivers/staging/gasket/TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
This is a list of things that need to be done to get this driver out of the
staging directory.
- Use SPDX tags to show the license of the file, and no more "boiler-plate"
license text is needed.
- Remove static function declarations.
- Document sysfs files with Documentation/ABI/ entries.
- Use misc interface instead of major number for driver version description.
- Add descriptions of module_param's
- Remove gasket-specific logging functions.
- apex_get_status() should actually check status.
- Static functions don't need kernel doc formatting, can be simplified.
- Fix multi-line alignment formatting to look like:
int ret = long_function_name(device, VARIABLE1, VARIABLE2,
VARIABLE3, VARIABLE4);
- "drivers" should never be dealing with "raw" sysfs calls or mess around with
kobjects at all. The driver core should handle all of this for you
automaically. There should not be a need for raw attribute macros.
95 changes: 95 additions & 0 deletions drivers/staging/gasket/apex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Apex kernel-userspace interface definition(s).
*
* Copyright (C) 2018 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __APEX_H__
#define __APEX_H__

#include <linux/ioctl.h>
#include <linux/bitops.h>

#include "gasket.h"

/* Structural definitions/macros. */
/* The number of PCI BARs. */
#define APEX_NUM_BARS 3

/* Size of a memory page in bytes, and the related number of bits to shift. */
#define APEX_PAGE_SHIFT 12
#define APEX_PAGE_SIZE BIT(APEX_PAGE_SHIFT)

#define APEX_EXTENDED_SHIFT 63 /* Extended address bit position. */

/* Addresses are 2^3=8 bytes each. */
/* page in second level page table */
/* holds APEX_PAGE_SIZE/8 addresses */
#define APEX_ADDR_SHIFT 3
#define APEX_LEVEL_SHIFT (APEX_PAGE_SHIFT - APEX_ADDR_SHIFT)
#define APEX_LEVEL_SIZE BIT(APEX_LEVEL_SHIFT)

#define APEX_PAGE_TABLE_MAX 65536
#define APEX_SIMPLE_PAGE_MAX APEX_PAGE_TABLE_MAX
#define APEX_EXTENDED_PAGE_MAX (APEX_PAGE_TABLE_MAX << APEX_LEVEL_SHIFT)

/* Check reset 120 times */
#define APEX_RESET_RETRY 120
/* Wait 100 ms between checks. Total 12 sec wait maximum. */
#define APEX_RESET_DELAY 100

#define APEX_CHIP_INIT_DONE 2
#define APEX_RESET_ACCEPTED 0

enum apex_reset_types {
APEX_CHIP_REINIT_RESET = 3,
};

/* Interrupt defines */
/* Gasket device interrupts enums must be dense (i.e., no empty slots). */
enum apex_interrupt {
APEX_INTERRUPT_INSTR_QUEUE = 0,
APEX_INTERRUPT_INPUT_ACTV_QUEUE = 1,
APEX_INTERRUPT_PARAM_QUEUE = 2,
APEX_INTERRUPT_OUTPUT_ACTV_QUEUE = 3,
APEX_INTERRUPT_SC_HOST_0 = 4,
APEX_INTERRUPT_SC_HOST_1 = 5,
APEX_INTERRUPT_SC_HOST_2 = 6,
APEX_INTERRUPT_SC_HOST_3 = 7,
APEX_INTERRUPT_TOP_LEVEL_0 = 8,
APEX_INTERRUPT_TOP_LEVEL_1 = 9,
APEX_INTERRUPT_TOP_LEVEL_2 = 10,
APEX_INTERRUPT_TOP_LEVEL_3 = 11,
APEX_INTERRUPT_FATAL_ERR = 12,
APEX_INTERRUPT_COUNT = 13,
};

/*
* Clock Gating ioctl.
*/
struct apex_gate_clock_ioctl {
/* Enter or leave clock gated state. */
u64 enable;

/* If set, enter clock gating state, regardless of custom block's
* internal idle state
*/
u64 force_idle;
};

/* Base number for all Apex-common IOCTLs */
#define APEX_IOCTL_BASE 0x7F

/* Enable/Disable clock gating. */
#define APEX_IOCTL_GATE_CLOCK \
_IOW(APEX_IOCTL_BASE, 0, struct apex_gate_clock_ioctl)

#endif /* __APEX_H__ */
Loading

0 comments on commit 9a69f50

Please sign in to comment.