Commit 784c711e authored by David S. Miller's avatar David S. Miller

Merge branch 'sparc64-dax-support'

Rob Gardner says:

====================
sparc64: Driver for Oracle Data Analytics Accelerator

v2:
  Revised example code and updated documentation
  New version of Hypervisor API specification

Recent Oracle Sparc processors (M7 and M8) have a coprocessor which
lives on the cpu chip. The coprocessor is called DAX (Data Analytics
Accelerator), and is controlled via sun4v hypercalls. The programmatic
interface to the coprocessor is somewhat unorthodox, and all commands
and parameters are documented in detail in dax-hv-api.txt. The driver
API is described in oracle-dax.txt, which has been expanded with new
example code along with detailed explanations to demonstrate how user
and kernel code can use the capabilities of DAX.  Those who wish to
use the coprocessor in the kernel will need to construct their own
command blocks to submit, as no higher level services are provided.
Note that it is expected that general use of the coprocessor will go
through the companion userspace library, which has been published
under UPL at:
	  https://oss.oracle.com/git/gitweb.cgi?p=libdax.git
This library is a comprehensive collection of higher level functions
along with tests, documentation, and code examples. The format of the
command control blocks is described in this library as well. Though
the primary purpose of the coprocessor is to accelerate data analytics
operations, it may be used for any suitable purpose.

