You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
634 lines
15 KiB
ArmAsm
634 lines
15 KiB
ArmAsm
2 years ago
|
# © IBM Corp. 2022
|
||
|
# Licensed under and subject to the terms of the CC-BY 4.0
|
||
|
# license (https://creativecommons.org/licenses/by/4.0/legalcode).
|
||
|
# Additional rights, including the right to physically implement a softcore
|
||
|
# that is compliant with the required sections of the Power ISA
|
||
|
# Specification, will be available at no cost via the OpenPOWER Foundation.
|
||
|
# This README will be updated with additional information when OpenPOWER's
|
||
|
# license is available.
|
||
|
|
||
|
# start conversion to simple boot which jumps to bios
|
||
|
# this version will work similarly to original fpga test version
|
||
|
# the original version did not run from rom; eventually will assume rom and do r/w data copy/init
|
||
|
# the rom and test are built into separate memory loads or a single one with addr/data format
|
||
|
|
||
|
# boot kernel
|
||
|
# set up translations
|
||
|
# set up timer facilities
|
||
|
# set up threads
|
||
|
# call user code
|
||
|
# process user rc
|
||
|
|
||
|
# todo:
|
||
|
# 1. skip_printf_init flag should be threaded
|
||
|
|
||
|
.include "defines.s"
|
||
|
|
||
|
# constants from linker script, or defsym
|
||
|
.ifndef STACKSIZE
|
||
|
.set STACKSIZE,_stack_size
|
||
|
.endif
|
||
|
|
||
|
.ifndef STACK0
|
||
|
.set STACK0,_stack_0
|
||
|
.endif
|
||
|
|
||
|
.ifndef STACK1
|
||
|
.set STACK1,_stack_1
|
||
|
.endif
|
||
|
|
||
|
.set STACK2, 0
|
||
|
.set STACK3, 0
|
||
|
|
||
|
.ifndef TEST
|
||
|
.set TEST,_test_start
|
||
|
.endif
|
||
|
|
||
|
.section .text
|
||
|
|
||
|
.global _start
|
||
|
_start:
|
||
|
|
||
|
int_000:
|
||
|
b boot_start
|
||
|
|
||
|
# critical input
|
||
|
.align 5
|
||
|
int_020:
|
||
|
b .
|
||
|
|
||
|
# debug
|
||
|
.align 5
|
||
|
int_040:
|
||
|
b .
|
||
|
|
||
|
# dsi
|
||
|
.align 5
|
||
|
int_060:
|
||
|
b .
|
||
|
|
||
|
# isi
|
||
|
.align 5
|
||
|
int_080:
|
||
|
b .
|
||
|
|
||
|
# external
|
||
|
.align 5
|
||
|
int_0A0:
|
||
|
b .
|
||
|
|
||
|
# alignment
|
||
|
.align 5
|
||
|
int_0C0:
|
||
|
b .
|
||
|
|
||
|
# program
|
||
|
.align 5
|
||
|
int_0E0:
|
||
|
b .
|
||
|
|
||
|
# fp unavailable
|
||
|
.align 5
|
||
|
int_100:
|
||
|
b .
|
||
|
|
||
|
# sc
|
||
|
.align 5
|
||
|
int_120:
|
||
|
b int_120_handler
|
||
|
|
||
|
# apu unavailable
|
||
|
.align 5
|
||
|
int_140:
|
||
|
b .
|
||
|
|
||
|
# decrementer
|
||
|
.align 5
|
||
|
int_160:
|
||
|
b .
|
||
|
|
||
|
# fit
|
||
|
.align 5
|
||
|
int_180:
|
||
|
b .
|
||
|
|
||
|
# watchdog
|
||
|
.align 5
|
||
|
int_1A0:
|
||
|
b .
|
||
|
|
||
|
# dtlb
|
||
|
.align 5
|
||
|
int_1C0:
|
||
|
b .
|
||
|
|
||
|
# itlb
|
||
|
.align 5
|
||
|
int_1E0:
|
||
|
b .
|
||
|
|
||
|
# vector unavailable
|
||
|
.align 5
|
||
|
int_200:
|
||
|
b .
|
||
|
|
||
|
#
|
||
|
.align 5
|
||
|
int_220:
|
||
|
b .
|
||
|
|
||
|
#
|
||
|
.align 5
|
||
|
int_240:
|
||
|
b .
|
||
|
|
||
|
#
|
||
|
.align 5
|
||
|
int_260:
|
||
|
b .
|
||
|
|
||
|
# doorbell
|
||
|
.align 5
|
||
|
int_280:
|
||
|
b .
|
||
|
|
||
|
# doorbell critical
|
||
|
.align 5
|
||
|
int_2A0:
|
||
|
b .
|
||
|
|
||
|
# doorbell guest
|
||
|
.align 5
|
||
|
int_2C0:
|
||
|
b .
|
||
|
|
||
|
# doorbell guest critical
|
||
|
.align 5
|
||
|
int_2E0:
|
||
|
b .
|
||
|
|
||
|
# hvsc
|
||
|
.align 8
|
||
|
int_300:
|
||
|
b int_300_handler
|
||
|
|
||
|
# hvpriv
|
||
|
.align 5
|
||
|
int_320:
|
||
|
b .
|
||
|
|
||
|
# lrat
|
||
|
.align 5
|
||
|
int_340:
|
||
|
b .
|
||
|
|
||
|
# ------------------------------------------------------------------------------------------------------------------------------
|
||
|
# initial translation
|
||
|
# both erats:
|
||
|
# 00000000 1M: (boot)
|
||
|
# 10000000 1M: (test)
|
||
|
|
||
|
.align 8
|
||
|
boot_start:
|
||
|
|
||
|
mfspr r5,tir # who am i?
|
||
|
cmpdi r5,0x00 # skip unless T0
|
||
|
bne init_t123
|
||
|
|
||
|
lis r3,0x8C00 # 32=ecl 36:37=tlbsel (10=i, 11=d)
|
||
|
# derat 31 @00000000
|
||
|
|
||
|
li r0,0x001F # entry #31
|
||
|
li r2,0x0015 # word 2 wlc=40:41 rsvd=42 u=44:47 r=48 c=49 wimge=52:56 vf=57 ux/sx=58:59 uw/sw=60:61 ur/sr=62:63
|
||
|
li r4,0 # word 1 rpn(32:51)=32:51 rpn(22:31)=54:63
|
||
|
li r8,0x025F # word 0 epn=32:51 class=52:53 v=54 x=55 size=56:59 thrd=60:63 size: 0001=4K 0011=64K 0101=1M 0111=16M 1010=1G
|
||
|
|
||
|
mtspr mmucr0,r3
|
||
|
eratwe r2,r0,2
|
||
|
eratwe r4,r0,1
|
||
|
eratwe r8,r0,0
|
||
|
isync
|
||
|
|
||
|
lwz r10,CONFIG+S_ERATW2(r0) # load parms for erat settings
|
||
|
|
||
|
# derat 30 @100000000
|
||
|
|
||
|
li r0,0x001E # entry #30
|
||
|
lis r4,0x1000 # word 1 rpn(32:51)=32:51 rpn(22:31)=54:63
|
||
|
li r8,0x025F # word 0 epn=32:51 class=52:53 v=54 x=55 size=56:59 thrd=60:63 size: 0001=4K 0011=64K 0101=1M 0111=16M 1010=1G
|
||
|
oris r8,r8,0x1000
|
||
|
|
||
|
eratwe r10,r0,2
|
||
|
eratwe r4,r0,1
|
||
|
eratwe r8,r0,0
|
||
|
isync
|
||
|
|
||
|
lis r3,0x8800 # 32=ecl 36:37=tlbsel (10=i, 11=d)
|
||
|
# ierat 15 @00000000
|
||
|
|
||
|
li r0,0x000F # entry #15
|
||
|
li r2,0x003F # word 2 wlc=40:41 rsvd=42 u=44:47 r=48 c=49 wimge=52:56 vf=57 ux/sx=58:59 uw/sw=60:61 ur/sr=62:63
|
||
|
li r4,0 # word 1 rpn(32:51)=32:51 rpn(22:31)=54:63
|
||
|
li r8,0x025F # word 0 epn=32:51 class=52:53 v=54 x=55 size=56:59 thrd=60:63 size: 0001=4K 0011=64K 0101=1M 0111=16M 1010=1G
|
||
|
|
||
|
mtspr mmucr0,r3
|
||
|
eratwe r2,r0,2
|
||
|
eratwe r4,r0,1
|
||
|
eratwe r8,r0,0
|
||
|
isync
|
||
|
|
||
|
# *** leave the init'd entry 14 for MT access to FFFFFFC0
|
||
|
# ierat 13 @10000000
|
||
|
|
||
|
li r0,0x000D # entry #13
|
||
|
lis r4,0x1000 # word 1 rpn(32:51)=32:51 rpn(22:31)=54:63
|
||
|
li r8,0x025F # word 0 epn=32:51 class=52:53 v=54 x=55 size=56:59 thrd=60:63 size: 0001=4K 0011=64K 0101=1M 0111=16M 1010=1G
|
||
|
oris r8,r8,0x1000
|
||
|
|
||
|
eratwe r10,r0,2
|
||
|
eratwe r4,r0,1
|
||
|
eratwe r8,r0,0
|
||
|
isync
|
||
|
|
||
|
# ------------------------------------------------------------------------------------------------------------------------------
|
||
|
# init
|
||
|
#
|
||
|
|
||
|
# T0-only
|
||
|
# set up any core facilities, then enable the others if config'd
|
||
|
init_t0:
|
||
|
|
||
|
# switch to 64b
|
||
|
|
||
|
lwz r10,CONFIG+S_MSR(r0)
|
||
|
mtmsr r10
|
||
|
isync
|
||
|
|
||
|
# other init
|
||
|
|
||
|
lis r1,0x0300 # icm=gicm=1
|
||
|
mtspr epcr,r1
|
||
|
|
||
|
# set up timer facs
|
||
|
|
||
|
li r1,0 # clear
|
||
|
mtspr dec,r1
|
||
|
mtspr tbh,r1
|
||
|
mtspr tbl,r1
|
||
|
|
||
|
lis r2,0xFE00 # mask: clear enw,wis,wrs,dis,fis,udis
|
||
|
mtspr tsr,r2
|
||
|
|
||
|
mfspr r2,xucr0
|
||
|
andi. r2,r2,0x0200 # set tcs=0
|
||
|
mtspr xucr0,r2
|
||
|
|
||
|
mtspr tsr,r1 # clear tsr
|
||
|
mtspr tcr,r1 # disable all timers
|
||
|
|
||
|
# set thread configuration
|
||
|
|
||
|
lwz r1,CONFIG+S_FLAGS(r0)
|
||
|
andi. r1,r1,0xF
|
||
|
mtspr tens,r1 # 60:63 = tid 3:0 enabled
|
||
|
#not r1,r1
|
||
|
#mtspr tenc,r1 # in case T0 is marked disabled
|
||
|
isync
|
||
|
|
||
|
b boot_complete
|
||
|
|
||
|
# except T0
|
||
|
# just worry about myself
|
||
|
|
||
|
init_t123:
|
||
|
|
||
|
# switch to 64b
|
||
|
|
||
|
lwz r10,CONFIG+S_MSR(r0)
|
||
|
mtmsr r10
|
||
|
isync
|
||
|
|
||
|
b boot_complete
|
||
|
|
||
|
# ------------------------------------------------------------------------------------------------------------------------------
|
||
|
boot_complete:
|
||
|
|
||
|
# set up thread and hop to it
|
||
|
|
||
|
lwz r1,CONFIG+S_FLAGS(r0)
|
||
|
andis. r1,r1,0x8000 # 1=skip initial printf init
|
||
|
bne boot_complete_1
|
||
|
bl printf_reset # wipe buffer
|
||
|
|
||
|
boot_complete_1:
|
||
|
|
||
|
lwz r1,CONFIG+S_FLAGS(r0)
|
||
|
lis r2,0x7FFF # clear printf flag
|
||
|
ori r2,r2,0xFFFF
|
||
|
and r1,r1,r2
|
||
|
stw r1,CONFIG+S_FLAGS(r0)
|
||
|
|
||
|
mfspr r5,tir # who am i?
|
||
|
sldi r5,r5,6 # 64B offset
|
||
|
addi r5,r5,CONFIG+T_CONFIG
|
||
|
|
||
|
lwz r11,T_MSR(r5)
|
||
|
ld r12,T_STACK(r5)
|
||
|
ld r13,T_ENTRY(r5)
|
||
|
|
||
|
lwz r1,CONFIG+S_FLAGS(r0)
|
||
|
andi. r1,r1,FLAG_EOT_SC
|
||
|
beq eot_blr
|
||
|
|
||
|
eot_sc:
|
||
|
|
||
|
lwz r2,CONFIG+S_EOT_SC(r0)
|
||
|
lis r1,0x4400 # 'sc 1'
|
||
|
ori r1,r1,0022
|
||
|
std r1,0x0(r2)
|
||
|
mtlr r1 # prog will blr to sc
|
||
|
b process_start
|
||
|
|
||
|
eot_blr:
|
||
|
|
||
|
bl 4
|
||
|
mflr r1
|
||
|
addi r1,r1,0x30 # !!!!!!!!!!!!!!! <-- WARNING!
|
||
|
mtlr r1 # prog will blr to exec_complete
|
||
|
|
||
|
process_start:
|
||
|
|
||
|
mtspr srr1,r11 # msr
|
||
|
mtspr srr0,r13 # @entry
|
||
|
mr r1,r12 # @stack
|
||
|
mfspr r3,tir # tid - main(tid) if yall want it
|
||
|
|
||
|
mfspr r2,tb
|
||
|
std r2,T_TIMER_START(r5)
|
||
|
rfi
|
||
|
nop # !!!!!!!!!!!!!!! pads for lr calc
|
||
|
nop
|
||
|
nop
|
||
|
|
||
|
# ------------------------------------------------------------------------------------------------------------------------------
|
||
|
exec_complete:
|
||
|
# allow blr to here, or it will be entered by sc directly
|
||
|
|
||
|
# user blr'd here...
|
||
|
sc 1 # hvsc back to sup state
|
||
|
|
||
|
exec_complete_sup:
|
||
|
mfspr r5,tir # who am i?
|
||
|
sldi r5,r5,6 # 64B offset
|
||
|
addi r5,r5,CONFIG+T_CONFIG
|
||
|
|
||
|
mfspr r2,tb
|
||
|
std r2,T_TIMER_END(r5)
|
||
|
|
||
|
cmpdi r3,0 # check rc
|
||
|
beq pass
|
||
|
b fail
|
||
|
|
||
|
# ------------------------------------------------------------------------------------------------------------------------------
|
||
|
# dead zone
|
||
|
.align 8
|
||
|
fail:
|
||
|
b .
|
||
|
|
||
|
# ------------------------------------------------------------------------------------------------------------------------------
|
||
|
# happy ending
|
||
|
.align 8
|
||
|
pass:
|
||
|
b .
|
||
|
|
||
|
# ------------------------------------------------------------------------------------------------------------------------------
|
||
|
|
||
|
# dec
|
||
|
.align 11
|
||
|
int_800:
|
||
|
b .
|
||
|
|
||
|
# perf
|
||
|
.align 5
|
||
|
int_820:
|
||
|
b .
|
||
|
|
||
|
.set CONFIG,0x0A00
|
||
|
# ------------------------------------------------------------------------------------------------------------------------------
|
||
|
# config info
|
||
|
.align 9
|
||
|
|
||
|
.long 0x8002B000 # sup MSR cm=1 ce=1 ee=1 pr=0 fp=1 me=1 fe=00 de=0 is=0 ds=0
|
||
|
.long 0x80000001 # flags: skip_printf_init=0 eot_sc=27 thr_en=28:31(T3:T0)
|
||
|
|
||
|
# LE
|
||
|
# .long 0x000000BF # erat w2 (test) # word 2 wlc=40:41 rsvd=42 u=44:47 r=48 c=49 wimge=52:56 vf=57 ux/sx=58:59 uw/sw=60:61 ur/sr=62:63
|
||
|
# BE
|
||
|
.long 0x0000003F # erat w2 (test) # word 2 wlc=40:41 rsvd=42 u=44:47 r=48 c=49 wimge=52:56 vf=57 ux/sx=58:59 uw/sw=60:61 ur/sr=62:63
|
||
|
.long 0x10000000 # @user eot sc
|
||
|
|
||
|
# per-thread configs (64B each)
|
||
|
.align 7
|
||
|
.long 0x8002F000 # usr MSR cm=1 ce=1 ee=1 pr=1 fp=1 me=1 fe=00 de=0 is=0 ds=0
|
||
|
.long 0x00000000 #
|
||
|
.long 0x00000000 #
|
||
|
.long STACK0 # @stack
|
||
|
.long 0x00000000 #
|
||
|
.long TEST # @entry
|
||
|
.long 0
|
||
|
.long 0x10030000 # @print_start
|
||
|
.long 0
|
||
|
.long 0x10031FFF # @print_end
|
||
|
.long 0
|
||
|
.long 0x10030000 # print ptr
|
||
|
.quad 0 # start tb
|
||
|
.quad 0 # end tb
|
||
|
|
||
|
.long 0x8002F000 # usr MSR cm=1 ce=1 ee=1 pr=1 fp=1 me=1 fe=00 de=0 is=0 ds=0
|
||
|
.long 0x00000000 #
|
||
|
.long 0x00000000 #
|
||
|
.long STACK1 # @stack
|
||
|
.long 0x00000000 #
|
||
|
.long TEST # @entry
|
||
|
.long 0
|
||
|
.long 0x10032000 # @print_start
|
||
|
.long 0
|
||
|
.long 0x10033FFF # @print_end
|
||
|
.long 0
|
||
|
.long 0x10032000 # print ptr
|
||
|
.quad 0 # start tb
|
||
|
.quad 0 # end tb
|
||
|
|
||
|
.long 0x8002F000 # usr MSR cm=1 ce=1 ee=1 pr=1 fp=1 me=1 fe=00 de=0 is=0 ds=0
|
||
|
.long 0x00000000 # flags
|
||
|
.long 0x00000000 #
|
||
|
.long STACK2 # @stack
|
||
|
.long 0x00000000 #
|
||
|
.long TEST # @entry
|
||
|
.long 0
|
||
|
.long 0x10034000 # @print_start
|
||
|
.long 0
|
||
|
.long 0x10035FFF # @print_end
|
||
|
.long 0
|
||
|
.long 0x10034000 # print ptr
|
||
|
.quad 0 # start tb
|
||
|
.quad 0 # end tb
|
||
|
|
||
|
.long 0x8002F000 # usr MSR cm=1 ce=1 ee=1 pr=1 fp=1 me=1 fe=00 de=0 is=0 ds=0
|
||
|
.long 0x00000000 # flags
|
||
|
.long 0x00000000 #
|
||
|
.long STACK3 # @stack
|
||
|
.long 0x00000000 #
|
||
|
.long TEST # @entry
|
||
|
.long 0
|
||
|
.long 0x10036000 # @print_start
|
||
|
.long 0
|
||
|
.long 0x10037FFF # @print_end
|
||
|
.long 0
|
||
|
.long 0x10036000 # print ptr
|
||
|
.quad 0 # start tb
|
||
|
.quad 0 # end tb
|
||
|
|
||
|
|
||
|
.set S_MSR,0x00
|
||
|
.set S_FLAGS,0x04
|
||
|
.set S_ERATW2,0x08
|
||
|
.set S_EOT_SC,0x0C
|
||
|
|
||
|
.set T_CONFIG,0x80
|
||
|
.set T_MSR,0x00
|
||
|
.set T_FLAGS,0x04
|
||
|
.set T_STACK,0x08
|
||
|
.set T_ENTRY,0x10
|
||
|
.set T_TIMER_START,0x30
|
||
|
.set T_TIMER_END,0x38
|
||
|
.set T_PRINTSTART, 0x18
|
||
|
.set T_PRINTEND, 0x20
|
||
|
.set T_PRINTF, 0x28
|
||
|
.set FLAG_EOT_SC,0x10
|
||
|
|
||
|
|
||
|
# ------------------------------------------------------------------------------------------------------------------------------
|
||
|
# other stuff
|
||
|
.align 10
|
||
|
|
||
|
# clear buffer and reset pointer to start
|
||
|
.align 6
|
||
|
printf_reset:
|
||
|
|
||
|
mfspr r5,tir # who am i?
|
||
|
sldi r5,r5,6 # 64B offset
|
||
|
addi r5,r5,CONFIG+T_CONFIG
|
||
|
|
||
|
addi r6,r5,T_PRINTSTART
|
||
|
ld r7,0(r6) # buffer start
|
||
|
addi r6,r5,T_PRINTEND
|
||
|
ld r8,0(r6) # buffer end
|
||
|
sub r8,r8,r7
|
||
|
addi r8,r8,1 # num bytes
|
||
|
|
||
|
mtctr r8
|
||
|
li r6,0
|
||
|
mr r8,r7
|
||
|
printf_reset_clr:
|
||
|
stb r6,0(r8)
|
||
|
addi r8,r8,1
|
||
|
bdnz printf_reset_clr
|
||
|
|
||
|
addi r8,r5,T_PRINTF
|
||
|
std r7,0(r8) # reset ptr
|
||
|
|
||
|
blr
|
||
|
|
||
|
|
||
|
# hvsc
|
||
|
.align 8
|
||
|
# go to exec_complete_sup in sup mode
|
||
|
int_300_handler:
|
||
|
|
||
|
lwz r0,CONFIG+S_MSR(r0)
|
||
|
mtmsr r0
|
||
|
isync
|
||
|
b exec_complete_sup
|
||
|
|
||
|
# sc
|
||
|
.align 8
|
||
|
# r3 is id, remaining are function-specific
|
||
|
# not preserving r0, r3-r9 right now
|
||
|
#
|
||
|
# 0001 whoami
|
||
|
# 0010 tick
|
||
|
# 0100 putchar r4=c
|
||
|
# 0106 printf_mode *NI*
|
||
|
# 0107 printf_rst
|
||
|
#
|
||
|
int_120_handler:
|
||
|
|
||
|
mflr r0
|
||
|
|
||
|
cmpdi r3,0x0001
|
||
|
beq sc_whoami
|
||
|
cmpdi r3,0x0010
|
||
|
beq sc_tick
|
||
|
cmpdi r3,0x100
|
||
|
beq sc_putchar
|
||
|
cmpdi r3,0x107
|
||
|
beq sc_printf_rst
|
||
|
|
||
|
li r3,-1
|
||
|
mtlr r0
|
||
|
rfi
|
||
|
|
||
|
# thread id
|
||
|
.align 6
|
||
|
sc_whoami:
|
||
|
mfspr r3,tir
|
||
|
rfi
|
||
|
|
||
|
# tb
|
||
|
.align 6
|
||
|
sc_tick:
|
||
|
mfspr r3,tb
|
||
|
rfi
|
||
|
|
||
|
# wrap buffer; could add flag to stop when full, or reset
|
||
|
.align 6
|
||
|
sc_putchar:
|
||
|
|
||
|
mfspr r5,tir # who am i?
|
||
|
sldi r5,r5,6 # 64B offset
|
||
|
addi r5,r5,CONFIG+T_CONFIG
|
||
|
|
||
|
addi r6,r5,T_PRINTF
|
||
|
ld r7,0(r6) # buffer ptr
|
||
|
stb r4,0(r7) # store char
|
||
|
addi r7,r7,1
|
||
|
|
||
|
addi r8,r5,T_PRINTEND
|
||
|
ld r8,0(r8) # buffer end
|
||
|
cmpd r7,r8
|
||
|
li r3,0 # rc=normal
|
||
|
ble sc_putchar_ok
|
||
|
addi r8,r5,T_PRINTSTART
|
||
|
ld r7,0(r8) # buffer start
|
||
|
li r3,-1 # rc=full
|
||
|
sc_putchar_ok:
|
||
|
std r7,0(r6) # save ptr
|
||
|
|
||
|
rfi
|
||
|
|
||
|
# clear buffer and reset pointer to start
|
||
|
.align 6
|
||
|
sc_printf_rst:
|
||
|
|
||
|
mfctr r3
|
||
|
|
||
|
bl printf_reset
|
||
|
|
||
|
mtctr r3
|
||
|
mtlr r0
|
||
|
li r3,0
|
||
|
|
||
|
rfi
|
||
|
|