| 1 | /* SPDX-License-Identifier: MIT */ |
| 2 | /* |
| 3 | * Copyright (c) 2020-2024, Intel Corporation. |
| 4 | */ |
| 5 | |
| 6 | #ifndef VPU_BOOT_API_H |
| 7 | #define VPU_BOOT_API_H |
| 8 | |
| 9 | /* |
| 10 | * The below values will be used to construct the version info this way: |
| 11 | * fw_bin_header->api_version[VPU_BOOT_API_VER_ID] = (VPU_BOOT_API_VER_MAJOR << 16) | |
| 12 | * VPU_BOOT_API_VER_MINOR; |
| 13 | * VPU_BOOT_API_VER_PATCH will be ignored. KMD and compatibility is not affected if this changes |
| 14 | * This information is collected by using vpuip_2/application/vpuFirmware/make_std_fw_image.py |
| 15 | * If a header is missing this info we ignore the header, if a header is missing or contains |
| 16 | * partial info a build error will be generated. |
| 17 | */ |
| 18 | |
| 19 | /* |
| 20 | * Major version changes that break backward compatibility. |
| 21 | * Major version must start from 1 and can only be incremented. |
| 22 | */ |
| 23 | #define VPU_BOOT_API_VER_MAJOR 3 |
| 24 | |
| 25 | /* |
| 26 | * Minor version changes when API backward compatibility is preserved. |
| 27 | * Resets to 0 if Major version is incremented. |
| 28 | */ |
| 29 | #define VPU_BOOT_API_VER_MINOR 28 |
| 30 | |
| 31 | /* |
| 32 | * API header changed (field names, documentation, formatting) but API itself has not been changed |
| 33 | */ |
| 34 | #define VPU_BOOT_API_VER_PATCH 3 |
| 35 | |
| 36 | /* |
| 37 | * Index in the API version table |
| 38 | * Must be unique for each API |
| 39 | */ |
| 40 | #define VPU_BOOT_API_VER_INDEX 0 |
| 41 | |
| 42 | #pragma pack(push, 4) |
| 43 | |
| 44 | /* |
| 45 | * Firmware image header format |
| 46 | */ |
| 47 | #define 4096 |
| 48 | #define 0x1 |
| 49 | #define VPU_FW_VERSION_SIZE 32 |
| 50 | #define VPU_FW_API_VER_NUM 16 |
| 51 | |
| 52 | struct { |
| 53 | u32 ; |
| 54 | u32 ; |
| 55 | u64 ; |
| 56 | u32 ; |
| 57 | u64 ; |
| 58 | u8 [VPU_FW_VERSION_SIZE]; |
| 59 | u32 ; |
| 60 | u64 ; |
| 61 | u32 ; |
| 62 | u64 ; |
| 63 | u32 [VPU_FW_API_VER_NUM]; |
| 64 | /* Size of memory require for firmware execution */ |
| 65 | u32 ; |
| 66 | u32 ; |
| 67 | /* |
| 68 | * Size of primary preemption buffer, assuming a 2-job submission queue. |
| 69 | * NOTE: host driver is expected to adapt size accordingly to actual |
| 70 | * submission queue size and device capabilities. |
| 71 | */ |
| 72 | u32 ; |
| 73 | /* |
| 74 | * Size of secondary preemption buffer, assuming a 2-job submission queue. |
| 75 | * NOTE: host driver is expected to adapt size accordingly to actual |
| 76 | * submission queue size and device capabilities. |
| 77 | */ |
| 78 | u32 ; |
| 79 | /* |
| 80 | * Maximum preemption buffer size that the FW can use: no need for the host |
| 81 | * driver to allocate more space than that specified by these fields. |
| 82 | * A value of 0 means no declared limit. |
| 83 | */ |
| 84 | u32 ; |
| 85 | u32 ; |
| 86 | /* Space reserved for future preemption-related fields. */ |
| 87 | u32 [4]; |
| 88 | /* FW image read only section start address, 4KB aligned */ |
| 89 | u64 ; |
| 90 | /* FW image read only section size, 4KB aligned */ |
| 91 | u32 ; |
| 92 | u32 ; |
| 93 | }; |
| 94 | |
| 95 | /* |
| 96 | * Firmware boot parameters format |
| 97 | */ |
| 98 | |
| 99 | #define VPU_BOOT_PLL_COUNT 3 |
| 100 | #define VPU_BOOT_PLL_OUT_COUNT 4 |
| 101 | |
| 102 | /** Values for boot_type field */ |
| 103 | #define VPU_BOOT_TYPE_COLDBOOT 0 |
| 104 | #define VPU_BOOT_TYPE_WARMBOOT 1 |
| 105 | |
| 106 | /** Value for magic filed */ |
| 107 | #define VPU_BOOT_PARAMS_MAGIC 0x10000 |
| 108 | |
| 109 | /** VPU scheduling mode. By default, OS scheduling is used. */ |
| 110 | #define VPU_SCHEDULING_MODE_OS 0 |
| 111 | #define VPU_SCHEDULING_MODE_HW 1 |
| 112 | |
| 113 | enum VPU_BOOT_L2_CACHE_CFG_TYPE { |
| 114 | VPU_BOOT_L2_CACHE_CFG_UPA = 0, |
| 115 | VPU_BOOT_L2_CACHE_CFG_NN = 1, |
| 116 | VPU_BOOT_L2_CACHE_CFG_NUM = 2 |
| 117 | }; |
| 118 | |
| 119 | /** VPU MCA ECC signalling mode. By default, no signalling is used */ |
| 120 | enum VPU_BOOT_MCA_ECC_SIGNAL_TYPE { |
| 121 | VPU_BOOT_MCA_ECC_NONE = 0, |
| 122 | VPU_BOOT_MCA_ECC_CORR = 1, |
| 123 | VPU_BOOT_MCA_ECC_FATAL = 2, |
| 124 | VPU_BOOT_MCA_ECC_BOTH = 3 |
| 125 | }; |
| 126 | |
| 127 | /** |
| 128 | * Logging destinations. |
| 129 | * |
| 130 | * Logging output can be directed to different logging destinations. This enum |
| 131 | * defines the list of logging destinations supported by the VPU firmware (NOTE: |
| 132 | * a specific VPU FW binary may support only a subset of such output |
| 133 | * destinations, depending on the target platform and compile options). |
| 134 | */ |
| 135 | enum vpu_trace_destination { |
| 136 | VPU_TRACE_DESTINATION_PIPEPRINT = 0x1, |
| 137 | VPU_TRACE_DESTINATION_VERBOSE_TRACING = 0x2, |
| 138 | VPU_TRACE_DESTINATION_NORTH_PEAK = 0x4, |
| 139 | }; |
| 140 | |
| 141 | /* |
| 142 | * Processor bit shifts (for loggable HW components). |
| 143 | */ |
| 144 | #define VPU_TRACE_PROC_BIT_RESERVED 0 |
| 145 | #define VPU_TRACE_PROC_BIT_LRT 1 |
| 146 | #define VPU_TRACE_PROC_BIT_LNN 2 |
| 147 | #define VPU_TRACE_PROC_BIT_SHV_0 3 |
| 148 | #define VPU_TRACE_PROC_BIT_SHV_1 4 |
| 149 | #define VPU_TRACE_PROC_BIT_SHV_2 5 |
| 150 | #define VPU_TRACE_PROC_BIT_SHV_3 6 |
| 151 | #define VPU_TRACE_PROC_BIT_SHV_4 7 |
| 152 | #define VPU_TRACE_PROC_BIT_SHV_5 8 |
| 153 | #define VPU_TRACE_PROC_BIT_SHV_6 9 |
| 154 | #define VPU_TRACE_PROC_BIT_SHV_7 10 |
| 155 | #define VPU_TRACE_PROC_BIT_SHV_8 11 |
| 156 | #define VPU_TRACE_PROC_BIT_SHV_9 12 |
| 157 | #define VPU_TRACE_PROC_BIT_SHV_10 13 |
| 158 | #define VPU_TRACE_PROC_BIT_SHV_11 14 |
| 159 | #define VPU_TRACE_PROC_BIT_SHV_12 15 |
| 160 | #define VPU_TRACE_PROC_BIT_SHV_13 16 |
| 161 | #define VPU_TRACE_PROC_BIT_SHV_14 17 |
| 162 | #define VPU_TRACE_PROC_BIT_SHV_15 18 |
| 163 | #define VPU_TRACE_PROC_BIT_ACT_SHV_0 19 |
| 164 | #define VPU_TRACE_PROC_BIT_ACT_SHV_1 20 |
| 165 | #define VPU_TRACE_PROC_BIT_ACT_SHV_2 21 |
| 166 | #define VPU_TRACE_PROC_BIT_ACT_SHV_3 22 |
| 167 | #define VPU_TRACE_PROC_NO_OF_HW_DEVS 23 |
| 168 | |
| 169 | /* VPU 30xx HW component IDs are sequential, so define first and last IDs. */ |
| 170 | #define VPU_TRACE_PROC_BIT_30XX_FIRST VPU_TRACE_PROC_BIT_LRT |
| 171 | #define VPU_TRACE_PROC_BIT_30XX_LAST VPU_TRACE_PROC_BIT_SHV_15 |
| 172 | |
| 173 | struct vpu_boot_l2_cache_config { |
| 174 | u8 use; |
| 175 | u8 cfg; |
| 176 | }; |
| 177 | |
| 178 | struct vpu_warm_boot_section { |
| 179 | u32 src; |
| 180 | u32 dst; |
| 181 | u32 size; |
| 182 | u32 core_id; |
| 183 | u32 is_clear_op; |
| 184 | }; |
| 185 | |
| 186 | /* |
| 187 | * When HW scheduling mode is enabled, a present period is defined. |
| 188 | * It will be used by VPU to swap between normal and focus priorities |
| 189 | * to prevent starving of normal priority band (when implemented). |
| 190 | * Host must provide a valid value at boot time in |
| 191 | * `vpu_focus_present_timer_ms`. If the value provided by the host is not within the |
| 192 | * defined range a default value will be used. Here we define the min. and max. |
| 193 | * allowed values and the and default value of the present period. Units are milliseconds. |
| 194 | */ |
| 195 | #define VPU_PRESENT_CALL_PERIOD_MS_DEFAULT 50 |
| 196 | #define VPU_PRESENT_CALL_PERIOD_MS_MIN 16 |
| 197 | #define VPU_PRESENT_CALL_PERIOD_MS_MAX 10000 |
| 198 | |
| 199 | /** |
| 200 | * Macros to enable various power profiles within the NPU. |
| 201 | * To be defined as part of 32 bit mask. |
| 202 | */ |
| 203 | #define POWER_PROFILE_SURVIVABILITY 0x1 |
| 204 | |
| 205 | /** |
| 206 | * Enum for dvfs_mode boot param. |
| 207 | */ |
| 208 | enum vpu_governor { |
| 209 | VPU_GOV_DEFAULT = 0, /* Default Governor for the system */ |
| 210 | VPU_GOV_MAX_PERFORMANCE = 1, /* Maximum performance governor */ |
| 211 | VPU_GOV_ON_DEMAND = 2, /* On Demand frequency control governor */ |
| 212 | VPU_GOV_POWER_SAVE = 3, /* Power save governor */ |
| 213 | VPU_GOV_ON_DEMAND_PRIORITY_AWARE = 4 /* On Demand priority based governor */ |
| 214 | }; |
| 215 | |
| 216 | struct vpu_boot_params { |
| 217 | u32 magic; |
| 218 | u32 vpu_id; |
| 219 | u32 vpu_count; |
| 220 | u32 pad0[5]; |
| 221 | /* Clock frequencies: 0x20 - 0xFF */ |
| 222 | u32 frequency; |
| 223 | u32 pll[VPU_BOOT_PLL_COUNT][VPU_BOOT_PLL_OUT_COUNT]; |
| 224 | u32 perf_clk_frequency; |
| 225 | u32 pad1[42]; |
| 226 | /* Memory regions: 0x100 - 0x1FF */ |
| 227 | u64 ; |
| 228 | u32 ; |
| 229 | u64 shared_region_base; |
| 230 | u32 shared_region_size; |
| 231 | u64 ipc_payload_area_start; |
| 232 | u32 ipc_payload_area_size; |
| 233 | u64 global_aliased_pio_base; |
| 234 | u32 global_aliased_pio_size; |
| 235 | u32 autoconfig; |
| 236 | struct vpu_boot_l2_cache_config cache_defaults[VPU_BOOT_L2_CACHE_CFG_NUM]; |
| 237 | u64 global_memory_allocator_base; |
| 238 | u32 global_memory_allocator_size; |
| 239 | /** |
| 240 | * ShaveNN FW section VPU base address |
| 241 | * On VPU2.7 HW this address must be within 2GB range starting from L2C_PAGE_TABLE base |
| 242 | */ |
| 243 | u64 shave_nn_fw_base; |
| 244 | u64 save_restore_ret_address; /* stores the address of FW's restore entry point */ |
| 245 | u32 pad2[43]; |
| 246 | /* IRQ re-direct numbers: 0x200 - 0x2FF */ |
| 247 | s32 watchdog_irq_mss; |
| 248 | s32 watchdog_irq_nce; |
| 249 | /* ARM -> VPU doorbell interrupt. ARM is notifying VPU of async command or compute job. */ |
| 250 | u32 host_to_vpu_irq; |
| 251 | /* VPU -> ARM job done interrupt. VPU is notifying ARM of compute job completion. */ |
| 252 | u32 job_done_irq; |
| 253 | /* VPU -> ARM IRQ line to use to request MMU update. */ |
| 254 | u32 mmu_update_request_irq; |
| 255 | /* ARM -> VPU IRQ line to use to notify of MMU update completion. */ |
| 256 | u32 mmu_update_done_irq; |
| 257 | /* ARM -> VPU IRQ line to use to request power level change. */ |
| 258 | u32 set_power_level_irq; |
| 259 | /* VPU -> ARM IRQ line to use to notify of power level change completion. */ |
| 260 | u32 set_power_level_done_irq; |
| 261 | /* VPU -> ARM IRQ line to use to notify of VPU idle state change */ |
| 262 | u32 set_vpu_idle_update_irq; |
| 263 | /* VPU -> ARM IRQ line to use to request counter reset. */ |
| 264 | u32 metric_query_event_irq; |
| 265 | /* ARM -> VPU IRQ line to use to notify of counter reset completion. */ |
| 266 | u32 metric_query_event_done_irq; |
| 267 | /* VPU -> ARM IRQ line to use to notify of preemption completion. */ |
| 268 | u32 preemption_done_irq; |
| 269 | /* Padding. */ |
| 270 | u32 pad3[52]; |
| 271 | /* Silicon information: 0x300 - 0x3FF */ |
| 272 | u32 host_version_id; |
| 273 | u32 si_stepping; |
| 274 | u64 device_id; |
| 275 | u64 feature_exclusion; |
| 276 | u64 sku; |
| 277 | /** PLL ratio for minimum clock frequency */ |
| 278 | u32 min_freq_pll_ratio; |
| 279 | /** PLL ratio for maximum clock frequency */ |
| 280 | u32 max_freq_pll_ratio; |
| 281 | /** |
| 282 | * Initial log level threshold (messages with log level severity less than |
| 283 | * the threshold will not be logged); applies to every enabled logging |
| 284 | * destination and loggable HW component. See 'mvLog_t' enum for acceptable |
| 285 | * values. |
| 286 | * TODO: EISW-33556: Move log level definition (mvLog_t) to this file. |
| 287 | */ |
| 288 | u32 default_trace_level; |
| 289 | u32 boot_type; |
| 290 | u64 punit_telemetry_sram_base; |
| 291 | u64 punit_telemetry_sram_size; |
| 292 | u32 vpu_telemetry_enable; |
| 293 | u64 crit_tracing_buff_addr; |
| 294 | u32 crit_tracing_buff_size; |
| 295 | u64 verbose_tracing_buff_addr; |
| 296 | u32 verbose_tracing_buff_size; |
| 297 | u64 verbose_tracing_sw_component_mask; /* TO BE REMOVED */ |
| 298 | /** |
| 299 | * Mask of destinations to which logging messages are delivered; bitwise OR |
| 300 | * of values defined in vpu_trace_destination enum. |
| 301 | */ |
| 302 | u32 trace_destination_mask; |
| 303 | /** |
| 304 | * Mask of hardware components for which logging is enabled; bitwise OR of |
| 305 | * bits defined by the VPU_TRACE_PROC_BIT_* macros. |
| 306 | */ |
| 307 | u64 trace_hw_component_mask; |
| 308 | /** Mask of trace message formats supported by the driver */ |
| 309 | u64 tracing_buff_message_format_mask; |
| 310 | u64 trace_reserved_1[2]; |
| 311 | /** |
| 312 | * Period at which the VPU reads the temp sensor values into MMIO, on |
| 313 | * platforms where that is necessary (in ms). 0 to disable reads. |
| 314 | */ |
| 315 | u32 temp_sensor_period_ms; |
| 316 | /** PLL ratio for efficient clock frequency */ |
| 317 | u32 pn_freq_pll_ratio; |
| 318 | /** |
| 319 | * DVFS Mode: |
| 320 | * 0 - Default, DVFS mode selected by the firmware |
| 321 | * 1 - Max Performance |
| 322 | * 2 - On Demand |
| 323 | * 3 - Power Save |
| 324 | * 4 - On Demand Priority Aware |
| 325 | */ |
| 326 | u32 dvfs_mode; |
| 327 | /** |
| 328 | * Depending on DVFS Mode: |
| 329 | * On-demand: Default if 0. |
| 330 | * Bit 0-7 - uint8_t: Highest residency percent |
| 331 | * Bit 8-15 - uint8_t: High residency percent |
| 332 | * Bit 16-23 - uint8_t: Low residency percent |
| 333 | * Bit 24-31 - uint8_t: Lowest residency percent |
| 334 | * Bit 32-35 - unsigned 4b: PLL Ratio increase amount on highest residency |
| 335 | * Bit 36-39 - unsigned 4b: PLL Ratio increase amount on high residency |
| 336 | * Bit 40-43 - unsigned 4b: PLL Ratio decrease amount on low residency |
| 337 | * Bit 44-47 - unsigned 4b: PLL Ratio decrease amount on lowest frequency |
| 338 | * Bit 48-55 - uint8_t: Period (ms) for residency decisions |
| 339 | * Bit 56-63 - uint8_t: Averaging windows (as multiples of period. Max: 30 decimal) |
| 340 | * Power Save/Max Performance: Unused |
| 341 | */ |
| 342 | u64 dvfs_param; |
| 343 | /** |
| 344 | * D0i3 delayed entry |
| 345 | * Bit0: Disable CPU state save on D0i2 entry flow. |
| 346 | * 0: Every D0i2 entry saves state. Save state IPC message ignored. |
| 347 | * 1: IPC message required to save state on D0i3 entry flow. |
| 348 | */ |
| 349 | u32 d0i3_delayed_entry; |
| 350 | /* Time spent by VPU in D0i3 state */ |
| 351 | u64 d0i3_residency_time_us; |
| 352 | /* Value of VPU perf counter at the time of entering D0i3 state . */ |
| 353 | u64 d0i3_entry_vpu_ts; |
| 354 | /* |
| 355 | * The system time of the host operating system in microseconds. |
| 356 | * E.g the number of microseconds since 1st of January 1970, or whatever |
| 357 | * date the host operating system uses to maintain system time. |
| 358 | * This value will be used to track system time on the VPU. |
| 359 | * The KMD is required to update this value on every VPU reset. |
| 360 | */ |
| 361 | u64 system_time_us; |
| 362 | u32 pad4[2]; |
| 363 | /* |
| 364 | * The delta between device monotonic time and the current value of the |
| 365 | * HW timestamp register, in ticks. Written by the firmware during boot. |
| 366 | * Can be used by the KMD to calculate device time. |
| 367 | */ |
| 368 | u64 device_time_delta_ticks; |
| 369 | u32 pad7[14]; |
| 370 | /* Warm boot information: 0x400 - 0x43F */ |
| 371 | u32 warm_boot_sections_count; |
| 372 | u32 warm_boot_start_address_reference; |
| 373 | u32 warm_boot_section_info_address_offset; |
| 374 | u32 pad5[13]; |
| 375 | /* Power States transitions timestamps: 0x440 - 0x46F*/ |
| 376 | struct { |
| 377 | /* VPU_IDLE -> VPU_ACTIVE transition initiated timestamp */ |
| 378 | u64 vpu_active_state_requested; |
| 379 | /* VPU_IDLE -> VPU_ACTIVE transition completed timestamp */ |
| 380 | u64 vpu_active_state_achieved; |
| 381 | /* VPU_ACTIVE -> VPU_IDLE transition initiated timestamp */ |
| 382 | u64 vpu_idle_state_requested; |
| 383 | /* VPU_ACTIVE -> VPU_IDLE transition completed timestamp */ |
| 384 | u64 vpu_idle_state_achieved; |
| 385 | /* VPU_IDLE -> VPU_STANDBY transition initiated timestamp */ |
| 386 | u64 vpu_standby_state_requested; |
| 387 | /* VPU_IDLE -> VPU_STANDBY transition completed timestamp */ |
| 388 | u64 vpu_standby_state_achieved; |
| 389 | } power_states_timestamps; |
| 390 | /* VPU scheduling mode. Values defined by VPU_SCHEDULING_MODE_* macros. */ |
| 391 | u32 vpu_scheduling_mode; |
| 392 | /* Present call period in milliseconds. */ |
| 393 | u32 vpu_focus_present_timer_ms; |
| 394 | /* VPU ECC Signaling */ |
| 395 | u32 vpu_uses_ecc_mca_signal; |
| 396 | /* Values defined by POWER_PROFILE* macros */ |
| 397 | u32 power_profile; |
| 398 | /* Microsecond value for DCT active cycle */ |
| 399 | u32 dct_active_us; |
| 400 | /* Microsecond value for DCT inactive cycle */ |
| 401 | u32 dct_inactive_us; |
| 402 | /* Unused/reserved: 0x488 - 0xFFF */ |
| 403 | u32 pad6[734]; |
| 404 | }; |
| 405 | |
| 406 | /* Magic numbers set between host and vpu to detect corruption of tracing init */ |
| 407 | #define VPU_TRACING_BUFFER_CANARY (0xCAFECAFE) |
| 408 | |
| 409 | /* Tracing buffer message format definitions */ |
| 410 | #define VPU_TRACING_FORMAT_STRING 0 |
| 411 | #define VPU_TRACING_FORMAT_MIPI 2 |
| 412 | /* |
| 413 | * Header of the tracing buffer. |
| 414 | * The below defined header will be stored at the beginning of |
| 415 | * each allocated tracing buffer, followed by a series of 256b |
| 416 | * of ASCII trace message entries. |
| 417 | */ |
| 418 | struct { |
| 419 | /** |
| 420 | * Magic number set by host to detect corruption |
| 421 | * @see VPU_TRACING_BUFFER_CANARY |
| 422 | */ |
| 423 | u32 ; |
| 424 | /* offset from start of buffer for trace entries */ |
| 425 | u32 ; |
| 426 | /* keeps track of wrapping on the reader side */ |
| 427 | u32 ; |
| 428 | u32 [13]; |
| 429 | /* End of first cache line */ |
| 430 | |
| 431 | /** |
| 432 | * Magic number set by host to detect corruption |
| 433 | * @see VPU_TRACING_BUFFER_CANARY |
| 434 | */ |
| 435 | u32 ; |
| 436 | /* offset from start of buffer from write start */ |
| 437 | u32 ; |
| 438 | /* counter for buffer wrapping */ |
| 439 | u32 ; |
| 440 | /* legacy field - do not use */ |
| 441 | u32 ; |
| 442 | /** |
| 443 | * Size of the log buffer include this header (@header_size) and space |
| 444 | * reserved for all messages. If @alignment` is greater that 0 the @Size |
| 445 | * must be multiple of @Alignment. |
| 446 | */ |
| 447 | u32 ; |
| 448 | /* Header version */ |
| 449 | u16 ; |
| 450 | /* Header size */ |
| 451 | u16 ; |
| 452 | /* |
| 453 | * Format of the messages in the trace buffer |
| 454 | * 0 - null terminated string |
| 455 | * 1 - size + null terminated string |
| 456 | * 2 - MIPI-SysT encoding |
| 457 | */ |
| 458 | u32 ; |
| 459 | /* |
| 460 | * Message alignment |
| 461 | * 0 - messages are place 1 after another |
| 462 | * n - every message starts and multiple on offset |
| 463 | */ |
| 464 | u32 ; /* 64, 128, 256 */ |
| 465 | /* Name of the logging entity, i.e "LRT", "LNN", "SHV0", etc */ |
| 466 | char [16]; |
| 467 | u32 [4]; |
| 468 | /* End of second cache line */ |
| 469 | }; |
| 470 | |
| 471 | #pragma pack(pop) |
| 472 | |
| 473 | #endif |
| 474 | |