The machine descriptor identifies the device as "dax", and all
internal documentation refers to it as "dax". But since the term "dax"
already has other meanings and uses in Linux, we call this driver
"oradax".
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0d665e7b dd027328
This diff is collapsed.
This diff is collapsed.
...@@ -76,6 +76,10 @@ ...@@ -76,6 +76,10 @@
#define HV_ETOOMANY 15 /* Too many items specified */ #define HV_ETOOMANY 15 /* Too many items specified */
#define HV_ECHANNEL 16 /* Invalid LDC channel */ #define HV_ECHANNEL 16 /* Invalid LDC channel */
#define HV_EBUSY 17 /* Resource busy */ #define HV_EBUSY 17 /* Resource busy */
#define HV_EUNAVAILABLE 23 /* Resource or operation not
* currently available, but may
* become available in the future
*/
/* mach_exit() /* mach_exit()
* TRAP: HV_FAST_TRAP * TRAP: HV_FAST_TRAP
...@@ -941,6 +945,139 @@ unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr, ...@@ -941,6 +945,139 @@ unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr,
*/ */
#define HV_FAST_MEM_SYNC 0x32 #define HV_FAST_MEM_SYNC 0x32
/* Coprocessor services
*
* M7 and later processors provide an on-chip coprocessor which
* accelerates database operations, and is known internally as
* DAX.
*/
/* ccb_submit()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_CCB_SUBMIT
* ARG0: address of CCB array
* ARG1: size (in bytes) of CCB array being submitted
* ARG2: flags
* ARG3: reserved
* RET0: status (success or error code)
* RET1: size (in bytes) of CCB array that was accepted (might be less
* than arg1)
* RET2: status data
* if status == ENOMAP or ENOACCESS, identifies the VA in question
* if status == EUNAVAILBLE, unavailable code
* RET3: reserved
*
* ERRORS: EOK successful submission (check size)
* EWOULDBLOCK could not finish submissions, try again
* EBADALIGN array not 64B aligned or size not 64B multiple
* ENORADDR invalid RA for array or in CCB
* ENOMAP could not translate address (see status data)
* EINVAL invalid ccb or arguments
* ETOOMANY too many ccbs with all-or-nothing flag
* ENOACCESS guest has no access to submit ccbs or address
* in CCB does not have correct permissions (check
* status data)
* EUNAVAILABLE ccb operation could not be performed at this
* time (check status data)
* Status data codes:
* 0 - exact CCB could not be executed
* 1 - CCB opcode cannot be executed
* 2 - CCB version cannot be executed
* 3 - vcpu cannot execute CCBs
* 4 - no CCBs can be executed
*/
#define HV_CCB_SUBMIT 0x34
#ifndef __ASSEMBLY__
unsigned long sun4v_ccb_submit(unsigned long ccb_buf,
unsigned long len,
unsigned long flags,
unsigned long reserved,
void *submitted_len,
void *status_data);
#endif
/* flags (ARG2) */
#define HV_CCB_QUERY_CMD BIT(1)
#define HV_CCB_ARG0_TYPE_REAL 0UL
#define HV_CCB_ARG0_TYPE_PRIMARY BIT(4)
#define HV_CCB_ARG0_TYPE_SECONDARY BIT(5)
#define HV_CCB_ARG0_TYPE_NUCLEUS GENMASK(5, 4)
#define HV_CCB_ARG0_PRIVILEGED BIT(6)
#define HV_CCB_ALL_OR_NOTHING BIT(7)
#define HV_CCB_QUEUE_INFO BIT(8)
#define HV_CCB_VA_REJECT 0UL
#define HV_CCB_VA_SECONDARY BIT(13)
#define HV_CCB_VA_NUCLEUS GENMASK(13, 12)
#define HV_CCB_VA_PRIVILEGED BIT(14)
#define HV_CCB_VA_READ_ADI_DISABLE BIT(15) /* DAX2 only */
/* ccb_info()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_CCB_INFO
* ARG0: real address of CCB completion area
* RET0: status (success or error code)
* RET1: info array
* - RET1[0]: CCB state
* - RET1[1]: dax unit
* - RET1[2]: queue number
* - RET1[3]: queue position
*
* ERRORS: EOK operation successful
* EBADALIGN address not 64B aligned
* ENORADDR RA in address not valid
* EINVAL CA not valid
* EWOULDBLOCK info not available for this CCB currently, try
* again
* ENOACCESS guest cannot use dax
*/
#define HV_CCB_INFO 0x35
#ifndef __ASSEMBLY__
unsigned long sun4v_ccb_info(unsigned long ca,
void *info_arr);
#endif
/* info array byte offsets (RET1) */
#define CCB_INFO_OFFSET_CCB_STATE 0
#define CCB_INFO_OFFSET_DAX_UNIT 2
#define CCB_INFO_OFFSET_QUEUE_NUM 4
#define CCB_INFO_OFFSET_QUEUE_POS 6
/* CCB state (RET1[0]) */
#define HV_CCB_STATE_COMPLETED 0
#define HV_CCB_STATE_ENQUEUED 1
#define HV_CCB_STATE_INPROGRESS 2
#define HV_CCB_STATE_NOTFOUND 3
/* ccb_kill()
* TRAP: HV_FAST_TRAP
* FUNCTION: HV_CCB_KILL
* ARG0: real address of CCB completion area
* RET0: status (success or error code)
* RET1: CCB kill status
*
* ERRORS: EOK operation successful
* EBADALIGN address not 64B aligned
* ENORADDR RA in address not valid
* EINVAL CA not valid
* EWOULDBLOCK kill not available for this CCB currently, try
* again
* ENOACCESS guest cannot use dax
*/
#define HV_CCB_KILL 0x36
#ifndef __ASSEMBLY__
unsigned long sun4v_ccb_kill(unsigned long ca,
void *kill_status);
#endif
/* CCB kill status (RET1) */
#define HV_CCB_KILL_COMPLETED 0
#define HV_CCB_KILL_DEQUEUED 1
#define HV_CCB_KILL_KILLED 2
#define HV_CCB_KILL_NOTFOUND 3
/* Time of day services. /* Time of day services.
* *
* The hypervisor maintains the time of day on a per-domain basis. * The hypervisor maintains the time of day on a per-domain basis.
...@@ -3355,6 +3492,7 @@ unsigned long sun4v_m7_set_perfreg(unsigned long reg_num, ...@@ -3355,6 +3492,7 @@ unsigned long sun4v_m7_set_perfreg(unsigned long reg_num,
#define HV_GRP_SDIO_ERR 0x0109 #define HV_GRP_SDIO_ERR 0x0109
#define HV_GRP_REBOOT_DATA 0x0110 #define HV_GRP_REBOOT_DATA 0x0110
#define HV_GRP_ATU 0x0111 #define HV_GRP_ATU 0x0111
#define HV_GRP_DAX 0x0113
#define HV_GRP_M7_PERF 0x0114 #define HV_GRP_M7_PERF 0x0114
#define HV_GRP_NIAG_PERF 0x0200 #define HV_GRP_NIAG_PERF 0x0200
#define HV_GRP_FIRE_PERF 0x0201 #define HV_GRP_FIRE_PERF 0x0201
......
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Oracle DAX driver API definitions
*/
#ifndef _ORADAX_H
#define _ORADAX_H
#include <linux/types.h>
#define CCB_KILL 0
#define CCB_INFO 1
#define CCB_DEQUEUE 2
struct dax_command {
__u16 command; /* CCB_KILL/INFO/DEQUEUE */
__u16 ca_offset; /* offset into mmapped completion area */
};
struct ccb_kill_result {
__u16 action; /* action taken to kill ccb */
};
struct ccb_info_result {
__u16 state; /* state of enqueued ccb */
__u16 inst_num; /* dax instance number of enqueued ccb */
__u16 q_num; /* queue number of enqueued ccb */
__u16 q_pos; /* ccb position in queue */
};
struct ccb_exec_result {
__u64 status_data; /* additional status data (e.g. bad VA) */
__u32 status; /* one of DAX_SUBMIT_* */
};
union ccb_result {
struct ccb_exec_result exec;
struct ccb_info_result info;
struct ccb_kill_result kill;
};
#define DAX_MMAP_LEN (16 * 1024)
#define DAX_MAX_CCBS 15
#define DAX_CCB_BUF_MAXLEN (DAX_MAX_CCBS * 64)
#define DAX_NAME "oradax"
/* CCB_EXEC status */
#define DAX_SUBMIT_OK 0
#define DAX_SUBMIT_ERR_RETRY 1
#define DAX_SUBMIT_ERR_WOULDBLOCK 2
#define DAX_SUBMIT_ERR_BUSY 3
#define DAX_SUBMIT_ERR_THR_INIT 4
#define DAX_SUBMIT_ERR_ARG_INVAL 5
#define DAX_SUBMIT_ERR_CCB_INVAL 6
#define DAX_SUBMIT_ERR_NO_CA_AVAIL 7
#define DAX_SUBMIT_ERR_CCB_ARR_MMU_MISS 8
#define DAX_SUBMIT_ERR_NOMAP 9
#define DAX_SUBMIT_ERR_NOACCESS 10
#define DAX_SUBMIT_ERR_TOOMANY 11
#define DAX_SUBMIT_ERR_UNAVAIL 12
#define DAX_SUBMIT_ERR_INTERNAL 13
/* CCB_INFO states - must match HV_CCB_STATE_* definitions */
#define DAX_CCB_COMPLETED 0
#define DAX_CCB_ENQUEUED 1
#define DAX_CCB_INPROGRESS 2
#define DAX_CCB_NOTFOUND 3
/* CCB_KILL actions - must match HV_CCB_KILL_* definitions */
#define DAX_KILL_COMPLETED 0
#define DAX_KILL_DEQUEUED 1
#define DAX_KILL_KILLED 2
#define DAX_KILL_NOTFOUND 3
#endif /* _ORADAX_H */
...@@ -41,6 +41,7 @@ static struct api_info api_table[] = { ...@@ -41,6 +41,7 @@ static struct api_info api_table[] = {
{ .group = HV_GRP_SDIO_ERR, }, { .group = HV_GRP_SDIO_ERR, },
{ .group = HV_GRP_REBOOT_DATA, }, { .group = HV_GRP_REBOOT_DATA, },
{ .group = HV_GRP_ATU, .flags = FLAG_PRE_API }, { .group = HV_GRP_ATU, .flags = FLAG_PRE_API },
{ .group = HV_GRP_DAX, },
{ .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API },
{ .group = HV_GRP_FIRE_PERF, }, { .group = HV_GRP_FIRE_PERF, },
{ .group = HV_GRP_N2_CPU, }, { .group = HV_GRP_N2_CPU, },
......
...@@ -871,3 +871,60 @@ ENTRY(sun4v_m7_set_perfreg) ...@@ -871,3 +871,60 @@ ENTRY(sun4v_m7_set_perfreg)
retl retl
nop nop
ENDPROC(sun4v_m7_set_perfreg) ENDPROC(sun4v_m7_set_perfreg)
/* %o0: address of CCB array
* %o1: size (in bytes) of CCB array
* %o2: flags
* %o3: reserved
*
* returns:
* %o0: status
* %o1: size (in bytes) of the CCB array that was accepted
* %o2: status data
* %o3: reserved
*/
ENTRY(sun4v_ccb_submit)
mov %o5, %g1
mov HV_CCB_SUBMIT, %o5
ta HV_FAST_TRAP
stx %o1, [%o4]
retl
stx %o2, [%g1]
ENDPROC(sun4v_ccb_submit)
EXPORT_SYMBOL(sun4v_ccb_submit)
/* %o0: completion area ra for the ccb to get info
*
* returns:
* %o0: status
* %o1: CCB state
* %o2: position
* %o3: dax unit
* %o4: queue
*/
ENTRY(sun4v_ccb_info)
mov %o1, %g1
mov HV_CCB_INFO, %o5
ta HV_FAST_TRAP
sth %o1, [%g1 + CCB_INFO_OFFSET_CCB_STATE]
sth %o2, [%g1 + CCB_INFO_OFFSET_QUEUE_POS]
sth %o3, [%g1 + CCB_INFO_OFFSET_DAX_UNIT]
retl
sth %o4, [%g1 + CCB_INFO_OFFSET_QUEUE_NUM]
ENDPROC(sun4v_ccb_info)
EXPORT_SYMBOL(sun4v_ccb_info)
/* %o0: completion area ra for the ccb to kill
*
* returns:
* %o0: status
* %o1: result of the kill
*/
ENTRY(sun4v_ccb_kill)
mov %o1, %g1
mov HV_CCB_KILL, %o5
ta HV_FAST_TRAP
retl
sth %o1, [%g1]
ENDPROC(sun4v_ccb_kill)
EXPORT_SYMBOL(sun4v_ccb_kill)
...@@ -70,5 +70,13 @@ config DISPLAY7SEG ...@@ -70,5 +70,13 @@ config DISPLAY7SEG
another UltraSPARC-IIi-cEngine boardset with a 7-segment display, another UltraSPARC-IIi-cEngine boardset with a 7-segment display,
you should say N to this option. you should say N to this option.
config ORACLE_DAX
tristate "Oracle Data Analytics Accelerator"
default m if SPARC64
help
Driver for Oracle Data Analytics Accelerator, which is
a coprocessor that performs database operations in hardware.
It is available on M7 and M8 based systems only.
endmenu endmenu
...@@ -17,3 +17,4 @@ obj-$(CONFIG_SUN_OPENPROMIO) += openprom.o ...@@ -17,3 +17,4 @@ obj-$(CONFIG_SUN_OPENPROMIO) += openprom.o
obj-$(CONFIG_TADPOLE_TS102_UCTRL) += uctrl.o obj-$(CONFIG_TADPOLE_TS102_UCTRL) += uctrl.o
obj-$(CONFIG_SUN_JSFLASH) += jsflash.o obj-$(CONFIG_SUN_JSFLASH) += jsflash.o
obj-$(CONFIG_BBC_I2C) += bbc.o obj-$(CONFIG_BBC_I2C) += bbc.o
obj-$(CONFIG_ORACLE_DAX) += oradax.o
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment