ARM Integrator-CP ITPTMME Phase2: Difference between revisions

Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content deleted Content added
Pancakes (talk | contribs)
Pancakes (talk | contribs)
m added kernel and idle thread and updated scheduler switch
Line 156: Line 156:
/* only wakeup if it is sleeping */
/* only wakeup if it is sleeping */
if (ks->cthread->flags & KTHREAD_SLEEPING) {
if (ks->cthread->flags & KTHREAD_SLEEPING) {
if (ks->ctime > ks->cthread->timeout) {
if (ks->cthread->timeout > 0 && ks->ctime > ks->cthread->timeout) {
kprintf("WOKE UP %x\n", ks->cthread);
//kprintf("WOKE UP (timeout) %x\n", ks->cthread);
/* wake up thread if passed timeout */
/* wake up thread if passed timeout */
ks->cthread->flags &= ~KTHREAD_SLEEPING;
ks->cthread->flags &= ~KTHREAD_SLEEPING;
ks->cthread->r0 = 0;
break;
}
}
/* wakeup thread is set to be woken up */
/* wakeup thread is set to be woken up */
if (ks->cthread->flags & KTHREAD_WAKEUP) {
if (ks->cthread->flags & KTHREAD_WAKEUP) {
//kprintf("WOKE UP (signal) %x\n", ks->cthread);
ks->cthread->flags &= ~(KTHREAD_WAKEUP | KTHREAD_SLEEPING);
ks->cthread->flags &= ~(KTHREAD_WAKEUP | KTHREAD_SLEEPING);
ks->cthread->r0 = ks->ctime - ks->cthread->timeout;
break;
}
}
}
} else {
/* run this thread */
/* run this thread */
if (!(ks->cthread->flags & KTHREAD_SLEEPING)) {
break;
break;
}
}
/* thread is sleeping or not able to run */
/* thread is sleeping or not able to run */
}
}
Line 178: Line 180:
/* hopefully we got something or the system should deadlock */
/* hopefully we got something or the system should deadlock */
kt = ks->cthread;
kt = ks->cthread;
if (!kt) {
PANIC("no-threads");
}
/*
/*
load registers
load registers
Line 224: Line 221:
*/
*/
asm("mcr p15, #0, r0, c8, c7, #0");
asm("mcr p15, #0, r0, c8, c7, #0");
//kprintf("SWITCH-TO thread:%x cpsr:%x fp:%x sp:%x pc:%x\n", kt, kt->cpsr, kt->r11, kt->sp, kt->pc);
uint32 *p;
if (!kvmm2_getphy(&ks->cproc->vmm, 0x90000000, (uintptr*)&p)) {
//kprintf("NO STACK EXISTS??\n");
} else {
//kprintf("writing to stack..%x\n", kt->sp);
//((uint32*)kt->sp)[-1] = 0xbb;
}
if (kvmm2_getphy(&ks->cproc->vmm, 0x80000000, (uintptr*)&p)) {
uint32 x;
//kprintf("CODE PAGE :%x\n", p);
p = (uint32*)(0x80000000);

//((uint32*)KSTACKEXC)[-1] = 0x80000800;
//for (x = 0; x < 1024; ++x) {
// p[x] = 0xeafffffe;
//}
} else {
//kprintf("CODE PAGE????\n");
}
}
}
</source>

=== Added Idle Thread And Kernel Thread ===
I added an ''idle'' thread that does nothing but yield, and a kernel work thread. The idle thread keeps the scheduler with something to switch too when no other threads are running (supposed to be), but in reality in the current code it just switches to it and it yields. Needs some improvement, but it is simple for now.
<source lang="c">
int ksleep(uint32 timeout) {
int result;
asm(" mov r0, %[in] \n\
swi #101 \n\
mov %[result], r0 \n\
" : [result]"=r" (result) : [in]"r" (timeout));
/* convert from ticks */
return result;
}

void kthread(KTHREAD *th) {
uint32 x;
for (;;) {
ksleep(0xffff);
kserdbg_putc('$');
}
}

void kidle() {
for (;;) {
asm("swi #102");
}
}
</source>

=== Creation Of Kernel And Idle Thread ===
<source lang="c">
.... in main ....
process = (KPROCESS*)kmalloc(sizeof(KPROCESS));
memset(process, 0, sizeof(KPROCESS));
kvmm2_init(&process->vmm);
ll_add((void**)&ks->procs, process);
th = (KTHREAD*)kmalloc(sizeof(KTHREAD));
memset(th, 0, sizeof(KTHREAD));
ll_add((void**)&process->threads, th);
th->pc = (uintptr)&kthread;
th->flags = 0;
th->cpsr = 0x60000000 | ARM4_MODE_SYS;
/* set stack */
th->sp = (uintptr)kmalloc(1024 * 2) + 1024 * 2 - 8;
th->r0 = (uint32)th;

th = (KTHREAD*)kmalloc(sizeof(KTHREAD));
memset(th, 0, sizeof(KTHREAD));
ll_add((void**)&process->threads, th);
th->pc = (uintptr)&kidle;
th->flags = KTHREAD_KIDLE;
th->cpsr = 0x60000000 | ARM4_MODE_SYS;
/* set stack (dont need anything big for idle thread at the moment) */
th->sp = (uintptr)kmalloc(128) + 128 - 8;
th->r0 = (uint32)th;
ks->idleth = th;
ks->idleproc = process;
....
</source>
</source>


Line 267: Line 354:
t0mmio[REG_INTCLR] = 1; /* according to the docs u can write any value */
t0mmio[REG_INTCLR] = 1; /* according to the docs u can write any value */
//kprintf("t0mmio[REG_BGLOAD]:%x ks->ctime:%x\n", t0mmio[REG_BGLOAD], ks->ctime);
ks->ctime += t0mmio[REG_BGLOAD];
ks->ctime += t0mmio[REG_BGLOAD];
Line 282: Line 370:
swi = ((uint32*)((uintptr)lr - 4))[0] & 0xffff;
swi = ((uint32*)((uintptr)lr - 4))[0] & 0xffff;
kprintf("SWI thread:%x code:%x\n", ks->cthread, swi);
//kprintf("SWI thread:%x code:%x\n", ks->cthread, swi);
//((uint32*)KSTACKEXC)[-14] = R0;
//((uint32*)KSTACKEXC)[-14] = R0;
Line 310: Line 398:
r0 = ((uint32*)KSTACKEXC)[-14];
r0 = ((uint32*)KSTACKEXC)[-14];
kprintf("SLEEPING thread:%x timeout:%x\n", ks->cthread, r0);
//kprintf("SLEEPING thread:%x timeout:%x\n", ks->cthread, r0);


if (ks->cthread) {
if (ks->cthread) {
Line 333: Line 421:
which requires that LR not be offset before return.
which requires that LR not be offset before return.
*/
*/
KTHREAD *tmp;
kprintf("!EXCEPTION\n");
kprintf("cproc:%x cthread:%x lr:%x\n", ks->cproc, ks->cthread, lr);
tmp = ks->cthread;
kprintf("!EXCEPTION\n");
kprintf("type:%x cproc:%x cthread:%x lr:%x\n", type, ks->cproc, ks->cthread, lr);

ll_rem((void**)&ks->cproc->threads, ks->cthread);
ll_rem((void**)&ks->cproc->threads, ks->cthread);
ks->cthread = 0;
ks->cthread = ks->cthread->next;
ksched();
ksched();
kdumpthreadinfo(tmp);
}
}