Sorry for the delay, I've been rather busy. I have finally managed to create an example program. Hopefully you are able to take this and adapt it for your own needs. Basically, I have written a custom handler which gets installed and on trap then resets the chip. Note this is designed for XS2 architectures:
Code: Select all
int main(void) {
par {
on tile[0]: {
// Install the custom trap handler
unsigned tile_id = get_local_tile_id();
install_handler(tile_id);
// Wait
delay_seconds(5);
// Cause trap
unsafe {
int *x = 0;
// Cause trap
*x = 0;
}
}
}
return 0;
}
Code: Select all
// Custom trap handler.
// It reads the SSWITCH PLL control register, clears bit 31 and writes it back
// to cause a reset
#include <xs1.h>
.align 4
tile_id:
.word 0
.align 4
.globl install_handler
.globl install_handler.nstackwords
.linkset install_handler.nstackwords, 0
install_handler:
nop // Need a NOP to align the ENTSP to the right lane
entsp 0
ldap r11, trap_handler
set kep, r11
ldap r11, tile_id
stw r0, r11[0]
retsp 0
.align XS1_KEP_ALIGNMENT
.globl trap_handler
.globl trap_handler.nstackwords
.linkset trap_handler.nstackwords, 0
trap_handler:
ldc r1, 0x6 // XS1_L_SSWITCH_PLL_CTL_NUM
ldc r2, 0x0 // Get a default value in r2
// Read the tile id from memory
ldap r11, tile_id
ldw r0, r11[0]
shl r0, r0, XS1_CHAN_ID_PROCESSOR_SHIFT
getr r3, XS1_RES_TYPE_CHANEND
// Set destination
ldc r11, XS1_RES_TYPE_CONFIG | (XS1_CT_SSCTRL << XS1_CHAN_ID_CHANNUM_SHIFT)
or r11, r11, r0
setd res[r3], r11
// Send read packet
ldc r11, XS1_CT_READC // Too big for outct immediate
outct res[r3], r11
shr r0, r3, 8
shl r0, r0, 8
shr r11, r1, 8
or r0, r0, r11
out res[r3], r0 // (c & 0xffffff00) | (reg >> 8)
outt res[r3], r1 // reg & 0xff
outct res[r3], XS1_CT_END
// Receive response
inct r11, res[r3] // receive ACK/NACK
eq r11, r11, XS1_CT_ACK
bf r11, got_nack
in r2, res[r3] // for ACK put response into r2
got_nack:
chkct res[r3], XS1_CT_END // consume END
// Send write packet
ldc r11, XS1_CT_WRITEC // Too big for outct immediate
outct res[r3], r11
out res[r3], r0 // (c & 0xffffff00) | (reg >> 8)
outt res[r3], r1 // reg & 0xff
// Clear bit 31 to request reset
ldc r11, 1
ldc r10, 31
shl r11, r11, r10
andnot r2, r11
out res[r3], r2 // Send value to write
outct res[r3], XS1_CT_END
// Consume response
inct r0, res[r3]
chkct res[r3], XS1_CT_END
freer res[r3]
// Wait for reset
waiteu
Peter