# © 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. # boot kernel # resets to 32BE # set up translations for starting bios (inc. BE/LE) # copy modifiable rom data to ram - or do in bios? # set up msr for running bios (inc. 32/64) # jump to bios .include "defines.s" .macro load32 rx,v li \rx,0 oris \rx,\rx,\v>>16 ori \rx,\rx,\v&0x0000FFFF .endm .macro load16swiz rx,v li \rx,0 ori \rx,\rx,(\v<<8)&0xFF00 ori \rx,\rx,(\v>>8)&0x00FF .endm # constants from linker script, or defsym .ifdef BIOS_32 # sup MSR cm=1 ce=1 ee=1 pr=0 fp=1 me=1 fe=00 de=0 is=0 ds=0 .set BIOS_MSR,0x0002B000 .else # sup MSR cm=1 ce=1 ee=1 pr=0 fp=1 me=1 fe=00 de=0 is=0 ds=0 .set BIOS_MSR,0x8002B000 .endif # 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 .ifdef BIOS_LE .set BIOS_ERATW2,0x000000BF .else .set BIOS_ERATW2,0x0000003F .endif # bios might be able to use one stack during thread startup if careful .ifndef BIOS_STACK_0 .set BIOS_STACK_0,_stack_0 .endif .ifndef BIOS_STACK_1 .set BIOS_STACK_1,_stack_1 .endif .ifndef BIOS_START .set BIOS_START,0x00010000 .endif .section .text .global _start .org 0x000 _start: int_000: b boot_start # critical input .org 0x020 int_020: .ifndef INT_UNHANDLED b . .else b INT_UNHANDLED .endif # debug .org 0x040 int_040: b . # dsi .org 0x060 int_060: b . # isi .org 0x080 int_080: b . # external .org 0x0A0 int_0A0: b . # alignment .org 0x0C0 int_0C0: b . # program .org 0x0E0 int_0E0: b . # fp unavailable .org 0x100 int_100: b . # sc .org 0x120 int_120: b . # apu unavailable .org 0x140 int_140: b . # decrementer .org 0x160 int_160: b . # fit .org 0x180 int_180: b . # watchdog .org 0x1A0 int_1A0: b . # dtlb .org 0x1C0 int_1C0: b . # itlb .org 0x1E0 int_1E0: b . # vector unavailable .org 0x200 int_200: b . # .org 0x220 int_220: b . # .org 0x240 int_240: b . # .org 0x260 int_260: b . # doorbell .org 0x280 int_280: b . # doorbell critical .org 0x2A0 int_2A0: b . # doorbell guest .org 0x2C0 int_2C0: b . # doorbell guest critical .org 0x2E0 int_2E0: b . # hvsc .org 0x300 int_300: b . # hvpriv .org 0x320 int_320: b . # lrat .org 0x340 int_340: b . # ------------------------------------------------------------------------------------------------------------------------------ # initial translation # both erats: # 00000000 64K: (rom, BE) # 00010000 64K: (ram, BE or LE) # .org 0x400 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,0x023F # 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 load32 r10,BIOS_ERATW2 # 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 # derat 30 @ li r0,0x001E # entry #30 load32 r4,BIOS_START # word 1 rpn(32:51)=32:51 rpn(22:31)=54:63 load32 r8,BIOS_START ori r8,r8,0x023F # 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 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,0x023F # 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 @ li r0,0x000D # entry #13 load32 r4,BIOS_START # word 1 rpn(32:51)=32:51 rpn(22:31)=54:63 load32 r8,BIOS_START ori r8,r8,0x023F # 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 eratwe r10,r0,2 eratwe r4,r0,1 eratwe r8,r0,0 isync b init_t0 # ------------------------------------------------------------------------------------------------------------------------------ # init # # T0 init_t0: # set up BIOS msr load32 r10,BIOS_MSR mtmsr r10 isync # can't use load32 unless you can .set BIOS_STACK_0 to the linked value # load32 r1,BIOS_STACK_0 # @stack_0 # this ignores def # lis r1,_stack_0@h # ori r1,r1,_stack_0@l # this requires data load lwz r1,stack_0(r0) b boot_complete # except T0 init_t123: # set up BIOS msr load32 r10,BIOS_MSR mtmsr r10 isync # check tir if more than 2 threads possible lwz r1,stack_1(r0) b boot_complete # ------------------------------------------------------------------------------------------------------------------------------ boot_complete: # set up thread and hop to it lis r3,main@h ori r3,r3,main@l mtctr r3 mfspr r3,tir # who am i? bctrl b kernel_return # ------------------------------------------------------------------------------------------------------------------------------ .org 0x7FC kernel_return: b . # dec .org 0x800 int_800: b . # perf .org 0x820 int_820: b . .org 0x8F0 .section .rodata stack_0: .long BIOS_STACK_0 stack_1: .long BIOS_STACK_1