selftests/powerpc: Add header files for NX compresion/decompression
Add files to be able to compress and decompress files using the powerpc NX-GZIP engine. Signed-off-by: Bulent Abali <abali@us.ibm.com> Signed-off-by: Raphael Moreira Zinsly <rzinsly@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20200420205538.25181-3-rzinsly@linux.ibm.com
This commit is contained in:
parent
d53979b589
commit
f49b75724c
|
@ -0,0 +1,56 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/* From asm-compat.h */
|
||||
#define __stringify_in_c(...) #__VA_ARGS__
|
||||
#define stringify_in_c(...) __stringify_in_c(__VA_ARGS__) " "
|
||||
|
||||
/*
|
||||
* Macros taken from arch/powerpc/include/asm/ppc-opcode.h and other
|
||||
* header files.
|
||||
*/
|
||||
#define ___PPC_RA(a) (((a) & 0x1f) << 16)
|
||||
#define ___PPC_RB(b) (((b) & 0x1f) << 11)
|
||||
|
||||
#define PPC_INST_COPY 0x7c20060c
|
||||
#define PPC_INST_PASTE 0x7c20070d
|
||||
|
||||
#define PPC_COPY(a, b) stringify_in_c(.long PPC_INST_COPY | \
|
||||
___PPC_RA(a) | ___PPC_RB(b))
|
||||
#define PPC_PASTE(a, b) stringify_in_c(.long PPC_INST_PASTE | \
|
||||
___PPC_RA(a) | ___PPC_RB(b))
|
||||
#define CR0_SHIFT 28
|
||||
#define CR0_MASK 0xF
|
||||
/*
|
||||
* Copy/paste instructions:
|
||||
*
|
||||
* copy RA,RB
|
||||
* Copy contents of address (RA) + effective_address(RB)
|
||||
* to internal copy-buffer.
|
||||
*
|
||||
* paste RA,RB
|
||||
* Paste contents of internal copy-buffer to the address
|
||||
* (RA) + effective_address(RB)
|
||||
*/
|
||||
static inline int vas_copy(void *crb, int offset)
|
||||
{
|
||||
asm volatile(PPC_COPY(%0, %1)";"
|
||||
:
|
||||
: "b" (offset), "b" (crb)
|
||||
: "memory");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int vas_paste(void *paste_address, int offset)
|
||||
{
|
||||
__u32 cr;
|
||||
|
||||
cr = 0;
|
||||
asm volatile(PPC_PASTE(%1, %2)";"
|
||||
"mfocrf %0, 0x80;"
|
||||
: "=r" (cr)
|
||||
: "b" (offset), "b" (paste_address)
|
||||
: "memory", "cr0");
|
||||
|
||||
return (cr >> CR0_SHIFT) & CR0_MASK;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright 2020 IBM Corporation
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NXU_DBG_H_
|
||||
#define _NXU_DBG_H_
|
||||
|
||||
#include <sys/file.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
extern FILE * nx_gzip_log;
|
||||
extern int nx_gzip_trace;
|
||||
extern unsigned int nx_gzip_inflate_impl;
|
||||
extern unsigned int nx_gzip_deflate_impl;
|
||||
extern unsigned int nx_gzip_inflate_flags;
|
||||
extern unsigned int nx_gzip_deflate_flags;
|
||||
|
||||
extern int nx_dbg;
|
||||
pthread_mutex_t mutex_log;
|
||||
|
||||
#define nx_gzip_trace_enabled() (nx_gzip_trace & 0x1)
|
||||
#define nx_gzip_hw_trace_enabled() (nx_gzip_trace & 0x2)
|
||||
#define nx_gzip_sw_trace_enabled() (nx_gzip_trace & 0x4)
|
||||
#define nx_gzip_gather_statistics() (nx_gzip_trace & 0x8)
|
||||
#define nx_gzip_per_stream_stat() (nx_gzip_trace & 0x10)
|
||||
|
||||
#define prt(fmt, ...) do { \
|
||||
pthread_mutex_lock(&mutex_log); \
|
||||
flock(nx_gzip_log->_fileno, LOCK_EX); \
|
||||
time_t t; struct tm *m; time(&t); m = localtime(&t); \
|
||||
fprintf(nx_gzip_log, "[%04d/%02d/%02d %02d:%02d:%02d] " \
|
||||
"pid %d: " fmt, \
|
||||
(int)m->tm_year + 1900, (int)m->tm_mon+1, (int)m->tm_mday, \
|
||||
(int)m->tm_hour, (int)m->tm_min, (int)m->tm_sec, \
|
||||
(int)getpid(), ## __VA_ARGS__); \
|
||||
fflush(nx_gzip_log); \
|
||||
flock(nx_gzip_log->_fileno, LOCK_UN); \
|
||||
pthread_mutex_unlock(&mutex_log); \
|
||||
} while (0)
|
||||
|
||||
/* Use in case of an error */
|
||||
#define prt_err(fmt, ...) do { if (nx_dbg >= 0) { \
|
||||
prt("%s:%u: Error: "fmt, \
|
||||
__FILE__, __LINE__, ## __VA_ARGS__); \
|
||||
}} while (0)
|
||||
|
||||
/* Use in case of an warning */
|
||||
#define prt_warn(fmt, ...) do { if (nx_dbg >= 1) { \
|
||||
prt("%s:%u: Warning: "fmt, \
|
||||
__FILE__, __LINE__, ## __VA_ARGS__); \
|
||||
}} while (0)
|
||||
|
||||
/* Informational printouts */
|
||||
#define prt_info(fmt, ...) do { if (nx_dbg >= 2) { \
|
||||
prt("Info: "fmt, ## __VA_ARGS__); \
|
||||
}} while (0)
|
||||
|
||||
/* Trace zlib wrapper code */
|
||||
#define prt_trace(fmt, ...) do { if (nx_gzip_trace_enabled()) { \
|
||||
prt("### "fmt, ## __VA_ARGS__); \
|
||||
}} while (0)
|
||||
|
||||
/* Trace statistics */
|
||||
#define prt_stat(fmt, ...) do { if (nx_gzip_gather_statistics()) { \
|
||||
prt("### "fmt, ## __VA_ARGS__); \
|
||||
}} while (0)
|
||||
|
||||
/* Trace zlib hardware implementation */
|
||||
#define hw_trace(fmt, ...) do { \
|
||||
if (nx_gzip_hw_trace_enabled()) \
|
||||
fprintf(nx_gzip_log, "hhh " fmt, ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
/* Trace zlib software implementation */
|
||||
#define sw_trace(fmt, ...) do { \
|
||||
if (nx_gzip_sw_trace_enabled()) \
|
||||
fprintf(nx_gzip_log, "sss " fmt, ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* str_to_num - Convert string into number and copy with endings like
|
||||
* KiB for kilobyte
|
||||
* MiB for megabyte
|
||||
* GiB for gigabyte
|
||||
*/
|
||||
uint64_t str_to_num(char *str);
|
||||
void nx_lib_debug(int onoff);
|
||||
|
||||
#endif /* _NXU_DBG_H_ */
|
|
@ -0,0 +1,650 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Hardware interface of the NX-GZIP compression accelerator
|
||||
*
|
||||
* Copyright (C) IBM Corporation, 2020
|
||||
*
|
||||
* Author: Bulent Abali <abali@us.ibm.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NXU_H
|
||||
#define _NXU_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
#include "nx.h"
|
||||
|
||||
/* deflate */
|
||||
#define LLSZ 286
|
||||
#define DSZ 30
|
||||
|
||||
/* nx */
|
||||
#define DHTSZ 18
|
||||
#define DHT_MAXSZ 288
|
||||
#define MAX_DDE_COUNT 256
|
||||
|
||||
/* util */
|
||||
#ifdef NXDBG
|
||||
#define NXPRT(X) X
|
||||
#else
|
||||
#define NXPRT(X)
|
||||
#endif
|
||||
|
||||
#ifdef NXTIMER
|
||||
#include <sys/platform/ppc.h>
|
||||
#define NX_CLK(X) X
|
||||
#define nx_get_time() __ppc_get_timebase()
|
||||
#define nx_get_freq() __ppc_get_timebase_freq()
|
||||
#else
|
||||
#define NX_CLK(X)
|
||||
#define nx_get_time() (-1)
|
||||
#define nx_get_freq() (-1)
|
||||
#endif
|
||||
|
||||
#define NX_MAX_FAULTS 500
|
||||
|
||||
/*
|
||||
* Definitions of acronyms used here. See
|
||||
* P9 NX Gzip Accelerator User's Manual for details:
|
||||
* https://github.com/libnxz/power-gzip/blob/develop/doc/power_nx_gzip_um.pdf
|
||||
*
|
||||
* adler/crc: 32 bit checksums appended to stream tail
|
||||
* ce: completion extension
|
||||
* cpb: coprocessor parameter block (metadata)
|
||||
* crb: coprocessor request block (command)
|
||||
* csb: coprocessor status block (status)
|
||||
* dht: dynamic huffman table
|
||||
* dde: data descriptor element (address, length)
|
||||
* ddl: list of ddes
|
||||
* dh/fh: dynamic and fixed huffman types
|
||||
* fc: coprocessor function code
|
||||
* histlen: history/dictionary length
|
||||
* history: sliding window of up to 32KB of data
|
||||
* lzcount: Deflate LZ symbol counts
|
||||
* rembytecnt: remaining byte count
|
||||
* sfbt: source final block type; last block's type during decomp
|
||||
* spbc: source processed byte count
|
||||
* subc: source unprocessed bit count
|
||||
* tebc: target ending bit count; valid bits in the last byte
|
||||
* tpbc: target processed byte count
|
||||
* vas: virtual accelerator switch; the user mode interface
|
||||
*/
|
||||
|
||||
union nx_qw_t {
|
||||
uint32_t word[4];
|
||||
uint64_t dword[2];
|
||||
} __aligned(16);
|
||||
|
||||
/*
|
||||
* Note: NX registers with fewer than 32 bits are declared by
|
||||
* convention as uint32_t variables in unions. If *_offset and *_mask
|
||||
* are defined for a variable, then use get_ put_ macros to
|
||||
* conveniently access the register fields for endian conversions.
|
||||
*/
|
||||
|
||||
struct nx_dde_t {
|
||||
/* Data Descriptor Element, Section 6.4 */
|
||||
union {
|
||||
uint32_t dde_count;
|
||||
/* When dde_count == 0 ddead is a pointer to a data buffer;
|
||||
* ddebc is the buffer length bytes.
|
||||
* When dde_count > 0 dde is an indirect dde; ddead is a
|
||||
* pointer to a contiguous list of direct ddes; ddebc is the
|
||||
* total length of all data pointed to by the list of direct
|
||||
* ddes. Note that only one level of indirection is permitted.
|
||||
* See Section 6.4 of the user manual for additional details.
|
||||
*/
|
||||
};
|
||||
uint32_t ddebc; /* dde byte count */
|
||||
uint64_t ddead; /* dde address */
|
||||
} __aligned(16);
|
||||
|
||||
struct nx_csb_t {
|
||||
/* Coprocessor Status Block, Section 6.6 */
|
||||
union {
|
||||
uint32_t csb_v;
|
||||
/* Valid bit. v must be set to 0 by the program
|
||||
* before submitting the coprocessor command.
|
||||
* Software can poll for the v bit
|
||||
*/
|
||||
|
||||
uint32_t csb_f;
|
||||
/* 16B CSB size. Written to 0 by DMA when it writes the CPB */
|
||||
|
||||
uint32_t csb_cs;
|
||||
/* cs completion sequence; unused */
|
||||
|
||||
uint32_t csb_cc;
|
||||
/* cc completion code; cc != 0 exception occurred */
|
||||
|
||||
uint32_t csb_ce;
|
||||
/* ce completion extension */
|
||||
|
||||
};
|
||||
uint32_t tpbc;
|
||||
/* target processed byte count TPBC */
|
||||
|
||||
uint64_t fsaddr;
|
||||
/* Section 6.12.1 CSB NonZero error summary. FSA Failing storage
|
||||
* address. Address where error occurred. When available, written
|
||||
* to A field of CSB
|
||||
*/
|
||||
} __aligned(16);
|
||||
|
||||
struct nx_ccb_t {
|
||||
/* Coprocessor Completion Block, Section 6.7 */
|
||||
|
||||
uint32_t reserved[3];
|
||||
union {
|
||||
/* When crb.c==0 (no ccb defined) it is reserved;
|
||||
* When crb.c==1 (ccb defined) it is cm
|
||||
*/
|
||||
|
||||
uint32_t ccb_cm;
|
||||
/* Signal interrupt of crb.c==1 and cm==1 */
|
||||
|
||||
uint32_t word;
|
||||
/* generic access to the 32bit word */
|
||||
};
|
||||
} __aligned(16);
|
||||
|
||||
struct vas_stamped_crb_t {
|
||||
/*
|
||||
* CRB operand of the paste coprocessor instruction is stamped
|
||||
* in quadword 4 with the information shown here as its written
|
||||
* in to the receive FIFO of the coprocessor
|
||||
*/
|
||||
|
||||
union {
|
||||
uint32_t vas_buf_num;
|
||||
/* Verification only vas buffer number which correlates to
|
||||
* the low order bits of the atag in the paste command
|
||||
*/
|
||||
|
||||
uint32_t send_wc_id;
|
||||
/* Pointer to Send Window Context that provides for NX address
|
||||
* translation information, such as MSR and LPCR bits, job
|
||||
* completion interrupt RA, PSWID, and job utilization counter.
|
||||
*/
|
||||
|
||||
};
|
||||
union {
|
||||
uint32_t recv_wc_id;
|
||||
/* Pointer to Receive Window Context. NX uses this to return
|
||||
* credits to a Receive FIFO as entries are dequeued.
|
||||
*/
|
||||
|
||||
};
|
||||
uint32_t reserved2;
|
||||
union {
|
||||
uint32_t vas_invalid;
|
||||
/* Invalid bit. If this bit is 1 the CRB is discarded by
|
||||
* NX upon fetching from the receive FIFO. If this bit is 0
|
||||
* the CRB is processed normally. The bit is stamped to 0
|
||||
* by VAS and may be written to 1 by hypervisor while
|
||||
* the CRB is in the receive FIFO (in memory).
|
||||
*/
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
struct nx_stamped_fault_crb_t {
|
||||
/*
|
||||
* A CRB that has a translation fault is stamped by NX in quadword 4
|
||||
* and pasted to the Fault Send Window in VAS.
|
||||
*/
|
||||
uint64_t fsa;
|
||||
union {
|
||||
uint32_t nxsf_t;
|
||||
uint32_t nxsf_fs;
|
||||
};
|
||||
uint32_t pswid;
|
||||
};
|
||||
|
||||
union stamped_crb_t {
|
||||
struct vas_stamped_crb_t vas;
|
||||
struct nx_stamped_fault_crb_t nx;
|
||||
};
|
||||
|
||||
struct nx_gzip_cpb_t {
|
||||
/*
|
||||
* Coprocessor Parameter Block In/Out are used to pass metadata
|
||||
* to/from accelerator. Tables 6.5 and 6.6 of the user manual.
|
||||
*/
|
||||
|
||||
/* CPBInput */
|
||||
|
||||
struct {
|
||||
union {
|
||||
union nx_qw_t qw0;
|
||||
struct {
|
||||
uint32_t in_adler; /* bits 0:31 */
|
||||
uint32_t in_crc; /* bits 32:63 */
|
||||
union {
|
||||
uint32_t in_histlen; /* bits 64:75 */
|
||||
uint32_t in_subc; /* bits 93:95 */
|
||||
};
|
||||
union {
|
||||
/* bits 108:111 */
|
||||
uint32_t in_sfbt;
|
||||
/* bits 112:127 */
|
||||
uint32_t in_rembytecnt;
|
||||
/* bits 116:127 */
|
||||
uint32_t in_dhtlen;
|
||||
};
|
||||
};
|
||||
};
|
||||
union {
|
||||
union nx_qw_t in_dht[DHTSZ]; /* qw[1:18] */
|
||||
char in_dht_char[DHT_MAXSZ]; /* byte access */
|
||||
};
|
||||
union nx_qw_t reserved[5]; /* qw[19:23] */
|
||||
};
|
||||
|
||||
/* CPBOutput */
|
||||
|
||||
volatile struct {
|
||||
union {
|
||||
union nx_qw_t qw24;
|
||||
struct {
|
||||
uint32_t out_adler; /* bits 0:31 qw[24] */
|
||||
uint32_t out_crc; /* bits 32:63 qw[24] */
|
||||
union {
|
||||
/* bits 77:79 qw[24] */
|
||||
uint32_t out_tebc;
|
||||
/* bits 80:95 qw[24] */
|
||||
uint32_t out_subc;
|
||||
};
|
||||
union {
|
||||
/* bits 108:111 qw[24] */
|
||||
uint32_t out_sfbt;
|
||||
/* bits 112:127 qw[24] */
|
||||
uint32_t out_rembytecnt;
|
||||
/* bits 116:127 qw[24] */
|
||||
uint32_t out_dhtlen;
|
||||
};
|
||||
};
|
||||
};
|
||||
union {
|
||||
union nx_qw_t qw25[79]; /* qw[25:103] */
|
||||
/* qw[25] compress no lzcounts or wrap */
|
||||
uint32_t out_spbc_comp_wrap;
|
||||
uint32_t out_spbc_wrap; /* qw[25] wrap */
|
||||
/* qw[25] compress no lzcounts */
|
||||
uint32_t out_spbc_comp;
|
||||
/* 286 LL and 30 D symbol counts */
|
||||
uint32_t out_lzcount[LLSZ+DSZ];
|
||||
struct {
|
||||
union nx_qw_t out_dht[DHTSZ]; /* qw[25:42] */
|
||||
/* qw[43] decompress */
|
||||
uint32_t out_spbc_decomp;
|
||||
};
|
||||
};
|
||||
/* qw[104] compress with lzcounts */
|
||||
uint32_t out_spbc_comp_with_count;
|
||||
};
|
||||
} __aligned(128);
|
||||
|
||||
struct nx_gzip_crb_t {
|
||||
union { /* byte[0:3] */
|
||||
uint32_t gzip_fc; /* bits[24-31] */
|
||||
};
|
||||
uint32_t reserved1; /* byte[4:7] */
|
||||
union {
|
||||
uint64_t csb_address; /* byte[8:15] */
|
||||
struct {
|
||||
uint32_t reserved2;
|
||||
union {
|
||||
uint32_t crb_c;
|
||||
/* c==0 no ccb defined */
|
||||
|
||||
uint32_t crb_at;
|
||||
/* at==0 address type is ignored;
|
||||
* all addrs effective assumed.
|
||||
*/
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
struct nx_dde_t source_dde; /* byte[16:31] */
|
||||
struct nx_dde_t target_dde; /* byte[32:47] */
|
||||
volatile struct nx_ccb_t ccb; /* byte[48:63] */
|
||||
volatile union {
|
||||
/* byte[64:239] shift csb by 128 bytes out of the crb; csb was
|
||||
* in crb earlier; JReilly says csb written with partial inject
|
||||
*/
|
||||
union nx_qw_t reserved64[11];
|
||||
union stamped_crb_t stamp; /* byte[64:79] */
|
||||
};
|
||||
volatile struct nx_csb_t csb;
|
||||
} __aligned(128);
|
||||
|
||||
struct nx_gzip_crb_cpb_t {
|
||||
struct nx_gzip_crb_t crb;
|
||||
struct nx_gzip_cpb_t cpb;
|
||||
} __aligned(2048);
|
||||
|
||||
|
||||
/*
|
||||
* NX hardware convention has the msb bit on the left numbered 0.
|
||||
* The defines below has *_offset defined as the right most bit
|
||||
* position of a field. x of size_mask(x) is the field width in bits.
|
||||
*/
|
||||
|
||||
#define size_mask(x) ((1U<<(x))-1)
|
||||
|
||||
/*
|
||||
* Offsets and Widths within the containing 32 bits of the various NX
|
||||
* gzip hardware registers. Use the getnn/putnn macros to access
|
||||
* these regs
|
||||
*/
|
||||
|
||||
#define dde_count_mask size_mask(8)
|
||||
#define dde_count_offset 23
|
||||
|
||||
/* CSB */
|
||||
|
||||
#define csb_v_mask size_mask(1)
|
||||
#define csb_v_offset 0
|
||||
#define csb_f_mask size_mask(1)
|
||||
#define csb_f_offset 6
|
||||
#define csb_cs_mask size_mask(8)
|
||||
#define csb_cs_offset 15
|
||||
#define csb_cc_mask size_mask(8)
|
||||
#define csb_cc_offset 23
|
||||
#define csb_ce_mask size_mask(8)
|
||||
#define csb_ce_offset 31
|
||||
|
||||
/* CCB */
|
||||
|
||||
#define ccb_cm_mask size_mask(3)
|
||||
#define ccb_cm_offset 31
|
||||
|
||||
/* VAS stamped CRB fields */
|
||||
|
||||
#define vas_buf_num_mask size_mask(6)
|
||||
#define vas_buf_num_offset 5
|
||||
#define send_wc_id_mask size_mask(16)
|
||||
#define send_wc_id_offset 31
|
||||
#define recv_wc_id_mask size_mask(16)
|
||||
#define recv_wc_id_offset 31
|
||||
#define vas_invalid_mask size_mask(1)
|
||||
#define vas_invalid_offset 31
|
||||
|
||||
/* NX stamped fault CRB fields */
|
||||
|
||||
#define nxsf_t_mask size_mask(1)
|
||||
#define nxsf_t_offset 23
|
||||
#define nxsf_fs_mask size_mask(8)
|
||||
#define nxsf_fs_offset 31
|
||||
|
||||
/* CPB input */
|
||||
|
||||
#define in_histlen_mask size_mask(12)
|
||||
#define in_histlen_offset 11
|
||||
#define in_dhtlen_mask size_mask(12)
|
||||
#define in_dhtlen_offset 31
|
||||
#define in_subc_mask size_mask(3)
|
||||
#define in_subc_offset 31
|
||||
#define in_sfbt_mask size_mask(4)
|
||||
#define in_sfbt_offset 15
|
||||
#define in_rembytecnt_mask size_mask(16)
|
||||
#define in_rembytecnt_offset 31
|
||||
|
||||
/* CPB output */
|
||||
|
||||
#define out_tebc_mask size_mask(3)
|
||||
#define out_tebc_offset 15
|
||||
#define out_subc_mask size_mask(16)
|
||||
#define out_subc_offset 31
|
||||
#define out_sfbt_mask size_mask(4)
|
||||
#define out_sfbt_offset 15
|
||||
#define out_rembytecnt_mask size_mask(16)
|
||||
#define out_rembytecnt_offset 31
|
||||
#define out_dhtlen_mask size_mask(12)
|
||||
#define out_dhtlen_offset 31
|
||||
|
||||
/* CRB */
|
||||
|
||||
#define gzip_fc_mask size_mask(8)
|
||||
#define gzip_fc_offset 31
|
||||
#define crb_c_mask size_mask(1)
|
||||
#define crb_c_offset 28
|
||||
#define crb_at_mask size_mask(1)
|
||||
#define crb_at_offset 30
|
||||
#define csb_address_mask ~(15UL) /* mask off bottom 4b */
|
||||
|
||||
/*
|
||||
* Access macros for the registers. Do not access registers directly
|
||||
* because of the endian conversion. P9 processor may run either as
|
||||
* Little or Big endian. However the NX coprocessor regs are always
|
||||
* big endian.
|
||||
* Use the 32 and 64b macros to access respective
|
||||
* register sizes.
|
||||
* Use nn forms for the register fields shorter than 32 bits.
|
||||
*/
|
||||
|
||||
#define getnn(ST, REG) ((be32toh(ST.REG) >> (31-REG##_offset)) \
|
||||
& REG##_mask)
|
||||
#define getpnn(ST, REG) ((be32toh((ST)->REG) >> (31-REG##_offset)) \
|
||||
& REG##_mask)
|
||||
#define get32(ST, REG) (be32toh(ST.REG))
|
||||
#define getp32(ST, REG) (be32toh((ST)->REG))
|
||||
#define get64(ST, REG) (be64toh(ST.REG))
|
||||
#define getp64(ST, REG) (be64toh((ST)->REG))
|
||||
|
||||
#define unget32(ST, REG) (get32(ST, REG) & ~((REG##_mask) \
|
||||
<< (31-REG##_offset)))
|
||||
/* get 32bits less the REG field */
|
||||
|
||||
#define ungetp32(ST, REG) (getp32(ST, REG) & ~((REG##_mask) \
|
||||
<< (31-REG##_offset)))
|
||||
/* get 32bits less the REG field */
|
||||
|
||||
#define clear_regs(ST) memset((void *)(&(ST)), 0, sizeof(ST))
|
||||
#define clear_dde(ST) do { ST.dde_count = ST.ddebc = 0; ST.ddead = 0; \
|
||||
} while (0)
|
||||
#define clearp_dde(ST) do { (ST)->dde_count = (ST)->ddebc = 0; \
|
||||
(ST)->ddead = 0; \
|
||||
} while (0)
|
||||
#define clear_struct(ST) memset((void *)(&(ST)), 0, sizeof(ST))
|
||||
#define putnn(ST, REG, X) (ST.REG = htobe32(unget32(ST, REG) | (((X) \
|
||||
& REG##_mask) << (31-REG##_offset))))
|
||||
#define putpnn(ST, REG, X) ((ST)->REG = htobe32(ungetp32(ST, REG) \
|
||||
| (((X) & REG##_mask) << (31-REG##_offset))))
|
||||
|
||||
#define put32(ST, REG, X) (ST.REG = htobe32(X))
|
||||
#define putp32(ST, REG, X) ((ST)->REG = htobe32(X))
|
||||
#define put64(ST, REG, X) (ST.REG = htobe64(X))
|
||||
#define putp64(ST, REG, X) ((ST)->REG = htobe64(X))
|
||||
|
||||
/*
|
||||
* Completion extension ce(0) ce(1) ce(2). Bits ce(3-7)
|
||||
* unused. Section 6.6 Figure 6.7.
|
||||
*/
|
||||
|
||||
#define get_csb_ce(ST) ((uint32_t)getnn(ST, csb_ce))
|
||||
#define get_csb_ce_ms3b(ST) (get_csb_ce(ST) >> 5)
|
||||
#define put_csb_ce_ms3b(ST, X) putnn(ST, csb_ce, ((uint32_t)(X) << 5))
|
||||
|
||||
#define CSB_CE_PARTIAL 0x4
|
||||
#define CSB_CE_TERMINATE 0x2
|
||||
#define CSB_CE_TPBC_VALID 0x1
|
||||
|
||||
#define csb_ce_termination(X) (!!((X) & CSB_CE_TERMINATE))
|
||||
/* termination, output buffers may be modified, SPBC/TPBC invalid Fig.6-7 */
|
||||
|
||||
#define csb_ce_check_completion(X) (!csb_ce_termination(X))
|
||||
/* if not terminated then check full or partial completion */
|
||||
|
||||
#define csb_ce_partial_completion(X) (!!((X) & CSB_CE_PARTIAL))
|
||||
#define csb_ce_full_completion(X) (!csb_ce_partial_completion(X))
|
||||
#define csb_ce_tpbc_valid(X) (!!((X) & CSB_CE_TPBC_VALID))
|
||||
/* TPBC indicates successfully stored data count */
|
||||
|
||||
#define csb_ce_default_err(X) csb_ce_termination(X)
|
||||
/* most error CEs have CE(0)=0 and CE(1)=1 */
|
||||
|
||||
#define csb_ce_cc3_partial(X) csb_ce_partial_completion(X)
|
||||
/* some CC=3 are partially completed, Table 6-8 */
|
||||
|
||||
#define csb_ce_cc64(X) ((X)&(CSB_CE_PARTIAL \
|
||||
| CSB_CE_TERMINATE) == 0)
|
||||
/* Compression: when TPBC>SPBC then CC=64 Table 6-8; target didn't
|
||||
* compress smaller than source.
|
||||
*/
|
||||
|
||||
/* Decompress SFBT combinations Tables 5-3, 6-4, 6-6 */
|
||||
|
||||
#define SFBT_BFINAL 0x1
|
||||
#define SFBT_LIT 0x4
|
||||
#define SFBT_FHT 0x5
|
||||
#define SFBT_DHT 0x6
|
||||
#define SFBT_HDR 0x7
|
||||
|
||||
/*
|
||||
* NX gzip function codes. Table 6.2.
|
||||
* Bits 0:4 are the FC. Bit 5 is used by the DMA controller to
|
||||
* select one of the two Byte Count Limits.
|
||||
*/
|
||||
|
||||
#define GZIP_FC_LIMIT_MASK 0x01
|
||||
#define GZIP_FC_COMPRESS_FHT 0x00
|
||||
#define GZIP_FC_COMPRESS_DHT 0x02
|
||||
#define GZIP_FC_COMPRESS_FHT_COUNT 0x04
|
||||
#define GZIP_FC_COMPRESS_DHT_COUNT 0x06
|
||||
#define GZIP_FC_COMPRESS_RESUME_FHT 0x08
|
||||
#define GZIP_FC_COMPRESS_RESUME_DHT 0x0a
|
||||
#define GZIP_FC_COMPRESS_RESUME_FHT_COUNT 0x0c
|
||||
#define GZIP_FC_COMPRESS_RESUME_DHT_COUNT 0x0e
|
||||
#define GZIP_FC_DECOMPRESS 0x10
|
||||
#define GZIP_FC_DECOMPRESS_SINGLE_BLK_N_SUSPEND 0x12
|
||||
#define GZIP_FC_DECOMPRESS_RESUME 0x14
|
||||
#define GZIP_FC_DECOMPRESS_RESUME_SINGLE_BLK_N_SUSPEND 0x16
|
||||
#define GZIP_FC_WRAP 0x1e
|
||||
|
||||
#define fc_is_compress(fc) (((fc) & 0x10) == 0)
|
||||
#define fc_has_count(fc) (fc_is_compress(fc) && (((fc) & 0x4) != 0))
|
||||
|
||||
/* CSB.CC Error codes */
|
||||
|
||||
#define ERR_NX_OK 0
|
||||
#define ERR_NX_ALIGNMENT 1
|
||||
#define ERR_NX_OPOVERLAP 2
|
||||
#define ERR_NX_DATA_LENGTH 3
|
||||
#define ERR_NX_TRANSLATION 5
|
||||
#define ERR_NX_PROTECTION 6
|
||||
#define ERR_NX_EXTERNAL_UE7 7
|
||||
#define ERR_NX_INVALID_OP 8
|
||||
#define ERR_NX_PRIVILEGE 9
|
||||
#define ERR_NX_INTERNAL_UE 10
|
||||
#define ERR_NX_EXTERN_UE_WR 12
|
||||
#define ERR_NX_TARGET_SPACE 13
|
||||
#define ERR_NX_EXCESSIVE_DDE 14
|
||||
#define ERR_NX_TRANSL_WR 15
|
||||
#define ERR_NX_PROTECT_WR 16
|
||||
#define ERR_NX_SUBFUNCTION 17
|
||||
#define ERR_NX_FUNC_ABORT 18
|
||||
#define ERR_NX_BYTE_MAX 19
|
||||
#define ERR_NX_CORRUPT_CRB 20
|
||||
#define ERR_NX_INVALID_CRB 21
|
||||
#define ERR_NX_INVALID_DDE 30
|
||||
#define ERR_NX_SEGMENTED_DDL 31
|
||||
#define ERR_NX_DDE_OVERFLOW 33
|
||||
#define ERR_NX_TPBC_GT_SPBC 64
|
||||
#define ERR_NX_MISSING_CODE 66
|
||||
#define ERR_NX_INVALID_DIST 67
|
||||
#define ERR_NX_INVALID_DHT 68
|
||||
#define ERR_NX_EXTERNAL_UE90 90
|
||||
#define ERR_NX_WDOG_TIMER 224
|
||||
#define ERR_NX_AT_FAULT 250
|
||||
#define ERR_NX_INTR_SERVER 252
|
||||
#define ERR_NX_UE253 253
|
||||
#define ERR_NX_NO_HW 254
|
||||
#define ERR_NX_HUNG_OP 255
|
||||
#define ERR_NX_END 256
|
||||
|
||||
/* initial values for non-resume operations */
|
||||
#define INIT_CRC 0 /* crc32(0L, Z_NULL, 0) */
|
||||
#define INIT_ADLER 1 /* adler32(0L, Z_NULL, 0) adler is initialized to 1 */
|
||||
|
||||
/* prototypes */
|
||||
int nxu_submit_job(struct nx_gzip_crb_cpb_t *c, void *handle);
|
||||
|
||||
extern void nxu_sigsegv_handler(int sig, siginfo_t *info, void *ctx);
|
||||
extern int nxu_touch_pages(void *buf, long buf_len, long page_len, int wr);
|
||||
|
||||
/* caller supplies a print buffer 4*sizeof(crb) */
|
||||
|
||||
char *nx_crb_str(struct nx_gzip_crb_t *crb, char *prbuf);
|
||||
char *nx_cpb_str(struct nx_gzip_cpb_t *cpb, char *prbuf);
|
||||
char *nx_prt_hex(void *cp, int sz, char *prbuf);
|
||||
char *nx_lzcount_str(struct nx_gzip_cpb_t *cpb, char *prbuf);
|
||||
char *nx_strerror(int e);
|
||||
|
||||
#ifdef NX_SIM
|
||||
#include <stdio.h>
|
||||
int nx_sim_init(void *ctx);
|
||||
int nx_sim_end(void *ctx);
|
||||
int nxu_run_sim_job(struct nx_gzip_crb_cpb_t *c, void *ctx);
|
||||
#endif /* NX_SIM */
|
||||
|
||||
/* Deflate stream manipulation */
|
||||
|
||||
#define set_final_bit(x) (x |= (unsigned char)1)
|
||||
#define clr_final_bit(x) (x &= ~(unsigned char)1)
|
||||
|
||||
#define append_empty_fh_blk(p, b) do { *(p) = (2 | (1&(b))); *((p)+1) = 0; \
|
||||
} while (0)
|
||||
/* append 10 bits 0000001b 00...... ;
|
||||
* assumes appending starts on a byte boundary; b is the final bit.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef NX_842
|
||||
|
||||
/* 842 Engine */
|
||||
|
||||
struct nx_eft_crb_t {
|
||||
union { /* byte[0:3] */
|
||||
uint32_t eft_fc; /* bits[29-31] */
|
||||
};
|
||||
uint32_t reserved1; /* byte[4:7] */
|
||||
union {
|
||||
uint64_t csb_address; /* byte[8:15] */
|
||||
struct {
|
||||
uint32_t reserved2;
|
||||
union {
|
||||
uint32_t crb_c;
|
||||
/* c==0 no ccb defined */
|
||||
|
||||
uint32_t crb_at;
|
||||
/* at==0 address type is ignored;
|
||||
* all addrs effective assumed.
|
||||
*/
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
struct nx_dde_t source_dde; /* byte[16:31] */
|
||||
struct nx_dde_t target_dde; /* byte[32:47] */
|
||||
struct nx_ccb_t ccb; /* byte[48:63] */
|
||||
union {
|
||||
union nx_qw_t reserved64[3]; /* byte[64:96] */
|
||||
};
|
||||
struct nx_csb_t csb;
|
||||
} __aligned(128);
|
||||
|
||||
/* 842 CRB */
|
||||
|
||||
#define EFT_FC_MASK size_mask(3)
|
||||
#define EFT_FC_OFFSET 31
|
||||
#define EFT_FC_COMPRESS 0x0
|
||||
#define EFT_FC_COMPRESS_WITH_CRC 0x1
|
||||
#define EFT_FC_DECOMPRESS 0x2
|
||||
#define EFT_FC_DECOMPRESS_WITH_CRC 0x3
|
||||
#define EFT_FC_BLK_DATA_MOVE 0x4
|
||||
#endif /* NX_842 */
|
||||
|
||||
#endif /* _NXU_H */
|
Loading…
Reference in New Issue