Merge branch 'master' into ohligs
This commit is contained in:
commit
1f74434a46
8 changed files with 128 additions and 53 deletions
|
@ -51,9 +51,9 @@ typedef struct {
|
|||
#define ICC_TYPE_PINGRESPONSE (1 << 3)
|
||||
|
||||
int icc_init(void);
|
||||
int icc_ping();
|
||||
int icc_ping(int ue);
|
||||
void icc_check(void);
|
||||
|
||||
int icc_halt(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -234,6 +234,9 @@ void irq_handler(struct state *s)
|
|||
/* This is a blank function pointer */
|
||||
void (*handler) (struct state * s);
|
||||
|
||||
// at first, we check our work queues
|
||||
check_workqueues();
|
||||
|
||||
/*
|
||||
* Find out if we have a custom handler to run for this
|
||||
* IRQ and then finally, run it
|
||||
|
|
|
@ -80,8 +80,15 @@ void timer_wait(unsigned int ticks)
|
|||
{
|
||||
uint64_t eticks = timer_ticks + ticks;
|
||||
|
||||
while (timer_ticks < eticks)
|
||||
while (timer_ticks < eticks) {
|
||||
check_workqueues();
|
||||
|
||||
// recheck break condition
|
||||
if (timer_ticks >= eticks)
|
||||
break;
|
||||
|
||||
reschedule();
|
||||
}
|
||||
}
|
||||
|
||||
#define LATCH(f) ((CLOCK_TICK_RATE + f/2) / f)
|
||||
|
|
|
@ -18,8 +18,10 @@
|
|||
#include <metalsvm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irqflags.h>
|
||||
#include <asm/irq.h>
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
#include <asm/RCCE.h>
|
||||
#include <asm/RCCE_lib.h>
|
||||
#include <asm/iRCCE.h>
|
||||
#include <asm/SCC_API.h>
|
||||
#include <asm/icc.h>
|
||||
|
@ -72,9 +74,20 @@ static int scc_clear(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void intr_handler(struct state *s)
|
||||
{
|
||||
// reset appropriate bit in the core configuration register
|
||||
int tmp, z;
|
||||
|
||||
z = Z_PID(RC_COREID[my_ue]);
|
||||
tmp=ReadConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1));
|
||||
tmp &= ~2;
|
||||
SetConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1), tmp);
|
||||
}
|
||||
|
||||
int icc_init(void)
|
||||
{
|
||||
int i;
|
||||
int i, z, tmp;
|
||||
uint64_t start, end, ticks, freq = 533;
|
||||
uint32_t cr4, msg = 0;
|
||||
|
||||
|
@ -117,9 +130,6 @@ int icc_init(void)
|
|||
num_ues = RCCE_num_ues();
|
||||
kprintf("Got rank %d of %d ranks\n", my_ue, num_ues);
|
||||
|
||||
i = ReadConfigReg(CRB_OWN+GLCFG0);
|
||||
kprintf("glcfg0 0x%x\n", i);
|
||||
|
||||
RCCE_barrier(&RCCE_COMM_WORLD);
|
||||
|
||||
kputs("RCCE test...\t");
|
||||
|
@ -130,34 +140,90 @@ int icc_init(void)
|
|||
else
|
||||
kprintf("failed! (0x%x)\n", msg);
|
||||
|
||||
// reset INTR/LINT0 flag
|
||||
z = Z_PID(RC_COREID[my_ue]);
|
||||
tmp=ReadConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1));
|
||||
tmp &= ~2;
|
||||
SetConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1), tmp);
|
||||
|
||||
// set interrupt handler (INTR/LINT0)
|
||||
irq_install_handler(124, intr_handler);
|
||||
|
||||
kputs("Now, the SCC is initialized!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int icc_send_irq(int ue)
|
||||
{
|
||||
int tmp, x, y, z, addr;
|
||||
|
||||
z = Z_PID(RC_COREID[ue]);
|
||||
x = X_PID(RC_COREID[ue]);
|
||||
y = Y_PID(RC_COREID[ue]);
|
||||
addr = CRB_ADDR(x,y) + (z==0 ? GLCFG0 : GLCFG1);
|
||||
|
||||
// send interrupt to ue
|
||||
do {
|
||||
NOP1;
|
||||
tmp=ReadConfigReg(addr);
|
||||
} while(tmp & 2);
|
||||
tmp |= 2;
|
||||
SetConfigReg(addr, tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int icc_halt(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
uint32_t do_send = 1;
|
||||
|
||||
do {
|
||||
// iRCCE is not thread save => disable interrupts
|
||||
flags = irq_nested_disable();
|
||||
|
||||
if (do_send)
|
||||
do_send = (iRCCE_isend_push() == iRCCE_PENDING);
|
||||
icc_check();
|
||||
|
||||
irq_nested_enable(flags);
|
||||
} while(do_send);
|
||||
|
||||
HALT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static volatile uint64_t ping_start = 0;
|
||||
static icc_header_t ping_request = {ICC_TYPE_PINGREQUEST, 0, 0};
|
||||
static icc_header_t ping_response = {ICC_TYPE_PINGRESPONSE, 0, 0};
|
||||
|
||||
int icc_ping(int ue)
|
||||
{
|
||||
icc_header_t ping_header = {ICC_TYPE_PINGREQUEST, 0, sizeof(uint64_t)};
|
||||
uint64_t tsc;
|
||||
uint32_t flags;
|
||||
iRCCE_SEND_REQUEST send_request;
|
||||
|
||||
if (BUILTIN_EXPECT(ue == my_ue, 0))
|
||||
return -EINVAL;
|
||||
if (BUILTIN_EXPECT((ue < 0) || (ue >= num_ues), 0))
|
||||
return -EINVAL;
|
||||
|
||||
tsc = rdtsc();
|
||||
while(ping_start) {
|
||||
NOP8;
|
||||
}
|
||||
|
||||
ping_start = rdtsc();
|
||||
|
||||
// iRCCE is not thread save => disable interrupts
|
||||
flags = irq_nested_disable();
|
||||
|
||||
iRCCE_isend((char*) &ping_header, sizeof(icc_header_t), ue, NULL);
|
||||
iRCCE_isend((char*) &tsc, sizeof(uint64_t), ue, &send_request);
|
||||
iRCCE_isend((char*) &ping_request, sizeof(icc_header_t), ue, NULL);
|
||||
|
||||
// waiting for the completion
|
||||
while(iRCCE_isend_test(&send_request, NULL) != iRCCE_SUCCESS)
|
||||
icc_check(); // oh, we have time to check incoming requests
|
||||
// wait some time
|
||||
NOP8;
|
||||
|
||||
// wake up receiver
|
||||
icc_send_irq(ue);
|
||||
|
||||
irq_nested_enable(flags);
|
||||
|
||||
|
@ -171,27 +237,19 @@ static void interpret_header(icc_header_t* header, int recv_ue)
|
|||
switch(header->type)
|
||||
{
|
||||
case ICC_TYPE_PINGREQUEST: {
|
||||
icc_header_t response = {ICC_TYPE_PINGRESPONSE, 0, sizeof(uint64_t)};
|
||||
iRCCE_RECV_REQUEST recv_req;
|
||||
uint64_t tsc;
|
||||
|
||||
iRCCE_isend((char*) &response, sizeof(icc_header_t), recv_ue, NULL);
|
||||
if (iRCCE_irecv((char*) &tsc, sizeof(uint64_t), recv_ue, &recv_req) != iRCCE_SUCCESS)
|
||||
iRCCE_irecv_wait(&recv_req);
|
||||
iRCCE_isend((char*) &ping_response, sizeof(icc_header_t), recv_ue, NULL);
|
||||
|
||||
iRCCE_isend((char*) &tsc, sizeof(uint64_t), recv_ue, NULL);
|
||||
iRCCE_isend_push();
|
||||
// wait some time
|
||||
NOP8;
|
||||
|
||||
// wake up remote core
|
||||
icc_send_irq(recv_ue);
|
||||
}
|
||||
break;
|
||||
case ICC_TYPE_PINGRESPONSE: {
|
||||
uint64_t start, end;
|
||||
iRCCE_RECV_REQUEST recv_req;
|
||||
|
||||
if (iRCCE_irecv((char*) &start, sizeof(uint64_t), recv_ue, &recv_req) != iRCCE_SUCCESS)
|
||||
iRCCE_irecv_wait(&recv_req);
|
||||
end = rdtsc();
|
||||
kprintf("Receive ping response. Ticks: %d\n", end-start);
|
||||
}
|
||||
case ICC_TYPE_PINGRESPONSE:
|
||||
kprintf("Receive ping response. Ticks: %d\n", rdtsc()-ping_start);
|
||||
ping_start = 0;
|
||||
break;
|
||||
default:
|
||||
kprintf("Receive unknown ICC message (%d)\n", header->type);
|
||||
|
@ -206,31 +264,36 @@ void icc_check(void)
|
|||
{
|
||||
static icc_header_t header[MAX_SCC_CORES];
|
||||
static iRCCE_RECV_REQUEST request[MAX_SCC_CORES];
|
||||
static int8_t pending[MAX_SCC_CORES] = {[0 ... MAX_SCC_CORES-1] = 0};
|
||||
static int8_t first_call = 1;
|
||||
int i, ret;
|
||||
|
||||
if (first_call) {
|
||||
first_call = 0;
|
||||
|
||||
for(i=0; i<num_ues; i++) {
|
||||
if (i == my_ue)
|
||||
continue;
|
||||
|
||||
iRCCE_irecv((char*) (header+i), sizeof(icc_header_t), i, request+i);
|
||||
}
|
||||
}
|
||||
|
||||
// pushes the progress of non-blocking communication requests
|
||||
iRCCE_isend_push();
|
||||
iRCCE_irecv_push();
|
||||
|
||||
for(i=0; i<num_ues; i++) {
|
||||
if (i == my_ue)
|
||||
continue;
|
||||
|
||||
if (!pending[i]) {
|
||||
ret = iRCCE_irecv((char*) (header+i), sizeof(icc_header_t), i, request+i);
|
||||
if (ret == iRCCE_SUCCESS)
|
||||
interpret_header(header+i, i);
|
||||
else
|
||||
pending[i] = 1;
|
||||
} else {
|
||||
ret = iRCCE_irecv_test(request+i, NULL);
|
||||
if (ret == iRCCE_SUCCESS) {
|
||||
interpret_header(header+i, i);
|
||||
pending[i] = 0;
|
||||
}
|
||||
|
||||
ret = iRCCE_irecv_test(request+i, NULL);
|
||||
if (ret == iRCCE_SUCCESS) {
|
||||
interpret_header(header+i, i);
|
||||
iRCCE_irecv((char*) (header+i), sizeof(icc_header_t), i, request+i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pushes the progress of non-blocking communication requests
|
||||
iRCCE_isend_push();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -117,7 +117,11 @@ int main(void)
|
|||
reschedule();
|
||||
|
||||
while(1) {
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
icc_halt();
|
||||
#else
|
||||
HALT;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -714,8 +714,6 @@ void scheduler(void)
|
|||
unsigned int i;
|
||||
unsigned int new_id;
|
||||
|
||||
check_workqueues();
|
||||
|
||||
#if MAX_CORES > 1
|
||||
spinlock_irqsave_lock(&table_lock);
|
||||
#endif
|
||||
|
|
|
@ -93,7 +93,7 @@ static int STDCALL ping(void* arg)
|
|||
|
||||
for(i=0; i<20; i++) {
|
||||
icc_ping(1);
|
||||
sleep(1);
|
||||
HALT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -118,7 +118,7 @@ int mmu_init(void)
|
|||
} else {
|
||||
kputs("Unable to initialize the memory management subsystem\n");
|
||||
while(1) {
|
||||
NOP8;
|
||||
HALT;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue