| 1 | /* | 
|---|
| 2 | * Copyright (c) 2011 Aeroflex Gaisler | 
|---|
| 3 | * | 
|---|
| 4 | * BSD license: | 
|---|
| 5 | * | 
|---|
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy | 
|---|
| 7 | * of this software and associated documentation files (the "Software"), to deal | 
|---|
| 8 | * in the Software without restriction, including without limitation the rights | 
|---|
| 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
|---|
| 10 | * copies of the Software, and to permit persons to whom the Software is | 
|---|
| 11 | * furnished to do so, subject to the following conditions: | 
|---|
| 12 | * | 
|---|
| 13 | * The above copyright notice and this permission notice shall be included in | 
|---|
| 14 | * all copies or substantial portions of the Software. | 
|---|
| 15 | * | 
|---|
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
|---|
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
|---|
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | 
|---|
| 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
|---|
| 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
|---|
| 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 
|---|
| 22 | * THE SOFTWARE. | 
|---|
| 23 | */ | 
|---|
| 24 |  | 
|---|
| 25 |  | 
|---|
| 26 | #ifndef _INCLUDE_LEON_h | 
|---|
| 27 | #define _INCLUDE_LEON_h | 
|---|
| 28 |  | 
|---|
| 29 | #include <asm-leon/leon3.h> | 
|---|
| 30 | #include <asm-leon/amba.h> | 
|---|
| 31 |  | 
|---|
| 32 | #ifdef __cplusplus | 
|---|
| 33 | extern "C" | 
|---|
| 34 | { | 
|---|
| 35 | #endif | 
|---|
| 36 |  | 
|---|
| 37 | /* psr defines */ | 
|---|
| 38 | #define SPARC_PSR_WIN_MASK  0x0000001f  /* bit   0-4 */ | 
|---|
| 39 | #define SPARC_PSR_ET_MASK   0x00000020  /* bit   5 */ | 
|---|
| 40 | #define SPARC_PSR_PS_MASK   0x00000040  /* bit   6 */ | 
|---|
| 41 | #define SPARC_PSR_S_MASK    0x00000080  /* bit   7 */ | 
|---|
| 42 | #define SPARC_PSR_PIL_MASK  0x00000F00  /* bits  8 - 11 */ | 
|---|
| 43 | #define SPARC_PSR_EF_MASK   0x00001000  /* bit  12 */ | 
|---|
| 44 | #define SPARC_PSR_EC_MASK   0x00002000  /* bit  13 */ | 
|---|
| 45 | #define SPARC_PSR_ICC_MASK  0x00F00000  /* bits 20 - 23 */ | 
|---|
| 46 | #define SPARC_PSR_VER_MASK  0x0F000000  /* bits 24 - 27 */ | 
|---|
| 47 | #define SPARC_PSR_IMPL_MASK 0xF0000000  /* bits 28 - 31 */ | 
|---|
| 48 | #define SPARC_PSR_PIL_SHIFT 8 | 
|---|
| 49 |  | 
|---|
| 50 | #define SPARC_NUM_REGWIN    _nwindows | 
|---|
| 51 |  | 
|---|
| 52 | #ifndef __ASSEMBLER__ | 
|---|
| 53 | extern int _nwindows; | 
|---|
| 54 | extern int _leon_version; | 
|---|
| 55 | #endif | 
|---|
| 56 |  | 
|---|
| 57 | #define LEON_VERSION _leon_version | 
|---|
| 58 |  | 
|---|
| 59 | /* | 
|---|
| 60 | *  Interrupt Sources | 
|---|
| 61 | * | 
|---|
| 62 | *  The interrupt source numbers directly map to the trap type and to | 
|---|
| 63 | *  the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask, | 
|---|
| 64 | *  and the Interrupt Pending Registers. | 
|---|
| 65 | */ | 
|---|
| 66 |  | 
|---|
| 67 | #define LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR  1 | 
|---|
| 68 | #define LEON2_INTERRUPT_UART_2_RX_TX             2 | 
|---|
| 69 | #define LEON2_INTERRUPT_UART_1_RX_TX             3 | 
|---|
| 70 | #define LEON23_INTERRUPT_UART_2_RX_TX            leon23_irqs[1] /*console.c */ | 
|---|
| 71 | #define LEON23_INTERRUPT_UART_1_RX_TX            leon23_irqs[0] /*console.c */ | 
|---|
| 72 | #define LEON_INTERRUPT_EXTERNAL_0                4 | 
|---|
| 73 | #define LEON_INTERRUPT_EXTERNAL_1                5 | 
|---|
| 74 | #define LEON_INTERRUPT_EXTERNAL_2                6 | 
|---|
| 75 | #define LEON_INTERRUPT_EXTERNAL_3                7 | 
|---|
| 76 | #define LEON2_INTERRUPT_TIMER1                   8 | 
|---|
| 77 | #define LEON2_INTERRUPT_TIMER2                   9 | 
|---|
| 78 | #define LEON23_INTERRUPT_TIMER1                  leon23_timerirqs[0]    /* timer.c */ | 
|---|
| 79 | #define LEON23_INTERRUPT_TIMER2                  leon23_timerirqs[1]    /* timer.c */ | 
|---|
| 80 | #define LEON_INTERRUPT_EMPTY1                    10 | 
|---|
| 81 | #define LEON_INTERRUPT_EMPTY2                    11 | 
|---|
| 82 | #define LEON_INTERRUPT_EMPTY3                    12 | 
|---|
| 83 | #define LEON_INTERRUPT_EMPTY4                    13 | 
|---|
| 84 | #define LEON_INTERRUPT_EMPTY5                    14 | 
|---|
| 85 | #define LEON_INTERRUPT_EMPTY6                    15 | 
|---|
| 86 |  | 
|---|
| 87 | #ifndef  __ASSEMBLER__ | 
|---|
| 88 |  | 
|---|
| 89 | /* | 
|---|
| 90 | *  Trap Types for on-chip peripherals | 
|---|
| 91 | * | 
|---|
| 92 | *  Source: Table 8 - Interrupt Trap Type and Default Priority Assignments | 
|---|
| 93 | * | 
|---|
| 94 | *  NOTE: The priority level for each source corresponds to the least | 
|---|
| 95 | *        significant nibble of the trap type. | 
|---|
| 96 | */ | 
|---|
| 97 |  | 
|---|
| 98 | #define LEON_TRAP_TYPE( _source ) SPARC_ASYNCHRONOUS_TRAP((_source) + 0x10) | 
|---|
| 99 |  | 
|---|
| 100 | #define LEON_TRAP_SOURCE( _trap ) ((_trap) - 0x10) | 
|---|
| 101 |  | 
|---|
| 102 | #define LEON_INT_TRAP( _trap ) \ | 
|---|
| 103 | ( (_trap) >= LEON_TRAP_TYPE( LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR ) && \ | 
|---|
| 104 | (_trap) <= LEON_TRAP_TYPE( LEON_INTERRUPT_EMPTY6 ) ) | 
|---|
| 105 |  | 
|---|
| 106 |  | 
|---|
| 107 | #endif | 
|---|
| 108 |  | 
|---|
| 109 |  | 
|---|
| 110 | /* | 
|---|
| 111 | *  The following defines the bits in Memory Configuration Register 1. | 
|---|
| 112 | */ | 
|---|
| 113 |  | 
|---|
| 114 | #define LEON_MEMORY_CONFIGURATION_PROM_SIZE_MASK  0x0003C000 | 
|---|
| 115 |  | 
|---|
| 116 | /* | 
|---|
| 117 | *  The following defines the bits in Memory Configuration Register 1. | 
|---|
| 118 | */ | 
|---|
| 119 |  | 
|---|
| 120 | #define LEON_MEMORY_CONFIGURATION_RAM_SIZE_MASK  0x00001E00 | 
|---|
| 121 |  | 
|---|
| 122 |  | 
|---|
| 123 | /* | 
|---|
| 124 | *  The following defines the bits in the Timer Control Register. | 
|---|
| 125 | */ | 
|---|
| 126 |  | 
|---|
| 127 | #define LEON_REG_TIMER_CONTROL_EN    0x00000001 /* 1 = enable counting */ | 
|---|
| 128 | /* 0 = hold scalar and counter */ | 
|---|
| 129 | #define LEON_REG_TIMER_CONTROL_RL    0x00000002 /* 1 = reload at 0 */ | 
|---|
| 130 | /* 0 = stop at 0 */ | 
|---|
| 131 | #define LEON_REG_TIMER_CONTROL_LD    0x00000004 /* 1 = load counter */ | 
|---|
| 132 | /* 0 = no function */ | 
|---|
| 133 |  | 
|---|
| 134 | /* | 
|---|
| 135 | *  The following defines the bits in the UART Control Registers. | 
|---|
| 136 | * | 
|---|
| 137 | */ | 
|---|
| 138 |  | 
|---|
| 139 | #define LEON_REG_UART_CONTROL_RTD  0x000000FF   /* RX/TX data */ | 
|---|
| 140 |  | 
|---|
| 141 | /* | 
|---|
| 142 | *  The following defines the bits in the LEON UART Status Registers. | 
|---|
| 143 | */ | 
|---|
| 144 |  | 
|---|
| 145 | #define LEON_REG_UART_STATUS_DR   0x00000001    /* Data Ready */ | 
|---|
| 146 | #define LEON_REG_UART_STATUS_TSE  0x00000002    /* TX Send Register Empty */ | 
|---|
| 147 | #define LEON_REG_UART_STATUS_THE  0x00000004    /* TX Hold Register Empty */ | 
|---|
| 148 | #define LEON_REG_UART_STATUS_BR   0x00000008    /* Break Error */ | 
|---|
| 149 | #define LEON_REG_UART_STATUS_OE   0x00000010    /* RX Overrun Error */ | 
|---|
| 150 | #define LEON_REG_UART_STATUS_PE   0x00000020    /* RX Parity Error */ | 
|---|
| 151 | #define LEON_REG_UART_STATUS_FE   0x00000040    /* RX Framing Error */ | 
|---|
| 152 | #define LEON_REG_UART_STATUS_ERR  0x00000078    /* Error Mask */ | 
|---|
| 153 |  | 
|---|
| 154 |  | 
|---|
| 155 | /* | 
|---|
| 156 | *  The following defines the bits in the LEON UART Status Registers. | 
|---|
| 157 | */ | 
|---|
| 158 |  | 
|---|
| 159 | #define LEON_REG_UART_CTRL_RE     0x00000001    /* Receiver enable */ | 
|---|
| 160 | #define LEON_REG_UART_CTRL_TE     0x00000002    /* Transmitter enable */ | 
|---|
| 161 | #define LEON_REG_UART_CTRL_RI     0x00000004    /* Receiver interrupt enable */ | 
|---|
| 162 | #define LEON_REG_UART_CTRL_TI     0x00000008    /* Transmitter interrupt enable */ | 
|---|
| 163 | #define LEON_REG_UART_CTRL_PS     0x00000010    /* Parity select */ | 
|---|
| 164 | #define LEON_REG_UART_CTRL_PE     0x00000020    /* Parity enable */ | 
|---|
| 165 | #define LEON_REG_UART_CTRL_FL     0x00000040    /* Flow control enable */ | 
|---|
| 166 | #define LEON_REG_UART_CTRL_LB     0x00000080    /* Loop Back enable */ | 
|---|
| 167 |  | 
|---|
| 168 | /* leon2 asis */ | 
|---|
| 169 | #define ASI_LEON2_IFLUSH                0x05 | 
|---|
| 170 | #define ASI_LEON2_DFLUSH                0x06 | 
|---|
| 171 | #define ASI_LEON2_CACHEMISS             1 | 
|---|
| 172 |  | 
|---|
| 173 | /* leon3 asis */ | 
|---|
| 174 | #define ASI_LEON3_IFLUSH                0x10 | 
|---|
| 175 | #define ASI_LEON3_DFLUSH                0x11 | 
|---|
| 176 | #define ASI_LEON3_CACHEMISS             1 | 
|---|
| 177 | #define ASI_LEON3_SYSCTRL               0x02 | 
|---|
| 178 |  | 
|---|
| 179 | #define ASI_LEON23_ITAG         0x0c | 
|---|
| 180 | #define ASI_LEON23_DTAG         0x0e | 
|---|
| 181 |  | 
|---|
| 182 |  | 
|---|
| 183 | #ifndef  __ASSEMBLER__ | 
|---|
| 184 |  | 
|---|
| 185 | unsigned int leonbare_leon23_loadnocache (unsigned int addr); | 
|---|
| 186 | unsigned int leonbare_leon23_loadnocache16 (unsigned int addr); | 
|---|
| 187 | unsigned int leonbare_leon23_loadnocache8 (unsigned int addr); | 
|---|
| 188 | unsigned int leonbare_leon23_storenocache (unsigned int addr, | 
|---|
| 189 | unsigned int value); | 
|---|
| 190 | unsigned int leonbare_leon23_storenocache16 (unsigned int addr, | 
|---|
| 191 | unsigned int value); | 
|---|
| 192 | unsigned int leonbare_leon23_storenocache8 (unsigned int addr, | 
|---|
| 193 | unsigned int value); | 
|---|
| 194 |  | 
|---|
| 195 | unsigned int leonbare_leon3_loadnocache (unsigned int addr); | 
|---|
| 196 | unsigned int leonbare_leon3_loadnocache16 (unsigned int addr); | 
|---|
| 197 | unsigned int leonbare_leon3_loadnocache8 (unsigned int addr); | 
|---|
| 198 |  | 
|---|
| 199 |  | 
|---|
| 200 | /* | 
|---|
| 201 | *  This is used to manipulate the on-chip registers. | 
|---|
| 202 | * | 
|---|
| 203 | *  The following symbol must be defined in the linkcmds file and point | 
|---|
| 204 | *  to the correct location. | 
|---|
| 205 | */ | 
|---|
| 206 |  | 
|---|
| 207 | extern unsigned long *LEON23_IRQ_mask_addr;   /* in peripherals.h */ | 
|---|
| 208 | extern unsigned long *LEON23_IRQ_force_addr;  /* in peripherals.h */ | 
|---|
| 209 | extern unsigned long *LEON23_IRQ_pending_addr;        /* in peripherals.h */ | 
|---|
| 210 | extern unsigned long *LEON23_IRQ_clear_addr;  /* in peripherals.h */ | 
|---|
| 211 |  | 
|---|
| 212 | /* | 
|---|
| 213 | *  Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask, | 
|---|
| 214 | *  and the Interrupt Pending Registers. | 
|---|
| 215 | * | 
|---|
| 216 | *  NOTE: For operations which are not atomic, this code disables interrupts | 
|---|
| 217 | *        to guarantee there are no intervening accesses to the same register. | 
|---|
| 218 | *        The operations which read the register, modify the value and then | 
|---|
| 219 | *        store the result back are vulnerable. | 
|---|
| 220 | */ | 
|---|
| 221 |  | 
|---|
| 222 | #define LEON_Clear_interrupt( _source ) \ | 
|---|
| 223 | do { \ | 
|---|
| 224 | (*LEON23_IRQ_clear_addr) = (1 << (_source)); \ | 
|---|
| 225 | } while (0) | 
|---|
| 226 |  | 
|---|
| 227 | #define LEON_Force_interrupt( _source ) \ | 
|---|
| 228 | do { \ | 
|---|
| 229 | (*LEON23_IRQ_force_addr) = (1 << (_source)); \ | 
|---|
| 230 | } while (0) | 
|---|
| 231 |  | 
|---|
| 232 | #define LEON_Is_interrupt_masked( _source ) \ | 
|---|
| 233 | ((*LEON23_IRQ_mask_addr) & (1 << (_source))) | 
|---|
| 234 |  | 
|---|
| 235 | #define LEON_Mask_interrupt( _source ) \ | 
|---|
| 236 | do { \ | 
|---|
| 237 | unsigned32 _level; \ | 
|---|
| 238 | \ | 
|---|
| 239 | _level = sparc_disable_interrupts(); \ | 
|---|
| 240 | (*LEON23_IRQ_mask_addr) &= ~(1 << (_source)); \ | 
|---|
| 241 | sparc_enable_interrupts( _level ); \ | 
|---|
| 242 | } while (0) | 
|---|
| 243 |  | 
|---|
| 244 | #define LEON_Unmask_interrupt( _source ) \ | 
|---|
| 245 | do { \ | 
|---|
| 246 | unsigned32 _level; \ | 
|---|
| 247 | \ | 
|---|
| 248 | _level = sparc_disable_interrupts(); \ | 
|---|
| 249 | (*LEON23_IRQ_mask_addr) |= (1 << (_source)); \ | 
|---|
| 250 | sparc_enable_interrupts( _level ); \ | 
|---|
| 251 | } while (0) | 
|---|
| 252 |  | 
|---|
| 253 | #define LEON_Disable_interrupt( _source, _previous ) \ | 
|---|
| 254 | do { \ | 
|---|
| 255 | unsigned32 _level; \ | 
|---|
| 256 | unsigned32 _mask = 1 << (_source); \ | 
|---|
| 257 | \ | 
|---|
| 258 | _level = sparc_disable_interrupts(); \ | 
|---|
| 259 | (_previous) = (*LEON23_IRQ_mask_addr); \ | 
|---|
| 260 | (*LEON23_IRQ_mask_addr) = _previous & ~_mask; \ | 
|---|
| 261 | sparc_enable_interrupts( _level ); \ | 
|---|
| 262 | (_previous) &= _mask; \ | 
|---|
| 263 | } while (0) | 
|---|
| 264 |  | 
|---|
| 265 | #define LEON_Restore_interrupt( _source, _previous ) \ | 
|---|
| 266 | do { \ | 
|---|
| 267 | unsigned32 _level; \ | 
|---|
| 268 | unsigned32 _mask = 1 << (_source); \ | 
|---|
| 269 | \ | 
|---|
| 270 | _level = sparc_disable_interrupts(); \ | 
|---|
| 271 | (*LEON23_IRQ_mask_addr) = \ | 
|---|
| 272 | ((*LEON23_IRQ_mask_addr) & ~_mask) | (_previous); \ | 
|---|
| 273 | sparc_enable_interrupts( _level ); \ | 
|---|
| 274 | } while (0) | 
|---|
| 275 |  | 
|---|
| 276 | /* | 
|---|
| 277 | *  Each timer control register is organized as follows: | 
|---|
| 278 | * | 
|---|
| 279 | *    D0 - Enable | 
|---|
| 280 | *          1 = enable counting | 
|---|
| 281 | *          0 = hold scaler and counter | 
|---|
| 282 | * | 
|---|
| 283 | *    D1 - Counter Reload | 
|---|
| 284 | *          1 = reload counter at zero and restart | 
|---|
| 285 | *          0 = stop counter at zero | 
|---|
| 286 | * | 
|---|
| 287 | *    D2 - Counter Load | 
|---|
| 288 | *          1 = load counter with preset value | 
|---|
| 289 | *          0 = no function | 
|---|
| 290 | * | 
|---|
| 291 | */ | 
|---|
| 292 |  | 
|---|
| 293 | #define LEON_REG_TIMER_COUNTER_IRQEN              0x00000008 | 
|---|
| 294 |  | 
|---|
| 295 | #define LEON_REG_TIMER_COUNTER_RELOAD_AT_ZERO     0x00000002 | 
|---|
| 296 | #define LEON_REG_TIMER_COUNTER_STOP_AT_ZERO       0x00000000 | 
|---|
| 297 |  | 
|---|
| 298 | #define LEON_REG_TIMER_COUNTER_LOAD_COUNTER       0x00000004 | 
|---|
| 299 |  | 
|---|
| 300 | #define LEON_REG_TIMER_COUNTER_ENABLE_COUNTING    0x00000001 | 
|---|
| 301 | #define LEON_REG_TIMER_COUNTER_DISABLE_COUNTING   0x00000000 | 
|---|
| 302 |  | 
|---|
| 303 | #define LEON_REG_TIMER_COUNTER_RELOAD_MASK        0x00000002 | 
|---|
| 304 | #define LEON_REG_TIMER_COUNTER_ENABLE_MASK        0x00000001 | 
|---|
| 305 |  | 
|---|
| 306 | #define LEON_REG_TIMER_COUNTER_DEFINED_MASK       0x00000003 | 
|---|
| 307 | #define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK  0x00000003 | 
|---|
| 308 |  | 
|---|
| 309 | /* console.c */ | 
|---|
| 310 | int lo_sprintf (char *buf, const char *fmt, ...); | 
|---|
| 311 |  | 
|---|
| 312 | /* do a virtual address read without cache */ | 
|---|
| 313 | static __inline__ unsigned long leon23_getpsr () | 
|---|
| 314 | { | 
|---|
| 315 | unsigned long retval; | 
|---|
| 316 | __asm__ __volatile__ ("mov %%psr, %0\n\t":"=r" (retval):); | 
|---|
| 317 | return retval; | 
|---|
| 318 | } | 
|---|
| 319 |  | 
|---|
| 320 | extern __inline__ void sparc_leon2_dcache_flush (void) | 
|---|
| 321 | { | 
|---|
| 322 | __asm__ | 
|---|
| 323 | __volatile__ ("sta %%g0, [%%g0] %0\n\t"::"i" | 
|---|
| 324 | (ASI_LEON2_IFLUSH):"memory"); | 
|---|
| 325 | __asm__ | 
|---|
| 326 | __volatile__ ("sta %%g0, [%%g0] %0\n\t"::"i" | 
|---|
| 327 | (ASI_LEON2_DFLUSH):"memory"); | 
|---|
| 328 | }; | 
|---|
| 329 |  | 
|---|
| 330 |  | 
|---|
| 331 | extern __inline__ void sparc_leon_dcache_flush (void) | 
|---|
| 332 | { | 
|---|
| 333 | switch (sparc_leon23_get_psr_version ()) | 
|---|
| 334 | { | 
|---|
| 335 | case 0: | 
|---|
| 336 | case 2: | 
|---|
| 337 | sparc_leon2_dcache_flush (); | 
|---|
| 338 | break; | 
|---|
| 339 | default: | 
|---|
| 340 | sparc_leon3_dcache_flush (); | 
|---|
| 341 | break; | 
|---|
| 342 | } | 
|---|
| 343 | } | 
|---|
| 344 |  | 
|---|
| 345 | extern int lolevelirqinstall (int irqnr, void (*handler) ()); | 
|---|
| 346 | extern unsigned long locore_readtbr (); | 
|---|
| 347 | extern void _leonbase_Stop (); | 
|---|
| 348 |  | 
|---|
| 349 | extern void uninstall_winoverflow_hook (); | 
|---|
| 350 | extern int install_winoverflow_hook (void (*func) (void)); | 
|---|
| 351 |  | 
|---|
| 352 | extern void sparc_leon23_icache_flush (); | 
|---|
| 353 | extern void sparc_leon23_dcache_flush (); | 
|---|
| 354 |  | 
|---|
| 355 | #endif /* ! __ASSEMBLER__ */ | 
|---|
| 356 |  | 
|---|
| 357 | #ifdef __cplusplus | 
|---|
| 358 | } | 
|---|
| 359 | #endif | 
|---|
| 360 |  | 
|---|
| 361 | #define TACODE_IRQCALL    2 | 
|---|
| 362 | #define TACODE_IRQCALL_FLUSH 6 | 
|---|
| 363 |  | 
|---|
| 364 | #define TACODE_FLUSH      3 | 
|---|
| 365 | #define TACODE_IRQCALLDIS 5 | 
|---|
| 366 |  | 
|---|
| 367 |  | 
|---|
| 368 |  | 
|---|
| 369 | #endif /* !_INCLUDE_LEON_h */ | 
|---|
| 370 | /* end of include file */ | 
|---|