move delay code into separate function.
[AROS.git] / arch / arm-raspi / kernel / kernel_cpu.c
blob112fc97668554d385c033e0b31b6bf209818cd43
1 /*
2 Copyright © 2013-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*
7 * This file is intended to make generic kernel.resource compiling.
8 * This code should NEVER be executed. This file MUST be overriden in
9 * architecture-specific code for the scheduler to work!
12 #include <aros/kernel.h>
13 #include <aros/libcall.h>
14 #include <exec/execbase.h>
15 #include <hardware/intbits.h>
17 #include <proto/kernel.h>
19 #include "etask.h"
21 #include "kernel_intern.h"
22 #include "kernel_debug.h"
23 #include "kernel_cpu.h"
24 #include "kernel_syscall.h"
25 #include "kernel_scheduler.h"
26 #include "kernel_intr.h"
28 #define D(x)
29 #define DREGS(x)
31 extern struct Task *sysIdleTask;
33 void cpu_Delay(IPTR len)
35 unsigned int delay;
36 for (delay = 0; delay < len; delay++) asm volatile ("mov r0, r0\n");
39 void cpu_Probe(struct ARM_Implementation *krnARMImpl)
41 uint32_t tmp;
43 asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r" (tmp));
44 if ((tmp & 0xfff0) == 0xc070) /* armv7 */
45 krnARMImpl->ARMI_Family = 7;
46 else
47 krnARMImpl->ARMI_Family = 6;
49 krnARMImpl->ARMI_Delay = cpu_Delay;
52 void cpu_Init(struct ARM_Implementation *krnARMImpl, struct TagItem *msg)
54 register unsigned int fpuflags;
56 core_SetupMMU(msg);
58 if (krnARMImpl->ARMI_LED_Toggle)
60 if (krnARMImpl->ARMI_Delay)
61 krnARMImpl->ARMI_Delay(100000);
62 krnARMImpl->ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_OFF);
65 /* Enable Vector Floating Point Calculations */
66 asm volatile("mrc p15,0,%[fpuflags],c1,c0,2\n" : [fpuflags] "=r" (fpuflags)); // Read Access Control Register
67 fpuflags |= (VFPSingle | VFPDouble); // Enable Single & Double Precision
68 asm volatile("mcr p15,0,%[fpuflags],c1,c0,2\n" : : [fpuflags] "r" (fpuflags)); // Set Access Control Register
69 asm volatile(
70 " mov %[fpuflags],%[vfpenable] \n" // Enable VFP
71 " fmxr fpexc,%[fpuflags] \n"
72 : [fpuflags] "=r" (fpuflags) : [vfpenable] "I" (VFPEnable));
74 if (krnARMImpl->ARMI_LED_Toggle)
76 if (krnARMImpl->ARMI_Delay)
77 krnARMImpl->ARMI_Delay(100000);
78 krnARMImpl->ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_ON);
82 void cpu_Switch(regs_t *regs)
84 struct Task *task;
86 D(bug("[Kernel] cpu_Switch()\n"));
88 task = SysBase->ThisTask;
90 /* Copy current task's context into the ETask structure */
91 /* Restore the task's state */
92 STORE_TASKSTATE(task, regs)
94 /* Update the taks CPU time .. */
95 GetIntETask(task)->iet_CpuTime += *((volatile unsigned int *)(SYSTIMER_CLO)) - GetIntETask(task)->iet_private1;
97 core_Switch();
100 void cpu_Dispatch(regs_t *regs)
102 struct Task *task;
104 D(bug("[Kernel] cpu_Dispatch()\n"));
106 /* Break Disable() if needed */
107 if (SysBase->IDNestCnt >= 0) {
108 SysBase->IDNestCnt = -1;
109 ((uint32_t *)regs)[13] &= ~0x80;
112 if (!(task = core_Dispatch()))
113 task = sysIdleTask;
115 D(bug("[Kernel] cpu_Dispatch: Letting '%s' run for a bit..\n", task->tc_Node.ln_Name));
117 /* Restore the task's state */
118 RESTORE_TASKSTATE(task, regs)
120 DREGS(cpu_DumpRegs(regs));
122 /* Handle tasks's flags */
123 if (task->tc_Flags & TF_EXCEPT)
124 Exception();
126 /* Store the launch time */
127 GetIntETask(task)->iet_private1 = *((volatile unsigned int *)(SYSTIMER_CLO));
129 if (task->tc_Flags & TF_LAUNCH)
131 AROS_UFC1(void, task->tc_Launch,
132 AROS_UFCA(struct ExecBase *, SysBase, A6));
136 void cpu_DumpRegs(regs_t *regs)
138 int i;
140 bug("[KRN] Register Dump:\n");
141 for (i = 0; i < 12; i++)
143 bug("[KRN] r%02d: 0x%08x\n", i, ((uint32_t *)regs)[i]);
145 bug("[KRN] (ip) r12: 0x%08x\n", ((uint32_t *)regs)[12]);
146 bug("[KRN] (sp) r13: 0x%08x\n", ((uint32_t *)regs)[13]);
147 bug("[KRN] (lr) r14: 0x%08x\n", ((uint32_t *)regs)[14]);
148 bug("[KRN] (pc) r15: 0x%08x\n", ((uint32_t *)regs)[15]);
149 bug("[KRN] cpsr: 0x%08x\n", ((uint32_t *)regs)[16]);