2 Copyright © 2013-2015, The AROS Development Team. All rights reserved.
6 #include <aros/kernel.h>
7 #include <aros/libcall.h>
8 #include <exec/execbase.h>
9 #include <hardware/intbits.h>
11 #include <proto/kernel.h>
15 #include "kernel_intern.h"
16 #include "kernel_debug.h"
17 #include "kernel_cpu.h"
18 #include "kernel_syscall.h"
19 #include "kernel_scheduler.h"
20 #include "kernel_intr.h"
25 extern struct Task
*sysIdleTask
;
26 uint32_t __arm_affinitymask
__attribute__((section(".data"))) = 1;
32 asm volatile (" mrc p15, 0, %0, c0, c0, 5 " : "=r" (tmp
));
34 __arm_affinitymask
|= (1 << (tmp
& 0x3));
39 void cpu_Delay(int usecs
)
42 for (delay
= 0; delay
< usecs
; delay
++) asm volatile ("mov r0, r0\n");
45 void cpu_Probe(struct ARM_Implementation
*krnARMImpl
)
49 asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r" (tmp
));
50 if ((tmp
& 0xfff0) == 0xc070)
52 krnARMImpl
->ARMI_Family
= 7;
54 // Read the Multiprocessor Affinity Register (MPIDR)
55 asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (tmp
));
63 krnARMImpl
->ARMI_Family
= 6;
65 krnARMImpl
->ARMI_Delay
= &cpu_Delay
;
68 void cpu_Init(struct ARM_Implementation
*krnARMImpl
, struct TagItem
*msg
)
70 register unsigned int fpuflags
;
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_OFF
);
81 /* Enable Vector Floating Point Calculations */
82 asm volatile("mrc p15,0,%[fpuflags],c1,c0,2\n" : [fpuflags
] "=r" (fpuflags
)); // Read Access Control Register
83 fpuflags
|= (VFPSingle
| VFPDouble
); // Enable Single & Double Precision
84 asm volatile("mcr p15,0,%[fpuflags],c1,c0,2\n" : : [fpuflags
] "r" (fpuflags
)); // Set Access Control Register
86 " mov %[fpuflags],%[vfpenable] \n" // Enable VFP
87 " fmxr fpexc,%[fpuflags] \n"
88 : [fpuflags
] "=r" (fpuflags
) : [vfpenable
] "I" (VFPEnable
));
90 if (krnARMImpl
->ARMI_LED_Toggle
)
92 if (krnARMImpl
->ARMI_Delay
)
93 krnARMImpl
->ARMI_Delay(100000);
94 krnARMImpl
->ARMI_LED_Toggle(ARM_LED_POWER
, ARM_LED_ON
);
98 void cpu_Switch(regs_t
*regs
)
102 D(bug("[Kernel] cpu_Switch()\n"));
104 task
= SysBase
->ThisTask
;
106 /* Copy current task's context into the ETask structure */
107 /* Restore the task's state */
108 STORE_TASKSTATE(task
, regs
)
110 if (__arm_arosintern
.ARMI_GetTime
)
112 /* Update the taks CPU time .. */
113 GetIntETask(task
)->iet_CpuTime
+= __arm_arosintern
.ARMI_GetTime() - GetIntETask(task
)->iet_private1
;
119 void cpu_Dispatch(regs_t
*regs
)
123 D(bug("[Kernel] cpu_Dispatch()\n"));
125 /* Break Disable() if needed */
126 if (SysBase
->IDNestCnt
>= 0) {
127 SysBase
->IDNestCnt
= -1;
128 ((uint32_t *)regs
)[13] &= ~0x80;
131 if (!(task
= core_Dispatch()))
134 D(bug("[Kernel] cpu_Dispatch: Letting '%s' run for a bit..\n", task
->tc_Node
.ln_Name
));
136 /* Restore the task's state */
137 RESTORE_TASKSTATE(task
, regs
)
139 DREGS(cpu_DumpRegs(regs
));
141 /* Handle tasks's flags */
142 if (task
->tc_Flags
& TF_EXCEPT
)
145 if (__arm_arosintern
.ARMI_GetTime
)
147 /* Store the launch time */
148 GetIntETask(task
)->iet_private1
= __arm_arosintern
.ARMI_GetTime();
151 if (task
->tc_Flags
& TF_LAUNCH
)
153 AROS_UFC1(void, task
->tc_Launch
,
154 AROS_UFCA(struct ExecBase
*, SysBase
, A6
));
158 void cpu_DumpRegs(regs_t
*regs
)
162 bug("[KRN] Register Dump:\n");
163 for (i
= 0; i
< 12; i
++)
165 bug("[KRN] r%02d: 0x%08x\n", i
, ((uint32_t *)regs
)[i
]);
167 bug("[KRN] (ip) r12: 0x%08x\n", ((uint32_t *)regs
)[12]);
168 bug("[KRN] (sp) r13: 0x%08x\n", ((uint32_t *)regs
)[13]);
169 bug("[KRN] (lr) r14: 0x%08x\n", ((uint32_t *)regs
)[14]);
170 bug("[KRN] (pc) r15: 0x%08x\n", ((uint32_t *)regs
)[15]);
171 bug("[KRN] cpsr: 0x%08x\n", ((uint32_t *)regs
)[16]);