Add code to execute a critical section

This commit is contained in:
Michael Rogenmoser 2023-02-06 19:24:10 +01:00
parent d7599d8b68
commit 2824f98dcc
4 changed files with 79 additions and 16 deletions

View file

@ -52,6 +52,7 @@
#define DMR_IS_MAIN_CORE(core_id) (DMR_IS_CORE(core_id) && (DMR_CORE_ID(DMR_GROUP_ID(core_id), 0) == core_id))
void pos_hmr_tmr_irq();
void pos_hmr_tmr_synch();
static inline unsigned int hmr_get_available_config(unsigned int cid) {
return pulp_read32(ARCHI_HMR_GLOBAL_ADDR(cid) + HMR_TOP_OFFSET + HMR_REGISTERS_AVAIL_CONFIG_REG_OFFSET);
@ -99,6 +100,11 @@ static inline void hmr_set_dmr_config_all(unsigned int cid, bool rapid_recovery)
(rapid_recovery ? 1<<HMR_REGISTERS_DMR_CONFIG_RAPID_RECOVERY_BIT : 0));
}
static inline void hmr_force_dmr_resynch(unsigned int cid, unsigned int dmr_id) {
unsigned int config = pulp_read32(ARCHI_HMR_GLOBAL_ADDR(cid) + HMR_DMR_OFFSET + HMR_DMR_INCREMENT*dmr_id + HMR_DMR_REGS_DMR_CONFIG_REG_OFFSET);
pulp_write32(ARCHI_HMR_GLOBAL_ADDR(cid) + HMR_DMR_OFFSET + HMR_DMR_INCREMENT*dmr_id + HMR_DMR_REGS_DMR_CONFIG_REG_OFFSET, config | (1<<HMR_DMR_REGS_DMR_CONFIG_FORCE_RECOVERY_BIT));
}
static inline unsigned int hmr_get_tmr_status_all(unsigned int cid) {
return pulp_read32(ARCHI_HMR_GLOBAL_ADDR(cid) + HMR_TOP_OFFSET + HMR_REGISTERS_TMR_ENABLE_REG_OFFSET);
}
@ -111,10 +117,18 @@ static inline void hmr_enable_all_tmr(unsigned int cid) {
hmr_set_tmr_status_all(cid, (1<<NUM_TMR_GROUPS)-1);
}
static inline void hmr_enable_tmr(unsigned int cid, unsigned int tmr_id) {
pulp_write32(ARCHI_HMR_GLOBAL_ADDR(cid) + HMR_TMR_OFFSET + HMR_TMR_INCREMENT*tmr_id + HMR_TMR_REGS_TMR_ENABLE_REG_OFFSET, 1<<HMR_TMR_REGS_TMR_ENABLE_TMR_ENABLE_BIT);
}
static inline void hmr_disable_all_tmr(unsigned int cid) {
hmr_set_tmr_status_all(cid, 0);
}
static inline void hmr_disable_tmr(unsigned int cid, unsigned int tmr_id) {
pulp_write32(ARCHI_HMR_GLOBAL_ADDR(cid) + HMR_TMR_OFFSET + HMR_TMR_INCREMENT*tmr_id + HMR_TMR_REGS_TMR_ENABLE_REG_OFFSET, 0);
}
static inline void hmr_set_tmr_config(unsigned int cid, unsigned int tmr_id, bool delay_resynch, bool setback, bool reload_setback, bool rapid_recovery) {
pulp_write32(ARCHI_HMR_GLOBAL_ADDR(0) + HMR_TMR_OFFSET + HMR_TMR_INCREMENT*tmr_id + HMR_TMR_REGS_TMR_CONFIG_REG_OFFSET,
(delay_resynch ? 1<<HMR_TMR_REGS_TMR_CONFIG_DELAY_RESYNCH_BIT : 0) |
@ -131,6 +145,11 @@ static inline void hmr_set_tmr_config_all(unsigned int cid, bool delay_resynch,
(rapid_recovery ? 1<<HMR_REGISTERS_TMR_CONFIG_RAPID_RECOVERY_BIT : 0));
}
static inline void hmr_force_tmr_resynch(unsigned int cid, unsigned int tmr_id) {
unsigned int config = pulp_read32(ARCHI_HMR_GLOBAL_ADDR(cid) + HMR_TMR_OFFSET + HMR_TMR_INCREMENT*tmr_id + HMR_TMR_REGS_TMR_CONFIG_REG_OFFSET);
pulp_write32(ARCHI_HMR_GLOBAL_ADDR(cid) + HMR_TMR_OFFSET + HMR_TMR_INCREMENT*tmr_id + HMR_TMR_REGS_TMR_CONFIG_REG_OFFSET, config | (1<<HMR_TMR_REGS_TMR_CONFIG_FORCE_RESYNCH_BIT));
}
static void hmr_tmr_barrier_setup_all() {
for (int i = 0; i < NUM_TMR_GROUPS; i++) {
eu_bar_setup(eu_bar_addr(TMR_BARRIER_ID(i)), TMR_BARRIER_SETUP(i));

View file

@ -41,6 +41,7 @@ static void cluster_core_init()
eu_evt_maskSet((1<<PULP_DISPATCH_EVENT) | (1<<PULP_MUTEX_EVENT) | (1<<PULP_HW_BAR_EVENT));
#ifdef ARCHI_HMR
eu_irq_maskSet(1<<24 | 1<<23); // Enable resynch and synch requests
eu_bar_setup(eu_bar_addr(0), hmr_get_active_cores(0));
#else
eu_bar_setup(eu_bar_addr(0), (1<<ARCHI_CLUSTER_NB_PE) - 1);

View file

@ -153,6 +153,13 @@ pos_semihosting_call:
#if defined(ARCHI_HAS_CLUSTER)
pe_start:
csrr t0, 0xf14
li t1, ARCHI_HMR_ADDR + HMR_CORE_OFFSET
andi t0, t0, 0x01f
sll t0, t0, HMR_CORE_SLL
add t0, t0, t1
lw t1, HMR_CORE_REGS_SP_STORE_REG_OFFSET(t0)
bnez t1, pos_hmr_tmr_reload
la x2, cluster_stacks
lw x2, 0(x2)
li x3, CLUSTER_STACK_SIZE

View file

@ -160,8 +160,7 @@ void __attribute__((interrupt)) pos_hmr_tmr_reload() {
// get sp from tmr reg
__asm__ __volatile__(
"csrr t0, 0xf14 \n\t" // Read core id
"li t1, " QU(ARCHI_HMR_ADDR) " \n\t"
"addi t1, t1, " QU(HMR_CORE_OFFSET) " \n\t"
"li t1, " QU(ARCHI_HMR_ADDR + HMR_CORE_OFFSET) " \n\t"
"andi t0, t0, 0x01f \n\t"
"sll t0, t0, " QU(HMR_CORE_SLL) " \n\t"
"add t0, t0, t1 \n\t"
@ -184,11 +183,10 @@ void __attribute__((interrupt)) pos_hmr_tmr_reload() {
void __attribute__((naked)) pos_hmr_tmr_irq() {
pos_hmr_store_state_to_stack();
// store sp to tmr reg
// store sp to hmr core reg
__asm__ __volatile__(
"csrr t0, 0xf14 \n\t" // Read core id
"li t1, " QU(ARCHI_HMR_ADDR) " \n\t"
"addi t1, t1, " QU(HMR_CORE_OFFSET) " \n\t"
"li t1, " QU(ARCHI_HMR_ADDR + HMR_CORE_OFFSET) " \n\t"
"andi t0, t0, 0x01f \n\t"
"sll t0, t0, " QU(HMR_CORE_SLL) " \n\t"
"add t0, t0, t1 \n\t"
@ -206,17 +204,55 @@ void __attribute__((naked)) pos_hmr_tmr_irq() {
pos_hmr_tmr_reload();
}
// void pos_hmr_tmr_sync() {
// pos_hmr_store_state_to_stack();
// if (TMR_IS_MAIN_CORE(core_id())) {
// // store sp to tmr reg
// } else {
// // store sp to core reg
// }
// // enter barrier -> this should lock the cores together
// // load sp from tmr reg
// pos_hmr_load_state_from_stack();
// }
void __attribute__((naked)) pos_hmr_tmr_synch() {
if (TMR_IS_MAIN_CORE(core_id())) {
eu_bar_setup(eu_bar_addr(TMR_BARRIER_ID(TMR_GROUP_ID(core_id()))), TMR_BARRIER_SETUP(TMR_GROUP_ID(core_id())));
// eu_bar_setup(eu_bar_addr(0), hmr_get_active_cores(0));
}
pos_hmr_store_state_to_stack();
// store sp to hmr core reg
__asm__ __volatile__(
"csrr t0, 0xf14 \n\t" // Read core id
"li t1, " QU(ARCHI_HMR_ADDR + HMR_CORE_OFFSET) " \n\t"
"andi t0, t0, 0x01f \n\t"
"sll t0, t0, " QU(HMR_CORE_SLL) " \n\t"
"add t0, t0, t1 \n\t"
"sw sp, " QU(HMR_CORE_REGS_SP_STORE_REG_OFFSET) "(t0) \n\t"
: : : "memory");
// enter barrier -> this should lock the cores together
eu_bar_trig_wait_clr(eu_bar_addr(TMR_BARRIER_ID(TMR_GROUP_ID(core_id()))));
// several nops to delay and allow for core reset
__asm__ __volatile__(
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
: : : "memory");
pos_hmr_tmr_reload();
}
int hmr_tmr_critical_section(int (*function_handle)()) {
int ret = 0;
if (TMR_IS_MAIN_CORE(core_id())) {
// enter critical section
hmr_enable_tmr(0, TMR_GROUP_ID(core_id()));
// do critical stuff
ret += function_handle();
// exit critical section
hmr_disable_tmr(0, TMR_GROUP_ID(core_id()));
}
synch_barrier();
return ret;
}
// void pos_hmr_tmr_unsync() {