Line 54... |
Line 54... |
|
|
/* Traverse linked list of MCBs and show individual messages. */
|
/* Traverse linked list of MCBs and show individual messages. */
|
void kernel_show_mcbs(struct mcb *mcb)
|
void kernel_show_mcbs(struct mcb *mcb)
|
{
|
{
|
for(;mcb; mcb = mcb->next) {
|
for(;mcb; mcb = mcb->next) {
|
printf("MCB len=%u origintask=%u ", mcb->length, mcb->origin);
|
PRINTF("MCB len=%u origintask=%u ", mcb->length, mcb->origin);
|
printf("msg:%s\n", mcb->msg);
|
PRINTF("msg:%s\n", mcb->msg);
|
}
|
}
|
}
|
}
|
|
|
/* Show all contexts. */
|
/* Show all contexts. */
|
void kernel_show_contexts()
|
void kernel_show_contexts()
|
{
|
{
|
int i;
|
int i;
|
tid_t t;
|
tid_t t;
|
|
|
for(t = 1; t <= MAX_TASKS; t++) {
|
for(t = 1; t <= MAX_TASKS; t++) {
|
printf("\ntask TID=%d: PC=0x%x ", t, (unsigned)tasks[t].regs.pc & ~0x3);
|
PRINTF("\ntask TID=%d: PC=0x%x ", t, (unsigned)tasks[t].regs.pc & ~0x3);
|
printf("SP(r1)=0x%x ", (unsigned)tasks[t].regs.sp);
|
PRINTF("SP(r1)=0x%x ", (unsigned)tasks[t].regs.sp);
|
printf("SR[IEE]=%d\n", (unsigned)tasks[t].regs.sr & SPR_SR_IEE);
|
PRINTF("SR[IEE]=%d\n", (unsigned)tasks[t].regs.sr & SPR_SR_IEE);
|
printf("SR[TEE]=%d\n", (unsigned)tasks[t].regs.sr & SPR_SR_TEE);
|
PRINTF("SR[TEE]=%d\n", (unsigned)tasks[t].regs.sr & SPR_SR_TEE);
|
printf("SR[SM]=%d\n", (unsigned)tasks[t].regs.sr & SPR_SR_SM);
|
PRINTF("SR[SM]=%d\n", (unsigned)tasks[t].regs.sr & SPR_SR_SM);
|
for(i = 1; i < GPRS; i++) {
|
for(i = 1; i < GPRS; i++) {
|
if (i % 4 == 0)
|
if (i % 4 == 0)
|
printf("\n");
|
PRINTF("\n");
|
printf("r%d=0x%.8x ", i, (unsigned)tasks[t].regs.gprs[i]);
|
PRINTF("r%d=0x%.8x ", i, (unsigned)tasks[t].regs.gprs[i]);
|
}
|
}
|
printf("\n");
|
PRINTF("\n");
|
kernel_show_mcbs(tasks[t].waiting_msgs);
|
kernel_show_mcbs(tasks[t].waiting_msgs);
|
}
|
}
|
printf("\n");
|
PRINTF("\n");
|
}
|
}
|
|
|
/* Simple round-robin scheduler that directly calls dispatcher. It is
|
/* Simple round-robin scheduler that directly calls dispatcher. It is
|
called by low level external interrupt exception handler or by
|
called by low level external interrupt exception handler or by
|
kernel_syscall if KERNEL_SYSCALL_SCHED is defined. */
|
kernel_syscall if KERNEL_SYSCALL_SCHED is defined. */
|
Line 92... |
Line 92... |
if ((++curtask > MAX_TASKS) || !(tasks[curtask].regs.pc & ~0x3))
|
if ((++curtask > MAX_TASKS) || !(tasks[curtask].regs.pc & ~0x3))
|
curtask = 1;
|
curtask = 1;
|
task_context = (unsigned long *)&tasks[curtask].regs;
|
task_context = (unsigned long *)&tasks[curtask].regs;
|
|
|
#if KERNEL_OUTPUT
|
#if KERNEL_OUTPUT
|
printf("kernel_sched(): entry number %d, ", ++kernel_sched_cnt);
|
PRINTF("kernel_sched(): entry number %d, ", ++kernel_sched_cnt);
|
printf("dispatching task TID=%d, time %u cycles", curtask, timestamp());
|
PRINTF("dispatching task TID=%d, time %u cycles", curtask, timestamp());
|
|
|
kernel_show_contexts();
|
kernel_show_contexts();
|
#endif
|
#endif
|
|
|
dispatch();
|
dispatch();
|
Line 227... |
Line 227... |
void kernel_syscall()
|
void kernel_syscall()
|
{
|
{
|
unsigned short syscall_num;
|
unsigned short syscall_num;
|
|
|
#if KERNEL_OUTPUT
|
#if KERNEL_OUTPUT
|
printf("kernel_syscall(): entry number %d, ", ++kernel_syscall_cnt);
|
PRINTF("kernel_syscall(): entry number %d, ", ++kernel_syscall_cnt);
|
printf("current TID=%d, time %u cycles", curtask, timestamp());
|
PRINTF("current TID=%d, time %u cycles", curtask, timestamp());
|
|
|
kernel_show_contexts();
|
kernel_show_contexts();
|
#endif
|
#endif
|
syscall_num = *(unsigned short *)((tasks[curtask].regs.pc & ~0x3) - 6);
|
syscall_num = *(unsigned short *)((tasks[curtask].regs.pc & ~0x3) - 6);
|
|
|
Line 242... |
Line 242... |
break;
|
break;
|
case IPC_MSGRCV:
|
case IPC_MSGRCV:
|
kernel_msgrcv(curtask);
|
kernel_msgrcv(curtask);
|
break;
|
break;
|
default:
|
default:
|
printf("kernel_syscall(): unknown syscall (%u)\n", syscall_num);
|
PRINTF("kernel_syscall(): unknown syscall (%u)\n", syscall_num);
|
}
|
}
|
|
|
#if KERNEL_SYSCALL_SCHED
|
#if KERNEL_SYSCALL_SCHED
|
kernel_sched();
|
kernel_sched();
|
#endif
|
#endif
|
Line 258... |
Line 258... |
int kernel_init()
|
int kernel_init()
|
{
|
{
|
tid_t t;
|
tid_t t;
|
int i;
|
int i;
|
|
|
printf("Initializing kernel:\n");
|
PRINTF("Initializing kernel:\n");
|
|
|
printf(" Clearing kernel structures...\n");
|
PRINTF(" Clearing kernel structures...\n");
|
memset(tasks, 0, sizeof(tasks));
|
memset(tasks, 0, sizeof(tasks));
|
memset(stacks, 0, sizeof(stacks));
|
memset(stacks, 0, sizeof(stacks));
|
memset(msgs, 0, sizeof(msgs));
|
memset(msgs, 0, sizeof(msgs));
|
|
|
printf(" Initializing MCBs... %d MCB(s)\n", MAX_MSGS);
|
PRINTF(" Initializing MCBs... %d MCB(s)\n", MAX_MSGS);
|
for(i = 0; i < (MAX_MSGS - 1); i++)
|
for(i = 0; i < (MAX_MSGS - 1); i++)
|
msgs[i].next = &msgs[i+1];
|
msgs[i].next = &msgs[i+1];
|
free_mcbs = &msgs[0];
|
free_mcbs = &msgs[0];
|
|
|
printf(" Initializing TCBs... %d user task(s)\n", MAX_TASKS);
|
PRINTF(" Initializing TCBs... %d user task(s)\n", MAX_TASKS);
|
|
|
tasks_entries();
|
tasks_entries();
|
|
|
for(t = 0; t <= MAX_TASKS; t++) {
|
for(t = 0; t <= MAX_TASKS; t++) {
|
tasks[t].regs.sp = (unsigned long)stacks[t] + STACK_SIZE - 4;
|
tasks[t].regs.sp = (unsigned long)stacks[t] + STACK_SIZE - 4;
|
Line 293... |
Line 293... |
task_context = (unsigned long *)&tasks[1].regs;
|
task_context = (unsigned long *)&tasks[1].regs;
|
|
|
/* Initialize initrrupt controller */
|
/* Initialize initrrupt controller */
|
int_init();
|
int_init();
|
|
|
printf(" Exceptions will be enabled when first task is dispatched.\n");
|
PRINTF(" Exceptions will be enabled when first task is dispatched.\n");
|
printf("Kernel initalized. Starting first user task.\n");
|
PRINTF("Kernel initalized. Starting first user task.\n");
|
|
|
#if KERNEL_SYSCALL_SCHED
|
#if KERNEL_SYSCALL_SCHED
|
kernel_sched(); /* Lets schedule and dispatch our first task */
|
kernel_sched(); /* Lets schedule and dispatch our first task */
|
#else
|
#else
|
tick_init(TICK_PERIOD, kernel_sched);
|
tick_init(TICK_PERIOD, kernel_sched);
|