Hardware mutexes

The PDAEMON has hardware support for 16 busy-waiting mutexes accessed by up to 254 clients simultanously. The clients may be anything able to read and write the PDAEMON registers - code running on host, on PDAEMON, or on any other falcon engine with MMIO access powers.

The clients are identified by tokens. Tokens are 8-bit numbers in 0x01-0xfe range. Tokens may be assigned to clients statically by software, or dynamically by hardware. Only tokens 0x08-0xfe will be dynamically allocated by hardware - software may use statically assigned tokens 0x01-0x07 even if dynamic tokens are in use at the same time. The registers used for dynamic token allocation are:

MMIO 0x488 / I[0x12200]: TOKEN_ALLOC
Read-only, each read to this register allocates a free token and gives it as the read result. If there are no free tokens, 0xff is returned.
MMIO 0x48c / I[0x12300]: TOKEN_FREE
A write to this register will free a token, ie. return it back to the pool used by TOKEN_ALLOC. Only low 8 bits of the written value are used. Attempting to free a token outside of the dynamic allocation range [0x08-0xff] or a token already in the free queue will have no effect. Reading this register will show the last written value, invalid or not.

The free tokens are stored in a FIFO - the freed tokens will be used by TOKEN_ALLOC in the order of freeing. After reset, the free token FIFO will contain tokens 0x08-0xfe in ascending order.

The actual mutex locking and unlocking is done by the MUTEX_TOKEN registers:

MMIO 0x580+i*4 / I[0x16000+i*0x100], i<16: MUTEX_TOKEN[i]
The 16 mutices. A value of 0 means unlocked, any other value means locked by the client holding the corresponding token. Only low 8 bits of the written value are used. A write of 0 will unlock the mutex and will always succeed. A write of 0x01-0xfe will succeed only if the mutex is currently unlocked. A write of 0xff is invalid and will always fail. A failed write has no effect.

The token allocation circuitry additionally exports four signals to PCOUNTER:

  • TOKEN_ALL_USED: 1 iff all tokens are currently allocated [ie. a read from TOKEN_ALLOC would return 0xff]
  • TOKEN_NONE_USED: 1 iff no tokens are currently allocated [ie. tokens 0x08-0xfe are all in free tokens queue]
  • TOKEN_FREE: pulses for 1 cycle whenever TOKEN_FREE is written, even if with invalid value
  • TOKEN_ALLOC: pulses for 1 cycle whenever TOKEN_ALLOC is read, even if allocation fails