509 lines
7.8 KiB
ArmAsm
509 lines
7.8 KiB
ArmAsm
#include "mem.h"
|
|
#include "io.h"
|
|
|
|
#define PUTC(c) MOVW $(c), R0; MOVW R0, (R8)
|
|
|
|
TEXT _start(SB), $-4
|
|
MOVW $(KTZERO-KZERO), R13
|
|
MOVW $(UART_BASE), R8
|
|
|
|
/* disable watchdog */
|
|
MOVW $(RESETMGR_BASE + 4*PERMODRST), R1
|
|
MOVW (R1), R0
|
|
ORR $(3<<6), R0
|
|
MOVW R0, (R1)
|
|
|
|
/* disable L2 cache */
|
|
MOVW $0, R0
|
|
MOVW $(L2_BASE+0x100), R1
|
|
MOVW R0, (R1)
|
|
|
|
PUTC('P')
|
|
/* disable MMU and L1 caches */
|
|
MOVW $0x20c5047a, R1
|
|
MOVW $_start0-KZERO(SB), R2
|
|
MCR 15, 0, R1, C(1), C(0), 0
|
|
MOVW R2, R15
|
|
|
|
TEXT _start0(SB), $-4
|
|
DSB
|
|
ISB
|
|
PUTC('l')
|
|
|
|
/* clean up to CONFADDR */
|
|
MOVW $0, R0
|
|
MOVW R0, R1
|
|
MOVW $(CONFADDR-KZERO), R2
|
|
_clrstart:
|
|
MOVW.P R0, 4(R1)
|
|
CMP.S R1, R2
|
|
BGE _clrstart
|
|
|
|
/* clean BSS */
|
|
MOVW $edata-KZERO(SB), R1
|
|
MOVW $end-KZERO(SB), R2
|
|
_clrbss:
|
|
MOVW.P R0, 4(R1)
|
|
CMP.S R1, R2
|
|
BGE _clrbss
|
|
|
|
PUTC('a')
|
|
|
|
/* KZERO to PERIPH is mapped to 0 */
|
|
MOVW $SECSZ, R0
|
|
MOVW $(MACHL1(0)-KZERO), R4
|
|
MOVW $KZERO, R1
|
|
ADD R1>>(SECSH-2), R4, R1
|
|
MOVW $(L1SEC|L1CACHED|L1KERRW), R2
|
|
MOVW $(PERIPH-KZERO), R3
|
|
_start1:
|
|
MOVW.P R2, 4(R1)
|
|
ADD R0, R2
|
|
CMP.S R2, R3
|
|
BGE _start1
|
|
|
|
/* memory above PERIPH is mapped to itself */
|
|
MOVW $(PERIPH|L1SEC|L1DEVICE|L1NOEXEC|L1KERRW), R2
|
|
_start2:
|
|
MOVW.P R2, 4(R1)
|
|
ADD.S R0, R2
|
|
BCC _start2
|
|
|
|
PUTC('n')
|
|
|
|
MOVW $(MACH(0)-KZERO), R(Rmach)
|
|
_start3:
|
|
/* enable MMU permission checking */
|
|
MOVW $0x55555555, R0
|
|
MCR 15, 0, R0, C(3), C(0), 0
|
|
|
|
/* select page table and enable MMU */
|
|
MOVW $0, R0
|
|
MCR 15, 0, R0, C(8), C(7), 0
|
|
DSB
|
|
ORR $TTBATTR, R4, R1
|
|
MCR 15, 0, R1, C(2), C(0), 0
|
|
MOVW $0x20c5047b, R1
|
|
MOVW $_virt(SB), R2
|
|
PUTC(' ')
|
|
MCR 15, 0, R1, C(1), C(0), 0
|
|
MOVW R2, R15
|
|
|
|
TEXT _virt(SB), $-4
|
|
DSB
|
|
ISB
|
|
|
|
ADD $KZERO, R(Rmach)
|
|
MOVW R(Rmach), R13
|
|
ADD $MACHSIZE, R13
|
|
|
|
MOVW R(Rmach), R0
|
|
ADD $12, R0
|
|
BL loadsp(SB)
|
|
|
|
MOVW $vectors(SB), R1
|
|
MCR 15, 0, R1, C(12), C(0)
|
|
|
|
/* enable maths coprocessors in CPACR but disable them in FPEXC */
|
|
MRC 15, 0, R0, C(1), C(0), 2
|
|
ORR $(15<<20), R0
|
|
MCR 15, 0, R0, C(1), C(0), 2
|
|
|
|
VMRS(0xe, FPEXC, 0)
|
|
BIC $(3<<30), R0
|
|
VMSR(0xe, 0, FPEXC)
|
|
|
|
/* enable L1 cache */
|
|
MOVW $0, R0
|
|
MCR 15, 0, R0, C(7), C(5), 0
|
|
MCR 15, 0, R0, C(7), C(5), 6
|
|
BL l1dclear(SB)
|
|
MRC 15, 0, R0, C(1), C(0), 1
|
|
ORR $(1|2|1<<6), R0
|
|
MCR 15, 0, R0, C(1), C(0), 1
|
|
MRC 15, 0, R0, C(1), C(0), 0
|
|
ORR $(3<<11|1<<2), R0
|
|
MCR 15, 0, R0, C(1), C(0), 0
|
|
DSB
|
|
ISB
|
|
|
|
MOVW $UART_BASE, R8
|
|
PUTC('9')
|
|
|
|
/* kernel Mach* in TPIDRPRW */
|
|
MCR 15, 0, R(Rmach), C(13), C(0), 4
|
|
|
|
MOVW $setR12(SB), R12
|
|
MOVW $0, R(Rup)
|
|
|
|
BL main(SB)
|
|
B idlehands(SB)
|
|
|
|
BL _div(SB) /* hack to load _div */
|
|
|
|
TEXT touser(SB), $-4
|
|
CPS(CPSID)
|
|
|
|
SUB $12, R13
|
|
MOVW R0, (R13)
|
|
MOVW $0, R1
|
|
MOVW R1, 4(R13)
|
|
MOVW $(UTZERO+0x20), R1
|
|
MOVW R1, 8(R13)
|
|
|
|
MOVW CPSR, R1
|
|
BIC $(PsrMask|PsrDirq|PsrDfiq), R1
|
|
ORR $PsrMusr, R1
|
|
MOVW R1, SPSR
|
|
|
|
MOVW $(KTZERO-(15*4)), R0
|
|
MOVM.IA (R0), [R0-R12]
|
|
|
|
MOVM.IA.S (R13), [R13-R14]
|
|
ADD $8, R13
|
|
MOVM.IA.W.S (R13), [R15]
|
|
|
|
TEXT forkret(SB), $-4
|
|
MOVW (16*4)(R13), R0
|
|
MOVW R0, SPSR
|
|
MOVM.IA.W (R13), [R0-R12]
|
|
MOVM.IA.S (R13), [R13-R14]
|
|
ADD $16, R13
|
|
DSB
|
|
ISB
|
|
MOVM.IA.W.S (R13), [R15]
|
|
|
|
TEXT loadsp(SB), $0
|
|
CPS(CPSMODE | PsrMabt)
|
|
MOVW R0, R13
|
|
CPS(CPSMODE | PsrMund)
|
|
MOVW R0, R13
|
|
CPS(CPSMODE | PsrMirq)
|
|
MOVW R0, R13
|
|
CPS(CPSMODE | PsrMfiq)
|
|
MOVW R0, R13
|
|
CPS(CPSMODE | PsrMsvc)
|
|
RET
|
|
|
|
TEXT cputhex(SB), $0
|
|
MOVW R0, R7
|
|
MOVW $UART_BASE, R8
|
|
TEXT puthex(SB), $0
|
|
_p0:
|
|
MOVW 0x14(R8), R6
|
|
AND.S $(1<<5), R6
|
|
BEQ _p0
|
|
#define DIG MOVW R7>>28, R6; AND $15, R6; ADD $'0', R6; CMP $'9', R6; ADD.GT $7, R6; MOVW R6, (R8); MOVW R7<<4, R7
|
|
DIG; DIG; DIG; DIG
|
|
DIG; DIG; DIG; DIG
|
|
MOVW $13, R6
|
|
MOVW R6, (R8)
|
|
MOVW $10, R6
|
|
MOVW R6, (R8)
|
|
RET
|
|
|
|
TEXT spllo(SB), $-4
|
|
MOVW CPSR, R0
|
|
CPS(CPSIE)
|
|
RET
|
|
|
|
TEXT splhi(SB), $-4
|
|
MOVW R14, 4(R(Rmach))
|
|
MOVW CPSR, R0
|
|
CPS(CPSID)
|
|
RET
|
|
|
|
TEXT splx(SB), $-4
|
|
MOVW R14, 4(R(Rmach))
|
|
MOVW R0, R1
|
|
MOVW CPSR, R0
|
|
MOVW R1, CPSR
|
|
RET
|
|
|
|
TEXT spldone(SB), $-4
|
|
RET
|
|
|
|
TEXT islo(SB), $0
|
|
MOVW CPSR, R0
|
|
AND $(PsrDirq), R0
|
|
EOR $(PsrDirq), R0
|
|
RET
|
|
|
|
TEXT setlabel(SB), $-4
|
|
MOVW R13, 0(R0)
|
|
MOVW R14, 4(R0)
|
|
MOVW $0, R0
|
|
RET
|
|
|
|
TEXT gotolabel(SB), $-4
|
|
MOVW 0(R0), R13
|
|
MOVW 4(R0), R14
|
|
MOVW $1, R0
|
|
RET
|
|
|
|
TEXT cas(SB), $0
|
|
TEXT cmpswap(SB), $0
|
|
MOVW ov+4(FP), R1
|
|
MOVW nv+8(FP), R2
|
|
spincas:
|
|
LDREX (R0), R3
|
|
CMP.S R3, R1
|
|
BNE fail
|
|
STREX R2, (R0), R4
|
|
CMP.S $0, R4
|
|
BNE spincas
|
|
MOVW $1, R0
|
|
DMB
|
|
RET
|
|
fail:
|
|
CLREX
|
|
MOVW $0, R0
|
|
RET
|
|
|
|
TEXT tas(SB), $0
|
|
TEXT _tas(SB), $0
|
|
MOVW $0xDEADDEAD, R2
|
|
_tas1:
|
|
LDREX (R0), R1
|
|
STREX R2, (R0), R3
|
|
CMP.S $0, R3
|
|
BNE _tas1
|
|
MOVW R1, R0
|
|
DMB
|
|
RET
|
|
|
|
TEXT coherence(SB), $0
|
|
DSB
|
|
RET
|
|
|
|
TEXT idlehands(SB), $0
|
|
DSB
|
|
WFE
|
|
RET
|
|
|
|
TEXT sendevent(SB), $0
|
|
SEV
|
|
RET
|
|
|
|
TEXT ttbget(SB), $0
|
|
MRC 15, 0, R0, C(2), C(0), 0
|
|
BIC $0x7f, R0
|
|
RET
|
|
|
|
TEXT ttbput(SB), $0
|
|
ORR $TTBATTR, R0
|
|
MCR 15, 0, R0, C(2), C(0), 0
|
|
RET
|
|
|
|
TEXT flushpg(SB), $0
|
|
MCR 15, 0, R0, C(8), C(7), 3
|
|
DSB
|
|
RET
|
|
|
|
TEXT flushtlb(SB), $0
|
|
MCR 15, 0, R0, C(8), C(3), 0
|
|
DSB
|
|
RET
|
|
|
|
TEXT setasid(SB), $0
|
|
DSB /* errata */
|
|
MCR 15, 0, R0, C(13), C(0), 1
|
|
RET
|
|
|
|
TEXT getifar(SB), $0
|
|
MRC 15, 0, R0, C(6), C(0), 2
|
|
RET
|
|
|
|
TEXT getdfar(SB), $0
|
|
MRC 15, 0, R0, C(6), C(0), 0
|
|
RET
|
|
|
|
TEXT getifsr(SB), $0
|
|
MRC 15, 0, R0, C(5), C(0), 1
|
|
RET
|
|
|
|
TEXT getdfsr(SB), $0
|
|
MRC 15, 0, R0, C(5), C(0), 0
|
|
RET
|
|
|
|
TEXT setpmcr(SB), $0
|
|
MCR 15, 0, R0, C(9), C(12), 0
|
|
RET
|
|
|
|
TEXT setpmcnten(SB), $0
|
|
MCR 15, 0, R0, C(9), C(12), 1
|
|
RET
|
|
|
|
TEXT perfticks(SB), $0
|
|
MRC 15, 0, R0, C(9), C(13), 0
|
|
RET
|
|
|
|
TEXT cycles(SB), $0
|
|
MRC 15, 0, R1, C(9), C(13), 0
|
|
MOVW R1, (R0)
|
|
MOVW 24(R(Rmach)), R1
|
|
MRC 15, 0, R2, C(9), C(12), 3
|
|
AND.S $(1<<31), R2
|
|
BEQ _cycles0
|
|
MCR 15, 0, R2, C(9), C(12), 3
|
|
ADD $1, R1
|
|
MOVW R1, 24(R(Rmach))
|
|
_cycles0:
|
|
MOVW R1, 4(R0)
|
|
RET
|
|
|
|
TEXT fpinit(SB), $0
|
|
MOVW $(1<<30), R0
|
|
VMSR(0xe, 0, FPEXC)
|
|
MOVW $0, R0
|
|
VMSR(0xe, 0, FPSCR)
|
|
RET
|
|
|
|
TEXT fprestore(SB), $0
|
|
MOVM.IA.W (R0), [R1-R2]
|
|
VMSR(0xe, 1, FPEXC)
|
|
VMSR(0xe, 2, FPSCR)
|
|
WORD $0xecb00b20
|
|
WORD $0xecf00b20
|
|
RET
|
|
|
|
TEXT fpsave(SB), $0
|
|
VMRS(0xe, FPEXC, 1)
|
|
VMRS(0xe, FPSCR, 2)
|
|
MOVM.IA.W [R1-R2], (R0)
|
|
WORD $0xeca00b20
|
|
WORD $0xece00b20
|
|
/* wet floor */
|
|
|
|
TEXT fpoff(SB), $0
|
|
TEXT fpclear(SB), $0
|
|
MOVW $0, R1
|
|
VMSR(0xe, 1, FPEXC)
|
|
RET
|
|
|
|
#define Rnoway R1
|
|
#define Rwayinc R2
|
|
#define Rmaxway R3
|
|
#define Rsetinc R4
|
|
#define Rmaxset R5
|
|
|
|
TEXT l1dclear(SB), $0
|
|
MOVW $0, R0
|
|
MCR 15, 2, R0, C(0), C(0), 0
|
|
MRC 15, 1, R9, C(0), C(0), 0
|
|
AND $7, R9, R8
|
|
ADD $4, R8
|
|
MOVW $1, Rsetinc
|
|
MOVW Rsetinc<<R8, Rsetinc
|
|
|
|
MOVW R9>>13, Rmaxset
|
|
AND $0x7fff, Rmaxset
|
|
MOVW Rmaxset<<R8, Rmaxset
|
|
|
|
MOVW R9>>3, R0
|
|
AND $0x3ff, R0
|
|
MOVW $(1<<31), Rwayinc
|
|
MOVW $(1<<31), Rnoway
|
|
MOVW R0, Rmaxway
|
|
ADD $1, R0
|
|
_l1dclear0:
|
|
MOVW.S R0>>1, R0
|
|
BEQ _l1dclear1
|
|
MOVW Rwayinc>>1, Rwayinc
|
|
MOVW Rnoway->1, Rnoway
|
|
MOVW Rmaxway@>1, Rmaxway
|
|
B _l1dclear0
|
|
_l1dclear1:
|
|
MOVW Rwayinc<<1, Rwayinc
|
|
MVN Rnoway<<1, Rnoway
|
|
BIC Rnoway, Rmaxway
|
|
|
|
MOVW $0, R0
|
|
_l1dclear2:
|
|
MCR 15, 0, R0, C(7), C(14), 2
|
|
ADD Rwayinc, R0
|
|
CMP.S Rmaxway, R0
|
|
BLT _l1dclear2
|
|
AND Rnoway, R0
|
|
ADD Rsetinc, R0
|
|
CMP.S Rmaxset, R0
|
|
BLT _l1dclear2
|
|
RET
|
|
|
|
TEXT invalise(SB), $0
|
|
MOVW 4(FP), R1
|
|
ADD $(LINSIZ - 1), R1
|
|
BIC $(LINSIZ - 1), R0
|
|
BIC $(LINSIZ - 1), R1
|
|
_invalise0:
|
|
MCR 15, 0, R0, C(7), C(5), 1
|
|
ADD $LINSIZ, R0
|
|
CMP.S R1, R0
|
|
BLT _invalise0
|
|
RET
|
|
|
|
TEXT cleandse(SB), $0
|
|
DSB
|
|
MOVW 4(FP), R1
|
|
ADD $(LINSIZ - 1), R1
|
|
BIC $(LINSIZ - 1), R0
|
|
BIC $(LINSIZ - 1), R1
|
|
_cleandse0:
|
|
MCR 15, 0, R0, C(7), C(10), 1
|
|
ADD $LINSIZ, R0
|
|
CMP.S R1, R0
|
|
BLT _cleandse0
|
|
DSB
|
|
RET
|
|
|
|
TEXT invaldse(SB), $0
|
|
MOVW 4(FP), R1
|
|
ADD $(LINSIZ - 1), R1
|
|
BIC $(LINSIZ - 1), R0
|
|
BIC $(LINSIZ - 1), R1
|
|
_invaldse0:
|
|
MCR 15, 0, R0, C(7), C(6), 1
|
|
ADD $LINSIZ, R0
|
|
CMP.S R1, R0
|
|
BLT _invaldse0
|
|
DSB
|
|
RET
|
|
|
|
TEXT clinvdse(SB), $0
|
|
DSB
|
|
MOVW 4(FP), R1
|
|
ADD $(LINSIZ - 1), R1
|
|
BIC $(LINSIZ - 1), R0
|
|
BIC $(LINSIZ - 1), R1
|
|
_clinvdse0:
|
|
MCR 15, 0, R0, C(7), C(14), 1
|
|
ADD $LINSIZ, R0
|
|
CMP.S R1, R0
|
|
BLT _clinvdse0
|
|
DSB
|
|
RET
|
|
|
|
TEXT cleandln(SB), $0
|
|
DSB
|
|
MCR 15, 0, R0, C(7), C(10), 1
|
|
DSB
|
|
RET
|
|
|
|
TEXT invaldln(SB), $0
|
|
MCR 15, 0, R0, C(7), C(6), 1
|
|
DSB
|
|
RET
|
|
|
|
TEXT clinvdln(SB), $0
|
|
DSB
|
|
MCR 15, 0, R0, C(7), C(14), 1
|
|
DSB
|
|
RET
|
|
|
|
TEXT palookur(SB), $0
|
|
MCR 15, 0, R0, C(7), C(8), 2
|
|
DSB
|
|
MRC 15, 0, R0, C(7), C(4), 0
|
|
RET
|
|
|