cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

boot.S (8576B)


      1/*
      2 * Minimal Alpha system boot code.
      3 *
      4 * Copyright Linaro Ltd 2019
      5 */
      6
      7	.set	noat
      8	.set	nomacro
      9	.arch	ev6
     10	.text
     11
     12.macro load_pci_io reg
     13	/* For typhoon, this is
     14	 *   0xfffffc0000000000  -- kseg identity map
     15	 * +      0x10000000000  -- typhoon pio base
     16	 * +        0x1fc000000  -- typhoon pchip0 pci base
     17	 * = 0xfffffd01fc000000
     18	 */
     19	ldah	\reg, -3		/* ff..fd0000 */
     20	lda	\reg, 0x1fc(\reg)	/* ff..fd01fc */
     21	sll	\reg, 24, \reg
     22.endm
     23
     24#define com1Rbr 0x3f8
     25#define com1Thr 0x3f8
     26#define com1Ier 0x3f9
     27#define com1Iir 0x3fa
     28#define com1Lcr 0x3fb
     29#define com1Mcr 0x3fc
     30#define com1Lsr 0x3fd
     31#define com1Msr 0x3fe
     32#define com1Scr 0x3ff
     33#define com1Dll 0x3f8
     34#define com1Dlm 0x3f9
     35
     36#define PAL_halt    0
     37#define PAL_wrent  52
     38#define PAL_wrkgp  55
     39
     40	.text
     41	.p2align 4
     42	.globl	_start
     43	.ent	_start
     44_start:
     45	br	$gp, .+4
     46	ldah	$gp, 0($gp)		!gpdisp!1
     47	lda	$gp, 0($gp)		!gpdisp!1
     48
     49	ldah	$sp, $stack_end($gp)	!gprelhigh
     50	lda	$sp, $stack_end($sp)	!gprellow
     51
     52	/* Install kernel gp for exception handlers.  */
     53	mov	$gp, $16
     54	call_pal PAL_wrkgp
     55
     56	/* Install exception handlers.  */
     57	ldah	$16, entInt($gp)	!gprelhigh
     58	lda	$16, entInt($16)	!gprellow
     59	lda	$17, 0
     60	call_pal PAL_wrent
     61
     62	ldah	$16, entArith($gp)	!gprelhigh
     63	lda	$16, entArith($16)	!gprellow
     64	lda	$17, 1
     65	call_pal PAL_wrent
     66
     67	ldah	$16, entMM($gp)		!gprelhigh
     68	lda	$16, entMM($16)		!gprellow
     69	lda	$17, 2
     70	call_pal PAL_wrent
     71
     72	ldah	$16, entIF($gp)		!gprelhigh
     73	lda	$16, entIF($16)		!gprellow
     74	lda	$17, 3
     75	call_pal PAL_wrent
     76
     77	ldah	$16, entUna($gp)	!gprelhigh
     78	lda	$16, entUna($16)	!gprellow
     79	lda	$17, 4
     80	call_pal PAL_wrent
     81
     82	ldah	$16, entSys($gp)	!gprelhigh
     83	lda	$16, entSys($16)	!gprellow
     84	lda	$17, 5
     85	call_pal PAL_wrent
     86
     87	/*
     88	 * Initialize COM1.
     89	 */
     90	load_pci_io $1
     91	lda	$2, 0x87		/* outb(0x87, com1Lcr); */
     92	stb	$2, com1Lcr($1)
     93	stb	$31, com1Dlm($1)	/* outb(0, com1Dlm); */
     94	lda	$2, 3			/* baudconst 3 => 56000 */
     95	stb	$2, com1Dll($1)		/* outb(baudconst, com1Dll); */
     96	lda	$2, 0x07
     97	stb	$2, com1Lcr($1)		/* outb(0x07, com1Lcr) */
     98	lda	$2, 0x0f
     99	stb	$2, com1Mcr($1)		/* outb(0x0f, com1Mcr) */
    100
    101	bsr	$26, main		!samegp
    102
    103	/* fall through to _exit */
    104	.end	_start
    105
    106	.globl	_exit
    107	.ent	_exit
    108_exit:
    109	.frame	$sp, 0, $26, 0
    110	.prologue 0
    111
    112	/* We cannot return an error code.  */
    113	call_pal PAL_halt
    114	.end	_exit
    115
    116/*
    117 * We have received an exception that we don't handle.  Log and exit.
    118 */
    119	.ent	log_exit
    120log_exit:
    121entInt:
    122entArith:
    123entMM:
    124entIF:
    125entUna:
    126entSys:
    127	ldah	$16, $errormsg($gp)	!gprelhigh
    128	lda	$16, $errormsg($16)	!gprellow
    129	bsr	$26, __sys_outs		!samegp
    130	bsr	$26, _exit		!samegp
    131	.end	log_exit
    132
    133	.section .rodata
    134$errormsg:
    135	.string "Terminated by exception.\n"
    136	.previous
    137
    138	/*
    139	 * Helper Functions
    140	 */
    141
    142	/* Output a single character to serial port */
    143	.global __sys_outc
    144	.ent	__sys_outc
    145__sys_outc:
    146	.frame	$sp, 0, $26, 0
    147	.prologue 0
    148
    149	load_pci_io $1
    150
    151	/* 
    152	 * while ((inb(com1Lsr) & 0x20) == 0)
    153	 *       continue;
    154	 */
    1551:	ldbu	$0, com1Lsr($1)
    156	and	$0, 0x20, $0
    157	beq	$0, 1b
    158
    159	/* outb(c, com1Thr); */
    160	stb	$16, com1Thr($1)
    161	ret
    162	.end	__sys_outc
    163
    164	/* Output a nul-terminated string to serial port */
    165	.global	__sys_outs
    166	.ent	__sys_outs
    167__sys_outs:
    168	.frame	$sp, 0, $26, 0
    169	.prologue 0
    170
    171	load_pci_io $1
    172
    173	ldbu	$2, 0($16)
    174	beq	$2, 9f
    175
    176	/* 
    177	 * while ((inb(com1Lsr) & 0x20) == 0)
    178	 *       continue;
    179	 */
    1801:	ldbu	$0, com1Lsr($1)
    181	and	$0, 0x20, $0
    182	beq	$0, 1b
    183
    184	/* outb(c, com1Thr); */
    185	stb	$2, com1Thr($1)
    186
    187	addq	$16, 1, $16
    188	ldbu	$2, 0($16)
    189	bne	$2, 1b
    190
    1919:	ret
    192	.end	__sys_outs
    193
    194/*
    195 * Division routines that are normally in libc.
    196 *
    197 * These do not follow the C calling convention.  Arguments are in $24+$25,
    198 * the result is in $27.  Register $28 may be clobbered; everything else
    199 * must be saved.
    200 *
    201 * We store the remainder in $28, so that we can share code.
    202 *
    203 * We do not signal divide by zero.
    204 */
    205
    206/*
    207 * Unsigned 64-bit division.
    208 */
    209
    210	.globl	__divqu
    211	.ent	__divqu
    212__divqu:
    213	.frame	$sp, 48, $23
    214	subq	$sp, 48, $sp
    215	stq	$0, 0($sp)
    216	stq	$1, 8($sp)
    217	stq	$2, 16($sp)
    218	stq	$3, 24($sp)
    219	stq	$4, 32($sp)
    220	.prologue 0
    221
    222#define mask     $0
    223#define divisor  $1
    224#define compare  $2
    225#define tmp1     $3
    226#define tmp2     $4
    227#define quotient $27
    228#define modulus  $28
    229
    230	mov	$24, modulus
    231	mov	$25, divisor
    232	mov	$31, quotient
    233	mov	1, mask
    234	beq	$25, 9f
    235
    236	/* Shift left until divisor >= modulus.  */
    2371:	cmpult	divisor, modulus, compare
    238	blt	divisor, 2f
    239	addq	divisor, divisor, divisor
    240	addq	mask, mask, mask
    241	bne	compare, 1b
    242
    2432:	addq	quotient, mask, tmp2
    244	srl	mask, 1, mask
    245	cmpule	divisor, modulus, compare
    246	subq	modulus, divisor, tmp1
    247	cmovne	compare, tmp2, quotient
    248	srl	divisor, 1, divisor
    249	cmovne	compare, tmp1, modulus
    250	bne	mask, 2b
    251
    2529:	ldq	$0, 0($sp)
    253	ldq	$1, 8($sp)
    254	ldq	$2, 16($sp)
    255	ldq	$3, 24($sp)
    256	ldq	$4, 32($sp)
    257	addq	$sp, 48, $sp
    258	ret	$31, ($23), 1
    259
    260#undef mask
    261#undef divisor
    262#undef compare
    263#undef tmp1
    264#undef tmp2
    265#undef quotient
    266#undef modulus
    267
    268	.end	__divqu
    269
    270/*
    271 * Unsigned 64-bit remainder.
    272 * Note that __divqu above leaves the result in $28.
    273 */
    274
    275	.globl	__remqu
    276	.ent	__remqu
    277__remqu:
    278	.frame	$sp, 16, $23
    279	subq	$sp, 16, $sp
    280	stq	$23, 0($sp)
    281	.prologue 0
    282
    283	bsr	$23, __divqu
    284
    285	ldq	$23, 0($sp)
    286	mov	$28, $27
    287	addq	$sp, 16, $sp
    288	ret	$31, ($23), 1
    289	.end	__remqu
    290
    291/*
    292 * Signed 64-bit division.
    293 */
    294
    295	.globl	__divqs
    296	.ent	__divqs
    297__divqs:
    298	.prologue 0
    299
    300	/* Common case: both arguments are positive.  */
    301	bis	$24, $25, $28
    302	bge	$28, __divqu
    303
    304	/* At least one argument is negative.  */
    305	subq	$sp, 32, $sp
    306	stq	$23, 0($sp)
    307	stq	$24, 8($sp)
    308	stq	$25, 16($sp)
    309
    310	/* Compute absolute values.  */
    311	subq	$31, $24, $28
    312	cmovlt	$24, $28, $24
    313	subq	$31, $25, $28
    314	cmovlt	$25, $28, $25
    315
    316	bsr	$23, __divqu
    317
    318	ldq	$24, 8($sp)
    319	ldq	$25, 16($sp)
    320
    321	/* -a / b = a / -b = -(a / b) */
    322	subq	$31, $27, $23
    323	xor	$24, $25, $28
    324	cmovlt	$28, $23, $27
    325
    326	ldq	$23, 0($sp)
    327	addq	$sp, 32, $sp
    328	ret	$31, ($23), 1
    329	.end	__divqs
    330
    331/*
    332 * Signed 64-bit remainder.
    333 */
    334
    335	.globl	__remqs
    336	.ent	__remqs
    337__remqs:
    338	.prologue 0
    339
    340	/* Common case: both arguments are positive.  */
    341	bis	$24, $25, $28
    342	bge	$28, __remqu
    343
    344	/* At least one argument is negative.  */
    345	subq	$sp, 32, $sp
    346	stq	$23, 0($sp)
    347	stq	$24, 8($sp)
    348	stq	$25, 16($sp)
    349
    350	/* Compute absolute values.  */
    351	subq	$31, $24, $28
    352	cmovlt	$24, $28, $24
    353	subq	$31, $25, $28
    354	cmovlt	$25, $28, $25
    355
    356	bsr	$23, __divqu
    357
    358	ldq	$23, 0($sp)
    359	ldq	$24, 8($sp)
    360	ldq	$25, 16($sp)
    361
    362	/* -a % b = -(a % b); a % -b = a % b.  */
    363	subq	$31, $28, $27
    364	cmovge	$24, $28, $27
    365
    366	addq	$sp, 32, $sp
    367	ret	$31, ($23), 1
    368	.end	__remqs
    369
    370/*
    371 * Unsigned 32-bit division.
    372 */
    373
    374	.globl	__divlu
    375	.ent	__divlu
    376__divlu:
    377	.frame	$sp, 32, $23
    378	subq	$sp, 32, $sp
    379	stq	$23, 0($sp)
    380	stq	$24, 8($sp)
    381	stq	$25, 16($sp)
    382	.prologue 0
    383
    384	/* Zero extend and use the 64-bit routine.  */
    385	zap	$24, 0xf0, $24
    386	zap	$25, 0xf0, $25
    387	bsr	$23, __divqu
    388
    389	addl	$27, 0, $27
    390	ldq	$23, 0($sp)
    391	ldq	$24, 8($sp)
    392	ldq	$25, 16($sp)
    393	addq	$sp, 32, $sp
    394	ret	$31, ($23), 1
    395	.end	__divlu
    396
    397/*
    398 * Unsigned 32-bit remainder.
    399 */
    400
    401	.globl	__remlu
    402	.ent	__remlu
    403__remlu:
    404	.frame	$sp, 32, $23
    405	subq	$sp, 32, $sp
    406	stq	$23, 0($sp)
    407	stq	$24, 8($sp)
    408	stq	$25, 16($sp)
    409	.prologue 0
    410
    411	/* Zero extend and use the 64-bit routine.  */
    412	zap	$24, 0xf0, $24
    413	zap	$25, 0xf0, $25
    414	bsr	$23, __divqu
    415
    416	/* Recall that the remainder is returned in $28.  */
    417	addl	$28, 0, $27
    418	ldq	$23, 0($sp)
    419	ldq	$24, 8($sp)
    420	ldq	$25, 16($sp)
    421	addq	$sp, 32, $sp
    422	ret	$31, ($23), 1
    423	.end	__remlu
    424
    425/*
    426 * Signed 32-bit division.
    427 */
    428
    429	.globl	__divls
    430	.ent	__divls
    431__divls:
    432	.frame	$sp, 32, $23
    433	subq	$sp, 32, $sp
    434	stq	$23, 0($sp)
    435	stq	$24, 8($sp)
    436	stq	$25, 16($sp)
    437	.prologue 0
    438
    439	/* Sign extend.  */
    440	addl	$24, 0, $24
    441	addl	$25, 0, $25
    442
    443	/* Compute absolute values.  */
    444	subq	$31, $24, $28
    445	cmovlt	$24, $28, $24
    446	subq	$31, $25, $28
    447	cmovlt	$25, $28, $25
    448
    449	bsr	$23, __divqu
    450
    451	ldq	$24, 8($sp)
    452	ldq	$25, 16($sp)
    453
    454	/* Negate the unsigned result, if necessary.  */
    455	xor	$24, $25, $28
    456	subl	$31, $27, $23
    457	addl	$27, 0, $27
    458	addl	$28, 0, $28
    459	cmovlt	$28, $23, $27
    460
    461	ldq	$23, 0($sp)
    462	addq	$sp, 32, $sp
    463	ret	$31, ($23), 1
    464	.end	__divls
    465
    466/*
    467 * Signed 32-bit remainder.
    468 */
    469
    470	.globl	__remls
    471	.ent	__remls
    472__remls:
    473	.frame	$sp, 32, $23
    474	subq	$sp, 32, $sp
    475	stq	$23, 0($sp)
    476	stq	$24, 8($sp)
    477	stq	$25, 16($sp)
    478	.prologue 0
    479
    480	/* Sign extend.  */
    481	addl	$24, 0, $24
    482	addl	$25, 0, $25
    483
    484	/* Compute absolute values.  */
    485	subq	$31, $24, $28
    486	cmovlt	$24, $28, $24
    487	subq	$31, $25, $28
    488	cmovlt	$25, $28, $25
    489
    490	bsr	$23, __divqu
    491
    492	ldq	$23, 0($sp)
    493	ldq	$24, 8($sp)
    494	ldq	$25, 16($sp)
    495
    496	/* Negate the unsigned result, if necessary.  */
    497	subl	$31, $28, $27
    498	addl	$28, 0, $28
    499	cmovge	$24, $28, $27
    500
    501	addq	$sp, 32, $sp
    502	ret	$31, ($23), 1
    503	.end	__remls
    504
    505	.data
    506	.p2align 4
    507stack:
    508	.skip	65536
    509$stack_end:
    510	.type	stack,@object
    511	.size	stack, . - stack