xref: /aosp_15_r20/external/libdrm/nouveau/nouveau.h (revision 7688df22e49036ff52a766b7101da3a49edadb8c)
1*7688df22SAndroid Build Coastguard Worker #ifndef __NOUVEAU_H__
2*7688df22SAndroid Build Coastguard Worker #define __NOUVEAU_H__
3*7688df22SAndroid Build Coastguard Worker 
4*7688df22SAndroid Build Coastguard Worker #include <stdint.h>
5*7688df22SAndroid Build Coastguard Worker #include <stdbool.h>
6*7688df22SAndroid Build Coastguard Worker 
7*7688df22SAndroid Build Coastguard Worker /* Supported class information, provided by the kernel */
8*7688df22SAndroid Build Coastguard Worker struct nouveau_sclass {
9*7688df22SAndroid Build Coastguard Worker 	int32_t oclass;
10*7688df22SAndroid Build Coastguard Worker 	int minver;
11*7688df22SAndroid Build Coastguard Worker 	int maxver;
12*7688df22SAndroid Build Coastguard Worker };
13*7688df22SAndroid Build Coastguard Worker 
14*7688df22SAndroid Build Coastguard Worker /* Client-provided array describing class versions that are desired.
15*7688df22SAndroid Build Coastguard Worker  *
16*7688df22SAndroid Build Coastguard Worker  * These are used to match against the kernel's list of supported classes.
17*7688df22SAndroid Build Coastguard Worker  */
18*7688df22SAndroid Build Coastguard Worker struct nouveau_mclass {
19*7688df22SAndroid Build Coastguard Worker 	int32_t oclass;
20*7688df22SAndroid Build Coastguard Worker 	int version;
21*7688df22SAndroid Build Coastguard Worker 	void *data;
22*7688df22SAndroid Build Coastguard Worker };
23*7688df22SAndroid Build Coastguard Worker 
24*7688df22SAndroid Build Coastguard Worker struct nouveau_object {
25*7688df22SAndroid Build Coastguard Worker 	struct nouveau_object *parent;
26*7688df22SAndroid Build Coastguard Worker 	uint64_t handle;
27*7688df22SAndroid Build Coastguard Worker 	uint32_t oclass;
28*7688df22SAndroid Build Coastguard Worker 	uint32_t length;	/* deprecated */
29*7688df22SAndroid Build Coastguard Worker 	void *data;		/* deprecated */
30*7688df22SAndroid Build Coastguard Worker };
31*7688df22SAndroid Build Coastguard Worker 
32*7688df22SAndroid Build Coastguard Worker int nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
33*7688df22SAndroid Build Coastguard Worker 		       uint32_t oclass, void *data, uint32_t length,
34*7688df22SAndroid Build Coastguard Worker 		       struct nouveau_object **);
35*7688df22SAndroid Build Coastguard Worker void nouveau_object_del(struct nouveau_object **);
36*7688df22SAndroid Build Coastguard Worker int nouveau_object_mthd(struct nouveau_object *, uint32_t mthd,
37*7688df22SAndroid Build Coastguard Worker 			void *data, uint32_t size);
38*7688df22SAndroid Build Coastguard Worker int nouveau_object_sclass_get(struct nouveau_object *,
39*7688df22SAndroid Build Coastguard Worker 			      struct nouveau_sclass **);
40*7688df22SAndroid Build Coastguard Worker void nouveau_object_sclass_put(struct nouveau_sclass **);
41*7688df22SAndroid Build Coastguard Worker int nouveau_object_mclass(struct nouveau_object *,
42*7688df22SAndroid Build Coastguard Worker 			  const struct nouveau_mclass *);
43*7688df22SAndroid Build Coastguard Worker 
44*7688df22SAndroid Build Coastguard Worker struct nouveau_drm {
45*7688df22SAndroid Build Coastguard Worker 	struct nouveau_object client;
46*7688df22SAndroid Build Coastguard Worker 	int fd;
47*7688df22SAndroid Build Coastguard Worker 	uint32_t version;
48*7688df22SAndroid Build Coastguard Worker 	bool nvif;
49*7688df22SAndroid Build Coastguard Worker };
50*7688df22SAndroid Build Coastguard Worker 
51*7688df22SAndroid Build Coastguard Worker static inline struct nouveau_drm *
nouveau_drm(struct nouveau_object * obj)52*7688df22SAndroid Build Coastguard Worker nouveau_drm(struct nouveau_object *obj)
53*7688df22SAndroid Build Coastguard Worker {
54*7688df22SAndroid Build Coastguard Worker 	while (obj && obj->parent)
55*7688df22SAndroid Build Coastguard Worker 		obj = obj->parent;
56*7688df22SAndroid Build Coastguard Worker 	return (struct nouveau_drm *)obj;
57*7688df22SAndroid Build Coastguard Worker }
58*7688df22SAndroid Build Coastguard Worker 
59*7688df22SAndroid Build Coastguard Worker int nouveau_drm_new(int fd, struct nouveau_drm **);
60*7688df22SAndroid Build Coastguard Worker void nouveau_drm_del(struct nouveau_drm **);
61*7688df22SAndroid Build Coastguard Worker 
62*7688df22SAndroid Build Coastguard Worker struct nouveau_device {
63*7688df22SAndroid Build Coastguard Worker 	struct nouveau_object object;
64*7688df22SAndroid Build Coastguard Worker 	int fd;			/* deprecated */
65*7688df22SAndroid Build Coastguard Worker 	uint32_t lib_version;	/* deprecated */
66*7688df22SAndroid Build Coastguard Worker 	uint32_t drm_version;	/* deprecated */
67*7688df22SAndroid Build Coastguard Worker 	uint32_t chipset;
68*7688df22SAndroid Build Coastguard Worker 	uint64_t vram_size;
69*7688df22SAndroid Build Coastguard Worker 	uint64_t gart_size;
70*7688df22SAndroid Build Coastguard Worker 	uint64_t vram_limit;
71*7688df22SAndroid Build Coastguard Worker 	uint64_t gart_limit;
72*7688df22SAndroid Build Coastguard Worker };
73*7688df22SAndroid Build Coastguard Worker 
74*7688df22SAndroid Build Coastguard Worker int nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
75*7688df22SAndroid Build Coastguard Worker 		       void *data, uint32_t size, struct nouveau_device **);
76*7688df22SAndroid Build Coastguard Worker void nouveau_device_del(struct nouveau_device **);
77*7688df22SAndroid Build Coastguard Worker 
78*7688df22SAndroid Build Coastguard Worker int nouveau_getparam(struct nouveau_device *, uint64_t param, uint64_t *value);
79*7688df22SAndroid Build Coastguard Worker int nouveau_setparam(struct nouveau_device *, uint64_t param, uint64_t value);
80*7688df22SAndroid Build Coastguard Worker 
81*7688df22SAndroid Build Coastguard Worker /* deprecated */
82*7688df22SAndroid Build Coastguard Worker int nouveau_device_wrap(int fd, int close, struct nouveau_device **);
83*7688df22SAndroid Build Coastguard Worker int nouveau_device_open(const char *busid, struct nouveau_device **);
84*7688df22SAndroid Build Coastguard Worker 
85*7688df22SAndroid Build Coastguard Worker struct nouveau_client {
86*7688df22SAndroid Build Coastguard Worker 	struct nouveau_device *device;
87*7688df22SAndroid Build Coastguard Worker 	int id;
88*7688df22SAndroid Build Coastguard Worker };
89*7688df22SAndroid Build Coastguard Worker 
90*7688df22SAndroid Build Coastguard Worker int nouveau_client_new(struct nouveau_device *, struct nouveau_client **);
91*7688df22SAndroid Build Coastguard Worker void nouveau_client_del(struct nouveau_client **);
92*7688df22SAndroid Build Coastguard Worker 
93*7688df22SAndroid Build Coastguard Worker union nouveau_bo_config {
94*7688df22SAndroid Build Coastguard Worker 	struct {
95*7688df22SAndroid Build Coastguard Worker #define NV04_BO_16BPP 0x00000001
96*7688df22SAndroid Build Coastguard Worker #define NV04_BO_32BPP 0x00000002
97*7688df22SAndroid Build Coastguard Worker #define NV04_BO_ZETA  0x00000004
98*7688df22SAndroid Build Coastguard Worker 		uint32_t surf_flags;
99*7688df22SAndroid Build Coastguard Worker 		uint32_t surf_pitch;
100*7688df22SAndroid Build Coastguard Worker 	} nv04;
101*7688df22SAndroid Build Coastguard Worker 	struct {
102*7688df22SAndroid Build Coastguard Worker 		uint32_t memtype;
103*7688df22SAndroid Build Coastguard Worker 		uint32_t tile_mode;
104*7688df22SAndroid Build Coastguard Worker 	} nv50;
105*7688df22SAndroid Build Coastguard Worker 	struct {
106*7688df22SAndroid Build Coastguard Worker 		uint32_t memtype;
107*7688df22SAndroid Build Coastguard Worker 		uint32_t tile_mode;
108*7688df22SAndroid Build Coastguard Worker 	} nvc0;
109*7688df22SAndroid Build Coastguard Worker 	uint32_t data[8];
110*7688df22SAndroid Build Coastguard Worker };
111*7688df22SAndroid Build Coastguard Worker 
112*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_VRAM    0x00000001
113*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_GART    0x00000002
114*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_APER   (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART)
115*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_RD      0x00000100
116*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_WR      0x00000200
117*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_RDWR   (NOUVEAU_BO_RD | NOUVEAU_BO_WR)
118*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_NOBLOCK 0x00000400
119*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_LOW     0x00001000
120*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_HIGH    0x00002000
121*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_OR      0x00004000
122*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_MAP     0x80000000
123*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_CONTIG  0x40000000
124*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_NOSNOOP 0x20000000
125*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_BO_COHERENT 0x10000000
126*7688df22SAndroid Build Coastguard Worker 
127*7688df22SAndroid Build Coastguard Worker struct nouveau_bo {
128*7688df22SAndroid Build Coastguard Worker 	struct nouveau_device *device;
129*7688df22SAndroid Build Coastguard Worker 	uint32_t handle;
130*7688df22SAndroid Build Coastguard Worker 	uint64_t size;
131*7688df22SAndroid Build Coastguard Worker 	uint32_t flags;
132*7688df22SAndroid Build Coastguard Worker 	uint64_t offset;
133*7688df22SAndroid Build Coastguard Worker 	void *map;
134*7688df22SAndroid Build Coastguard Worker 	union nouveau_bo_config config;
135*7688df22SAndroid Build Coastguard Worker };
136*7688df22SAndroid Build Coastguard Worker 
137*7688df22SAndroid Build Coastguard Worker int nouveau_bo_new(struct nouveau_device *, uint32_t flags, uint32_t align,
138*7688df22SAndroid Build Coastguard Worker 		   uint64_t size, union nouveau_bo_config *,
139*7688df22SAndroid Build Coastguard Worker 		   struct nouveau_bo **);
140*7688df22SAndroid Build Coastguard Worker void nouveau_bo_make_global(struct nouveau_bo *);
141*7688df22SAndroid Build Coastguard Worker int nouveau_bo_wrap(struct nouveau_device *, uint32_t handle,
142*7688df22SAndroid Build Coastguard Worker 		    struct nouveau_bo **);
143*7688df22SAndroid Build Coastguard Worker int nouveau_bo_name_ref(struct nouveau_device *v, uint32_t name,
144*7688df22SAndroid Build Coastguard Worker 			struct nouveau_bo **);
145*7688df22SAndroid Build Coastguard Worker int nouveau_bo_name_get(struct nouveau_bo *, uint32_t *name);
146*7688df22SAndroid Build Coastguard Worker void nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **);
147*7688df22SAndroid Build Coastguard Worker int nouveau_bo_map(struct nouveau_bo *, uint32_t access,
148*7688df22SAndroid Build Coastguard Worker 		   struct nouveau_client *);
149*7688df22SAndroid Build Coastguard Worker int nouveau_bo_wait(struct nouveau_bo *, uint32_t access,
150*7688df22SAndroid Build Coastguard Worker 		    struct nouveau_client *);
151*7688df22SAndroid Build Coastguard Worker int nouveau_bo_prime_handle_ref(struct nouveau_device *, int prime_fd,
152*7688df22SAndroid Build Coastguard Worker 				struct nouveau_bo **);
153*7688df22SAndroid Build Coastguard Worker int nouveau_bo_set_prime(struct nouveau_bo *, int *prime_fd);
154*7688df22SAndroid Build Coastguard Worker 
155*7688df22SAndroid Build Coastguard Worker struct nouveau_list {
156*7688df22SAndroid Build Coastguard Worker 	struct nouveau_list *prev;
157*7688df22SAndroid Build Coastguard Worker 	struct nouveau_list *next;
158*7688df22SAndroid Build Coastguard Worker };
159*7688df22SAndroid Build Coastguard Worker 
160*7688df22SAndroid Build Coastguard Worker struct nouveau_bufref {
161*7688df22SAndroid Build Coastguard Worker 	struct nouveau_list thead;
162*7688df22SAndroid Build Coastguard Worker 	struct nouveau_bo *bo;
163*7688df22SAndroid Build Coastguard Worker 	uint32_t packet;
164*7688df22SAndroid Build Coastguard Worker 	uint32_t flags;
165*7688df22SAndroid Build Coastguard Worker 	uint32_t data;
166*7688df22SAndroid Build Coastguard Worker 	uint32_t vor;
167*7688df22SAndroid Build Coastguard Worker 	uint32_t tor;
168*7688df22SAndroid Build Coastguard Worker 	uint32_t priv_data;
169*7688df22SAndroid Build Coastguard Worker 	void *priv;
170*7688df22SAndroid Build Coastguard Worker };
171*7688df22SAndroid Build Coastguard Worker 
172*7688df22SAndroid Build Coastguard Worker struct nouveau_bufctx {
173*7688df22SAndroid Build Coastguard Worker 	struct nouveau_client *client;
174*7688df22SAndroid Build Coastguard Worker 	struct nouveau_list head;
175*7688df22SAndroid Build Coastguard Worker 	struct nouveau_list pending;
176*7688df22SAndroid Build Coastguard Worker 	struct nouveau_list current;
177*7688df22SAndroid Build Coastguard Worker 	int relocs;
178*7688df22SAndroid Build Coastguard Worker };
179*7688df22SAndroid Build Coastguard Worker 
180*7688df22SAndroid Build Coastguard Worker int nouveau_bufctx_new(struct nouveau_client *, int bins,
181*7688df22SAndroid Build Coastguard Worker 		       struct nouveau_bufctx **);
182*7688df22SAndroid Build Coastguard Worker void nouveau_bufctx_del(struct nouveau_bufctx **);
183*7688df22SAndroid Build Coastguard Worker struct nouveau_bufref *
184*7688df22SAndroid Build Coastguard Worker nouveau_bufctx_refn(struct nouveau_bufctx *, int bin,
185*7688df22SAndroid Build Coastguard Worker 		    struct nouveau_bo *, uint32_t flags);
186*7688df22SAndroid Build Coastguard Worker struct nouveau_bufref *
187*7688df22SAndroid Build Coastguard Worker nouveau_bufctx_mthd(struct nouveau_bufctx *, int bin,  uint32_t packet,
188*7688df22SAndroid Build Coastguard Worker 		    struct nouveau_bo *, uint64_t data, uint32_t flags,
189*7688df22SAndroid Build Coastguard Worker 		    uint32_t vor, uint32_t tor);
190*7688df22SAndroid Build Coastguard Worker void nouveau_bufctx_reset(struct nouveau_bufctx *, int bin);
191*7688df22SAndroid Build Coastguard Worker 
192*7688df22SAndroid Build Coastguard Worker struct nouveau_pushbuf_krec;
193*7688df22SAndroid Build Coastguard Worker struct nouveau_pushbuf {
194*7688df22SAndroid Build Coastguard Worker 	struct nouveau_client *client;
195*7688df22SAndroid Build Coastguard Worker 	struct nouveau_object *channel;
196*7688df22SAndroid Build Coastguard Worker 	struct nouveau_bufctx *bufctx;
197*7688df22SAndroid Build Coastguard Worker 	void (*kick_notify)(struct nouveau_pushbuf *);
198*7688df22SAndroid Build Coastguard Worker 	void *user_priv;
199*7688df22SAndroid Build Coastguard Worker 	uint32_t rsvd_kick;
200*7688df22SAndroid Build Coastguard Worker 	uint32_t flags;
201*7688df22SAndroid Build Coastguard Worker 	uint32_t *cur;
202*7688df22SAndroid Build Coastguard Worker 	uint32_t *end;
203*7688df22SAndroid Build Coastguard Worker };
204*7688df22SAndroid Build Coastguard Worker 
205*7688df22SAndroid Build Coastguard Worker struct nouveau_pushbuf_refn {
206*7688df22SAndroid Build Coastguard Worker 	struct nouveau_bo *bo;
207*7688df22SAndroid Build Coastguard Worker 	uint32_t flags;
208*7688df22SAndroid Build Coastguard Worker };
209*7688df22SAndroid Build Coastguard Worker 
210*7688df22SAndroid Build Coastguard Worker int nouveau_pushbuf_new(struct nouveau_client *, struct nouveau_object *chan,
211*7688df22SAndroid Build Coastguard Worker 			int nr, uint32_t size, bool immediate,
212*7688df22SAndroid Build Coastguard Worker 			struct nouveau_pushbuf **);
213*7688df22SAndroid Build Coastguard Worker void nouveau_pushbuf_del(struct nouveau_pushbuf **);
214*7688df22SAndroid Build Coastguard Worker int nouveau_pushbuf_space(struct nouveau_pushbuf *, uint32_t dwords,
215*7688df22SAndroid Build Coastguard Worker 			  uint32_t relocs, uint32_t pushes);
216*7688df22SAndroid Build Coastguard Worker void nouveau_pushbuf_data(struct nouveau_pushbuf *, struct nouveau_bo *,
217*7688df22SAndroid Build Coastguard Worker 			  uint64_t offset, uint64_t length);
218*7688df22SAndroid Build Coastguard Worker int nouveau_pushbuf_refn(struct nouveau_pushbuf *,
219*7688df22SAndroid Build Coastguard Worker 			 struct nouveau_pushbuf_refn *, int nr);
220*7688df22SAndroid Build Coastguard Worker /* Emits a reloc into the push buffer at the current position, you *must*
221*7688df22SAndroid Build Coastguard Worker  * have previously added the referenced buffer to a buffer context, and
222*7688df22SAndroid Build Coastguard Worker  * validated it against the current push buffer.
223*7688df22SAndroid Build Coastguard Worker  */
224*7688df22SAndroid Build Coastguard Worker void nouveau_pushbuf_reloc(struct nouveau_pushbuf *, struct nouveau_bo *,
225*7688df22SAndroid Build Coastguard Worker 			   uint32_t data, uint32_t flags,
226*7688df22SAndroid Build Coastguard Worker 			   uint32_t vor, uint32_t tor);
227*7688df22SAndroid Build Coastguard Worker int nouveau_pushbuf_validate(struct nouveau_pushbuf *);
228*7688df22SAndroid Build Coastguard Worker uint32_t nouveau_pushbuf_refd(struct nouveau_pushbuf *, struct nouveau_bo *);
229*7688df22SAndroid Build Coastguard Worker int nouveau_pushbuf_kick(struct nouveau_pushbuf *, struct nouveau_object *chan);
230*7688df22SAndroid Build Coastguard Worker struct nouveau_bufctx *
231*7688df22SAndroid Build Coastguard Worker nouveau_pushbuf_bufctx(struct nouveau_pushbuf *, struct nouveau_bufctx *);
232*7688df22SAndroid Build Coastguard Worker 
233*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_DEVICE_CLASS       0x80000000
234*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_FIFO_CHANNEL_CLASS 0x80000001
235*7688df22SAndroid Build Coastguard Worker #define NOUVEAU_NOTIFIER_CLASS     0x80000002
236*7688df22SAndroid Build Coastguard Worker 
237*7688df22SAndroid Build Coastguard Worker struct nouveau_fifo {
238*7688df22SAndroid Build Coastguard Worker 	struct nouveau_object *object;
239*7688df22SAndroid Build Coastguard Worker 	uint32_t channel;
240*7688df22SAndroid Build Coastguard Worker 	uint32_t pushbuf;
241*7688df22SAndroid Build Coastguard Worker 	uint64_t unused1[3];
242*7688df22SAndroid Build Coastguard Worker };
243*7688df22SAndroid Build Coastguard Worker 
244*7688df22SAndroid Build Coastguard Worker struct nv04_fifo {
245*7688df22SAndroid Build Coastguard Worker 	struct nouveau_fifo base;
246*7688df22SAndroid Build Coastguard Worker 	uint32_t vram;
247*7688df22SAndroid Build Coastguard Worker 	uint32_t gart;
248*7688df22SAndroid Build Coastguard Worker 	uint32_t notify;
249*7688df22SAndroid Build Coastguard Worker };
250*7688df22SAndroid Build Coastguard Worker 
251*7688df22SAndroid Build Coastguard Worker struct nvc0_fifo {
252*7688df22SAndroid Build Coastguard Worker 	struct nouveau_fifo base;
253*7688df22SAndroid Build Coastguard Worker 	uint32_t notify;
254*7688df22SAndroid Build Coastguard Worker };
255*7688df22SAndroid Build Coastguard Worker 
256*7688df22SAndroid Build Coastguard Worker #define NVE0_FIFO_ENGINE_GR  0x00000001
257*7688df22SAndroid Build Coastguard Worker #define NVE0_FIFO_ENGINE_VP  0x00000002
258*7688df22SAndroid Build Coastguard Worker #define NVE0_FIFO_ENGINE_PPP 0x00000004
259*7688df22SAndroid Build Coastguard Worker #define NVE0_FIFO_ENGINE_BSP 0x00000008
260*7688df22SAndroid Build Coastguard Worker #define NVE0_FIFO_ENGINE_CE0 0x00000010
261*7688df22SAndroid Build Coastguard Worker #define NVE0_FIFO_ENGINE_CE1 0x00000020
262*7688df22SAndroid Build Coastguard Worker #define NVE0_FIFO_ENGINE_ENC 0x00000040
263*7688df22SAndroid Build Coastguard Worker 
264*7688df22SAndroid Build Coastguard Worker struct nve0_fifo {
265*7688df22SAndroid Build Coastguard Worker 	struct {
266*7688df22SAndroid Build Coastguard Worker 		struct nouveau_fifo base;
267*7688df22SAndroid Build Coastguard Worker 		uint32_t notify;
268*7688df22SAndroid Build Coastguard Worker 	};
269*7688df22SAndroid Build Coastguard Worker 	uint32_t engine;
270*7688df22SAndroid Build Coastguard Worker };
271*7688df22SAndroid Build Coastguard Worker 
272*7688df22SAndroid Build Coastguard Worker struct nv04_notify {
273*7688df22SAndroid Build Coastguard Worker 	struct nouveau_object *object;
274*7688df22SAndroid Build Coastguard Worker 	uint32_t offset;
275*7688df22SAndroid Build Coastguard Worker 	uint32_t length;
276*7688df22SAndroid Build Coastguard Worker };
277*7688df22SAndroid Build Coastguard Worker 
278*7688df22SAndroid Build Coastguard Worker bool
279*7688df22SAndroid Build Coastguard Worker nouveau_check_dead_channel(struct nouveau_drm *, struct nouveau_object *chan);
280*7688df22SAndroid Build Coastguard Worker 
281*7688df22SAndroid Build Coastguard Worker #endif
282