From 28b52f5a000b2498d0357e5af1e78784e960b700 Mon Sep 17 00:00:00 2001 From: John Bauman Date: Mon, 24 Feb 2025 18:38:53 +0000 Subject: [PATCH] #0: Remove grayskull support from BRISC and NCRISC firmware Grayskull needed a mode where the NCRISC firmware is loaded into IRAM, which complicates everything. --- tt_metal/hw/CMakeLists.txt | 20 +----- tt_metal/hw/firmware/src/brisc.cc | 99 ++--------------------------- tt_metal/hw/firmware/src/ncrisc.cc | 26 +------- tt_metal/hw/toolchain/ncrisc-halt.S | 84 ------------------------ tt_metal/jit_build/build.cpp | 6 -- 5 files changed, 10 insertions(+), 225 deletions(-) delete mode 100644 tt_metal/hw/toolchain/ncrisc-halt.S diff --git a/tt_metal/hw/CMakeLists.txt b/tt_metal/hw/CMakeLists.txt index 6b26e0403b1..8c2c83bc56e 100644 --- a/tt_metal/hw/CMakeLists.txt +++ b/tt_metal/hw/CMakeLists.txt @@ -169,7 +169,6 @@ foreach(ARCH IN LISTS ARCHS) substitutes tdma_xmov noc - ncrisc-halt ncrisc-halt-wormhole ) @@ -180,7 +179,6 @@ foreach(ARCH IN LISTS ARCHS) set(substitutes_SOURCE "${PROJECT_SOURCE_DIR}/tt_metal/hw/toolchain/substitutes.cpp") set(tdma_xmov_SOURCE "${PROJECT_SOURCE_DIR}/tt_metal/hw/firmware/src/tdma_xmov.c") set(noc_SOURCE "${PROJECT_SOURCE_DIR}/tt_metal/hw/firmware/src/${ARCH}/noc.c") - set(ncrisc-halt_SOURCE "${PROJECT_SOURCE_DIR}/tt_metal/hw/toolchain/ncrisc-halt.S") set(ncrisc-halt-wormhole_SOURCE "${PROJECT_SOURCE_DIR}/tt_metal/hw/toolchain/ncrisc-halt-wormhole.S") # Set GPP_FLAGS based on ARCH @@ -217,23 +215,7 @@ foreach(ARCH IN LISTS ARCHS) list(APPEND GPP_INCLUDES -I${PROJECT_SOURCE_DIR}/tt_metal/third_party/tt_llk/tt_llk_${ARCH_B0}/llk_lib) foreach(HWLIB IN LISTS HWLIBS) - if( - "${ARCH}" - STREQUAL - "blackhole" - AND ( - ( - "${HWLIB}" - STREQUAL - "ncrisc-halt" - ) - OR ( - "${HWLIB}" - STREQUAL - "tmu-crt0k-ncrisc" - ) - ) - ) + if("${ARCH}" STREQUAL "blackhole" AND ("${HWLIB}" STREQUAL "tmu-crt0k-ncrisc")) continue() # Skip the iteration, blackhole doesn't have IRAM endif() if((NOT "${ARCH}" STREQUAL "wormhole") AND "${HWLIB}" STREQUAL "ncrisc-halt-wormhole") diff --git a/tt_metal/hw/firmware/src/brisc.cc b/tt_metal/hw/firmware/src/brisc.cc index 03e78e1be33..80543aa8e0f 100644 --- a/tt_metal/hw/firmware/src/brisc.cc +++ b/tt_metal/hw/firmware/src/brisc.cc @@ -41,14 +41,6 @@ constexpr uint32_t RISCV_IC_TRISC1_MASK = 0x4; constexpr uint32_t RISCV_IC_TRISC2_MASK = 0x8; constexpr uint32_t RISCV_IC_TRISC_ALL_MASK = RISCV_IC_TRISC0_MASK | RISCV_IC_TRISC1_MASK | RISCV_IC_TRISC2_MASK; -#define NCRISC_FIRMWARE_IN_IRAM (defined(ARCH_GRAYSKULL)) - -#if NCRISC_FIRMWARE_IN_IRAM -constexpr uint32_t num_cbs_to_early_init = 4; // safe small number to overlap w/ ncrisc copy -#else -constexpr uint32_t num_cbs_to_early_init = 0; -#endif - tt_l1_ptr mailboxes_t* const mailboxes = (tt_l1_ptr mailboxes_t*)(MEM_MAILBOX_BASE); uint32_t ncrisc_kernel_start_offset16; @@ -183,26 +175,6 @@ void set_deassert_addresses() { #endif } -void l1_to_ncrisc_iram_copy(uint32_t src_addr, uint16_t size, uint32_t address_offset = 0) { -#if NCRISC_FIRMWARE_IN_IRAM - // Always copy ncrisc even if its size is 0 (save branch)... - // Copy NCRISC firmware from L1 to local IRAM using tensix DMA - tdma_xmov( - TDMA_MOVER0, - src_addr, - MEM_MOVER_VIEW_IRAM_BASE_ADDR + address_offset, - size, - XMOV_L1_TO_L0); -#endif -} - -void l1_to_ncrisc_iram_copy_wait() { -#if NCRISC_FIRMWARE_IN_IRAM - // Wait for DMA to finish - wait_tdma_movers_done(RISCV_TDMA_STATUS_FLAG_MOVER0_BUSY_MASK); -#endif -} - void device_setup() { instrn_buf[0] = core.instrn_buf_base(0); instrn_buf[1] = core.instrn_buf_base(1); @@ -270,51 +242,14 @@ void device_setup() { // core.ex_sem_init(semaphore::CFG_STATE_BUSY, MAX_CONFIG_STATES, 0, instrn_buf[0]); } -inline void init_ncrisc_iram() { -#if NCRISC_FIRMWARE_IN_IRAM - uint16_t fw_size16 = mailboxes->launch[mailboxes->launch_msg_rd_ptr].kernel_config.ncrisc_kernel_size16; - ncrisc_kernel_start_offset16 = fw_size16; - - // Copies from L1 to IRAM on chips where NCRISC has IRAM - l1_to_ncrisc_iram_copy(MEM_NCRISC_INIT_IRAM_L1_BASE >> 4, fw_size16); - l1_to_ncrisc_iram_copy_wait(); -#endif -} - inline void deassert_ncrisc_trisc() { // Below sets ncrisc to go so we can wait until it is cleared on first iteration mailboxes->slave_sync.all = RUN_SYNC_MSG_ALL_SLAVES_DONE; - init_ncrisc_iram(); - // Bring ncrisc/triscs out of reset deassert_all_reset(); } -inline __attribute__((always_inline)) void wait_for_ncrisc_to_halt() { -#if NCRISC_FIRMWARE_IN_IRAM - WAYPOINT("INW"); - while (mailboxes->slave_sync.dm1 != RUN_SYNC_MSG_DONE); - WAYPOINT("IND"); -#endif -} - -inline __attribute__((always_inline)) void reset_ncrisc_with_iram() { -#if NCRISC_FIRMWARE_IN_IRAM - assert_just_ncrisc_reset(); -#endif -} - -inline void set_ncrisc_kernel_resume_deassert_address() { -#if NCRISC_FIRMWARE_IN_IRAM - volatile tt_reg_ptr uint32_t* cfg_regs = core.cfg_regs_base(0); - WAYPOINT("INRW"); - while (mailboxes->ncrisc_halt.resume_addr == 0); - WAYPOINT("INRD"); - cfg_regs[NCRISC_RESET_PC_PC_ADDR32] = mailboxes->ncrisc_halt.resume_addr; -#endif -} - inline void run_triscs(dispatch_core_processor_masks enables) { // Wait for init_sync_registers to complete. Should always be done by the time we get here. while (mailboxes->slave_sync.trisc0 != RUN_SYNC_MSG_DONE) { @@ -328,17 +263,13 @@ inline void run_triscs(dispatch_core_processor_masks enables) { } } -inline void finish_ncrisc_copy_and_run(dispatch_core_processor_masks enables) { - // On Wormhole, start_ncrisc_kernel_run will reset NCRISC to start the kernel running. +inline void start_ncrisc_kernel_run_early(dispatch_core_processor_masks enables) { + // On Wormhole, start_ncrisc_kernel_run will reset NCRISC to start the + // kernel running. We delay it until later to give the NCRISC time to load + // CBs before we wait on it. #if !defined(NCRISC_FIRMWARE_KERNEL_SPLIT) if (enables & DISPATCH_CLASS_MASK_TENSIX_ENABLE_DM1) { - l1_to_ncrisc_iram_copy_wait(); mailboxes->slave_sync.dm1 = RUN_SYNC_MSG_GO; - -#if NCRISC_FIRMWARE_IN_IRAM - // Note: only ncrisc is in reset, so just deasserts ncrisc - deassert_all_reset(); -#endif } #endif } @@ -386,12 +317,6 @@ int main() { mailboxes->ncrisc_halt.resume_addr = 0; mailboxes->slave_sync.dm1 = RUN_SYNC_MSG_GO; deassert_ncrisc_trisc(); - // When NCRISC has IRAM, it needs to be halted before data can be copied from L1 to IRAM - // This routine allows us to resume NCRISC after the copy is done - set_ncrisc_kernel_resume_deassert_address(); - - // Wait for ncrisc to halt - wait_for_ncrisc_to_halt(); mailboxes->go_message.signal = RUN_MSG_DONE; @@ -414,7 +339,6 @@ int main() { #endif while (1) { - reset_ncrisc_with_iram(); WAYPOINT("GW"); uint8_t go_message_signal = RUN_MSG_DONE; @@ -466,20 +390,12 @@ int main() { DeviceZoneSetCounter(launch_msg_address->kernel_config.host_assigned_id); enum dispatch_core_processor_masks enables = (enum dispatch_core_processor_masks)launch_msg_address->kernel_config.enables; -#if !NCRISC_FIRMWARE_IN_IRAM - // On Wormhole and Blackhole, trigger the NCRISC to start loading CBs and IRAM as soon as possible. + // Trigger the NCRISC to start loading CBs and IRAM as soon as possible. if (enables & DISPATCH_CLASS_MASK_TENSIX_ENABLE_DM1) { mailboxes->slave_sync.dm1 = RUN_SYNC_MSG_LOAD; } -#endif // Copies from L1 to IRAM on chips where NCRISC has IRAM uint32_t kernel_config_base = firmware_config_init(mailboxes, ProgrammableCoreType::TENSIX, DISPATCH_CLASS_TENSIX_DM0); - int ncrisc_index = static_cast::type>(TensixProcessorTypes::DM1); - uint32_t ncrisc_kernel_src_address = - kernel_config_base + launch_msg_address->kernel_config.kernel_text_offset[ncrisc_index]; - l1_to_ncrisc_iram_copy(ncrisc_kernel_src_address >> 4, - launch_msg_address->kernel_config.ncrisc_kernel_size16, - ncrisc_kernel_start_offset16); // Invalidate the i$ now the kernels have loaded and before running volatile tt_reg_ptr uint32_t* cfg_regs = core.cfg_regs_base(0); cfg_regs[RISCV_IC_INVALIDATE_InvalidateAll_ADDR32] = RISCV_IC_BRISC_MASK | RISCV_IC_TRISC_ALL_MASK | RISCV_IC_NCRISC_MASK; @@ -507,15 +423,14 @@ int main() { uint32_t tt_l1_ptr* cb_l1_base = (uint32_t tt_l1_ptr*)(kernel_config_base + launch_msg_address->kernel_config.local_cb_offset); - setup_local_cb_read_write_interfaces(cb_l1_base, 0, num_cbs_to_early_init, true, true, false); - finish_ncrisc_copy_and_run(enables); + start_ncrisc_kernel_run_early(enables); // Run the BRISC kernel WAYPOINT("R"); if (enables & DISPATCH_CLASS_MASK_TENSIX_ENABLE_DM0) { uint32_t end_cb_index = launch_msg_address->kernel_config.max_local_cb_end_index; setup_local_cb_read_write_interfaces( - cb_l1_base, num_cbs_to_early_init, end_cb_index, true, true, false); + cb_l1_base, 0, end_cb_index, true, true, false); cb_l1_base = (uint32_t tt_l1_ptr*)(kernel_config_base + launch_msg_address->kernel_config.remote_cb_offset); end_cb_index = launch_msg_address->kernel_config.min_remote_cb_start_index; diff --git a/tt_metal/hw/firmware/src/ncrisc.cc b/tt_metal/hw/firmware/src/ncrisc.cc index ef1a79a5477..28b40ea6746 100644 --- a/tt_metal/hw/firmware/src/ncrisc.cc +++ b/tt_metal/hw/firmware/src/ncrisc.cc @@ -22,8 +22,6 @@ #include "debug/stack_usage.h" // clang-format on -#define NCRISC_FIRMWARE_IN_IRAM (defined(ARCH_GRAYSKULL)) - uint32_t halt_stack_ptr_save; tt_l1_ptr mailboxes_t *const mailboxes = (tt_l1_ptr mailboxes_t *)(MEM_MAILBOX_BASE); @@ -60,20 +58,9 @@ namespace kernel_profiler { } #endif -extern "C" void ncrisc_resume(void); -extern "C" void notify_brisc_and_halt(uint32_t status); extern "C" void notify_brisc_and_halt_to_iram(uint32_t status, uint32_t first_argument); -inline __attribute__((always_inline)) void set_ncrisc_resume_addr() { -#if NCRISC_FIRMWARE_IN_IRAM - mailboxes->ncrisc_halt.resume_addr = (uint32_t)ncrisc_resume; -#endif -} - inline __attribute__((always_inline)) void notify_brisc_and_wait() { -#if NCRISC_FIRMWARE_IN_IRAM - notify_brisc_and_halt(RUN_SYNC_MSG_DONE); -#else while (true) { uint8_t run_value = *ncrisc_run; if (run_value == RUN_SYNC_MSG_GO || run_value == RUN_SYNC_MSG_LOAD) { @@ -81,13 +68,10 @@ inline __attribute__((always_inline)) void notify_brisc_and_wait() { } invalidate_l1_cache(); } -#endif } inline __attribute__((always_inline)) void signal_ncrisc_completion() { -#if !NCRISC_FIRMWARE_IN_IRAM *ncrisc_run = RUN_SYNC_MSG_DONE; -#endif } #if defined(ARCH_WORMHOLE) @@ -115,10 +99,6 @@ int main(int argc, char *argv[]) { risc_init(); - // If NCRISC has IRAM it needs to halt before BRISC copies data from L1 to IRAM - // Need to save address to jump to after BRISC resumes NCRISC - set_ncrisc_resume_addr(); - // Cleanup profiler buffer incase we never get the go message while (1) { WAYPOINT("W"); @@ -152,17 +132,15 @@ int main(int argc, char *argv[]) { void (*kernel_address)(uint32_t) = (void (*)(uint32_t)) (kernel_config_base + launch_msg->kernel_config.kernel_text_offset[index]); -#ifdef ARCH_BLACKHOLE +#if !defined(ARCH_WORMHOLE) while (*ncrisc_run != RUN_SYNC_MSG_GO) { invalidate_l1_cache(); } (*kernel_address)((uint32_t)kernel_address); -#elif defined(ARCH_WORMHOLE) +#else // Jumping to IRAM causes bizarre behavior, so signal the brisc to reset the ncrisc to the IRAM address. mailboxes->ncrisc_halt.resume_addr = (uint32_t)kernel_init; notify_brisc_and_halt_to_iram(RUN_SYNC_MSG_WAITING_FOR_RESET, (uint32_t)kernel_address); -#else - kernel_init((uint32_t)kernel_address); #endif RECORD_STACK_USAGE(); WAYPOINT("D"); diff --git a/tt_metal/hw/toolchain/ncrisc-halt.S b/tt_metal/hw/toolchain/ncrisc-halt.S deleted file mode 100644 index e5f4910452d..00000000000 --- a/tt_metal/hw/toolchain/ncrisc-halt.S +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-FileCopyrightText: © 2023 Tenstorrent Inc. -// -// SPDX-License-Identifier: Apache-2.0 -#include - -.section .text - -.extern halt_stack_ptr_save -.global notify_brisc_and_halt -.global ncrisc_resume - -/* - brisc copies ncrisc's kernel to iram - copying to iram requires that ncrisc goes into reset (asserts reset) - this code saves the register state on the stack, and the stack - ptr to a well-known-address and notifies brisc it is done - - no need to save caller saves regs or the gp or tp -*/ - -/* save 13 registers, but round up to keep stack 16-byte aligned */ -#define CONTEXT_SIZE (16 * 4) - -.align 4 -.func -notify_brisc_and_halt: - /* Save context */ - addi sp, sp, -CONTEXT_SIZE - sw x1, 0 * 4( sp ) - sw x8, 1 * 4( sp ) - sw x9, 2 * 4( sp ) - sw x18, 3 * 4( sp ) - sw x19, 4 * 4( sp ) - sw x20, 5 * 4( sp ) - sw x21, 6 * 4( sp ) - sw x22, 7 * 4( sp ) - sw x23, 8 * 4( sp ) - sw x24, 9 * 4( sp ) - sw x25, 10 * 4( sp ) - sw x26, 11 * 4( sp ) - sw x27, 12 * 4( sp ) - sw sp, MEM_NCRISC_HALT_STACK_MAILBOX_ADDRESS( zero ) - sb x10, MEM_SLAVE_RUN_MAILBOX_ADDRESS( zero ) /* Tell brisc we're done */ - - /*Program flow will end here as ncrisc will go into reset*/ -halt: - j halt - -.endfunc - -/* - ncrisc fw saves the address of this routine so brisc can start ncrisc here - when a new kernel is ready to run -*/ -.align 4 -.func -ncrisc_resume: - .option push - .option norelax - // Initialize global pointer, - // Use an absolute reloc, so text placement is irrelevant. - lui gp,%hi(__global_pointer$) - addi gp,gp,%lo(__global_pointer$) - .option pop - lw sp, MEM_NCRISC_HALT_STACK_MAILBOX_ADDRESS( zero ) - /* Restore context */ - lw x1, 0 * 4( sp ) - lw x8, 1 * 4( sp ) - lw x9, 2 * 4( sp ) - lw x18, 3 * 4( sp ) - lw x19, 4 * 4( sp ) - lw x20, 5 * 4( sp ) - lw x21, 6 * 4( sp ) - lw x22, 7 * 4( sp ) - lw x23, 8 * 4( sp ) - lw x24, 9 * 4( sp ) - lw x25, 10 * 4( sp ) - lw x26, 11 * 4( sp ) - lw x27, 12 * 4( sp ) - - addi sp, sp, CONTEXT_SIZE - - ret -.endfunc diff --git a/tt_metal/jit_build/build.cpp b/tt_metal/jit_build/build.cpp index 875196c6fe0..31d063a10d7 100644 --- a/tt_metal/jit_build/build.cpp +++ b/tt_metal/jit_build/build.cpp @@ -229,15 +229,9 @@ void JitBuildState::finish_init() { std::string build_dir = llrt::RunTimeOptions::get_instance().get_root_dir() + "runtime/hw/lib/" + get_alias(env_.arch_) + "/"; if (this->is_fw_) { - if (this->target_name_ == "brisc" and this->env_.arch_ == tt::ARCH::GRAYSKULL) { - this->link_objs_ += build_dir + "tdma_xmov.o "; - } if (this->target_name_ != "erisc") { this->link_objs_ += build_dir + "tmu-crt0.o "; } - if (this->target_name_ == "ncrisc" and this->env_.arch_ == tt::ARCH::GRAYSKULL) { - this->link_objs_ += build_dir + "ncrisc-halt.o "; - } if (this->target_name_ == "ncrisc" and this->env_.arch_ == tt::ARCH::WORMHOLE_B0) { this->link_objs_ += build_dir + "ncrisc-halt-wormhole.o "; this->link_objs_ += build_dir + "tdma_xmov.o ";