142421Syokota/*-
242421Syokota * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
342421Syokota * All rights reserved.
442421Syokota *
542421Syokota * Redistribution and use in source and binary forms, with or without
642421Syokota * modification, are permitted provided that the following conditions
742421Syokota * are met:
842421Syokota * 1. Redistributions of source code must retain the above copyright
942421Syokota *    notice, this list of conditions and the following disclaimer as
1042421Syokota *    the first lines of this file unmodified.
1142421Syokota * 2. Redistributions in binary form must reproduce the above copyright
1242421Syokota *    notice, this list of conditions and the following disclaimer in the
1342421Syokota *    documentation and/or other materials provided with the distribution.
1442421Syokota *
1542421Syokota * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1642421Syokota * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1742421Syokota * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1842421Syokota * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1942421Syokota * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2042421Syokota * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2142421Syokota * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2242421Syokota * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2342421Syokota * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2442421Syokota * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2542421Syokota *
2650477Speter * $FreeBSD$
2742421Syokota */
2842421Syokota
2942421Syokota#ifndef _DEV_FB_FBREG_H_
3042421Syokota#define _DEV_FB_FBREG_H_
3142421Syokota
3255205Speter#ifdef _KERNEL
3342421Syokota
3442421Syokota#define V_MAX_ADAPTERS		8		/* XXX */
3542421Syokota
3642421Syokota/* some macros */
37209460Skib#if defined(__amd64__) || defined(__i386__)
38238555Skib
39238555Skibstatic __inline void
40238555Skibcopyw(uint16_t *src, uint16_t *dst, size_t size)
41238555Skib{
42238555Skib	size >>= 1;
43238555Skib	while (size--)
44238555Skib		*dst++ = *src++;
45238555Skib}
46238555Skib#define bcopy_io(s, d, c)	copyw((void*)(s), (void*)(d), (c))
47238555Skib#define bcopy_toio(s, d, c)	copyw((void*)(s), (void*)(d), (c))
48238555Skib#define bcopy_fromio(s, d, c)	copyw((void*)(s), (void*)(d), (c))
49114383Speter#define bzero_io(d, c)		bzero((void *)(d), (c))
50114383Speter#define fill_io(p, d, c)	fill((p), (void *)(d), (c))
51114383Speter#define fillw_io(p, d, c)	fillw((p), (void *)(d), (c))
52166090Smarius#elif defined(__ia64__) || defined(__sparc64__)
53166090Smarius#if defined(__ia64__)
54114199Smarcel#include <machine/bus.h>
55114199Smarcel#define	bcopy_fromio(s, d, c)	\
56114199Smarcel	bus_space_read_region_1(IA64_BUS_SPACE_MEM, s, 0, (void*)(d), c)
57114199Smarcel#define	bcopy_io(s, d, c)	\
58114199Smarcel	bus_space_copy_region_1(IA64_BUS_SPACE_MEM, s, 0, d, 0, c)
59114199Smarcel#define	bcopy_toio(s, d, c)	\
60114199Smarcel	bus_space_write_region_1(IA64_BUS_SPACE_MEM, d, 0, (void*)(s), c)
61114199Smarcel#define	bzero_io(d, c)		\
62119359Smarcel	bus_space_set_region_1(IA64_BUS_SPACE_MEM, (intptr_t)(d), 0, 0, c)
63114199Smarcel#define	fill_io(p, d, c)	\
64119359Smarcel	bus_space_set_region_1(IA64_BUS_SPACE_MEM, (intptr_t)(d), 0, p, c)
65114199Smarcel#define	fillw_io(p, d, c)	\
66119359Smarcel	bus_space_set_region_2(IA64_BUS_SPACE_MEM, (intptr_t)(d), 0, p, c)
67119359Smarcel#define	readb(a)		bus_space_read_1(IA64_BUS_SPACE_MEM, a, 0)
68119359Smarcel#define	readw(a)		bus_space_read_2(IA64_BUS_SPACE_MEM, a, 0)
69119359Smarcel#define	writeb(a, v)		bus_space_write_1(IA64_BUS_SPACE_MEM, a, 0, v)
70119359Smarcel#define	writew(a, v)		bus_space_write_2(IA64_BUS_SPACE_MEM, a, 0, v)
71119359Smarcel#define	writel(a, v)		bus_space_write_4(IA64_BUS_SPACE_MEM, a, 0, v)
72166090Smarius#endif /* __ia64__ */
73114199Smarcelstatic __inline void
74114199Smarcelfillw(int val, uint16_t *buf, size_t size)
75114199Smarcel{
76114199Smarcel	while (size--)
77114199Smarcel		*buf++ = val;
78114199Smarcel}
79153165Sru#elif defined(__powerpc__)
80124770Sgrehan
81124770Sgrehan#define bcopy_io(s, d, c)	ofwfb_bcopy((void *)(s), (void *)(d), (c))
82124770Sgrehan#define bcopy_toio(s, d, c)	ofwfb_bcopy((void *)(s), (void *)(d), (c))
83124770Sgrehan#define bcopy_fromio(s, d, c)	ofwfb_bcopy((void *)(s), (void *)(d), (c))
84124770Sgrehan#define bzero_io(d, c)		ofwfb_bzero((void *)(d), (c))
85124770Sgrehan#define fillw(p, d, c)		ofwfb_fillw((p), (void *)(d), (c))
86124770Sgrehan#define fillw_io(p, d, c)	ofwfb_fillw((p), (void *)(d), (c))
87124770Sgrehan#define	readw(a)		ofwfb_readw((u_int16_t *)(a))
88124770Sgrehan#define	writew(a, v)		ofwfb_writew((u_int16_t *)(a), (v))
89124770Sgrehanvoid ofwfb_bcopy(const void *s, void *d, size_t c);
90124770Sgrehanvoid ofwfb_bzero(void *d, size_t c);
91124770Sgrehanvoid ofwfb_fillw(int pat, void *base, size_t cnt);
92124770Sgrehanu_int16_t ofwfb_readw(u_int16_t *addr);
93124770Sgrehanvoid ofwfb_writew(u_int16_t *addr, u_int16_t val);
94124770Sgrehan
95166090Smarius#else /* !__i386__ && !__amd64__ && !__ia64__ && !__sparc64__ && !__powerpc__ */
9648104Syokota#define bcopy_io(s, d, c)	memcpy_io((d), (s), (c))
9748104Syokota#define bcopy_toio(s, d, c)	memcpy_toio((d), (void *)(s), (c))
9848104Syokota#define bcopy_fromio(s, d, c)	memcpy_fromio((void *)(d), (s), (c))
9948104Syokota#define bzero_io(d, c)		memset_io((d), 0, (c))
10048104Syokota#define fill_io(p, d, c)	memset_io((d), (p), (c))
10148104Syokota#define fillw(p, d, c)		memsetw((d), (p), (c))
10248104Syokota#define fillw_io(p, d, c)	memsetw_io((d), (p), (c))
10342421Syokota#endif /* !__i386__ */
10442421Syokota
10542421Syokota/* video function table */
10642421Syokotatypedef int vi_probe_t(int unit, video_adapter_t **adpp, void *arg, int flags);
10742421Syokotatypedef int vi_init_t(int unit, video_adapter_t *adp, int flags);
10842421Syokotatypedef int vi_get_info_t(video_adapter_t *adp, int mode, video_info_t *info);
10942421Syokotatypedef int vi_query_mode_t(video_adapter_t *adp, video_info_t *info);
11042421Syokotatypedef int vi_set_mode_t(video_adapter_t *adp, int mode);
111150686Smariustypedef int vi_save_font_t(video_adapter_t *adp, int page, int size, int width,
11242421Syokota			   u_char *data, int c, int count);
113150686Smariustypedef int vi_load_font_t(video_adapter_t *adp, int page, int size, int width,
11442421Syokota			   u_char *data, int c, int count);
11542421Syokotatypedef int vi_show_font_t(video_adapter_t *adp, int page);
11642421Syokotatypedef int vi_save_palette_t(video_adapter_t *adp, u_char *palette);
11742421Syokotatypedef int vi_load_palette_t(video_adapter_t *adp, u_char *palette);
11842421Syokotatypedef int vi_set_border_t(video_adapter_t *adp, int border);
11942421Syokotatypedef int vi_save_state_t(video_adapter_t *adp, void *p, size_t size);
12042421Syokotatypedef int vi_load_state_t(video_adapter_t *adp, void *p);
12142421Syokotatypedef int vi_set_win_org_t(video_adapter_t *adp, off_t offset);
12242421Syokotatypedef int vi_read_hw_cursor_t(video_adapter_t *adp, int *col, int *row);
12342421Syokotatypedef int vi_set_hw_cursor_t(video_adapter_t *adp, int col, int row);
12442421Syokotatypedef int vi_set_hw_cursor_shape_t(video_adapter_t *adp, int base,
12542421Syokota				     int height, int celsize, int blink);
12642421Syokotatypedef int vi_blank_display_t(video_adapter_t *adp, int mode);
12781038Syokota/* defined in sys/fbio.h
12848104Syokota#define V_DISPLAY_ON		0
12948104Syokota#define V_DISPLAY_BLANK		1
13048104Syokota#define V_DISPLAY_STAND_BY	2
13148104Syokota#define V_DISPLAY_SUSPEND	3
13281038Syokota*/
133201223Srnolandtypedef int vi_mmap_t(video_adapter_t *adp, vm_ooffset_t offset,
134201223Srnoland		      vm_paddr_t *paddr, int prot, vm_memattr_t *memattr);
13548104Syokotatypedef int vi_ioctl_t(video_adapter_t *adp, u_long cmd, caddr_t data);
13648104Syokotatypedef int vi_clear_t(video_adapter_t *adp);
13748104Syokotatypedef int vi_fill_rect_t(video_adapter_t *adp, int val, int x, int y,
13848104Syokota			   int cx, int cy);
13994617Sobrientypedef int vi_bitblt_t(video_adapter_t *adp, ...);
14042421Syokotatypedef int vi_diag_t(video_adapter_t *adp, int level);
14194617Sobrientypedef int vi_save_cursor_palette_t(video_adapter_t *adp, u_char *palette);
14294617Sobrientypedef int vi_load_cursor_palette_t(video_adapter_t *adp, u_char *palette);
14394617Sobrientypedef int vi_copy_t(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst,
14494617Sobrien		      int n);
14594617Sobrientypedef int vi_putp_t(video_adapter_t *adp, vm_offset_t off, u_int32_t p,
14694617Sobrien		       u_int32_t a, int size, int bpp, int bit_ltor,
14794617Sobrien		       int byte_ltor);
14894617Sobrientypedef int vi_putc_t(video_adapter_t *adp, vm_offset_t off, u_int8_t c,
14994617Sobrien		      u_int8_t a);
15094617Sobrientypedef int vi_puts_t(video_adapter_t *adp, vm_offset_t off, u_int16_t *s,
15194617Sobrien		       int len);
152150686Smariustypedef int vi_putm_t(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image,
153150686Smarius		      u_int32_t pixel_mask, int size, int width);
15442421Syokota
15542421Syokotatypedef struct video_switch {
15642421Syokota    vi_probe_t		*probe;
15742421Syokota    vi_init_t		*init;
15842421Syokota    vi_get_info_t	*get_info;
15942421Syokota    vi_query_mode_t	*query_mode;
16042421Syokota    vi_set_mode_t	*set_mode;
16142421Syokota    vi_save_font_t	*save_font;
16242421Syokota    vi_load_font_t	*load_font;
16342421Syokota    vi_show_font_t	*show_font;
16442421Syokota    vi_save_palette_t	*save_palette;
16542421Syokota    vi_load_palette_t	*load_palette;
16642421Syokota    vi_set_border_t	*set_border;
16742421Syokota    vi_save_state_t	*save_state;
16842421Syokota    vi_load_state_t	*load_state;
16942421Syokota    vi_set_win_org_t	*set_win_org;
17042421Syokota    vi_read_hw_cursor_t	*read_hw_cursor;
17142421Syokota    vi_set_hw_cursor_t	*set_hw_cursor;
17242421Syokota    vi_set_hw_cursor_shape_t *set_hw_cursor_shape;
17342421Syokota    vi_blank_display_t	*blank_display;
17442421Syokota    vi_mmap_t		*mmap;
17548104Syokota    vi_ioctl_t		*ioctl;
17648104Syokota    vi_clear_t		*clear;
17748104Syokota    vi_fill_rect_t	*fill_rect;
17848104Syokota    vi_bitblt_t		*bitblt;
17948104Syokota    int			(*reserved1)(void);
18048104Syokota    int			(*reserved2)(void);
18142421Syokota    vi_diag_t		*diag;
18294617Sobrien    vi_save_cursor_palette_t	*save_cursor_palette;
18394617Sobrien    vi_load_cursor_palette_t	*load_cursor_palette;
18494617Sobrien    vi_copy_t		*copy;
18594617Sobrien    vi_putp_t		*putp;
18694617Sobrien    vi_putc_t		*putc;
18794617Sobrien    vi_puts_t		*puts;
18894617Sobrien    vi_putm_t		*putm;
18942421Syokota} video_switch_t;
19042421Syokota
191174985Swkoszek#define vidd_probe(unit, adpp, arg, flags)				\
192174985Swkoszek	(*vidsw[(adp)->va_index]->probe)((unit), (adpp), (arg), (flags))
193174985Swkoszek#define vidd_init(unit, adp, flags)					\
194174985Swkoszek	(*vidsw[(adp)->va_index]->init)((unit), (adp), (flags))
195174985Swkoszek#define vidd_get_info(adp, mode, info)					\
196174985Swkoszek	(*vidsw[(adp)->va_index]->get_info)((adp), (mode), (info))
197174985Swkoszek#define vidd_query_mode(adp, mode)					\
198174985Swkoszek	(*vidsw[(adp)->va_index]->query_mode)((adp), (mode))
199174985Swkoszek#define vidd_set_mode(adp, mode)					\
20045616Sdes	(*vidsw[(adp)->va_index]->set_mode)((adp), (mode))
201174985Swkoszek#define vidd_save_font(adp, page, size, width, data, c, count)		\
202174985Swkoszek	(*vidsw[(adp)->va_index]->save_font)((adp), (page), (size),	\
203174985Swkoszek	    (width), (data), (c), (count))
204174985Swkoszek#define vidd_load_font(adp, page, size, width, data, c, count)		\
205174985Swkoszek	(*vidsw[(adp)->va_index]->load_font)((adp), (page), (size),	\
206174985Swkoszek	    (width), (data), (c), (count))
207174985Swkoszek#define vidd_show_font(adp, page)					\
208174985Swkoszek	(*vidsw[(adp)->va_index]->show_font)((adp), (page))
209174985Swkoszek#define vidd_save_palette(adp, pallete)					\
210174985Swkoszek	(*vidsw[(adp)->va_index]->save_palette)((adp), (pallete))
211174985Swkoszek#define vidd_load_palette(adp, pallete)					\
212174985Swkoszek	(*vidsw[(adp)->va_index]->load_palette)((adp), (pallete))
213174985Swkoszek#define vidd_set_border(adp, border)					\
21445616Sdes	(*vidsw[(adp)->va_index]->set_border)((adp), (border))
215174985Swkoszek#define vidd_save_state(adp, p, size)					\
216174985Swkoszek	(*vidsw[(adp)->va_index]->save_state)((adp), (p), (size))
217174985Swkoszek#define vidd_load_state(adp, p)						\
218174985Swkoszek	(*vidsw[(adp)->va_index]->load_state)((adp), (p))
219174985Swkoszek#define vidd_set_win_org(adp, offset)					\
220174985Swkoszek	(*vidsw[(adp)->va_index]->set_win_org)((adp), (offset))
221174985Swkoszek#define vidd_read_hw_cursor(adp, col, row)				\
222174985Swkoszek	(*vidsw[(adp)->va_index]->read_hw_cursor)((adp), (col), (row))
223174985Swkoszek#define vidd_set_hw_cursor(adp, col, row)				\
224174985Swkoszek	(*vidsw[(adp)->va_index]->set_hw_cursor)((adp), (col), (row))
225174985Swkoszek#define vidd_set_hw_cursor_shape(adp, base, height, celsize, blink)	\
226174985Swkoszek	(*vidsw[(adp)->va_index]->set_hw_cursor_shape)((adp), (base),	\
227174985Swkoszek	    (height), (celsize), (blink))
228174985Swkoszek#define vidd_blank_display(adp, mode)					\
229174985Swkoszek	(*vidsw[(adp)->va_index]->blank_display)((adp), (mode))
230201223Srnoland#define vidd_mmap(adp, offset, paddr, prot, memattr)			\
231201223Srnoland	(*vidsw[(adp)->va_index]->mmap)((adp), (offset), (paddr),	\
232201223Srnoland	    (prot), (memattr))
233174985Swkoszek#define vidd_ioctl(adp, cmd, data)					\
234174985Swkoszek	(*vidsw[(adp)->va_index]->ioctl)((adp), (cmd), (data))
235174985Swkoszek#define vidd_clear(adp)							\
236174985Swkoszek	(*vidsw[(adp)->va_index]->clear)((adp))
237174985Swkoszek#define vidd_fill_rect(adp, val, x, y, cx, cy)				\
238174985Swkoszek	(*vidsw[(adp)->va_index]->fill_rect)((adp), (val), (x), (y),	\
239174985Swkoszek	    (cx), (cy))
240174985Swkoszek#define vidd_bitblt(adp, ...)						\
241174985Swkoszek	(*vidsw[(adp)->va_index]->bitblt)(adp, __VA_ARGS__)
242174985Swkoszek#define vidd_diag(adp, level)						\
243174985Swkoszek	(*vidsw[(adp)->va_index]->diag)((adp), (level))
244174985Swkoszek#define vidd_save_cursor_palette(adp, palette)				\
245174985Swkoszek	(*vidsw[(adp)->va_index]->save_cursor_palette)((adp), (palette))
246174985Swkoszek#define vidd_load_cursor_palette(adp, palette)				\
247174985Swkoszek	(*vidsw[(adp)->va_index]->load_cursor_palette)((adp), (palette))
248174985Swkoszek#define vidd_copy(adp, src, dst, n)					\
249174985Swkoszek	(*vidsw[(adp)->va_index]->copy)((adp), (src), (dst), (n))
250174985Swkoszek#define vidd_putp(adp, offset, p, a, size, bpp, bit_ltor1, byte_ltor2)	\
251174985Swkoszek	(*vidsw[(adp)->va_index]->putp)((adp), (offset), (p), (a), 	\
252174985Swkoszek	    (size), (bpp), (bit_ltor1), (bit_ltor2))
253174985Swkoszek#define vidd_putc(adp, offset, c, a)					\
254174985Swkoszek	(*vidsw[(adp)->va_index]->putc)((adp), (offset), (c), (a))
255174985Swkoszek#define vidd_puts(adp, offset, s, len)					\
256174985Swkoszek	(*vidsw[(adp)->va_index]->puts)((adp), (offset), (s), (len))
257174985Swkoszek#define vidd_putm(adp, x, y, pixel_image, pixel_mask, size, width)	\
258174985Swkoszek	(*vidsw[(adp)->va_index]->putm)((adp), (x), (y), (pixel_image),	\
259174985Swkoszek	    (pixel_mask), (size), (width))
26045616Sdes
26142421Syokota/* video driver */
26242421Syokotatypedef struct video_driver {
26342421Syokota    char		*name;
26442421Syokota    video_switch_t	*vidsw;
26542421Syokota    int			(*configure)(int); /* backdoor for the console driver */
26642421Syokota} video_driver_t;
26742421Syokota
26842421Syokota#define VIDEO_DRIVER(name, sw, config)			\
26942421Syokota	static struct video_driver name##_driver = {	\
27042421Syokota		#name, &sw, config			\
27142421Syokota	};						\
27242421Syokota	DATA_SET(videodriver_set, name##_driver);
27342421Syokota
27442421Syokota/* global variables */
27542421Syokotaextern struct video_switch **vidsw;
27642421Syokota
27742421Syokota/* functions for the video card driver */
27842421Syokotaint		vid_register(video_adapter_t *adp);
27942421Syokotaint		vid_unregister(video_adapter_t *adp);
28042421Syokotavideo_switch_t	*vid_get_switch(char *name);
28142421Syokotavoid		vid_init_struct(video_adapter_t *adp, char *name, int type,
28242421Syokota				int unit);
28342421Syokota
28442421Syokota/* functions for the video card client */
28542421Syokotaint		vid_allocate(char *driver, int unit, void *id);
28642421Syokotaint		vid_release(video_adapter_t *adp, void *id);
28742421Syokotaint		vid_find_adapter(char *driver, int unit);
28842421Syokotavideo_adapter_t	*vid_get_adapter(int index);
28942421Syokota
29042421Syokota/* a backdoor for the console driver to tickle the video driver XXX */
29142421Syokotaint		vid_configure(int flags);
29242421Syokota#define VIO_PROBE_ONLY	(1 << 0)	/* probe only, don't initialize */
29342421Syokota
29442421Syokota#ifdef FB_INSTALL_CDEV
29542421Syokota
29642421Syokota/* virtual frame buffer driver functions */
297120465Sphkint		fb_attach(int unit, video_adapter_t *adp,
29842421Syokota			  struct cdevsw *cdevsw);
299120465Sphkint		fb_detach(int unit, video_adapter_t *adp,
30042421Syokota			  struct cdevsw *cdevsw);
30142421Syokota
30248104Syokota/* generic frame buffer cdev driver functions */
30348104Syokota
30448104Syokotatypedef struct genfb_softc {
30548104Syokota	int		gfb_flags;	/* flag/status bits */
30648104Syokota#define FB_OPEN		(1 << 0)
30748104Syokota} genfb_softc_t;
30848104Syokota
30948104Syokotaint		genfbopen(genfb_softc_t *sc, video_adapter_t *adp,
31083366Sjulian			  int flag, int mode, struct thread *td);
31148104Syokotaint		genfbclose(genfb_softc_t *sc, video_adapter_t *adp,
31283366Sjulian			   int flag, int mode, struct thread *td);
31348104Syokotaint		genfbread(genfb_softc_t *sc, video_adapter_t *adp,
31448104Syokota			  struct uio *uio, int flag);
31548104Syokotaint		genfbwrite(genfb_softc_t *sc, video_adapter_t *adp,
31648104Syokota			   struct uio *uio, int flag);
31748104Syokotaint		genfbioctl(genfb_softc_t *sc, video_adapter_t *adp,
31883366Sjulian			   u_long cmd, caddr_t arg, int flag, struct thread *td);
31948104Syokotaint		genfbmmap(genfb_softc_t *sc, video_adapter_t *adp,
320201223Srnoland			  vm_ooffset_t offset, vm_offset_t *paddr,
321201223Srnoland			  int prot, vm_memattr_t *memattr);
32248104Syokota
32342421Syokota#endif /* FB_INSTALL_CDEV */
32442421Syokota
32542421Syokota/* generic low-level driver functions */
32642421Syokota
32742421Syokotavoid		fb_dump_adp_info(char *driver, video_adapter_t *adp, int level);
32842421Syokotavoid		fb_dump_mode_info(char *driver, video_adapter_t *adp,
32942421Syokota				  video_info_t *info, int level);
33048104Syokotaint		fb_type(int adp_type);
33148104Syokotaint		fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg);
33242421Syokota
33355205Speter#endif /* _KERNEL */
33442421Syokota
33542421Syokota#endif /* !_DEV_FB_FBREG_H_ */
336