1/* 2 * arch/s390/kernel/head.S 3 * 4 * S390 version 5 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 6 * Author(s): Hartmut Penner (hp@de.ibm.com), 7 * Martin Schwidefsky (schwidefsky@de.ibm.com), 8 * Rob van der Heij (rvdhei@iae.nl) 9 * 10 * There are 5 different IPL methods 11 * 1) load the image directly into ram at address 0 and do an PSW restart 12 * 2) linload will load the image from address 0x10000 to memory 0x10000 13 * and start the code thru LPSW 0x0008000080010000 (VM only, deprecated) 14 * 3) generate the tape ipl header, store the generated image on a tape 15 * and ipl from it 16 * In case of SL tape you need to IPL 5 times to get past VOL1 etc 17 * 4) generate the vm reader ipl header, move the generated image to the 18 * VM reader (use option NOH!) and do a ipl from reader (VM only) 19 * 5) direct call of start by the SALIPL loader 20 * We use the cpuid to distinguish between VM and native ipl 21 * params for kernel are pushed to 0x10400 (see setup.h) 22 23 Changes: 24 Okt 25 2000 <rvdheij@iae.nl> 25 added code to skip HDR and EOF to allow SL tape IPL (5 retries) 26 changed first CCW from rewind to backspace block 27 28 */ 29 30#include <linux/config.h> 31#include <asm/setup.h> 32#include <asm/lowcore.h> 33 34#ifndef CONFIG_IPL 35 .org 0 36 .long 0x00080000,0x80000000+startup # Just a restart PSW 37#else 38#ifdef CONFIG_IPL_TAPE 39#define IPL_BS 1024 40 .org 0 41 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded 42 .long 0x27000000,0x60000001 # by ipl to addresses 0-23. 43 .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs). 44 .long 0x00000000,0x00000000 # external old psw 45 .long 0x00000000,0x00000000 # svc old psw 46 .long 0x00000000,0x00000000 # program check old psw 47 .long 0x00000000,0x00000000 # machine check old psw 48 .long 0x00000000,0x00000000 # io old psw 49 .long 0x00000000,0x00000000 50 .long 0x00000000,0x00000000 51 .long 0x00000000,0x00000000 52 .long 0x000a0000,0x00000058 # external new psw 53 .long 0x000a0000,0x00000060 # svc new psw 54 .long 0x000a0000,0x00000068 # program check new psw 55 .long 0x000a0000,0x00000070 # machine check new psw 56 .long 0x00080000,0x80000000+.Lioint # io new psw 57 58 .org 0x100 59# 60# subroutine for loading from tape 61# Paramters: 62# R1 = device number 63# R2 = load address 64.Lloader: 65 st %r14,.Lldret 66 la %r3,.Lorbread # r3 = address of orb 67 la %r5,.Lirb # r5 = address of irb 68 st %r2,.Lccwread+4 # initialize CCW data addresses 69 lctl %c6,%c6,.Lcr6 70 slr %r2,%r2 71.Lldlp: 72 la %r6,3 # 3 retries 73.Lssch: 74 ssch 0(%r3) # load chunk of IPL_BS bytes 75 bnz .Llderr 76.Lw4end: 77 bas %r14,.Lwait4io 78 tm 8(%r5),0x82 # do we have a problem ? 79 bnz .Lrecov 80 slr %r7,%r7 81 icm %r7,3,10(%r5) # get residual count 82 lcr %r7,%r7 83 la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read 84 ar %r2,%r7 # add to total size 85 tm 8(%r5),0x01 # found a tape mark ? 86 bnz .Ldone 87 l %r0,.Lccwread+4 # update CCW data addresses 88 ar %r0,%r7 89 st %r0,.Lccwread+4 90 b .Lldlp 91.Ldone: 92 l %r14,.Lldret 93 br %r14 # r2 contains the total size 94.Lrecov: 95 bas %r14,.Lsense # do the sensing 96 bct %r6,.Lssch # dec. retry count & branch 97 b .Llderr 98# 99# Sense subroutine 100# 101.Lsense: 102 st %r14,.Lsnsret 103 la %r7,.Lorbsense 104 ssch 0(%r7) # start sense command 105 bnz .Llderr 106 bas %r14,.Lwait4io 107 l %r14,.Lsnsret 108 tm 8(%r5),0x82 # do we have a problem ? 109 bnz .Llderr 110 br %r14 111# 112# Wait for interrupt subroutine 113# 114.Lwait4io: 115 lpsw .Lwaitpsw 116.Lioint: 117 c %r1,0xb8 # compare subchannel number 118 bne .Lwait4io 119 tsch 0(%r5) 120 slr %r0,%r0 121 tm 8(%r5),0x82 # do we have a problem ? 122 bnz .Lwtexit 123 tm 8(%r5),0x04 # got device end ? 124 bz .Lwait4io 125.Lwtexit: 126 br %r14 127.Llderr: 128 lpsw .Lcrash 129 130 .align 8 131.Lorbread: 132 .long 0x00000000,0x0080ff00,.Lccwread 133 .align 8 134.Lorbsense: 135 .long 0x00000000,0x0080ff00,.Lccwsense 136 .align 8 137.Lccwread: 138 .long 0x02200000+IPL_BS,0x00000000 139.Lccwsense: 140 .long 0x04200001,0x00000000 141.Lwaitpsw: 142 .long 0x020a0000,0x80000000+.Lioint 143 144.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 145.Lcr6: .long 0xff000000 146 .align 8 147.Lcrash:.long 0x000a0000,0x00000000 148.Lldret:.long 0 149.Lsnsret: .long 0 150#endif /* CONFIG_IPL_TAPE */ 151 152#ifdef CONFIG_IPL_VM 153#define IPL_BS 0x730 154 .org 0 155 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded 156 .long 0x02000018,0x60000050 # by ipl to addresses 0-23. 157 .long 0x02000068,0x60000050 # (a PSW and two CCWs). 158 .fill 80-24,1,0x40 # bytes 24-79 are discarded !! 159 .long 0x020000f0,0x60000050 # The next 160 byte are loaded 160 .long 0x02000140,0x60000050 # to addresses 0x18-0xb7 161 .long 0x02000190,0x60000050 # They form the continuation 162 .long 0x020001e0,0x60000050 # of the CCW program started 163 .long 0x02000230,0x60000050 # by ipl and load the range 164 .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image 165 .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730 166 .long 0x02000320,0x60000050 # in memory. At the end of 167 .long 0x02000370,0x60000050 # the channel program the PSW 168 .long 0x020003c0,0x60000050 # at location 0 is loaded. 169 .long 0x02000410,0x60000050 # Initial processing starts 170 .long 0x02000460,0x60000050 # at 0xf0 = iplstart. 171 .long 0x020004b0,0x60000050 172 .long 0x02000500,0x60000050 173 .long 0x02000550,0x60000050 174 .long 0x020005a0,0x60000050 175 .long 0x020005f0,0x60000050 176 .long 0x02000640,0x60000050 177 .long 0x02000690,0x60000050 178 .long 0x020006e0,0x20000050 179 180 .org 0xf0 181# 182# subroutine for loading cards from the reader 183# 184.Lloader: 185 la %r3,.Lorb # r2 = address of orb into r2 186 la %r5,.Lirb # r4 = address of irb 187 la %r6,.Lccws 188 la %r7,20 189.Linit: 190 st %r2,4(%r6) # initialize CCW data addresses 191 la %r2,0x50(%r2) 192 la %r6,8(%r6) 193 bct 7,.Linit 194 195 lctl %c6,%c6,.Lcr6 # set IO subclass mask 196 slr %r2,%r2 197.Lldlp: 198 ssch 0(%r3) # load chunk of 1600 bytes 199 bnz .Llderr 200.Lwait4irq: 201 mvc __LC_IO_NEW_PSW(8),.Lnewpsw # set up IO interrupt psw 202 lpsw .Lwaitpsw 203.Lioint: 204 c %r1,0xb8 # compare subchannel number 205 bne .Lwait4irq 206 tsch 0(%r5) 207 208 slr %r0,%r0 209 ic %r0,8(%r5) # get device status 210 chi %r0,8 # channel end ? 211 be .Lcont 212 chi %r0,12 # channel end + device end ? 213 be .Lcont 214 215 l %r0,4(%r5) 216 s %r0,8(%r3) # r0/8 = number of ccws executed 217 mhi %r0,10 # *10 = number of bytes in ccws 218 lh %r3,10(%r5) # get residual count 219 sr %r0,%r3 # #ccws*80-residual=#bytes read 220 ar %r2,%r0 221 222 br %r14 # r2 contains the total size 223 224.Lcont: 225 ahi %r2,0x640 # add 0x640 to total size 226 la %r6,.Lccws 227 la %r7,20 228.Lincr: 229 l %r0,4(%r6) # update CCW data addresses 230 ahi %r0,0x640 231 st %r0,4(%r6) 232 ahi %r6,8 233 bct 7,.Lincr 234 235 b .Lldlp 236.Llderr: 237 lpsw .Lcrash 238 239 .align 8 240.Lorb: .long 0x00000000,0x0080ff00,.Lccws 241.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 242.Lcr6: .long 0xff000000 243.Lloadp:.long 0,0 244 .align 8 245.Lcrash:.long 0x000a0000,0x00000000 246.Lnewpsw: 247 .long 0x00080000,0x80000000+.Lioint 248.Lwaitpsw: 249 .long 0x020a0000,0x80000000+.Lioint 250 251 .align 8 252.Lccws: .rept 19 253 .long 0x02600050,0x00000000 254 .endr 255 .long 0x02200050,0x00000000 256#endif /* CONFIG_IPL_VM */ 257 258iplstart: 259 lh %r1,0xb8 # test if subchannel number 260 bct %r1,.Lnoload # is valid 261 l %r1,0xb8 # load ipl subchannel number 262 la %r2,IPL_BS # load start address 263 bas %r14,.Lloader # load rest of ipl image 264 l %r12,.Lparm # pointer to parameter area 265 st %r1,IPL_DEVICE-PARMAREA(%r12) # store ipl device number 266 267# 268# load parameter file from ipl device 269# 270.Lagain1: 271 l %r2,INITRD_START-PARMAREA(%r12) # use ramdisk location as temp 272 bas %r14,.Lloader # load parameter file 273 ltr %r2,%r2 # got anything ? 274 bz .Lnopf 275 chi %r2,895 276 bnh .Lnotrunc 277 la %r2,895 278.Lnotrunc: 279 l %r4,INITRD_START-PARMAREA(%r12) 280 clc 0(3,%r4),.L_hdr # if it is HDRx 281 bz .Lagain1 # skip dataset header 282 clc 0(3,%r4),.L_eof # if it is EOFx 283 bz .Lagain1 # skip dateset trailer 284 la %r5,0(%r4,%r2) 285 lr %r3,%r2 286.Lidebc: 287 tm 0(%r5),0x80 # high order bit set ? 288 bo .Ldocv # yes -> convert from EBCDIC 289 ahi %r5,-1 290 bct %r3,.Lidebc 291 b .Lnocv 292.Ldocv: 293 l %r3,.Lcvtab 294 tr 0(256,%r4),0(%r3) # convert parameters to ascii 295 tr 256(256,%r4),0(%r3) 296 tr 512(256,%r4),0(%r3) 297 tr 768(122,%r4),0(%r3) 298.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line 299 mvc 0(256,%r3),0(%r4) 300 mvc 256(256,%r3),256(%r4) 301 mvc 512(256,%r3),512(%r4) 302 mvc 768(122,%r3),768(%r4) 303 slr %r0,%r0 304 b .Lcntlp 305.Ldelspc: 306 ic %r0,0(%r2,%r3) 307 chi %r0,0x20 # is it a space ? 308 be .Lcntlp 309 ahi %r2,1 310 b .Leolp 311.Lcntlp: 312 brct %r2,.Ldelspc 313.Leolp: 314 slr %r0,%r0 315 stc %r0,0(%r2,%r3) # terminate buffer 316.Lnopf: 317 318# 319# load ramdisk from ipl device 320# 321.Lagain2: 322 l %r2,INITRD_START-PARMAREA(%r12) # load adr. of ramdisk 323 bas %r14,.Lloader # load ramdisk 324 st %r2,INITRD_SIZE-PARMAREA(%r12) # store size of ramdisk 325 ltr %r2,%r2 326 bnz .Lrdcont 327 st %r2,INITRD_START-PARMAREA(%r12) # no ramdisk found, null it 328.Lrdcont: 329 l %r2,INITRD_START-PARMAREA(%r12) 330 331 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx 332 bz .Lagain2 333 clc 0(3,%r2),.L_eof 334 bz .Lagain2 335 336#ifdef CONFIG_IPL_VM 337# 338# reset files in VM reader 339# 340 stidp __LC_CPUID # store cpuid 341 tm __LC_CPUID,0xff # running VM ? 342 bno .Lnoreset 343 la %r2,.Lreset 344 lhi %r3,26 345 .long 0x83230008 346.Lnoreset: 347#endif 348 349# 350# everything loaded, go for it 351# 352.Lnoload: 353 l %r1,.Lstartup 354 br %r1 355 356.Lparm: .long PARMAREA 357.Lstartup: .long startup 358.Lcvtab:.long _ebcasc # ebcdic to ascii table 359.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40 360 .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6 361 .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold" 362.L_eof: .long 0xc5d6c600 /* C'EOF' */ 363.L_hdr: .long 0xc8c4d900 /* C'HDR' */ 364 365#endif /* CONFIG_IPL */ 366 367# 368# SALIPL loader support. Based on a patch by Rob van der Heij. 369# This entry point is called directly from the SALIPL loader and 370# doesn't need a builtin ipl record. 371# 372 .org 0x800 373 .globl start 374start: 375 stm %r0,%r15,0x07b0 # store registers 376 basr %r12,%r0 377.base: 378 l %r11,.parm 379 l %r8,.cmd # pointer to command buffer 380 381 ltr %r9,%r9 # do we have SALIPL parameters? 382 bp .sk8x8 383 384 mvc 0(64,%r8),0x00b0 # copy saved registers 385 xc 64(240-64,%r8),0(%r8) # remainder of buffer 386 tr 0(64,%r8),.lowcase 387 b .gotr 388.sk8x8: 389 mvc 0(240,%r8),0(%r9) # copy iplparms into buffer 390.gotr: 391 l %r10,.tbl # EBCDIC to ASCII table 392 tr 0(240,%r8),0(%r10) 393 stidp __LC_CPUID # Are we running on VM maybe 394 cli __LC_CPUID,0xff 395 bnz .test 396 .long 0x83300060 # diag 3,0,x'0060' - storage size 397 b .done 398.test: 399 mvc 0x68(8),.pgmnw # set up pgm check handler 400 l %r2,.fourmeg 401 lr %r3,%r2 402 bctr %r3,%r0 # 4M-1 403.loop: iske %r0,%r3 404 ar %r3,%r2 405.pgmx: 406 sr %r3,%r2 407 la %r3,1(%r3) 408.done: 409 l %r1,.memsize 410 st %r3,0(%r1) 411 slr %r0,%r0 412 st %r0,INITRD_SIZE-PARMAREA(%r11) 413 st %r0,INITRD_START-PARMAREA(%r11) 414 j startup # continue with startup 415.tbl: .long _ebcasc # translate table 416.cmd: .long COMMAND_LINE # address of command line buffer 417.parm: .long PARMAREA 418.memsize: .long memory_size 419.fourmeg: .long 0x00400000 # 4M 420.pgmnw: .long 0x00080000,.pgmx 421.lowcase: 422 .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 423 .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f 424 .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 425 .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f 426 .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 427 .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f 428 .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 429 .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f 430 .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 431 .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f 432 .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 433 .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f 434 .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 435 .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f 436 .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 437 .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f 438 439 .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 440 .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f 441 .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97 442 .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f 443 .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 444 .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf 445 .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7 446 .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf 447 .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg 448 .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi 449 .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop 450 .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf # qr 451 .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 # ..stuvwx 452 .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef # yz 453 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 454 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff 455 456# 457# startup-code at 0x10000, running in real mode 458# this is called either by the ipl loader or directly by PSW restart 459# or linload or SALIPL 460# 461 .org 0x10000 462startup:basr %r13,0 # get base 463.LPG1: lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers 464 la %r12,_pstart-.LPG1(%r13) # pointer to parameter area 465 # move IPL device to lowcore 466 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) 467 468# 469# clear bss memory 470# 471 l %r2,.Lbss_bgn-.LPG1(%r13) # start of bss 472 l %r3,.Lbss_end-.LPG1(%r13) # end of bss 473 sr %r3,%r2 # length of bss 474 sr %r4,%r4 # 475 sr %r5,%r5 # set src,length and pad to zero 476 sr %r0,%r0 # 477 mvcle %r2,%r4,0 # clear mem 478 jo .-4 # branch back, if not finish 479 480# 481# find memory chunks. 482# 483 mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13) 484 la %r1,1 # test in increments of 128KB 485 sll %r1,17 486 l %r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array 487 slr %r4,%r4 # set start of chunk to zero 488 slr %r5,%r5 # set end of chunk to zero 489 slr %r6,%r6 # set access code to zero 490.Lloop: 491 tprot 0(%r5),0 # test protection of first byte 492 ipm %r7 493 srl %r7,28 494 clr %r6,%r7 # compare cc with last access code 495 be .Lsame-.LPG1(%r13) 496 clr %r4,%r5 # chunk size > 0? 497 be .Lsize0-.LPG1(%r13) 498 st %r4,0(%r3) # store start address of chunk 499 lr %r0,%r5 500 slr %r0,%r4 501 st %r0,4(%r3) # store size of chunk 502 st %r6,8(%r3) # store type of chunk 503 la %r3,12(%r3) 504 lr %r4,%r5 # set start to end 505.Lsize0: 506 lr %r6,%r7 # set access code to last cc 507.Lsame: 508 ar %r5,%r1 # add 128KB to end of chunk 509 bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop 510.Lchkmem: # > 2GB or tprot got a program check 511 clr %r4,%r5 # chunk size > 0? 512 be .Ldonemem-.LPG1(%r13) 513 st %r4,0(%r3) # store start address of chunk 514 lr %r0,%r5 515 slr %r0,%r4 516 st %r0,4(%r3) # store size of chunk 517 st %r6,8(%r3) # store type of chunk 518.Ldonemem: 519 l %r1,.Lmemsize-.LPG1(%r13) # address of variable memory_size 520 st %r5,0(%r1) # store last end to memory size 521 522 l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags 523# 524# find out if we are running under VM 525# 526 stidp __LC_CPUID # store cpuid 527 tm __LC_CPUID,0xff # running under VM ? 528 bno .Lchkpfix-.LPG1(%r13) 529 oi 3(%r12),1 # set VM flag 530# 531# we are running under VM, find out if we have PFIX 532# 533 mvc __LC_PGM_NEW_PSW(8),.Lpcpfix-.LPG1(%r13) 534 lhi %r0,0x4000 535 slr %r2,%r2 536 .long 0x83200098 # diag 2,0,x'0098' - lock page 537 lhi %r2,4 538 .long 0x83200098 # diag 2,0,x'0098' - unlock page 539 oi 3(%r12),128 # set PFIX flag 540.Lchkpfix: 541 lh %r0,__LC_CPUID+4 # get cpu version 542 chi %r0,0x7490 # running on a P/390 ? 543 bne .Lnop390-.LPG1(%r13) 544 oi 3(%r12),4 # set P/390 flag 545.Lnop390: 546 chi %r0,0x2084 # new stidp format? 547 bne .Loldfmt-.LPG1(%r13) 548 oi 3(%r12),64 # set new stidp flag 549.Loldfmt: 550 551# 552# find out if we have an IEEE fpu 553# 554 mvc __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13) 555 efpc %r0,0 # test IEEE extract fpc instruction 556 oi 3(%r12),2 # set IEEE fpu flag 557.Lchkfpu: 558 559# 560# find out if we have the CSP instruction 561# 562 mvc __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13) 563 la %r0,0 564 lr %r1,%r0 565 la %r2,4 566 csp %r0,%r2 # Test CSP instruction 567 oi 3(%r12),8 # set CSP flag 568.Lchkcsp: 569 570# 571# find out if we have the MVPG instruction 572# 573 mvc __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13) 574 sr %r0,%r0 575 la %r1,0 576 la %r2,0 577 mvpg %r1,%r2 # Test CSP instruction 578 oi 3(%r12),16 # set MVPG flag 579.Lchkmvpg: 580 581 lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space, 582 # virtual and never return ... 583 .align 8 584.Lentry:.long 0x00080000,0x80000000 + _stext 585.Lctl: .long 0x04b50002 # cr0: various things 586 .long 0 # cr1: primary space segment table 587 .long .Lduct # cr2: dispatchable unit control table 588 .long 0 # cr3: instruction authorization 589 .long 0 # cr4: instruction authorization 590 .long 0xffffffff # cr5: primary-aste origin 591 .long 0 # cr6: I/O interrupts 592 .long 0 # cr7: secondary space segment table 593 .long 0 # cr8: access registers translation 594 .long 0 # cr9: tracing off 595 .long 0 # cr10: tracing off 596 .long 0 # cr11: tracing off 597 .long 0 # cr12: tracing off 598 .long 0 # cr13: home space segment table 599 .long 0xc0000000 # cr14: machine check handling off 600 .long 0 # cr15: linkage stack operations 601.Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem 602.Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu 603.Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp 604.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg 605.Lpcpfix:.long 0x00080000,0x80000000 + .Lchkpfix 606.Lmemsize:.long memory_size 607.Lmchunk:.long memory_chunk 608.Lmflags:.long machine_flags 609.Lbss_bgn: .long __bss_start 610.Lbss_end: .long _end 611 612 .org PARMAREA-64 613.Lduct: .long 0,0,0,0,0,0,0,0 614 .long 0,0,0,0,0,0,0,0 615 616# 617# params at 10400 (setup.h) 618# 619 .org PARMAREA 620 .global _pstart 621_pstart: 622 .long 0,0 # IPL_DEVICE 623 .long 0,RAMDISK_ORIGIN # INITRD_START 624 .long 0,RAMDISK_SIZE # INITRD_SIZE 625 626 .org COMMAND_LINE 627 .byte "root=/dev/ram0 ro" 628 .byte 0 629 .org 0x11000 630 .global _pend 631_pend: 632 633#ifdef CONFIG_SHARED_KERNEL 634 .org 0x100000 635#endif 636 637# 638# startup-code, running in virtual mode 639# 640 .globl _stext 641_stext: basr %r13,0 # get base 642.LPG2: 643# 644# Setup stack 645# 646 l %r15,.Linittu-.LPG2(%r13) 647 ahi %r15,8192 # init_task_union + 8192 648 st %r15,__LC_KERNEL_STACK # set end of kernel stack 649 ahi %r15,-96 650 xc 0(4,%r15),0(%r15) # set backchain to zero 651 652# check control registers 653 stctl %c0,%c15,0(%r15) 654 oi 2(%r15),0x20 # enable sigp external interrupts 655 oi 0(%r15),0x10 # switch on low address protection 656 lctl %c0,%c15,0(%r15) 657 658# 659 lam 0,15,.Laregs-.LPG2(%r13) # load access regs needed by uaccess 660 l %r14,.Lstart-.LPG2(%r13) 661 basr %r14,%r14 # call start_kernel 662# 663# We returned from start_kernel ?!? PANIK 664# 665 basr %r13,0 666 lpsw .Ldw-.(%r13) # load disabled wait psw 667# 668 .align 8 669.Ldw: .long 0x000a0000,0x00000000 670.Linittu: .long init_task_union 671.Lstart: .long start_kernel 672.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 673 674