Foundry/tt/fw/ft_noc.c

61 lines
2.6 KiB
C

/* SPDX-License-Identifier: AGPL-3.0-or-later */
/**
* @file ft_noc.c
* @brief Implementation of ft_noc.h: BRISC firmware's one-time NIU setup.
*
* Plain 32-bit stores to the NIU's own registers. Nothing here issues a NoC transaction, and
* in particular nothing uses an inline write (the recorded boot-wedge hazard).
*
* @status Clean-room replacement of the staged tree's noc.c, plan Phase 6.
* @issues None
* @todo None
*/
#include "ft_noc.h"
#define FT_NOC_INITIATOR_1_CTRL 0x2090u /* measured preset (spec §7.4) */
#define FT_NOC_COORDINATE_MASK 0xFFFu
static inline volatile uint32_t *niu_register(uint32_t noc, uint32_t offset)
{
return (volatile uint32_t *)(FT_NOC_NIU_BASE(noc) + offset);
}
void ft_noc_set_niu_and_router_config(void)
{
for (uint32_t noc = 0; noc < FT_NOC_COUNT; noc++) {
*niu_register(noc, FT_NOC_NIU_CFG_0) |= 1u;
*niu_register(noc, FT_NOC_ROUTER_CFG_0) |= 1u;
}
}
void ft_noc_preset_command_buffers(uint32_t noc, uint32_t atomic_return_address)
{
uint32_t coordinate = *niu_register(noc, FT_NOC_ID_LOGICAL) & FT_NOC_COORDINATE_MASK;
*niu_register(noc, FT_NOC_INITIATOR(0) + FT_NOC_TARG_ADDR_MID) = 0u;
*niu_register(noc, FT_NOC_INITIATOR(0) + FT_NOC_TARG_ADDR_HI) = coordinate;
*niu_register(noc, FT_NOC_INITIATOR(2) + FT_NOC_TARG_ADDR_MID) = 0u;
*niu_register(noc, FT_NOC_INITIATOR(2) + FT_NOC_TARG_ADDR_HI) = coordinate;
*niu_register(noc, FT_NOC_INITIATOR(3) + FT_NOC_RET_ADDR_LO) = atomic_return_address;
*niu_register(noc, FT_NOC_INITIATOR(3) + FT_NOC_RET_ADDR_MID) = 0u;
*niu_register(noc, FT_NOC_INITIATOR(3) + FT_NOC_RET_ADDR_HI) = coordinate;
*niu_register(noc, FT_NOC_INITIATOR(1) + FT_NOC_CTRL) = FT_NOC_INITIATOR_1_CTRL;
*niu_register(noc, FT_NOC_INITIATOR(1) + FT_NOC_RET_ADDR_MID) = 0u;
*niu_register(noc, FT_NOC_INITIATOR(1) + FT_NOC_RET_ADDR_HI) = coordinate;
}
void ft_noc_clear_packet_tags(uint32_t noc)
{
for (uint32_t initiator = 0; initiator < 4u; initiator++)
*niu_register(noc, FT_NOC_INITIATOR(initiator) + FT_NOC_PACKET_TAG) = 0u;
}
void ft_noc_seed_software_counters(uint32_t noc, const ft_noc_software_counters *counters)
{
counters->reads_issued[noc] = *niu_register(noc, FT_NOC_RD_RESP_RECEIVED);
counters->nonposted_writes_issued[noc] = *niu_register(noc, FT_NOC_NONPOSTED_WR_REQ_SENT);
counters->nonposted_writes_acked[noc] = *niu_register(noc, FT_NOC_WR_ACK_RECEIVED);
counters->nonposted_atomics_acked[noc] = *niu_register(noc, FT_NOC_ATOMIC_RESP_RECEIVED);
counters->posted_writes_issued[noc] = *niu_register(noc, FT_NOC_POSTED_WR_REQ_SENT);
}