--- /dev/null
+/*
+ * Acess2 ARMv7
+ * - By John Hodge (thePowersGang)
+ *
+ * arch/arm7/include/assembly.h
+ * - Assembly specific macros
+ */
+#ifndef _ASSEMBLY_H_
+#define _ASSEMBLY_H_
+
+#define PUSH_GPRS \
+ str r0, [sp,#-1*4];\
+ str r1, [sp,#-2*4];\
+ str r2, [sp,#-3*4];\
+ str r3, [sp,#-4*4];\
+ str r4, [sp,#-5*4];\
+ str r5, [sp,#-6*4];\
+ str r6, [sp,#-7*4];\
+ str r7, [sp,#-8*4];\
+ str r8, [sp,#-9*4];\
+ str r9, [sp,#-10*4];\
+ str r10, [sp,#-11*4];\
+ str r11, [sp,#-12*4];\
+ str r12, [sp,#-13*4];\
+ str sp, [sp,#-14*4];\
+ str lr, [sp,#-15*4];\
+ sub sp, #16*4
+
+#define POP_GPRS add sp, #16*4; \
+ ldr r0, [sp,#-1*4]; \
+ ldr r1, [sp,#-2*4]; \
+ ldr r2, [sp,#-3*4]; \
+ ldr r3, [sp,#-4*4]; \
+ ldr r4, [sp,#-5*4]; \
+ ldr r5, [sp,#-6*4]; \
+ ldr r6, [sp,#-7*4]; \
+ ldr r7, [sp,#-8*4]; \
+ ldr r8, [sp,#-9*4]; \
+ ldr r9, [sp,#-10*4]; \
+ ldr r10, [sp,#-11*4]; \
+ ldr r11, [sp,#-12*4]; \
+ ldr r12, [sp,#-13*4]; \
+ ldr lr, [sp,#-15*4];
+
+#endif
+
* arch/arm7/main.c
*/
#include <acess.h>
+#include <modules.h>
// === IMPORTS ===
extern void Interrupts_Setup(void);
VFS_Init();
// Boot modules?
+ Module_EnsureLoaded("armv7_GIC");
//
LogF("Moving to arch-independent init\n");
// 1 guard page
for( ofs = PAGE_SIZE; ofs < MM_KSTACK_SIZE; ofs += PAGE_SIZE )
{
- if( MM_Allocate(addr + ofs) == 0 ) {
+ if( MM_Allocate(addr + ofs) == 0 )
+ {
while(ofs)
{
ofs -= PAGE_SIZE;
* - Process management assembly
*/
-#define PUSH_GPRS \
- str r0, [sp,#-1*4];\
- str r1, [sp,#-2*4];\
- str r2, [sp,#-3*4];\
- str r3, [sp,#-4*4];\
- str r4, [sp,#-5*4];\
- str r5, [sp,#-6*4];\
- str r6, [sp,#-7*4];\
- str r7, [sp,#-8*4];\
- str r8, [sp,#-9*4];\
- str r9, [sp,#-10*4];\
- str r10, [sp,#-11*4];\
- str r11, [sp,#-12*4];\
- str r12, [sp,#-13*4];\
- str sp, [sp,#-14*4];\
- str lr, [sp,#-15*4];\
- sub sp, #16*4
-
-#define POP_GPRS add sp, #16*4; \
- ldr r0, [sp,#-1*4]; \
- ldr r1, [sp,#-2*4]; \
- ldr r2, [sp,#-3*4]; \
- ldr r3, [sp,#-4*4]; \
- ldr r4, [sp,#-5*4]; \
- ldr r5, [sp,#-6*4]; \
- ldr r6, [sp,#-7*4]; \
- ldr r7, [sp,#-8*4]; \
- ldr r8, [sp,#-9*4]; \
- ldr r9, [sp,#-10*4]; \
- ldr r10, [sp,#-11*4]; \
- ldr r11, [sp,#-12*4]; \
- ldr r12, [sp,#-13*4]; \
- ldr lr, [sp,#-15*4];
+#include "include/assembly.h"
.globl KernelThreadHeader
@ SP+12: Argument 1
@ Get arguments
sub r5, #1
ldrhs r0, [sp],#4
- sub r5, #1
- ldrhs r1, [sp],#4
- sub r5, #1
- ldrhs r2, [sp],#4
- sub r5, #1
- ldrhs r3, [sp],#4
+@ suble r5, #1
+@ ldrhs r1, [sp],#4
+@ suble r5, #1
+@ ldrhs r2, [sp],#4
+@ suble r5, #1
+@ ldrhs r3, [sp],#4
- mov lr, pc
- mov pc, r4
+ blx r4
ldr r0, =0
bl Threads_Exit
@ SP+0: New address space
SwitchTask:
PUSH_GPRS
-
+
+ @ Save IP
ldr r4, =.return
str r4, [r3]
+ @ Save SP
str sp, [r1]
- mov r0, sp
-
+
@ Only update TTBR0 if the task has an explicit address space
- ldr r0, [sp,#0x40]
- tst r0, r0
- mcrne p15, 0, r0, c2, c0, 0 @ Set TTBR0 to r0
+ ldr r1, [sp,#0x40]
+ tst r1, r1
+ mcrne p15, 0, r1, c2, c0, 0 @ Set TTBR0 to r0
+
+ @ Restore SP
+ mov sp, r0
- mov pc, r2
+ bx r2
.return:
POP_GPRS
void Proc_IdleThread(void *unused)
{
+ Threads_SetPriority(gpIdleThread, -1);
+ Threads_SetName("Idle Thread");
for(;;) {
__asm__ __volatile__ ("wfi");
Proc_Reschedule();
tTID Proc_SpawnWorker( void (*Fnc)(void*), void *Ptr )
{
- return -1;
+ tThread *new;
+ Uint32 sp;
+
+ new = Threads_CloneTCB(NULL, 0);
+ if(!new) return -1;
+
+ new->KernelStack = MM_NewKStack(1);
+ if(!new->KernelStack) {
+ // TODO: Delete thread
+ Log_Error("Proc", "Unable to allocate kernel stack");
+ return -1;
+ }
+
+ sp = new->KernelStack;
+
+ *(Uint32*)(sp -= 4) = (Uint)Ptr;
+ *(Uint32*)(sp -= 4) = 1;
+ *(Uint32*)(sp -= 4) = (Uint)Fnc;
+ *(Uint32*)(sp -= 4) = (Uint)new;
+
+ new->SavedState.SP = sp;
+ new->SavedState.IP = (Uint)KernelThreadHeader;
+
+ Threads_AddActive(new);
+
+ return new->TID;
}
tTID Proc_NewKThread( void (*Fnc)(void*), void *Ptr )
new = Threads_CloneTCB(NULL, 0);
if(!new) return -1;
+ // TODO: Non-shared stack
new->KernelStack = MM_NewKStack(1);
if(!new->KernelStack) {
// TODO: Delete thread
sp = new->KernelStack;
- *(Uint32*)(sp -= 4) = (Uint)new;
- *(Uint32*)(sp -= 4) = (Uint)Fnc;
- *(Uint32*)(sp -= 4) = 1;
*(Uint32*)(sp -= 4) = (Uint)Ptr;
+ *(Uint32*)(sp -= 4) = 1;
+ *(Uint32*)(sp -= 4) = (Uint)Fnc;
+ *(Uint32*)(sp -= 4) = (Uint)new;
new->SavedState.SP = sp;
new->SavedState.IP = (Uint)KernelThreadHeader;
if(!next) next = gpIdleThread;
if(!next || next == cur) return;
- Log("Switching to %p (%i) IP=%p SP=%p", next, next->TID, next->SavedState.IP, next->SavedState.SP);
+ Log("Switching to %p (%i %s) IP=%p SP=%p", next, next->TID, next->ThreadName, next->SavedState.IP, next->SavedState.SP);
+ Log("Requested by %p", __builtin_return_address(0));
gpCurrentThread = next;
// TODO: Change kernel stack?
+
+#include "include/assembly.h"
+
KERNEL_BASE = 0x80000000
PCI_PADDR = 0x60000000 @ Realview
UART0_PADDR = 0x10009000 @ Realview
@
.section .init
interrupt_vector_table:
- b _start @ Reset
- b . @ #UD
- b SyscallHandler @ SVC (SWI assume)
- b . @ Prefetch abort
- b . @ Data abort
- b . @ Not Used
- b IRQHandler @ IRQ
- b . @ FIQ (Fast interrupt)
+ivt_reset: b _start @ Reset
+ivt_undef: b . @ #UD
+ivt_svc: b SyscallHandler @ SVC (SWI assume)
+ivt_prefetch: b DataAbort @ Prefetch abort
+ivt_data: b DataAbort @ Data abort
+ivt_unused: b . @ Not Used
+ivt_irq: b IRQHandler @ IRQ
+ivt_fiq: b . @ FIQ (Fast interrupt)
.globl _start
_start:
orr r0, r0, #1 << 23
mcr p15, 0, r0, c1, c0, 0
+ @ Prepare for interrupts
+ cps #19
+
ldr sp, =stack+0x10000 @ Set up stack
ldr r0, =kmain
mov pc, r0
SyscallHandler:
b .
+.globl gpIRQHandler
+gpIRQHandler: .long 0
+IRQ_saved_sp: .long 0
+IRQ_saved_lr: .long 0
+.globl IRQHandler
IRQHandler:
+ sub lr, #4 @ Adjust LR to the correct value
+ srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
+ cpsie i, #19
+
+ PUSH_GPRS
+
+ ldr r0, =csIRQ_Tag
+ ldr r1, =csIRQ_Fmt
+ ldr r4, =Log_Debug
+ blx r4
+
+ @ Call the registered handler
+ ldr r0, gpIRQHandler
+ blx r0
+
+ @ Restore CPU state
+ POP_GPRS
+ rfeia sp! @ Pop state (actually RFEFD)
+ bx lr
+
+.globl DataAbort
+DataAbort:
+ sub lr, #8 @ Adjust LR to the correct value
+ srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
+ cpsie i, #19
+ PUSH_GPRS
+
+ mov r2, lr
+ ldr r1, =csDataAbort_Fmt
+ ldr r0, =csDataAbort_Tag
+ ldr r4, =Log_Error
+ blx r4
b .
+ POP_GPRS
+ rfeia sp! @ Pop state (actually RFEFD)
+ bx lr
+
+csIRQ_Tag:
+csDataAbort_Tag:
+ .asciz "ARMv7"
+csIRQ_Fmt:
+ .asciz "IRQ"
+csDataAbort_Fmt:
+ .asciz "Data Abort at %p"
+
+.comm irqstack, 0x1000
+
.section .padata
.globl kernel_table0