1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include "xe_bo.h" 7 #include "xe_device.h" 8 #include "xe_engine.h" 9 #include "xe_gt.h" 10 #include "xe_platform_types.h" 11 #include "xe_mmio.h" 12 #include "xe_mocs.h" 13 #include "xe_step_types.h" 14 15 #include "gt/intel_gt_regs.h" 16 17 #if IS_ENABLED(CONFIG_DRM_XE_DEBUG) 18 #define mocs_dbg drm_dbg 19 #else 20 __printf(2, 3) 21 static inline void mocs_dbg(const struct drm_device *dev, 22 const char *format, ...) 23 { /* noop */ } 24 #endif 25 26 /* 27 * MOCS indexes used for GPU surfaces, defining the cacheability of the 28 * surface data and the coherency for this data wrt. CPU vs. GPU accesses. 29 */ 30 enum xe_mocs_info_index { 31 /* 32 * Not cached anywhere, coherency between CPU and GPU accesses is 33 * guaranteed. 34 */ 35 XE_MOCS_UNCACHED, 36 /* 37 * Cacheability and coherency controlled by the kernel automatically 38 * based on the xxxx IOCTL setting and the current 39 * usage of the surface (used for display scanout or not). 40 */ 41 XE_MOCS_PTE, 42 /* 43 * Cached in all GPU caches available on the platform. 44 * Coherency between CPU and GPU accesses to the surface is not 45 * guaranteed without extra synchronization. 46 */ 47 XE_MOCS_CACHED, 48 }; 49 50 enum { 51 HAS_GLOBAL_MOCS = BIT(0), 52 HAS_RENDER_L3CC = BIT(1), 53 }; 54 55 struct xe_mocs_entry { 56 u32 control_value; 57 u16 l3cc_value; 58 u16 used; 59 }; 60 61 struct xe_mocs_info { 62 unsigned int size; 63 unsigned int n_entries; 64 const struct xe_mocs_entry *table; 65 u8 uc_index; 66 u8 wb_index; 67 u8 unused_entries_index; 68 }; 69 70 /* Defines for the tables (XXX_MOCS_0 - XXX_MOCS_63) */ 71 #define _LE_CACHEABILITY(value) ((value) << 0) 72 #define _LE_TGT_CACHE(value) ((value) << 2) 73 #define LE_LRUM(value) ((value) << 4) 74 #define LE_AOM(value) ((value) << 6) 75 #define LE_RSC(value) ((value) << 7) 76 #define LE_SCC(value) ((value) << 8) 77 #define LE_PFM(value) ((value) << 11) 78 #define LE_SCF(value) ((value) << 14) 79 #define LE_COS(value) ((value) << 15) 80 #define LE_SSE(value) ((value) << 17) 81 82 /* Defines for the tables (LNCFMOCS0 - LNCFMOCS31) - two entries per word */ 83 #define L3_ESC(value) ((value) << 0) 84 #define L3_SCC(value) ((value) << 1) 85 #define _L3_CACHEABILITY(value) ((value) << 4) 86 #define L3_GLBGO(value) ((value) << 6) 87 #define L3_LKUP(value) ((value) << 7) 88 89 /* Helper defines */ 90 #define GEN9_NUM_MOCS_ENTRIES 64 /* 63-64 are reserved, but configured. */ 91 #define PVC_NUM_MOCS_ENTRIES 3 92 #define MTL_NUM_MOCS_ENTRIES 16 93 94 /* (e)LLC caching options */ 95 /* 96 * Note: LE_0_PAGETABLE works only up to Gen11; for newer gens it means 97 * the same as LE_UC 98 */ 99 #define LE_0_PAGETABLE _LE_CACHEABILITY(0) 100 #define LE_1_UC _LE_CACHEABILITY(1) 101 #define LE_2_WT _LE_CACHEABILITY(2) 102 #define LE_3_WB _LE_CACHEABILITY(3) 103 104 /* Target cache */ 105 #define LE_TC_0_PAGETABLE _LE_TGT_CACHE(0) 106 #define LE_TC_1_LLC _LE_TGT_CACHE(1) 107 #define LE_TC_2_LLC_ELLC _LE_TGT_CACHE(2) 108 #define LE_TC_3_LLC_ELLC_ALT _LE_TGT_CACHE(3) 109 110 /* L3 caching options */ 111 #define L3_0_DIRECT _L3_CACHEABILITY(0) 112 #define L3_1_UC _L3_CACHEABILITY(1) 113 #define L3_2_RESERVED _L3_CACHEABILITY(2) 114 #define L3_3_WB _L3_CACHEABILITY(3) 115 116 #define MOCS_ENTRY(__idx, __control_value, __l3cc_value) \ 117 [__idx] = { \ 118 .control_value = __control_value, \ 119 .l3cc_value = __l3cc_value, \ 120 .used = 1, \ 121 } 122 123 /* 124 * MOCS tables 125 * 126 * These are the MOCS tables that are programmed across all the rings. 127 * The control value is programmed to all the rings that support the 128 * MOCS registers. While the l3cc_values are only programmed to the 129 * LNCFCMOCS0 - LNCFCMOCS32 registers. 130 * 131 * These tables are intended to be kept reasonably consistent across 132 * HW platforms, and for ICL+, be identical across OSes. To achieve 133 * that, for Icelake and above, list of entries is published as part 134 * of bspec. 135 * 136 * Entries not part of the following tables are undefined as far as 137 * userspace is concerned and shouldn't be relied upon. For Gen < 12 138 * they will be initialized to PTE. Gen >= 12 don't have a setting for 139 * PTE and those platforms except TGL/RKL will be initialized L3 WB to 140 * catch accidental use of reserved and unused mocs indexes. 141 * 142 * The last few entries are reserved by the hardware. For ICL+ they 143 * should be initialized according to bspec and never used, for older 144 * platforms they should never be written to. 145 * 146 * NOTE1: These tables are part of bspec and defined as part of hardware 147 * interface for ICL+. For older platforms, they are part of kernel 148 * ABI. It is expected that, for specific hardware platform, existing 149 * entries will remain constant and the table will only be updated by 150 * adding new entries, filling unused positions. 151 * 152 * NOTE2: For GEN >= 12 except TGL and RKL, reserved and unspecified MOCS 153 * indices have been set to L3 WB. These reserved entries should never 154 * be used, they may be changed to low performant variants with better 155 * coherency in the future if more entries are needed. 156 * For TGL/RKL, all the unspecified MOCS indexes are mapped to L3 UC. 157 */ 158 159 #define GEN11_MOCS_ENTRIES \ 160 /* Entries 0 and 1 are defined per-platform */ \ 161 /* Base - L3 + LLC */ \ 162 MOCS_ENTRY(2, \ 163 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), \ 164 L3_3_WB), \ 165 /* Base - Uncached */ \ 166 MOCS_ENTRY(3, \ 167 LE_1_UC | LE_TC_1_LLC, \ 168 L3_1_UC), \ 169 /* Base - L3 */ \ 170 MOCS_ENTRY(4, \ 171 LE_1_UC | LE_TC_1_LLC, \ 172 L3_3_WB), \ 173 /* Base - LLC */ \ 174 MOCS_ENTRY(5, \ 175 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), \ 176 L3_1_UC), \ 177 /* Age 0 - LLC */ \ 178 MOCS_ENTRY(6, \ 179 LE_3_WB | LE_TC_1_LLC | LE_LRUM(1), \ 180 L3_1_UC), \ 181 /* Age 0 - L3 + LLC */ \ 182 MOCS_ENTRY(7, \ 183 LE_3_WB | LE_TC_1_LLC | LE_LRUM(1), \ 184 L3_3_WB), \ 185 /* Age: Don't Chg. - LLC */ \ 186 MOCS_ENTRY(8, \ 187 LE_3_WB | LE_TC_1_LLC | LE_LRUM(2), \ 188 L3_1_UC), \ 189 /* Age: Don't Chg. - L3 + LLC */ \ 190 MOCS_ENTRY(9, \ 191 LE_3_WB | LE_TC_1_LLC | LE_LRUM(2), \ 192 L3_3_WB), \ 193 /* No AOM - LLC */ \ 194 MOCS_ENTRY(10, \ 195 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_AOM(1), \ 196 L3_1_UC), \ 197 /* No AOM - L3 + LLC */ \ 198 MOCS_ENTRY(11, \ 199 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_AOM(1), \ 200 L3_3_WB), \ 201 /* No AOM; Age 0 - LLC */ \ 202 MOCS_ENTRY(12, \ 203 LE_3_WB | LE_TC_1_LLC | LE_LRUM(1) | LE_AOM(1), \ 204 L3_1_UC), \ 205 /* No AOM; Age 0 - L3 + LLC */ \ 206 MOCS_ENTRY(13, \ 207 LE_3_WB | LE_TC_1_LLC | LE_LRUM(1) | LE_AOM(1), \ 208 L3_3_WB), \ 209 /* No AOM; Age:DC - LLC */ \ 210 MOCS_ENTRY(14, \ 211 LE_3_WB | LE_TC_1_LLC | LE_LRUM(2) | LE_AOM(1), \ 212 L3_1_UC), \ 213 /* No AOM; Age:DC - L3 + LLC */ \ 214 MOCS_ENTRY(15, \ 215 LE_3_WB | LE_TC_1_LLC | LE_LRUM(2) | LE_AOM(1), \ 216 L3_3_WB), \ 217 /* Self-Snoop - L3 + LLC */ \ 218 MOCS_ENTRY(18, \ 219 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SSE(3), \ 220 L3_3_WB), \ 221 /* Skip Caching - L3 + LLC(12.5%) */ \ 222 MOCS_ENTRY(19, \ 223 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SCC(7), \ 224 L3_3_WB), \ 225 /* Skip Caching - L3 + LLC(25%) */ \ 226 MOCS_ENTRY(20, \ 227 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SCC(3), \ 228 L3_3_WB), \ 229 /* Skip Caching - L3 + LLC(50%) */ \ 230 MOCS_ENTRY(21, \ 231 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SCC(1), \ 232 L3_3_WB), \ 233 /* Skip Caching - L3 + LLC(75%) */ \ 234 MOCS_ENTRY(22, \ 235 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_RSC(1) | LE_SCC(3), \ 236 L3_3_WB), \ 237 /* Skip Caching - L3 + LLC(87.5%) */ \ 238 MOCS_ENTRY(23, \ 239 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_RSC(1) | LE_SCC(7), \ 240 L3_3_WB), \ 241 /* HW Reserved - SW program but never use */ \ 242 MOCS_ENTRY(62, \ 243 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), \ 244 L3_1_UC), \ 245 /* HW Reserved - SW program but never use */ \ 246 MOCS_ENTRY(63, \ 247 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), \ 248 L3_1_UC) 249 250 static const struct xe_mocs_entry tgl_mocs_desc[] = { 251 /* 252 * NOTE: 253 * Reserved and unspecified MOCS indices have been set to (L3 + LCC). 254 * These reserved entries should never be used, they may be changed 255 * to low performant variants with better coherency in the future if 256 * more entries are needed. We are programming index XE_MOCS_PTE(1) 257 * only, __init_mocs_table() take care to program unused index with 258 * this entry. 259 */ 260 MOCS_ENTRY(XE_MOCS_PTE, 261 LE_0_PAGETABLE | LE_TC_0_PAGETABLE, 262 L3_1_UC), 263 GEN11_MOCS_ENTRIES, 264 265 /* Implicitly enable L1 - HDC:L1 + L3 + LLC */ 266 MOCS_ENTRY(48, 267 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), 268 L3_3_WB), 269 /* Implicitly enable L1 - HDC:L1 + L3 */ 270 MOCS_ENTRY(49, 271 LE_1_UC | LE_TC_1_LLC, 272 L3_3_WB), 273 /* Implicitly enable L1 - HDC:L1 + LLC */ 274 MOCS_ENTRY(50, 275 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), 276 L3_1_UC), 277 /* Implicitly enable L1 - HDC:L1 */ 278 MOCS_ENTRY(51, 279 LE_1_UC | LE_TC_1_LLC, 280 L3_1_UC), 281 /* HW Special Case (CCS) */ 282 MOCS_ENTRY(60, 283 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), 284 L3_1_UC), 285 /* HW Special Case (Displayable) */ 286 MOCS_ENTRY(61, 287 LE_1_UC | LE_TC_1_LLC, 288 L3_3_WB), 289 }; 290 291 static const struct xe_mocs_entry dg1_mocs_desc[] = { 292 /* UC */ 293 MOCS_ENTRY(1, 0, L3_1_UC), 294 /* WB - L3 */ 295 MOCS_ENTRY(5, 0, L3_3_WB), 296 /* WB - L3 50% */ 297 MOCS_ENTRY(6, 0, L3_ESC(1) | L3_SCC(1) | L3_3_WB), 298 /* WB - L3 25% */ 299 MOCS_ENTRY(7, 0, L3_ESC(1) | L3_SCC(3) | L3_3_WB), 300 /* WB - L3 12.5% */ 301 MOCS_ENTRY(8, 0, L3_ESC(1) | L3_SCC(7) | L3_3_WB), 302 303 /* HDC:L1 + L3 */ 304 MOCS_ENTRY(48, 0, L3_3_WB), 305 /* HDC:L1 */ 306 MOCS_ENTRY(49, 0, L3_1_UC), 307 308 /* HW Reserved */ 309 MOCS_ENTRY(60, 0, L3_1_UC), 310 MOCS_ENTRY(61, 0, L3_1_UC), 311 MOCS_ENTRY(62, 0, L3_1_UC), 312 MOCS_ENTRY(63, 0, L3_1_UC), 313 }; 314 315 static const struct xe_mocs_entry gen12_mocs_desc[] = { 316 GEN11_MOCS_ENTRIES, 317 /* Implicitly enable L1 - HDC:L1 + L3 + LLC */ 318 MOCS_ENTRY(48, 319 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), 320 L3_3_WB), 321 /* Implicitly enable L1 - HDC:L1 + L3 */ 322 MOCS_ENTRY(49, 323 LE_1_UC | LE_TC_1_LLC, 324 L3_3_WB), 325 /* Implicitly enable L1 - HDC:L1 + LLC */ 326 MOCS_ENTRY(50, 327 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), 328 L3_1_UC), 329 /* Implicitly enable L1 - HDC:L1 */ 330 MOCS_ENTRY(51, 331 LE_1_UC | LE_TC_1_LLC, 332 L3_1_UC), 333 /* HW Special Case (CCS) */ 334 MOCS_ENTRY(60, 335 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), 336 L3_1_UC), 337 /* HW Special Case (Displayable) */ 338 MOCS_ENTRY(61, 339 LE_1_UC | LE_TC_1_LLC, 340 L3_3_WB), 341 }; 342 343 static const struct xe_mocs_entry dg2_mocs_desc[] = { 344 /* UC - Coherent; GO:L3 */ 345 MOCS_ENTRY(0, 0, L3_1_UC | L3_LKUP(1)), 346 /* UC - Coherent; GO:Memory */ 347 MOCS_ENTRY(1, 0, L3_1_UC | L3_GLBGO(1) | L3_LKUP(1)), 348 /* UC - Non-Coherent; GO:Memory */ 349 MOCS_ENTRY(2, 0, L3_1_UC | L3_GLBGO(1)), 350 351 /* WB - LC */ 352 MOCS_ENTRY(3, 0, L3_3_WB | L3_LKUP(1)), 353 }; 354 355 static const struct xe_mocs_entry dg2_mocs_desc_g10_ax[] = { 356 /* Wa_14011441408: Set Go to Memory for MOCS#0 */ 357 MOCS_ENTRY(0, 0, L3_1_UC | L3_GLBGO(1) | L3_LKUP(1)), 358 /* UC - Coherent; GO:Memory */ 359 MOCS_ENTRY(1, 0, L3_1_UC | L3_GLBGO(1) | L3_LKUP(1)), 360 /* UC - Non-Coherent; GO:Memory */ 361 MOCS_ENTRY(2, 0, L3_1_UC | L3_GLBGO(1)), 362 363 /* WB - LC */ 364 MOCS_ENTRY(3, 0, L3_3_WB | L3_LKUP(1)), 365 }; 366 367 static const struct xe_mocs_entry pvc_mocs_desc[] = { 368 /* Error */ 369 MOCS_ENTRY(0, 0, L3_3_WB), 370 371 /* UC */ 372 MOCS_ENTRY(1, 0, L3_1_UC), 373 374 /* WB */ 375 MOCS_ENTRY(2, 0, L3_3_WB), 376 }; 377 378 static unsigned int get_mocs_settings(struct xe_device *xe, 379 struct xe_mocs_info *info) 380 { 381 unsigned int flags; 382 383 memset(info, 0, sizeof(struct xe_mocs_info)); 384 385 info->unused_entries_index = XE_MOCS_PTE; 386 switch (xe->info.platform) { 387 case XE_PVC: 388 info->size = ARRAY_SIZE(pvc_mocs_desc); 389 info->table = pvc_mocs_desc; 390 info->n_entries = PVC_NUM_MOCS_ENTRIES; 391 info->uc_index = 1; 392 info->wb_index = 2; 393 info->unused_entries_index = 2; 394 break; 395 case XE_METEORLAKE: 396 info->size = ARRAY_SIZE(dg2_mocs_desc); 397 info->table = dg2_mocs_desc; 398 info->n_entries = MTL_NUM_MOCS_ENTRIES; 399 info->uc_index = 1; 400 info->unused_entries_index = 3; 401 break; 402 case XE_DG2: 403 if (xe->info.subplatform == XE_SUBPLATFORM_DG2_G10 && 404 xe->info.step.graphics >= STEP_A0 && 405 xe->info.step.graphics <= STEP_B0) { 406 info->size = ARRAY_SIZE(dg2_mocs_desc_g10_ax); 407 info->table = dg2_mocs_desc_g10_ax; 408 } else { 409 info->size = ARRAY_SIZE(dg2_mocs_desc); 410 info->table = dg2_mocs_desc; 411 } 412 info->uc_index = 1; 413 info->n_entries = GEN9_NUM_MOCS_ENTRIES; 414 info->unused_entries_index = 3; 415 break; 416 case XE_DG1: 417 info->size = ARRAY_SIZE(dg1_mocs_desc); 418 info->table = dg1_mocs_desc; 419 info->uc_index = 1; 420 info->n_entries = GEN9_NUM_MOCS_ENTRIES; 421 info->uc_index = 1; 422 info->unused_entries_index = 5; 423 break; 424 case XE_TIGERLAKE: 425 info->size = ARRAY_SIZE(tgl_mocs_desc); 426 info->table = tgl_mocs_desc; 427 info->n_entries = GEN9_NUM_MOCS_ENTRIES; 428 info->uc_index = 3; 429 break; 430 case XE_ALDERLAKE_S: 431 case XE_ALDERLAKE_P: 432 info->size = ARRAY_SIZE(gen12_mocs_desc); 433 info->table = gen12_mocs_desc; 434 info->n_entries = GEN9_NUM_MOCS_ENTRIES; 435 info->uc_index = 3; 436 info->unused_entries_index = 2; 437 break; 438 default: 439 drm_err(&xe->drm, "Platform that should have a MOCS table does not.\n"); 440 return 0; 441 } 442 443 if (XE_WARN_ON(info->size > info->n_entries)) 444 return 0; 445 446 flags = HAS_RENDER_L3CC; 447 if (!IS_DGFX(xe)) 448 flags |= HAS_GLOBAL_MOCS; 449 450 return flags; 451 } 452 453 /* 454 * Get control_value from MOCS entry taking into account when it's not used 455 * then if unused_entries_index is non-zero then its value will be returned 456 * otherwise XE_MOCS_PTE's value is returned in this case. 457 */ 458 static u32 get_entry_control(const struct xe_mocs_info *info, 459 unsigned int index) 460 { 461 if (index < info->size && info->table[index].used) 462 return info->table[index].control_value; 463 return info->table[info->unused_entries_index].control_value; 464 } 465 466 static void __init_mocs_table(struct xe_gt *gt, 467 const struct xe_mocs_info *info, 468 u32 addr) 469 { 470 struct xe_device *xe = gt_to_xe(gt); 471 472 unsigned int i; 473 u32 mocs; 474 475 mocs_dbg(>->xe->drm, "entries:%d\n", info->n_entries); 476 drm_WARN_ONCE(&xe->drm, !info->unused_entries_index, 477 "Unused entries index should have been defined\n"); 478 for (i = 0; 479 i < info->n_entries ? (mocs = get_entry_control(info, i)), 1 : 0; 480 i++) { 481 mocs_dbg(>->xe->drm, "%d 0x%x 0x%x\n", i, _MMIO(addr + i * 4).reg, mocs); 482 xe_mmio_write32(gt, _MMIO(addr + i * 4).reg, mocs); 483 } 484 } 485 486 /* 487 * Get l3cc_value from MOCS entry taking into account when it's not used 488 * then if unused_entries_index is not zero then its value will be returned 489 * otherwise I915_MOCS_PTE's value is returned in this case. 490 */ 491 static u16 get_entry_l3cc(const struct xe_mocs_info *info, 492 unsigned int index) 493 { 494 if (index < info->size && info->table[index].used) 495 return info->table[index].l3cc_value; 496 return info->table[info->unused_entries_index].l3cc_value; 497 } 498 499 static u32 l3cc_combine(u16 low, u16 high) 500 { 501 return low | (u32)high << 16; 502 } 503 504 static void init_l3cc_table(struct xe_gt *gt, 505 const struct xe_mocs_info *info) 506 { 507 unsigned int i; 508 u32 l3cc; 509 510 mocs_dbg(>->xe->drm, "entries:%d\n", info->n_entries); 511 for (i = 0; 512 i < (info->n_entries + 1) / 2 ? 513 (l3cc = l3cc_combine(get_entry_l3cc(info, 2 * i), 514 get_entry_l3cc(info, 2 * i + 1))), 1 : 0; 515 i++) { 516 mocs_dbg(>->xe->drm, "%d 0x%x 0x%x\n", i, GEN9_LNCFCMOCS(i).reg, l3cc); 517 xe_mmio_write32(gt, GEN9_LNCFCMOCS(i).reg, l3cc); 518 } 519 } 520 521 void xe_mocs_init_engine(const struct xe_engine *engine) 522 { 523 struct xe_mocs_info table; 524 unsigned int flags; 525 526 flags = get_mocs_settings(engine->gt->xe, &table); 527 if (!flags) 528 return; 529 530 if (flags & HAS_RENDER_L3CC && engine->class == XE_ENGINE_CLASS_RENDER) 531 init_l3cc_table(engine->gt, &table); 532 } 533 534 void xe_mocs_init(struct xe_gt *gt) 535 { 536 struct xe_mocs_info table; 537 unsigned int flags; 538 539 /* 540 * LLC and eDRAM control values are not applicable to dgfx 541 */ 542 flags = get_mocs_settings(gt->xe, &table); 543 mocs_dbg(>->xe->drm, "flag:0x%x\n", flags); 544 gt->mocs.uc_index = table.uc_index; 545 gt->mocs.wb_index = table.wb_index; 546 547 if (flags & HAS_GLOBAL_MOCS) 548 __init_mocs_table(gt, &table, GEN12_GLOBAL_MOCS(0).reg); 549 550 /* 551 * Initialize the L3CC table as part of mocs initalization to make 552 * sure the LNCFCMOCSx registers are programmed for the subsequent 553 * memory transactions including guc transactions 554 */ 555 if (flags & HAS_RENDER_L3CC) 556 init_l3cc_table(gt, &table); 557 } 558