162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Hardware interface of the NX-GZIP compression accelerator
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) IBM Corporation, 2020
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Author: Bulent Abali <abali@us.ibm.com>
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef _NXU_H
1262306a36Sopenharmony_ci#define _NXU_H
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <stdint.h>
1562306a36Sopenharmony_ci#include <endian.h>
1662306a36Sopenharmony_ci#include "nx.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* deflate */
1962306a36Sopenharmony_ci#define LLSZ   286
2062306a36Sopenharmony_ci#define DSZ    30
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/* nx */
2362306a36Sopenharmony_ci#define DHTSZ  18
2462306a36Sopenharmony_ci#define DHT_MAXSZ 288
2562306a36Sopenharmony_ci#define MAX_DDE_COUNT 256
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/* util */
2862306a36Sopenharmony_ci#ifdef NXDBG
2962306a36Sopenharmony_ci#define NXPRT(X)	X
3062306a36Sopenharmony_ci#else
3162306a36Sopenharmony_ci#define NXPRT(X)
3262306a36Sopenharmony_ci#endif
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#ifdef NXTIMER
3562306a36Sopenharmony_ci#include <sys/platform/ppc.h>
3662306a36Sopenharmony_ci#define NX_CLK(X)	X
3762306a36Sopenharmony_ci#define nx_get_time()	__ppc_get_timebase()
3862306a36Sopenharmony_ci#define nx_get_freq()	__ppc_get_timebase_freq()
3962306a36Sopenharmony_ci#else
4062306a36Sopenharmony_ci#define NX_CLK(X)
4162306a36Sopenharmony_ci#define nx_get_time()  (-1)
4262306a36Sopenharmony_ci#define nx_get_freq()  (-1)
4362306a36Sopenharmony_ci#endif
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#define NX_MAX_FAULTS  500
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci/*
4862306a36Sopenharmony_ci * Definitions of acronyms used here. See
4962306a36Sopenharmony_ci * P9 NX Gzip Accelerator User's Manual for details:
5062306a36Sopenharmony_ci * https://github.com/libnxz/power-gzip/blob/develop/doc/power_nx_gzip_um.pdf
5162306a36Sopenharmony_ci *
5262306a36Sopenharmony_ci * adler/crc: 32 bit checksums appended to stream tail
5362306a36Sopenharmony_ci * ce:       completion extension
5462306a36Sopenharmony_ci * cpb:      coprocessor parameter block (metadata)
5562306a36Sopenharmony_ci * crb:      coprocessor request block (command)
5662306a36Sopenharmony_ci * csb:      coprocessor status block (status)
5762306a36Sopenharmony_ci * dht:      dynamic huffman table
5862306a36Sopenharmony_ci * dde:      data descriptor element (address, length)
5962306a36Sopenharmony_ci * ddl:      list of ddes
6062306a36Sopenharmony_ci * dh/fh:    dynamic and fixed huffman types
6162306a36Sopenharmony_ci * fc:       coprocessor function code
6262306a36Sopenharmony_ci * histlen:  history/dictionary length
6362306a36Sopenharmony_ci * history:  sliding window of up to 32KB of data
6462306a36Sopenharmony_ci * lzcount:  Deflate LZ symbol counts
6562306a36Sopenharmony_ci * rembytecnt: remaining byte count
6662306a36Sopenharmony_ci * sfbt:     source final block type; last block's type during decomp
6762306a36Sopenharmony_ci * spbc:     source processed byte count
6862306a36Sopenharmony_ci * subc:     source unprocessed bit count
6962306a36Sopenharmony_ci * tebc:     target ending bit count; valid bits in the last byte
7062306a36Sopenharmony_ci * tpbc:     target processed byte count
7162306a36Sopenharmony_ci * vas:      virtual accelerator switch; the user mode interface
7262306a36Sopenharmony_ci */
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ciunion nx_qw_t {
7562306a36Sopenharmony_ci	uint32_t word[4];
7662306a36Sopenharmony_ci	uint64_t dword[2];
7762306a36Sopenharmony_ci} __aligned(16);
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci/*
8062306a36Sopenharmony_ci * Note: NX registers with fewer than 32 bits are declared by
8162306a36Sopenharmony_ci * convention as uint32_t variables in unions. If *_offset and *_mask
8262306a36Sopenharmony_ci * are defined for a variable, then use get_ put_ macros to
8362306a36Sopenharmony_ci * conveniently access the register fields for endian conversions.
8462306a36Sopenharmony_ci */
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_cistruct nx_dde_t {
8762306a36Sopenharmony_ci	/* Data Descriptor Element, Section 6.4 */
8862306a36Sopenharmony_ci	union {
8962306a36Sopenharmony_ci		uint32_t dde_count;
9062306a36Sopenharmony_ci		/* When dde_count == 0 ddead is a pointer to a data buffer;
9162306a36Sopenharmony_ci		 * ddebc is the buffer length bytes.
9262306a36Sopenharmony_ci		 * When dde_count > 0 dde is an indirect dde; ddead is a
9362306a36Sopenharmony_ci		 * pointer to a contiguous list of direct ddes; ddebc is the
9462306a36Sopenharmony_ci		 * total length of all data pointed to by the list of direct
9562306a36Sopenharmony_ci		 * ddes. Note that only one level of indirection is permitted.
9662306a36Sopenharmony_ci		 * See Section 6.4 of the user manual for additional details.
9762306a36Sopenharmony_ci		 */
9862306a36Sopenharmony_ci	};
9962306a36Sopenharmony_ci	uint32_t ddebc; /* dde byte count */
10062306a36Sopenharmony_ci	uint64_t ddead; /* dde address */
10162306a36Sopenharmony_ci} __aligned(16);
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_cistruct nx_csb_t {
10462306a36Sopenharmony_ci	/* Coprocessor Status Block, Section 6.6  */
10562306a36Sopenharmony_ci	union {
10662306a36Sopenharmony_ci		uint32_t csb_v;
10762306a36Sopenharmony_ci		/* Valid bit. v must be set to 0 by the program
10862306a36Sopenharmony_ci		 * before submitting the coprocessor command.
10962306a36Sopenharmony_ci		 * Software can poll for the v bit
11062306a36Sopenharmony_ci		 */
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci		uint32_t csb_f;
11362306a36Sopenharmony_ci		/* 16B CSB size. Written to 0 by DMA when it writes the CPB */
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci		uint32_t csb_cs;
11662306a36Sopenharmony_ci		/* cs completion sequence; unused */
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci		uint32_t csb_cc;
11962306a36Sopenharmony_ci		/* cc completion code; cc != 0 exception occurred */
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci		uint32_t csb_ce;
12262306a36Sopenharmony_ci		/* ce completion extension */
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci	};
12562306a36Sopenharmony_ci	uint32_t tpbc;
12662306a36Sopenharmony_ci	/* target processed byte count TPBC */
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	uint64_t fsaddr;
12962306a36Sopenharmony_ci	/* Section 6.12.1 CSB NonZero error summary.  FSA Failing storage
13062306a36Sopenharmony_ci	 * address.  Address where error occurred. When available, written
13162306a36Sopenharmony_ci	 * to A field of CSB
13262306a36Sopenharmony_ci	 */
13362306a36Sopenharmony_ci} __aligned(16);
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistruct nx_ccb_t {
13662306a36Sopenharmony_ci	/* Coprocessor Completion Block, Section 6.7 */
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	uint32_t reserved[3];
13962306a36Sopenharmony_ci	union {
14062306a36Sopenharmony_ci		/* When crb.c==0 (no ccb defined) it is reserved;
14162306a36Sopenharmony_ci		 * When crb.c==1 (ccb defined) it is cm
14262306a36Sopenharmony_ci		 */
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci		uint32_t ccb_cm;
14562306a36Sopenharmony_ci		/* Signal interrupt of crb.c==1 and cm==1 */
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci		uint32_t word;
14862306a36Sopenharmony_ci		/* generic access to the 32bit word */
14962306a36Sopenharmony_ci	};
15062306a36Sopenharmony_ci} __aligned(16);
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_cistruct vas_stamped_crb_t {
15362306a36Sopenharmony_ci	/*
15462306a36Sopenharmony_ci	 * CRB operand of the paste coprocessor instruction is stamped
15562306a36Sopenharmony_ci	 * in quadword 4 with the information shown here as its written
15662306a36Sopenharmony_ci	 * in to the receive FIFO of the coprocessor
15762306a36Sopenharmony_ci	 */
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	union {
16062306a36Sopenharmony_ci		uint32_t vas_buf_num;
16162306a36Sopenharmony_ci		/* Verification only vas buffer number which correlates to
16262306a36Sopenharmony_ci		 * the low order bits of the atag in the paste command
16362306a36Sopenharmony_ci		 */
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci		uint32_t send_wc_id;
16662306a36Sopenharmony_ci		/* Pointer to Send Window Context that provides for NX address
16762306a36Sopenharmony_ci		 * translation information, such as MSR and LPCR bits, job
16862306a36Sopenharmony_ci		 * completion interrupt RA, PSWID, and job utilization counter.
16962306a36Sopenharmony_ci		 */
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	};
17262306a36Sopenharmony_ci	union {
17362306a36Sopenharmony_ci		uint32_t recv_wc_id;
17462306a36Sopenharmony_ci		/* Pointer to Receive Window Context. NX uses this to return
17562306a36Sopenharmony_ci		 * credits to a Receive FIFO as entries are dequeued.
17662306a36Sopenharmony_ci		 */
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci	};
17962306a36Sopenharmony_ci	uint32_t reserved2;
18062306a36Sopenharmony_ci	union {
18162306a36Sopenharmony_ci		uint32_t vas_invalid;
18262306a36Sopenharmony_ci		/* Invalid bit. If this bit is 1 the CRB is discarded by
18362306a36Sopenharmony_ci		 * NX upon fetching from the receive FIFO. If this bit is 0
18462306a36Sopenharmony_ci		 * the CRB is processed normally. The bit is stamped to 0
18562306a36Sopenharmony_ci		 * by VAS and may be written to 1 by hypervisor while
18662306a36Sopenharmony_ci		 * the CRB is in the receive FIFO (in memory).
18762306a36Sopenharmony_ci		 */
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	};
19062306a36Sopenharmony_ci};
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_cistruct nx_stamped_fault_crb_t {
19362306a36Sopenharmony_ci	/*
19462306a36Sopenharmony_ci	 * A CRB that has a translation fault is stamped by NX in quadword 4
19562306a36Sopenharmony_ci	 * and pasted to the Fault Send Window in VAS.
19662306a36Sopenharmony_ci	 */
19762306a36Sopenharmony_ci	uint64_t fsa;
19862306a36Sopenharmony_ci	union {
19962306a36Sopenharmony_ci		uint32_t nxsf_t;
20062306a36Sopenharmony_ci		uint32_t nxsf_fs;
20162306a36Sopenharmony_ci	};
20262306a36Sopenharmony_ci	uint32_t pswid;
20362306a36Sopenharmony_ci};
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ciunion stamped_crb_t {
20662306a36Sopenharmony_ci	struct vas_stamped_crb_t      vas;
20762306a36Sopenharmony_ci	struct nx_stamped_fault_crb_t nx;
20862306a36Sopenharmony_ci};
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_cistruct nx_gzip_cpb_t {
21162306a36Sopenharmony_ci	/*
21262306a36Sopenharmony_ci	 * Coprocessor Parameter Block In/Out are used to pass metadata
21362306a36Sopenharmony_ci	 * to/from accelerator.  Tables 6.5 and 6.6 of the user manual.
21462306a36Sopenharmony_ci	 */
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci	/* CPBInput */
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	struct {
21962306a36Sopenharmony_ci		union {
22062306a36Sopenharmony_ci		union nx_qw_t qw0;
22162306a36Sopenharmony_ci			struct {
22262306a36Sopenharmony_ci				uint32_t in_adler;            /* bits 0:31  */
22362306a36Sopenharmony_ci				uint32_t in_crc;              /* bits 32:63 */
22462306a36Sopenharmony_ci				union {
22562306a36Sopenharmony_ci					uint32_t in_histlen;  /* bits 64:75 */
22662306a36Sopenharmony_ci					uint32_t in_subc;     /* bits 93:95 */
22762306a36Sopenharmony_ci				};
22862306a36Sopenharmony_ci				union {
22962306a36Sopenharmony_ci					/* bits 108:111 */
23062306a36Sopenharmony_ci					uint32_t in_sfbt;
23162306a36Sopenharmony_ci					/* bits 112:127 */
23262306a36Sopenharmony_ci					uint32_t in_rembytecnt;
23362306a36Sopenharmony_ci					/* bits 116:127 */
23462306a36Sopenharmony_ci					uint32_t in_dhtlen;
23562306a36Sopenharmony_ci				};
23662306a36Sopenharmony_ci			};
23762306a36Sopenharmony_ci		};
23862306a36Sopenharmony_ci		union {
23962306a36Sopenharmony_ci			union nx_qw_t  in_dht[DHTSZ];	/* qw[1:18]     */
24062306a36Sopenharmony_ci			char in_dht_char[DHT_MAXSZ];	/* byte access  */
24162306a36Sopenharmony_ci		};
24262306a36Sopenharmony_ci		union nx_qw_t  reserved[5];		/* qw[19:23]    */
24362306a36Sopenharmony_ci	};
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	/* CPBOutput */
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	volatile struct {
24862306a36Sopenharmony_ci		union {
24962306a36Sopenharmony_ci			union nx_qw_t qw24;
25062306a36Sopenharmony_ci			struct {
25162306a36Sopenharmony_ci				uint32_t out_adler;    /* bits 0:31  qw[24] */
25262306a36Sopenharmony_ci				uint32_t out_crc;      /* bits 32:63 qw[24] */
25362306a36Sopenharmony_ci				union {
25462306a36Sopenharmony_ci					/* bits 77:79 qw[24] */
25562306a36Sopenharmony_ci					uint32_t out_tebc;
25662306a36Sopenharmony_ci					/* bits 80:95 qw[24] */
25762306a36Sopenharmony_ci					uint32_t out_subc;
25862306a36Sopenharmony_ci				};
25962306a36Sopenharmony_ci				union {
26062306a36Sopenharmony_ci					/* bits 108:111 qw[24] */
26162306a36Sopenharmony_ci					uint32_t out_sfbt;
26262306a36Sopenharmony_ci					/* bits 112:127 qw[24] */
26362306a36Sopenharmony_ci					uint32_t out_rembytecnt;
26462306a36Sopenharmony_ci					/* bits 116:127 qw[24] */
26562306a36Sopenharmony_ci					uint32_t out_dhtlen;
26662306a36Sopenharmony_ci				};
26762306a36Sopenharmony_ci			};
26862306a36Sopenharmony_ci		};
26962306a36Sopenharmony_ci		union {
27062306a36Sopenharmony_ci			union nx_qw_t  qw25[79];        /* qw[25:103] */
27162306a36Sopenharmony_ci			/* qw[25] compress no lzcounts or wrap */
27262306a36Sopenharmony_ci			uint32_t out_spbc_comp_wrap;
27362306a36Sopenharmony_ci			uint32_t out_spbc_wrap;         /* qw[25] wrap */
27462306a36Sopenharmony_ci			/* qw[25] compress no lzcounts */
27562306a36Sopenharmony_ci			uint32_t out_spbc_comp;
27662306a36Sopenharmony_ci			 /* 286 LL and 30 D symbol counts */
27762306a36Sopenharmony_ci			uint32_t out_lzcount[LLSZ+DSZ];
27862306a36Sopenharmony_ci			struct {
27962306a36Sopenharmony_ci				union nx_qw_t  out_dht[DHTSZ];  /* qw[25:42] */
28062306a36Sopenharmony_ci				/* qw[43] decompress */
28162306a36Sopenharmony_ci				uint32_t out_spbc_decomp;
28262306a36Sopenharmony_ci			};
28362306a36Sopenharmony_ci		};
28462306a36Sopenharmony_ci		/* qw[104] compress with lzcounts */
28562306a36Sopenharmony_ci		uint32_t out_spbc_comp_with_count;
28662306a36Sopenharmony_ci	};
28762306a36Sopenharmony_ci} __aligned(128);
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_cistruct nx_gzip_crb_t {
29062306a36Sopenharmony_ci	union {                   /* byte[0:3]   */
29162306a36Sopenharmony_ci		uint32_t gzip_fc;     /* bits[24-31] */
29262306a36Sopenharmony_ci	};
29362306a36Sopenharmony_ci	uint32_t reserved1;       /* byte[4:7]   */
29462306a36Sopenharmony_ci	union {
29562306a36Sopenharmony_ci		uint64_t csb_address; /* byte[8:15]  */
29662306a36Sopenharmony_ci		struct {
29762306a36Sopenharmony_ci			uint32_t reserved2;
29862306a36Sopenharmony_ci			union {
29962306a36Sopenharmony_ci				uint32_t crb_c;
30062306a36Sopenharmony_ci				/* c==0 no ccb defined */
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci				uint32_t crb_at;
30362306a36Sopenharmony_ci				/* at==0 address type is ignored;
30462306a36Sopenharmony_ci				 * all addrs effective assumed.
30562306a36Sopenharmony_ci				 */
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci			};
30862306a36Sopenharmony_ci		};
30962306a36Sopenharmony_ci	};
31062306a36Sopenharmony_ci	struct nx_dde_t source_dde;           /* byte[16:31] */
31162306a36Sopenharmony_ci	struct nx_dde_t target_dde;           /* byte[32:47] */
31262306a36Sopenharmony_ci	volatile struct nx_ccb_t ccb;         /* byte[48:63] */
31362306a36Sopenharmony_ci	volatile union {
31462306a36Sopenharmony_ci		/* byte[64:239] shift csb by 128 bytes out of the crb; csb was
31562306a36Sopenharmony_ci		 * in crb earlier; JReilly says csb written with partial inject
31662306a36Sopenharmony_ci		 */
31762306a36Sopenharmony_ci		union nx_qw_t reserved64[11];
31862306a36Sopenharmony_ci		union stamped_crb_t stamp;       /* byte[64:79] */
31962306a36Sopenharmony_ci	};
32062306a36Sopenharmony_ci	volatile struct nx_csb_t csb;
32162306a36Sopenharmony_ci} __aligned(128);
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_cistruct nx_gzip_crb_cpb_t {
32462306a36Sopenharmony_ci	struct nx_gzip_crb_t crb;
32562306a36Sopenharmony_ci	struct nx_gzip_cpb_t cpb;
32662306a36Sopenharmony_ci} __aligned(2048);
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci/*
33062306a36Sopenharmony_ci * NX hardware convention has the msb bit on the left numbered 0.
33162306a36Sopenharmony_ci * The defines below has *_offset defined as the right most bit
33262306a36Sopenharmony_ci * position of a field.  x of size_mask(x) is the field width in bits.
33362306a36Sopenharmony_ci */
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci#define size_mask(x)          ((1U<<(x))-1)
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci/*
33862306a36Sopenharmony_ci * Offsets and Widths within the containing 32 bits of the various NX
33962306a36Sopenharmony_ci * gzip hardware registers.  Use the getnn/putnn macros to access
34062306a36Sopenharmony_ci * these regs
34162306a36Sopenharmony_ci */
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci#define dde_count_mask        size_mask(8)
34462306a36Sopenharmony_ci#define dde_count_offset      23
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci/* CSB */
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci#define csb_v_mask            size_mask(1)
34962306a36Sopenharmony_ci#define csb_v_offset          0
35062306a36Sopenharmony_ci#define csb_f_mask            size_mask(1)
35162306a36Sopenharmony_ci#define csb_f_offset          6
35262306a36Sopenharmony_ci#define csb_cs_mask           size_mask(8)
35362306a36Sopenharmony_ci#define csb_cs_offset         15
35462306a36Sopenharmony_ci#define csb_cc_mask           size_mask(8)
35562306a36Sopenharmony_ci#define csb_cc_offset         23
35662306a36Sopenharmony_ci#define csb_ce_mask           size_mask(8)
35762306a36Sopenharmony_ci#define csb_ce_offset         31
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci/* CCB */
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci#define ccb_cm_mask           size_mask(3)
36262306a36Sopenharmony_ci#define ccb_cm_offset         31
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci/* VAS stamped CRB fields */
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci#define vas_buf_num_mask      size_mask(6)
36762306a36Sopenharmony_ci#define vas_buf_num_offset    5
36862306a36Sopenharmony_ci#define send_wc_id_mask       size_mask(16)
36962306a36Sopenharmony_ci#define send_wc_id_offset     31
37062306a36Sopenharmony_ci#define recv_wc_id_mask       size_mask(16)
37162306a36Sopenharmony_ci#define recv_wc_id_offset     31
37262306a36Sopenharmony_ci#define vas_invalid_mask      size_mask(1)
37362306a36Sopenharmony_ci#define vas_invalid_offset    31
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci/* NX stamped fault CRB fields */
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci#define nxsf_t_mask           size_mask(1)
37862306a36Sopenharmony_ci#define nxsf_t_offset         23
37962306a36Sopenharmony_ci#define nxsf_fs_mask          size_mask(8)
38062306a36Sopenharmony_ci#define nxsf_fs_offset        31
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci/* CPB input */
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci#define in_histlen_mask       size_mask(12)
38562306a36Sopenharmony_ci#define in_histlen_offset     11
38662306a36Sopenharmony_ci#define in_dhtlen_mask        size_mask(12)
38762306a36Sopenharmony_ci#define in_dhtlen_offset      31
38862306a36Sopenharmony_ci#define in_subc_mask          size_mask(3)
38962306a36Sopenharmony_ci#define in_subc_offset        31
39062306a36Sopenharmony_ci#define in_sfbt_mask          size_mask(4)
39162306a36Sopenharmony_ci#define in_sfbt_offset        15
39262306a36Sopenharmony_ci#define in_rembytecnt_mask    size_mask(16)
39362306a36Sopenharmony_ci#define in_rembytecnt_offset  31
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci/* CPB output */
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci#define out_tebc_mask         size_mask(3)
39862306a36Sopenharmony_ci#define out_tebc_offset       15
39962306a36Sopenharmony_ci#define out_subc_mask         size_mask(16)
40062306a36Sopenharmony_ci#define out_subc_offset       31
40162306a36Sopenharmony_ci#define out_sfbt_mask         size_mask(4)
40262306a36Sopenharmony_ci#define out_sfbt_offset       15
40362306a36Sopenharmony_ci#define out_rembytecnt_mask   size_mask(16)
40462306a36Sopenharmony_ci#define out_rembytecnt_offset 31
40562306a36Sopenharmony_ci#define out_dhtlen_mask       size_mask(12)
40662306a36Sopenharmony_ci#define out_dhtlen_offset     31
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci/* CRB */
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci#define gzip_fc_mask          size_mask(8)
41162306a36Sopenharmony_ci#define gzip_fc_offset        31
41262306a36Sopenharmony_ci#define crb_c_mask            size_mask(1)
41362306a36Sopenharmony_ci#define crb_c_offset          28
41462306a36Sopenharmony_ci#define crb_at_mask           size_mask(1)
41562306a36Sopenharmony_ci#define crb_at_offset         30
41662306a36Sopenharmony_ci#define csb_address_mask      ~(15UL) /* mask off bottom 4b */
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci/*
41962306a36Sopenharmony_ci * Access macros for the registers.  Do not access registers directly
42062306a36Sopenharmony_ci * because of the endian conversion.  P9 processor may run either as
42162306a36Sopenharmony_ci * Little or Big endian. However the NX coprocessor regs are always
42262306a36Sopenharmony_ci * big endian.
42362306a36Sopenharmony_ci * Use the 32 and 64b macros to access respective
42462306a36Sopenharmony_ci * register sizes.
42562306a36Sopenharmony_ci * Use nn forms for the register fields shorter than 32 bits.
42662306a36Sopenharmony_ci */
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci#define getnn(ST, REG)      ((be32toh(ST.REG) >> (31-REG##_offset)) \
42962306a36Sopenharmony_ci				 & REG##_mask)
43062306a36Sopenharmony_ci#define getpnn(ST, REG)     ((be32toh((ST)->REG) >> (31-REG##_offset)) \
43162306a36Sopenharmony_ci				 & REG##_mask)
43262306a36Sopenharmony_ci#define get32(ST, REG)      (be32toh(ST.REG))
43362306a36Sopenharmony_ci#define getp32(ST, REG)     (be32toh((ST)->REG))
43462306a36Sopenharmony_ci#define get64(ST, REG)      (be64toh(ST.REG))
43562306a36Sopenharmony_ci#define getp64(ST, REG)     (be64toh((ST)->REG))
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci#define unget32(ST, REG)    (get32(ST, REG) & ~((REG##_mask) \
43862306a36Sopenharmony_ci				<< (31-REG##_offset)))
43962306a36Sopenharmony_ci/* get 32bits less the REG field */
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci#define ungetp32(ST, REG)   (getp32(ST, REG) & ~((REG##_mask) \
44262306a36Sopenharmony_ci				<< (31-REG##_offset)))
44362306a36Sopenharmony_ci/* get 32bits less the REG field */
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci#define clear_regs(ST)      memset((void *)(&(ST)), 0, sizeof(ST))
44662306a36Sopenharmony_ci#define clear_dde(ST)       do { ST.dde_count = ST.ddebc = 0; ST.ddead = 0; \
44762306a36Sopenharmony_ci				} while (0)
44862306a36Sopenharmony_ci#define clearp_dde(ST)      do { (ST)->dde_count = (ST)->ddebc = 0; \
44962306a36Sopenharmony_ci				 (ST)->ddead = 0; \
45062306a36Sopenharmony_ci				} while (0)
45162306a36Sopenharmony_ci#define clear_struct(ST)    memset((void *)(&(ST)), 0, sizeof(ST))
45262306a36Sopenharmony_ci#define putnn(ST, REG, X)   (ST.REG = htobe32(unget32(ST, REG) | (((X) \
45362306a36Sopenharmony_ci				 & REG##_mask) << (31-REG##_offset))))
45462306a36Sopenharmony_ci#define putpnn(ST, REG, X)  ((ST)->REG = htobe32(ungetp32(ST, REG) \
45562306a36Sopenharmony_ci				| (((X) & REG##_mask) << (31-REG##_offset))))
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci#define put32(ST, REG, X)   (ST.REG = htobe32(X))
45862306a36Sopenharmony_ci#define putp32(ST, REG, X)  ((ST)->REG = htobe32(X))
45962306a36Sopenharmony_ci#define put64(ST, REG, X)   (ST.REG = htobe64(X))
46062306a36Sopenharmony_ci#define putp64(ST, REG, X)  ((ST)->REG = htobe64(X))
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci/*
46362306a36Sopenharmony_ci * Completion extension ce(0) ce(1) ce(2).  Bits ce(3-7)
46462306a36Sopenharmony_ci * unused.  Section 6.6 Figure 6.7.
46562306a36Sopenharmony_ci */
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci#define get_csb_ce(ST) ((uint32_t)getnn(ST, csb_ce))
46862306a36Sopenharmony_ci#define get_csb_ce_ms3b(ST) (get_csb_ce(ST) >> 5)
46962306a36Sopenharmony_ci#define put_csb_ce_ms3b(ST, X) putnn(ST, csb_ce, ((uint32_t)(X) << 5))
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ci#define CSB_CE_PARTIAL         0x4
47262306a36Sopenharmony_ci#define CSB_CE_TERMINATE       0x2
47362306a36Sopenharmony_ci#define CSB_CE_TPBC_VALID      0x1
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci#define csb_ce_termination(X)         (!!((X) & CSB_CE_TERMINATE))
47662306a36Sopenharmony_ci/* termination, output buffers may be modified, SPBC/TPBC invalid Fig.6-7 */
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci#define csb_ce_check_completion(X)    (!csb_ce_termination(X))
47962306a36Sopenharmony_ci/* if not terminated then check full or partial completion */
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci#define csb_ce_partial_completion(X)  (!!((X) & CSB_CE_PARTIAL))
48262306a36Sopenharmony_ci#define csb_ce_full_completion(X)     (!csb_ce_partial_completion(X))
48362306a36Sopenharmony_ci#define csb_ce_tpbc_valid(X)          (!!((X) & CSB_CE_TPBC_VALID))
48462306a36Sopenharmony_ci/* TPBC indicates successfully stored data count */
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci#define csb_ce_default_err(X)         csb_ce_termination(X)
48762306a36Sopenharmony_ci/* most error CEs have CE(0)=0 and CE(1)=1 */
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci#define csb_ce_cc3_partial(X)         csb_ce_partial_completion(X)
49062306a36Sopenharmony_ci/* some CC=3 are partially completed, Table 6-8 */
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci#define csb_ce_cc64(X)                ((X)&(CSB_CE_PARTIAL \
49362306a36Sopenharmony_ci					| CSB_CE_TERMINATE) == 0)
49462306a36Sopenharmony_ci/* Compression: when TPBC>SPBC then CC=64 Table 6-8; target didn't
49562306a36Sopenharmony_ci * compress smaller than source.
49662306a36Sopenharmony_ci */
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci/* Decompress SFBT combinations Tables 5-3, 6-4, 6-6 */
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci#define SFBT_BFINAL 0x1
50162306a36Sopenharmony_ci#define SFBT_LIT    0x4
50262306a36Sopenharmony_ci#define SFBT_FHT    0x5
50362306a36Sopenharmony_ci#define SFBT_DHT    0x6
50462306a36Sopenharmony_ci#define SFBT_HDR    0x7
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci/*
50762306a36Sopenharmony_ci * NX gzip function codes. Table 6.2.
50862306a36Sopenharmony_ci * Bits 0:4 are the FC. Bit 5 is used by the DMA controller to
50962306a36Sopenharmony_ci * select one of the two Byte Count Limits.
51062306a36Sopenharmony_ci */
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci#define GZIP_FC_LIMIT_MASK                               0x01
51362306a36Sopenharmony_ci#define GZIP_FC_COMPRESS_FHT                             0x00
51462306a36Sopenharmony_ci#define GZIP_FC_COMPRESS_DHT                             0x02
51562306a36Sopenharmony_ci#define GZIP_FC_COMPRESS_FHT_COUNT                       0x04
51662306a36Sopenharmony_ci#define GZIP_FC_COMPRESS_DHT_COUNT                       0x06
51762306a36Sopenharmony_ci#define GZIP_FC_COMPRESS_RESUME_FHT                      0x08
51862306a36Sopenharmony_ci#define GZIP_FC_COMPRESS_RESUME_DHT                      0x0a
51962306a36Sopenharmony_ci#define GZIP_FC_COMPRESS_RESUME_FHT_COUNT                0x0c
52062306a36Sopenharmony_ci#define GZIP_FC_COMPRESS_RESUME_DHT_COUNT                0x0e
52162306a36Sopenharmony_ci#define GZIP_FC_DECOMPRESS                               0x10
52262306a36Sopenharmony_ci#define GZIP_FC_DECOMPRESS_SINGLE_BLK_N_SUSPEND          0x12
52362306a36Sopenharmony_ci#define GZIP_FC_DECOMPRESS_RESUME                        0x14
52462306a36Sopenharmony_ci#define GZIP_FC_DECOMPRESS_RESUME_SINGLE_BLK_N_SUSPEND   0x16
52562306a36Sopenharmony_ci#define GZIP_FC_WRAP                                     0x1e
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci#define fc_is_compress(fc)  (((fc) & 0x10) == 0)
52862306a36Sopenharmony_ci#define fc_has_count(fc)    (fc_is_compress(fc) && (((fc) & 0x4) != 0))
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci/* CSB.CC Error codes */
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci#define ERR_NX_OK             0
53362306a36Sopenharmony_ci#define ERR_NX_ALIGNMENT      1
53462306a36Sopenharmony_ci#define ERR_NX_OPOVERLAP      2
53562306a36Sopenharmony_ci#define ERR_NX_DATA_LENGTH    3
53662306a36Sopenharmony_ci#define ERR_NX_TRANSLATION    5
53762306a36Sopenharmony_ci#define ERR_NX_PROTECTION     6
53862306a36Sopenharmony_ci#define ERR_NX_EXTERNAL_UE7   7
53962306a36Sopenharmony_ci#define ERR_NX_INVALID_OP     8
54062306a36Sopenharmony_ci#define ERR_NX_PRIVILEGE      9
54162306a36Sopenharmony_ci#define ERR_NX_INTERNAL_UE   10
54262306a36Sopenharmony_ci#define ERR_NX_EXTERN_UE_WR  12
54362306a36Sopenharmony_ci#define ERR_NX_TARGET_SPACE  13
54462306a36Sopenharmony_ci#define ERR_NX_EXCESSIVE_DDE 14
54562306a36Sopenharmony_ci#define ERR_NX_TRANSL_WR     15
54662306a36Sopenharmony_ci#define ERR_NX_PROTECT_WR    16
54762306a36Sopenharmony_ci#define ERR_NX_SUBFUNCTION   17
54862306a36Sopenharmony_ci#define ERR_NX_FUNC_ABORT    18
54962306a36Sopenharmony_ci#define ERR_NX_BYTE_MAX      19
55062306a36Sopenharmony_ci#define ERR_NX_CORRUPT_CRB   20
55162306a36Sopenharmony_ci#define ERR_NX_INVALID_CRB   21
55262306a36Sopenharmony_ci#define ERR_NX_INVALID_DDE   30
55362306a36Sopenharmony_ci#define ERR_NX_SEGMENTED_DDL 31
55462306a36Sopenharmony_ci#define ERR_NX_DDE_OVERFLOW  33
55562306a36Sopenharmony_ci#define ERR_NX_TPBC_GT_SPBC  64
55662306a36Sopenharmony_ci#define ERR_NX_MISSING_CODE  66
55762306a36Sopenharmony_ci#define ERR_NX_INVALID_DIST  67
55862306a36Sopenharmony_ci#define ERR_NX_INVALID_DHT   68
55962306a36Sopenharmony_ci#define ERR_NX_EXTERNAL_UE90 90
56062306a36Sopenharmony_ci#define ERR_NX_WDOG_TIMER   224
56162306a36Sopenharmony_ci#define ERR_NX_AT_FAULT     250
56262306a36Sopenharmony_ci#define ERR_NX_INTR_SERVER  252
56362306a36Sopenharmony_ci#define ERR_NX_UE253        253
56462306a36Sopenharmony_ci#define ERR_NX_NO_HW        254
56562306a36Sopenharmony_ci#define ERR_NX_HUNG_OP      255
56662306a36Sopenharmony_ci#define ERR_NX_END          256
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci/* initial values for non-resume operations */
56962306a36Sopenharmony_ci#define INIT_CRC   0  /* crc32(0L, Z_NULL, 0) */
57062306a36Sopenharmony_ci#define INIT_ADLER 1  /* adler32(0L, Z_NULL, 0)  adler is initialized to 1 */
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci/* prototypes */
57362306a36Sopenharmony_ciint nxu_submit_job(struct nx_gzip_crb_cpb_t *c, void *handle);
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ciextern void nxu_sigsegv_handler(int sig, siginfo_t *info, void *ctx);
57662306a36Sopenharmony_ciextern int nxu_touch_pages(void *buf, long buf_len, long page_len, int wr);
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci/* caller supplies a print buffer 4*sizeof(crb) */
57962306a36Sopenharmony_ci
58062306a36Sopenharmony_cichar *nx_crb_str(struct nx_gzip_crb_t *crb, char *prbuf);
58162306a36Sopenharmony_cichar *nx_cpb_str(struct nx_gzip_cpb_t *cpb, char *prbuf);
58262306a36Sopenharmony_cichar *nx_prt_hex(void *cp, int sz, char *prbuf);
58362306a36Sopenharmony_cichar *nx_lzcount_str(struct nx_gzip_cpb_t *cpb, char *prbuf);
58462306a36Sopenharmony_cichar *nx_strerror(int e);
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ci#ifdef NX_SIM
58762306a36Sopenharmony_ci#include <stdio.h>
58862306a36Sopenharmony_ciint nx_sim_init(void *ctx);
58962306a36Sopenharmony_ciint nx_sim_end(void *ctx);
59062306a36Sopenharmony_ciint nxu_run_sim_job(struct nx_gzip_crb_cpb_t *c, void *ctx);
59162306a36Sopenharmony_ci#endif /* NX_SIM */
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci/* Deflate stream manipulation */
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci#define set_final_bit(x)	(x |= (unsigned char)1)
59662306a36Sopenharmony_ci#define clr_final_bit(x)	(x &= ~(unsigned char)1)
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ci#define append_empty_fh_blk(p, b) do { *(p) = (2 | (1&(b))); *((p)+1) = 0; \
59962306a36Sopenharmony_ci					} while (0)
60062306a36Sopenharmony_ci/* append 10 bits 0000001b 00...... ;
60162306a36Sopenharmony_ci * assumes appending starts on a byte boundary; b is the final bit.
60262306a36Sopenharmony_ci */
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci#ifdef NX_842
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci/* 842 Engine */
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_cistruct nx_eft_crb_t {
61062306a36Sopenharmony_ci	union {                   /* byte[0:3]   */
61162306a36Sopenharmony_ci		uint32_t eft_fc;      /* bits[29-31] */
61262306a36Sopenharmony_ci	};
61362306a36Sopenharmony_ci	uint32_t reserved1;       /* byte[4:7]   */
61462306a36Sopenharmony_ci	union {
61562306a36Sopenharmony_ci		uint64_t csb_address; /* byte[8:15]  */
61662306a36Sopenharmony_ci		struct {
61762306a36Sopenharmony_ci			uint32_t reserved2;
61862306a36Sopenharmony_ci			union {
61962306a36Sopenharmony_ci				uint32_t crb_c;
62062306a36Sopenharmony_ci				/* c==0 no ccb defined */
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci				uint32_t crb_at;
62362306a36Sopenharmony_ci				/* at==0 address type is ignored;
62462306a36Sopenharmony_ci				 * all addrs effective assumed.
62562306a36Sopenharmony_ci				 */
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci			};
62862306a36Sopenharmony_ci		};
62962306a36Sopenharmony_ci	};
63062306a36Sopenharmony_ci	struct nx_dde_t source_dde;           /* byte[16:31] */
63162306a36Sopenharmony_ci	struct nx_dde_t target_dde;           /* byte[32:47] */
63262306a36Sopenharmony_ci	struct nx_ccb_t ccb;                  /* byte[48:63] */
63362306a36Sopenharmony_ci	union {
63462306a36Sopenharmony_ci		union nx_qw_t reserved64[3];     /* byte[64:96] */
63562306a36Sopenharmony_ci	};
63662306a36Sopenharmony_ci	struct nx_csb_t csb;
63762306a36Sopenharmony_ci} __aligned(128);
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci/* 842 CRB */
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci#define EFT_FC_MASK                 size_mask(3)
64262306a36Sopenharmony_ci#define EFT_FC_OFFSET               31
64362306a36Sopenharmony_ci#define EFT_FC_COMPRESS             0x0
64462306a36Sopenharmony_ci#define EFT_FC_COMPRESS_WITH_CRC    0x1
64562306a36Sopenharmony_ci#define EFT_FC_DECOMPRESS           0x2
64662306a36Sopenharmony_ci#define EFT_FC_DECOMPRESS_WITH_CRC  0x3
64762306a36Sopenharmony_ci#define EFT_FC_BLK_DATA_MOVE        0x4
64862306a36Sopenharmony_ci#endif /* NX_842 */
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ci#endif /* _NXU_H */
651