71 lines
1.6 KiB
ArmAsm
71 lines
1.6 KiB
ArmAsm
|
|
.section .init
|
|
|
|
.global _start
|
|
_start:
|
|
/* Erkennen ob Hypervisor Mode aktiv */
|
|
mrs r0, cpsr
|
|
and r0, r0, #0x1F
|
|
mov r1, #0x1A //Modebits = 0x1A = Hypervisor Mode
|
|
cmp r0, r1 //Vergleichen und Statusbits setzen für bedingte Sprünge
|
|
|
|
/* Wenn Hypemode erkannt: abschalten (sprung nach _exitHyper)
|
|
* wenn nicht erkannt: dann weitermachen (weiterlaufen nach _bsprak)
|
|
*/
|
|
beq _exitHyper
|
|
|
|
/* Qemu startet immer alle 4 Kerne
|
|
* Wir lassen alle anderen Kerne endless loopen
|
|
*/
|
|
_checkCores:
|
|
/* Id des Cpu Cores Abfragen */
|
|
mrc p15, 0, r0, c0, c0, 5
|
|
/* Falls nicht core 0 Core disablen */
|
|
tst r0, #3
|
|
bne _parkCore
|
|
|
|
/* not modeled in qemu 6.0 */
|
|
_enableAlignCheck:
|
|
/* SCTLR des cp15 laden */
|
|
mrc p15, 0, r0, c1, c0, 0
|
|
/* A-bit (c1[1]) auf 1 setzen */
|
|
orr r0, r0, #0x2
|
|
/* neues SCTLR speichern */
|
|
mcr p15, 0, r0, c1, c0, 0
|
|
|
|
|
|
_bsprak:
|
|
/* Validen Stack Pointer setzten */
|
|
ldr sp,=0x100000
|
|
/* Zu c Code springen */
|
|
bl start_kernel
|
|
.Lend:
|
|
WFI
|
|
b .Lend
|
|
|
|
_parkCore:
|
|
/* Interrupts für Core 1 bis 3 ausschalten */
|
|
cpsid if
|
|
/* In Endlosschleife springen */
|
|
b .Lend
|
|
|
|
_exitHyper:
|
|
|
|
/* Rücksprungadresse ins Hypervisor Rücksprungregister schreiben.
|
|
* Dies ist das Label _bsprak für die normale Programmausfürung.
|
|
*/
|
|
ldr lr, =_checkCores
|
|
msr ELR_hyp, lr
|
|
|
|
/* Der Hypervisor mode ist auch "nur" eine etwas kompliziertere Exception.
|
|
* Also springen wir aus dieser zurück.
|
|
* (Rücksprunge in Aufgabe 2 sind anders zu lösen!).
|
|
* Dazu zunächst das CPSR auslesen und die Modebits zum Supervisor ändern.
|
|
* Danach dies in das SPSR für den Rücksprung schreiben.
|
|
*/
|
|
mrs r0, cpsr
|
|
bic r0, r0, #0x1F
|
|
orr r0, r0, #0x13 //Supervisormode
|
|
msr spsr_hyp, r0
|
|
eret
|