akaros/user/perfmon/pfmlib_priv.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2002-2006 Hewlett-Packard Development Company, L.P.
   3 * Contributed by Stephane Eranian <eranian@hpl.hp.com>
   4 *
   5 * Permission is hereby granted, free of charge, to any person obtaining a copy
   6 * of this software and associated documentation files (the "Software"), to deal
   7 * in the Software without restriction, including without limitation the rights
   8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   9 * of the Software, and to permit persons to whom the Software is furnished to do so,
  10 * subject to the following conditions:
  11 *
  12 * The above copyright notice and this permission notice shall be included in all
  13 * copies or substantial portions of the Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * This file is part of libpfm, a performance monitoring support library for
  23 * applications on Linux.
  24 */
  25#ifndef __PFMLIB_PRIV_H__
  26#define __PFMLIB_PRIV_H__
  27#include <perfmon/pfmlib.h>
  28#include <string.h>
  29
  30#define PFM_PLM_ALL (PFM_PLM0|PFM_PLM1|PFM_PLM2|PFM_PLM3|PFM_PLMH)
  31
  32#define PFMLIB_ATTR_DELIM       ':'     /* event attribute delimiter */
  33#define PFMLIB_PMU_DELIM        "::"    /* pmu to event delimiter */
  34#define PFMLIB_EVENT_DELIM      ','     /* event to event delimiter */
  35
  36#define PFM_ATTR_I(y, d) { .name = (y), .type = PFM_ATTR_MOD_INTEGER, .desc = (d) }
  37#define PFM_ATTR_B(y, d) { .name = (y), .type = PFM_ATTR_MOD_BOOL, .desc = (d) }
  38#define PFM_ATTR_SKIP    { .name = "" } /* entry not populated (skipped) */
  39#define PFM_ATTR_NULL   { .name = NULL }
  40
  41#define PFMLIB_EVT_MAX_NAME_LEN 256
  42
  43/*
  44 * event identifier encoding:
  45 * bit 00-20 : event table specific index (2097152 possibilities)
  46 * bit 21-30 : PMU identifier (1024 possibilities)
  47 * bit 31    : reserved (to distinguish from a negative error code)
  48 */
  49#define PFMLIB_PMU_SHIFT        21
  50#define PFMLIB_PMU_MASK         0x3ff /* must fit PFM_PMU_MAX */
  51#define PFMLIB_PMU_PIDX_MASK    ((1<< PFMLIB_PMU_SHIFT)-1)
  52
  53typedef struct {
  54        const char      *name;  /* name */
  55        const char      *desc;  /* description */
  56        pfm_attr_t      type;   /* used to validate value (if any) */
  57} pfmlib_attr_desc_t;
  58
  59/*
  60 * attribute description passed to model-specific layer
  61 */
  62typedef struct {
  63        int     id;                     /* attribute index */
  64        union {
  65                uint64_t        ival;   /* integer value (incl. bool) */
  66                char            *sval;  /* string */
  67        };
  68} pfmlib_attr_t;
  69
  70/*
  71 * must be big enough to hold all possible priv level attributes
  72 */
  73#define PFMLIB_MAX_ATTRS        64 /* max attributes per event desc */
  74#define PFMLIB_MAX_ENCODING     4  /* max encoding length */
  75
  76/*
  77 * we add one entry to hold any raw umask users may specify
  78 * the last entry in pattrs[] hold that raw umask info
  79 */
  80#define PFMLIB_MAX_PATTRS       (PFMLIB_MAX_ATTRS+1)
  81
  82struct pfmlib_pmu;
  83typedef struct {
  84        struct pfmlib_pmu       *pmu;                           /* pmu */
  85        int                     dfl_plm;                        /* default priv level mask */
  86        int                     event;                          /* pidx */
  87        int                     npattrs;                        /* number of attrs in pattrs[] */
  88        int                     nattrs;                         /* number of attrs in attrs[] */
  89        pfm_os_t                osid;                           /* OS API requested */
  90        int                     count;                          /* number of entries in codes[] */
  91        pfmlib_attr_t           attrs[PFMLIB_MAX_ATTRS];        /* list of requested attributes */
  92
  93        pfm_event_attr_info_t   *pattrs;                        /* list of possible attributes */
  94        char                    fstr[PFMLIB_EVT_MAX_NAME_LEN];  /* fully qualified event string */
  95        uint64_t                codes[PFMLIB_MAX_ENCODING];     /* event encoding */
  96        void                    *os_data;
  97} pfmlib_event_desc_t;
  98#define modx(atdesc, a, z)      (atdesc[(a)].z)
  99#define attr(e, k)              ((e)->pattrs + (e)->attrs[k].id)
 100
 101typedef struct pfmlib_pmu {
 102        const char      *desc;                  /* PMU description */
 103        const char      *name;                  /* pmu short name */
 104        const char      *perf_name;             /* perf_event pmu name (optional) */
 105        pfm_pmu_t       pmu;                    /* PMU model */
 106        int             pme_count;              /* number of events */
 107        int             max_encoding;           /* max number of uint64_t to encode an event */
 108        int             flags;                  /* 16 LSB: common, 16 MSB: arch spec*/
 109        int             pmu_rev;                /* PMU model specific revision */
 110        int             num_cntrs;              /* number of generic counters */
 111        int             num_fixed_cntrs;        /* number of fixed counters */
 112        int             supported_plm;          /* supported priv levels */
 113
 114        pfm_pmu_type_t  type;                   /* PMU type */
 115        const void      *pe;                    /* pointer to event table */
 116
 117        const pfmlib_attr_desc_t *atdesc;       /* pointer to attrs table */
 118
 119        const int       cpu_family;             /* cpu family number for detection */
 120        const int       *cpu_models;            /* cpu model numbers for detection (zero terminated) */
 121
 122        int              (*pmu_detect)(void *this);
 123        int              (*pmu_init)(void *this);       /* optional */
 124        void             (*pmu_terminate)(void *this); /* optional */
 125        int              (*get_event_first)(void *this);
 126        int              (*get_event_next)(void *this, int pidx);
 127        int              (*get_event_info)(void *this, int pidx, pfm_event_info_t *info);
 128        unsigned int     (*get_event_nattrs)(void *this, int pidx);
 129        int              (*event_is_valid)(void *this, int pidx);
 130        int              (*can_auto_encode)(void *this, int pidx, int uidx);
 131
 132        int              (*get_event_attr_info)(void *this, int pidx, int umask_idx, pfm_event_attr_info_t *info);
 133        int              (*get_event_encoding[PFM_OS_MAX])(void *this, pfmlib_event_desc_t *e);
 134
 135        void             (*validate_pattrs[PFM_OS_MAX])(void *this, pfmlib_event_desc_t *e);
 136        int              (*os_detect[PFM_OS_MAX])(void *this);
 137        int              (*validate_table)(void *this, FILE *fp);
 138        /*
 139         * optional callbacks
 140         */
 141        int              (*get_num_events)(void *this);
 142        void             (*display_reg)(void *this, pfmlib_event_desc_t *e, void *val);
 143        int              (*match_event)(void *this, pfmlib_event_desc_t *d, const char *e, const char *s);
 144} pfmlib_pmu_t;
 145
 146typedef struct {
 147        const char                      *name;
 148        const pfmlib_attr_desc_t        *atdesc;
 149        pfm_os_t                        id;
 150        int                             flags;
 151        int                             (*detect)(void *this);
 152        int                             (*get_os_attr_info)(void *this, pfmlib_event_desc_t *e);
 153        int                             (*get_os_nattrs)(void *this, pfmlib_event_desc_t *e);
 154        int                             (*encode)(void *this, const char *str, int dfl_plm, void *args);
 155} pfmlib_os_t;
 156
 157#define PFMLIB_OS_FL_ACTIVATED  0x1     /* OS layer detected */
 158
 159/*
 160 * pfmlib_pmu_t common flags (LSB 16 bits)
 161 */
 162#define PFMLIB_PMU_FL_INIT      0x1     /* PMU initialized correctly */
 163#define PFMLIB_PMU_FL_ACTIVE    0x2     /* PMU is initialized + detected on host */
 164#define PFMLIB_PMU_FL_RAW_UMASK 0x4     /* PMU supports PFM_ATTR_RAW_UMASKS */
 165#define PFMLIB_PMU_FL_ARCH_DFL  0x8     /* PMU is arch default */
 166#define PFMLIB_PMU_FL_NO_SMPL   0x10    /* PMU does not support sampling */
 167
 168typedef struct {
 169        int     initdone;
 170        int     verbose;
 171        int     debug;
 172        int     inactive;
 173        char    *forced_pmu;
 174        char    *blacklist_pmus;
 175        FILE    *fp;    /* verbose and debug file descriptor, default stderr or PFMLIB_DEBUG_STDOUT */
 176} pfmlib_config_t;      
 177
 178#define PFMLIB_INITIALIZED()    (pfm_cfg.initdone)
 179
 180extern pfmlib_config_t pfm_cfg;
 181
 182extern void __pfm_vbprintf(const char *fmt,...);
 183extern void __pfm_dbprintf(const char *fmt,...);
 184extern void pfmlib_strconcat(char *str, size_t max, const char *fmt, ...);
 185extern int pfmlib_getl(char **buffer, size_t *len, FILE *fp);
 186extern void pfmlib_compact_pattrs(pfmlib_event_desc_t *e, int i);
 187#define evt_strcat(str, fmt, a...) pfmlib_strconcat(str, PFMLIB_EVT_MAX_NAME_LEN, fmt, a)
 188
 189extern int pfmlib_parse_event(const char *event, pfmlib_event_desc_t *d);
 190extern int pfmlib_build_fstr(pfmlib_event_desc_t *e, char **fstr);
 191extern void pfmlib_sort_attr(pfmlib_event_desc_t *e);
 192extern pfmlib_pmu_t * pfmlib_get_pmu_by_type(pfm_pmu_type_t t);
 193extern void pfmlib_release_event(pfmlib_event_desc_t *e);
 194
 195extern size_t pfmlib_check_struct(void *st, size_t usz, size_t refsz, size_t sz);
 196
 197#ifdef CONFIG_PFMLIB_DEBUG
 198#define DPRINT(fmt, a...) \
 199        do { \
 200                __pfm_dbprintf("%s (%s.%d): " fmt, __FILE__, __func__, __LINE__, ## a); \
 201        } while (0)
 202#else
 203#define DPRINT(fmt, a...) do { } while (0)
 204#endif
 205
 206extern pfmlib_pmu_t montecito_support;
 207extern pfmlib_pmu_t itanium2_support;
 208extern pfmlib_pmu_t itanium_support;
 209extern pfmlib_pmu_t generic_ia64_support;
 210extern pfmlib_pmu_t amd64_k7_support;
 211extern pfmlib_pmu_t amd64_k8_revb_support;
 212extern pfmlib_pmu_t amd64_k8_revc_support;
 213extern pfmlib_pmu_t amd64_k8_revd_support;
 214extern pfmlib_pmu_t amd64_k8_reve_support;
 215extern pfmlib_pmu_t amd64_k8_revf_support;
 216extern pfmlib_pmu_t amd64_k8_revg_support;
 217extern pfmlib_pmu_t amd64_fam10h_barcelona_support;
 218extern pfmlib_pmu_t amd64_fam10h_shanghai_support;
 219extern pfmlib_pmu_t amd64_fam10h_istanbul_support;
 220extern pfmlib_pmu_t amd64_fam11h_turion_support;
 221extern pfmlib_pmu_t amd64_fam12h_llano_support;
 222extern pfmlib_pmu_t amd64_fam14h_bobcat_support;
 223extern pfmlib_pmu_t amd64_fam15h_interlagos_support;
 224extern pfmlib_pmu_t amd64_fam15h_nb_support;
 225extern pfmlib_pmu_t intel_p6_support;
 226extern pfmlib_pmu_t intel_ppro_support;
 227extern pfmlib_pmu_t intel_pii_support;
 228extern pfmlib_pmu_t intel_pm_support;
 229extern pfmlib_pmu_t sicortex_support;
 230extern pfmlib_pmu_t netburst_support;
 231extern pfmlib_pmu_t netburst_p_support;
 232extern pfmlib_pmu_t intel_coreduo_support;
 233extern pfmlib_pmu_t intel_core_support;
 234extern pfmlib_pmu_t intel_x86_arch_support;
 235extern pfmlib_pmu_t intel_atom_support;
 236extern pfmlib_pmu_t intel_nhm_support;
 237extern pfmlib_pmu_t intel_nhm_ex_support;
 238extern pfmlib_pmu_t intel_nhm_unc_support;
 239extern pfmlib_pmu_t intel_snb_support;
 240extern pfmlib_pmu_t intel_snb_unc_cbo0_support;
 241extern pfmlib_pmu_t intel_snb_unc_cbo1_support;
 242extern pfmlib_pmu_t intel_snb_unc_cbo2_support;
 243extern pfmlib_pmu_t intel_snb_unc_cbo3_support;
 244extern pfmlib_pmu_t intel_snb_ep_support;
 245extern pfmlib_pmu_t intel_ivb_support;
 246extern pfmlib_pmu_t intel_ivb_unc_cbo0_support;
 247extern pfmlib_pmu_t intel_ivb_unc_cbo1_support;
 248extern pfmlib_pmu_t intel_ivb_unc_cbo2_support;
 249extern pfmlib_pmu_t intel_ivb_unc_cbo3_support;
 250extern pfmlib_pmu_t intel_ivb_ep_support;
 251extern pfmlib_pmu_t intel_hsw_support;
 252extern pfmlib_pmu_t intel_hsw_ep_support;
 253extern pfmlib_pmu_t intel_bdw_support;
 254extern pfmlib_pmu_t intel_rapl_support;
 255extern pfmlib_pmu_t intel_snbep_unc_cb0_support;
 256extern pfmlib_pmu_t intel_snbep_unc_cb1_support;
 257extern pfmlib_pmu_t intel_snbep_unc_cb2_support;
 258extern pfmlib_pmu_t intel_snbep_unc_cb3_support;
 259extern pfmlib_pmu_t intel_snbep_unc_cb4_support;
 260extern pfmlib_pmu_t intel_snbep_unc_cb5_support;
 261extern pfmlib_pmu_t intel_snbep_unc_cb6_support;
 262extern pfmlib_pmu_t intel_snbep_unc_cb7_support;
 263extern pfmlib_pmu_t intel_snbep_unc_ha_support;
 264extern pfmlib_pmu_t intel_snbep_unc_imc0_support;
 265extern pfmlib_pmu_t intel_snbep_unc_imc1_support;
 266extern pfmlib_pmu_t intel_snbep_unc_imc2_support;
 267extern pfmlib_pmu_t intel_snbep_unc_imc3_support;
 268extern pfmlib_pmu_t intel_snbep_unc_pcu_support;
 269extern pfmlib_pmu_t intel_snbep_unc_qpi0_support;
 270extern pfmlib_pmu_t intel_snbep_unc_qpi1_support;
 271extern pfmlib_pmu_t intel_snbep_unc_ubo_support;
 272extern pfmlib_pmu_t intel_snbep_unc_r2pcie_support;
 273extern pfmlib_pmu_t intel_snbep_unc_r3qpi0_support;
 274extern pfmlib_pmu_t intel_snbep_unc_r3qpi1_support;
 275extern pfmlib_pmu_t intel_ivbep_unc_cb0_support;
 276extern pfmlib_pmu_t intel_ivbep_unc_cb1_support;
 277extern pfmlib_pmu_t intel_ivbep_unc_cb2_support;
 278extern pfmlib_pmu_t intel_ivbep_unc_cb3_support;
 279extern pfmlib_pmu_t intel_ivbep_unc_cb4_support;
 280extern pfmlib_pmu_t intel_ivbep_unc_cb5_support;
 281extern pfmlib_pmu_t intel_ivbep_unc_cb6_support;
 282extern pfmlib_pmu_t intel_ivbep_unc_cb7_support;
 283extern pfmlib_pmu_t intel_ivbep_unc_cb8_support;
 284extern pfmlib_pmu_t intel_ivbep_unc_cb9_support;
 285extern pfmlib_pmu_t intel_ivbep_unc_cb10_support;
 286extern pfmlib_pmu_t intel_ivbep_unc_cb11_support;
 287extern pfmlib_pmu_t intel_ivbep_unc_cb12_support;
 288extern pfmlib_pmu_t intel_ivbep_unc_cb13_support;
 289extern pfmlib_pmu_t intel_ivbep_unc_cb14_support;
 290extern pfmlib_pmu_t intel_ivbep_unc_ha0_support;
 291extern pfmlib_pmu_t intel_ivbep_unc_ha1_support;
 292extern pfmlib_pmu_t intel_ivbep_unc_imc0_support;
 293extern pfmlib_pmu_t intel_ivbep_unc_imc1_support;
 294extern pfmlib_pmu_t intel_ivbep_unc_imc2_support;
 295extern pfmlib_pmu_t intel_ivbep_unc_imc3_support;
 296extern pfmlib_pmu_t intel_ivbep_unc_imc4_support;
 297extern pfmlib_pmu_t intel_ivbep_unc_imc5_support;
 298extern pfmlib_pmu_t intel_ivbep_unc_imc6_support;
 299extern pfmlib_pmu_t intel_ivbep_unc_imc7_support;
 300extern pfmlib_pmu_t intel_ivbep_unc_pcu_support;
 301extern pfmlib_pmu_t intel_ivbep_unc_qpi0_support;
 302extern pfmlib_pmu_t intel_ivbep_unc_qpi1_support;
 303extern pfmlib_pmu_t intel_ivbep_unc_qpi2_support;
 304extern pfmlib_pmu_t intel_ivbep_unc_ubo_support;
 305extern pfmlib_pmu_t intel_ivbep_unc_r2pcie_support;
 306extern pfmlib_pmu_t intel_ivbep_unc_r3qpi0_support;
 307extern pfmlib_pmu_t intel_ivbep_unc_r3qpi1_support;
 308extern pfmlib_pmu_t intel_ivbep_unc_r3qpi2_support;
 309extern pfmlib_pmu_t intel_ivbep_unc_irp_support;
 310extern pfmlib_pmu_t intel_knc_support;
 311extern pfmlib_pmu_t intel_slm_support;
 312extern pfmlib_pmu_t power4_support;
 313extern pfmlib_pmu_t ppc970_support;
 314extern pfmlib_pmu_t ppc970mp_support;
 315extern pfmlib_pmu_t power5_support;
 316extern pfmlib_pmu_t power5p_support;
 317extern pfmlib_pmu_t power6_support;
 318extern pfmlib_pmu_t power7_support;
 319extern pfmlib_pmu_t power8_support;
 320extern pfmlib_pmu_t torrent_support;
 321extern pfmlib_pmu_t sparc_support;
 322extern pfmlib_pmu_t sparc_ultra12_support;
 323extern pfmlib_pmu_t sparc_ultra3_support;
 324extern pfmlib_pmu_t sparc_ultra3i_support;
 325extern pfmlib_pmu_t sparc_ultra3plus_support;
 326extern pfmlib_pmu_t sparc_ultra4plus_support;
 327extern pfmlib_pmu_t sparc_niagara1_support;
 328extern pfmlib_pmu_t sparc_niagara2_support;
 329extern pfmlib_pmu_t cell_support;
 330extern pfmlib_pmu_t perf_event_support;
 331extern pfmlib_pmu_t perf_event_raw_support;
 332extern pfmlib_pmu_t intel_wsm_sp_support;
 333extern pfmlib_pmu_t intel_wsm_dp_support;
 334extern pfmlib_pmu_t intel_wsm_unc_support;
 335extern pfmlib_pmu_t arm_cortex_a7_support;
 336extern pfmlib_pmu_t arm_cortex_a8_support;
 337extern pfmlib_pmu_t arm_cortex_a9_support;
 338extern pfmlib_pmu_t arm_cortex_a15_support;
 339extern pfmlib_pmu_t arm_1176_support;
 340extern pfmlib_pmu_t arm_qcom_krait_support;
 341extern pfmlib_pmu_t arm_cortex_a57_support;
 342extern pfmlib_pmu_t arm_cortex_a53_support;
 343extern pfmlib_pmu_t arm_xgene_support;
 344extern pfmlib_pmu_t mips_74k_support;
 345extern pfmlib_pmu_t s390x_cpum_cf_support;
 346extern pfmlib_pmu_t s390x_cpum_sf_support;
 347
 348extern pfmlib_os_t *pfmlib_os;
 349extern pfmlib_os_t pfmlib_os_perf;
 350extern pfmlib_os_t pfmlib_os_perf_ext;
 351
 352extern char *pfmlib_forced_pmu;
 353
 354#define this_pe(t)              (((pfmlib_pmu_t *)t)->pe)
 355#define this_atdesc(t)          (((pfmlib_pmu_t *)t)->atdesc)
 356
 357#define LIBPFM_ARRAY_SIZE(a) (sizeof(a) / sizeof(typeof(*(a))))
 358/*
 359 * population count (number of bits set)
 360 */
 361static inline int
 362pfmlib_popcnt(unsigned long v)
 363{
 364        int sum = 0;
 365
 366        for(; v ; v >>=1) {
 367                if (v & 0x1) sum++;
 368        }
 369        return sum;
 370}
 371
 372/*
 373 * find next bit set
 374 */
 375static inline size_t
 376pfmlib_fnb(unsigned long value, size_t nbits, int p)
 377{
 378        unsigned long m;
 379        size_t i;
 380
 381        for(i=p; i < nbits; i++) {
 382                m = 1 << i;
 383                if (value & m)
 384                        return i;
 385        }
 386        return i;
 387}
 388
 389/*
 390 * PMU + internal idx -> external opaque idx
 391 */
 392static inline int
 393pfmlib_pidx2idx(pfmlib_pmu_t *pmu, int pidx)
 394{
 395        int idx;
 396
 397        idx = pmu->pmu << PFMLIB_PMU_SHIFT;
 398        idx |= pidx;
 399
 400        return  idx;
 401}
 402
 403#define pfmlib_for_each_bit(x, m) \
 404        for((x) = pfmlib_fnb((m), (sizeof(m)<<3), 0); (x) < (sizeof(m)<<3); (x) = pfmlib_fnb((m), (sizeof(m)<<3), (x)+1))
 405
 406#ifdef __linux__
 407
 408#define PFMLIB_VALID_PERF_PATTRS(f)  \
 409        .validate_pattrs[PFM_OS_PERF_EVENT] = f, \
 410        .validate_pattrs[PFM_OS_PERF_EVENT_EXT] = f
 411
 412#define PFMLIB_ENCODE_PERF(f)  \
 413        .get_event_encoding[PFM_OS_PERF_EVENT] = f, \
 414        .get_event_encoding[PFM_OS_PERF_EVENT_EXT] = f
 415
 416#define PFMLIB_OS_DETECT(f)  \
 417        .os_detect[PFM_OS_PERF_EVENT] = f, \
 418        .os_detect[PFM_OS_PERF_EVENT_EXT] = f
 419#else
 420#define PFMLIB_VALID_PERF_PATTRS(f) \
 421        .validate_pattrs[PFM_OS_PERF_EVENT] = NULL, \
 422        .validate_pattrs[PFM_OS_PERF_EVENT_EXT] = NULL
 423
 424#define PFMLIB_ENCODE_PERF(f)  \
 425        .get_event_encoding[PFM_OS_PERF_EVENT] = NULL, \
 426        .get_event_encoding[PFM_OS_PERF_EVENT_EXT] = NULL
 427
 428#define PFMLIB_OS_DETECT(f)  \
 429        .os_detect[PFM_OS_PERF_EVENT] = NULL, \
 430        .os_detect[PFM_OS_PERF_EVENT_EXT] = NULL
 431#endif
 432
 433static inline int
 434is_empty_attr(const pfmlib_attr_desc_t *a)
 435{
 436        return !a || !a->name || strlen(a->name) == 0 ? 1 : 0;
 437}
 438
 439#endif /* __PFMLIB_PRIV_H__ */
 440