fix(native-usb): service masked completions and trace startup stalls
Keep native backend locking IRQ-permitting and service USB hardware from SRAM during BOOTSEL sampling. Add bounded input/control flight recording, root IN and EP0 snapshots, and masked-window handoff coverage. Record PC qualification and the remaining Switch stability limitations.
This commit is contained in:
parent
a699a6920b
commit
d424fe0f4a
12 changed files with 884 additions and 195 deletions
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
#if defined(SWITCH2_PROBE_HUB) && SWITCH2_PROBE_HUB
|
||||
extern bool native_hub_select_device(uint8_t address, uint8_t owner, uint32_t cutoff);
|
||||
#if defined(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
#include "usb/native_hub/native_hub_trace.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !PICO_RP2350 || defined(__riscv)
|
||||
|
|
@ -30,6 +33,10 @@ extern bool native_hub_select_device(uint8_t address, uint8_t owner, uint32_t cu
|
|||
#define PID_OUT 0xe1u
|
||||
#define PID_IN 0x69u
|
||||
#define PID_SETUP 0x2du
|
||||
// NRZI SYNC+PID words, with K=2 and J=1 packed into two-bit samples.
|
||||
#define TOKEN_OUT_SIGNATURE 0xaa66a666u
|
||||
#define TOKEN_IN_SIGNATURE 0x95a6a666u
|
||||
#define TOKEN_SETUP_SIGNATURE 0x9a56a666u
|
||||
#define NO_READER 2u
|
||||
#define SETUP_SEQUENCE_MASK 0x3fffffffu
|
||||
#define SETUP_SLOT_SHIFT 30u
|
||||
|
|
@ -175,9 +182,9 @@ static void build_table(routing_table* table,
|
|||
|
||||
void probe_router_init(uint32_t system_clock_hz) {
|
||||
// Explicit SRAM data: Core1 must never fetch flash during durable saves.
|
||||
token_words[6] = 0xaa66a666u;
|
||||
token_words[10] = 0x95a6a666u;
|
||||
token_words[5] = 0x9a56a666u;
|
||||
token_words[6] = TOKEN_OUT_SIGNATURE;
|
||||
token_words[10] = TOKEN_IN_SIGNATURE;
|
||||
token_words[5] = TOKEN_SETUP_SIGNATURE;
|
||||
const uint8_t addresses[PROBE_ROUTER_SLOTS] = {0u, PROBE_ROUTER_UNASSIGNED,
|
||||
PROBE_ROUTER_UNASSIGNED};
|
||||
memset(&counters, 0, sizeof(counters));
|
||||
|
|
@ -295,7 +302,7 @@ static __force_inline bool sample_line(uint32_t* deadline, uint32_t* line) {
|
|||
}
|
||||
|
||||
static __force_inline void route_header(const routing_table* table, uint32_t address,
|
||||
bool setup, uint32_t initial_address,
|
||||
uint32_t signature, uint32_t initial_address,
|
||||
uint32_t cutoff, raw_packet* packet) {
|
||||
// TinyUSB clears SETUP_REC only AFTER copying the hardware-validated SETUP
|
||||
// into its event callback. Until then, preserve both address and owner.
|
||||
|
|
@ -306,8 +313,21 @@ static __force_inline void route_header(const routing_table* table, uint32_t add
|
|||
return;
|
||||
#if defined(SWITCH2_PROBE_HUB) && SWITCH2_PROBE_HUB
|
||||
if (atomic_read(&enabled) != 0u) {
|
||||
if (!native_hub_select_device((uint8_t)address, table->owner[address], cutoff))
|
||||
#if defined(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
const uint8_t pid = signature == TOKEN_OUT_SIGNATURE ? PID_OUT :
|
||||
signature == TOKEN_IN_SIGNATURE ? PID_IN : PID_SETUP;
|
||||
const bool selected = (pid == PID_OUT || (pid == PID_IN && table->owner[address] == 0))
|
||||
? native_hub_select_device_traced((uint8_t)address, table->owner[address], cutoff, pid)
|
||||
: native_hub_select_device((uint8_t)address, table->owner[address], cutoff);
|
||||
#else
|
||||
const bool selected = native_hub_select_device((uint8_t)address, table->owner[address], cutoff);
|
||||
#endif
|
||||
if (!selected) {
|
||||
#if defined(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
native_hub_note_failed_select((uint8_t)address, table->owner[address], cutoff, pid);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (initial_address != address) ++packet->retargets;
|
||||
}
|
||||
#else
|
||||
|
|
@ -324,7 +344,7 @@ static __force_inline void route_header(const routing_table* table, uint32_t add
|
|||
// Candidate observations qualify calibration only. Runtime ownership
|
||||
// comes from the hardware address frozen by SETUP_REC. A missed software
|
||||
// candidate must not reject a correctly addressed, hardware-accepted SETUP.
|
||||
if (setup)
|
||||
if (signature == TOKEN_SETUP_SIGNATURE)
|
||||
publish_setup(table->owner[address]);
|
||||
}
|
||||
|
||||
|
|
@ -438,7 +458,7 @@ edge:
|
|||
if ((base) + (bit) == 19u && decoder != NULL) { \
|
||||
uint8_t candidate = early_decoder[word1 & 0xffu]; \
|
||||
if (candidate < 128u) \
|
||||
route_header(table, candidate, word0 == 0x9a56a666u, initial_address, \
|
||||
route_header(table, candidate, word0, initial_address, \
|
||||
deadline + 11u * FS_BIT_CYCLES, &result); \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
@ -465,7 +485,7 @@ edge:
|
|||
address_wire = (address_wire | (address_wire >> 1u)) & 0x3333u; \
|
||||
address_wire = (address_wire | (address_wire >> 2u)) & 0x0f0fu; \
|
||||
address_wire = (address_wire | (address_wire >> 4u)) & 0xffu; \
|
||||
route_header(table, decoder[address_wire], word0 == 0x9a56a666u, \
|
||||
route_header(table, decoder[address_wire], word0, \
|
||||
initial_address, deadline + 7u * FS_BIT_CYCLES, &result); \
|
||||
if (result.late) { result.count = (base) + (bit) + 1u; goto done; } \
|
||||
} \
|
||||
|
|
|
|||
|
|
@ -124,6 +124,10 @@ int probe_debug_printf(const char* format, ...) {
|
|||
if (result <= 0) return result;
|
||||
const size_t size = (size_t)result < sizeof(message) ? (size_t)result : sizeof(message) - 1;
|
||||
const uint32_t interrupts = save_and_disable_interrupts();
|
||||
#if SWITCH2_PROBE_HUB && defined(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
const uint32_t mask_started = time_us_32();
|
||||
const uint32_t trace_parent = native_hub_trace_phase(NATIVE_HUB_TRACE_PHASE_LOG_COPY);
|
||||
#endif
|
||||
if (LOG_CAPACITY - (log_written - log_read) >= size) {
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
log_bytes[(log_written + i) % LOG_CAPACITY] = message[i];
|
||||
|
|
@ -132,7 +136,14 @@ int probe_debug_printf(const char* format, ...) {
|
|||
} else {
|
||||
log_dropped += (uint32_t)result;
|
||||
}
|
||||
#if SWITCH2_PROBE_HUB && defined(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
native_hub_trace_phase(trace_parent);
|
||||
const uint32_t mask_elapsed = time_us_32() - mask_started;
|
||||
#endif
|
||||
restore_interrupts(interrupts);
|
||||
#if SWITCH2_PROBE_HUB && defined(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
native_hub_note_log_mask(mask_elapsed, (uint32_t)size, interrupts != 0);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -847,12 +858,24 @@ int main(void) {
|
|||
uint32_t last_heartbeat = 0;
|
||||
while (true) {
|
||||
#if SWITCH2_PROBE_HUB
|
||||
#if defined(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
native_hub_trace_phase(NATIVE_HUB_TRACE_PHASE_RADIO_POLL);
|
||||
#endif
|
||||
probe_controller_input_task();
|
||||
#if defined(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
native_hub_trace_phase(NATIVE_HUB_TRACE_PHASE_USB_TASK);
|
||||
#endif
|
||||
native_hub_task();
|
||||
#else
|
||||
tud_task();
|
||||
#endif
|
||||
#if SWITCH2_PROBE_HUB && defined(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
native_hub_trace_phase(NATIVE_HUB_TRACE_PHASE_LOG_DRAIN);
|
||||
#endif
|
||||
drain_log();
|
||||
#if SWITCH2_PROBE_HUB && defined(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
native_hub_trace_phase(NATIVE_HUB_TRACE_PHASE_PROTOCOL);
|
||||
#endif
|
||||
const uint32_t now = to_ms_since_boot(get_absolute_time());
|
||||
#ifdef SWITCH_PICO_SWITCH2_USB_BRIDGE
|
||||
probe_bootsel_task(now);
|
||||
|
|
@ -917,6 +940,9 @@ int main(void) {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
#if SWITCH2_PROBE_HUB && defined(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
native_hub_trace_phase(NATIVE_HUB_TRACE_PHASE_SLEEP);
|
||||
#endif
|
||||
sleep_us(100);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -369,12 +369,16 @@ function(switch2_usb_probe_configure target)
|
|||
endif()
|
||||
if(SWITCH2_PROBE_HUB AND SWITCH2_BRIDGE_FULL_INPUT)
|
||||
if(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
pico_set_program_version(${target} "0.78-native-tx-bank-trace")
|
||||
pico_set_program_version(${target} "0.87-native-enumeration-flight")
|
||||
else()
|
||||
pico_set_program_version(${target} "0.78-native-gamepad")
|
||||
pico_set_program_version(${target} "0.86-native-flash-service")
|
||||
endif()
|
||||
elseif(SWITCH2_PROBE_HUB)
|
||||
pico_set_program_version(${target} "0.78-native-hub-tx-bank")
|
||||
if(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
pico_set_program_version(${target} "0.87-native-hub-enumeration-flight")
|
||||
else()
|
||||
pico_set_program_version(${target} "0.86-native-hub-flash-service")
|
||||
endif()
|
||||
elseif(SWITCH2_PROBE_JOIN_CHORD_GATE)
|
||||
if(SWITCH2_PROBE_TRACE_NATIVE_INPUT)
|
||||
pico_set_program_version(${target} "0.37-pair-chord-trace")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue