shithub: riscv

ref: fe1eb39db7ae6904924f3ab1f6f9b34416f2eb1b
dir: /sys/src/9/cycv/l.s/

View raw version
#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
	BGT _clrstart

	/* clean BSS */
	MOVW $edata-KZERO(SB), R1
	MOVW $end-KZERO(SB), R2
_clrbss:
	MOVW.P R0, 4(R1)
	CMP.S R1, R2
	BGT _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