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

# © 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