Home | History | Annotate | Download | only in ppc32-linux
      1 #
      2 #  linux_logo in ppc assembly language
      3 #    based on the code from ll_asm-0.36
      4 #
      5 #  By Vince Weaver <vince _at_ deater.net>
      6 #
      7 # Modified to remove non-deterministic system calls
      8 # And to avoid reading from /proc
      9 #
     10 
     11 # offsets into the results returned by the uname syscall
     12 .equ U_SYSNAME,0
     13 .equ U_NODENAME,65
     14 .equ U_RELEASE,65*2
     15 .equ U_VERSION,(65*3)
     16 .equ U_MACHINE,(65*4)
     17 .equ U_DOMAINNAME,65*5
     18 
     19 # offset into the SYSCALL_SYSINFO buffer
     20 .equ S_TOTALRAM,16
     21 
     22 # Sycscalls
     23 .equ SYSCALL_EXIT,     1
     24 #.equ SYSCALL_READ,     3
     25 .equ SYSCALL_WRITE,    4
     26 #.equ SYSCALL_OPEN,     5
     27 #.equ SYSCALL_CLOSE,    6
     28 #.equ SYSCALL_SYSINFO,116
     29 #.equ SYSCALL_UNAME,  122
     30 
     31 #
     32 .equ STDIN, 0
     33 .equ STDOUT,1
     34 .equ STDERR,2
     35 
     36 .equ BSS_BEGIN,25
     37 .equ DATA_BEGIN,26
     38 
     39 .include "logo.include"
     40 
     41 	.globl _start
     42 _start:
     43 
     44         #========================
     45 	# Initialization
     46 	#========================
     47 
     48 
     49 #	eieio				# coolest opcode of all time ;)
     50 					# not needed, but I had to put it here
     51   	# the hack loading BSS_BEGIN and DATA_BEGIN
     52 	# saves one instruction on any future load from memory
     53 	# as we can just do an addi rather than an lis;addi
     54 
     55 	lis	25,bss_begin@ha
     56 	addi	25,25,bss_begin@l
     57 
     58 	lis	26,data_begin@ha
     59 	addi	26,26,data_begin@l
     60 
     61 	addi	14,BSS_BEGIN,(out_buffer-bss_begin)
     62 					# the output buffer
     63 
     64 	addi	21,BSS_BEGIN,(text_buf-bss_begin)
     65 
     66 
     67 	mr	17,14		    	# store out-buffer for later
     68 
     69         #=========================
     70 	# PRINT LOGO
     71 	#=========================
     72 
     73 # LZSS decompression algorithm implementation
     74 # by Stephan Walter 2002, based on LZSS.C by Haruhiko Okumura 1989
     75 # optimized some more by Vince Weaver
     76 
     77 
     78 	li	8,(N-F)			# grab "R"
     79 
     80 	addi	9,DATA_BEGIN,(logo-data_begin)-1
     81 					# logo_pointer
     82 
     83 	addi	12,DATA_BEGIN,(logo_end-data_begin)-1
     84 					# end of the logo
     85 
     86 
     87 	mr      16,17
     88 
     89 decompression_loop:
     90 	lbzu 	10,1(9)			# load in a byte
     91 					# auto-update
     92 	mr	11,10			# copy to 11
     93 	ori	11,11,0xff00		# re-load top as a hackish
     94 					# 8-bit counter
     95 
     96 test_flags:
     97 	cmpw	0,12,9			# have we reached the end?
     98 	ble	done_logo		# ! if so exit
     99 
    100 	andi.	13,11,0x1
    101 	srawi   11,11,1
    102 
    103 	bne	0,discrete_char
    104 
    105 offset_length:
    106 	lbzu  	10,1(9)
    107 	lbzu	24,1(9)
    108 	slwi	24,24,8
    109 	or	24,24,10
    110 
    111 	mr	10,24
    112 
    113 	srawi  15,10,P_BITS
    114 	addi   15,15,THRESHOLD+1 # cl = ax >> (P_BITS)+THRESH+1
    115 	       			 # = match length
    116 
    117 output_loop:
    118 	andi.  24,24,(POSITION_MASK<<8+0xff)	# mask it
    119 	lbzx   10,21,24
    120 	addi   24,24,1
    121 
    122 store_byte:
    123 	stbu   10,1(16)
    124 
    125 	stbx    10,21,8
    126 	addi	8,8,1
    127 	andi.	8,8,(N-1)
    128 
    129 	addic.	15,15,-1
    130 	bne	0,output_loop
    131 
    132 	andi.	13,11,0xff00
    133 	bne	test_flags
    134 
    135 	b	decompression_loop
    136 
    137 discrete_char:
    138 
    139 	lbzu    10,1(9)
    140 	li	15,1
    141 
    142 	b       store_byte
    143 
    144 done_logo:
    145 
    146 	addi	4,17,1		# restore (plus one because r17 is decremented)
    147 	bl	write_stdout	# and print the logo
    148 
    149 
    150         #==========================
    151 	# First Line
    152 	#==========================
    153 
    154 
    155 	#==========================
    156 	# PRINT VERSION
    157 	#==========================
    158 
    159 #	li	0,SYSCALL_UNAME		# uname syscall
    160 #	addi	3,BSS_BEGIN,(uname_info-bss_begin)
    161 					# uname struct
    162 #	sc				# do syscall
    163 
    164 
    165 	addi	16,DATA_BEGIN,(uname_info-data_begin)+U_SYSNAME@l-1
    166 					# os-name from uname "Linux"
    167 	bl	strcat
    168 
    169 	addi	16,DATA_BEGIN,(ver_string-data_begin)-1
    170 					# source is " Version "
    171 	bl 	strcat
    172 
    173 	addi	16,DATA_BEGIN,(uname_info-data_begin)+U_RELEASE@l-1
    174 					# version from uname "2.4.1"
    175 	bl 	strcat
    176 
    177 	addi	16,DATA_BEGIN,(compiled_string-data_begin)-1
    178 					# source is ", Compiled "
    179 	bl 	strcat
    180 
    181 	addi	16,DATA_BEGIN,(uname_info-data_begin)+U_VERSION-1
    182       					# compiled date
    183 	bl 	strcat
    184 
    185 	bl	center_and_print	# write it to screen
    186 
    187 
    188 	#===============================
    189 	# Middle-Line
    190 	#===============================
    191 
    192 	#=========
    193 	# Load /proc/cpuinfo into buffer
    194 	#=========
    195 
    196 #	li	0,SYSCALL_OPEN		# open()
    197 #	addi	3,DATA_BEGIN,(cpuinfo-data_begin)
    198 					# '/proc/cpuinfo'
    199 #	li	4,0			# O_RDONLY <bits/fcntl.h>
    200 #	sc				# syscall.  fd in r0.
    201 					# we should check that r0>=0
    202 
    203 #	mr	13,3			# save fd in r13
    204 
    205 #	li	0,SYSCALL_READ		# read
    206 #	addi	4,BSS_BEGIN,(disk_buffer-bss_begin)
    207 #	li	5,4096		 	# 4096 is maximum size of proc file ;)
    208 #	sc
    209 
    210 #	mr	3,13			# restore fd
    211 #	li	0,6			# close
    212 #	sc
    213 
    214 	#=============
    215 	# Number of CPUs
    216 	#=============
    217 
    218 	mr	14,17 			# point output to out_buf
    219 
    220 	# Assume 1 CPU for now
    221 	# my iBook's /proc/cpuinfo does not have a "processor" line ???
    222 
    223 	addi	16,DATA_BEGIN,(one-data_begin)-1
    224 	bl	strcat
    225 
    226 	#=========
    227 	# MHz
    228 	#=========
    229 
    230     	lis	20,('l'<<8)+'o'		# find 'lock ' and grab up to M
    231 	addi	20,20,('c'<<8)+'k'
    232 	li	23,'M'
    233    	bl	find_string
    234 
    235 	addi	16,DATA_BEGIN,(megahertz-data_begin)-1
    236 					# print 'MHz '
    237 	bl	strcat
    238 
    239 
    240 	#=========
    241 	# Chip Name
    242 	#=========
    243 
    244    	lis     20,('c'<<8)+'p'     	# find 'cpu\t: ' and grab up to \n
    245 	addi	20,20,('u'<<8)+'\t'
    246 	li	23,'\n'
    247 	bl	find_string
    248 
    249 	addi	16,DATA_BEGIN,(comma-data_begin)-1
    250 					# print ', '
    251 	bl	strcat
    252 
    253 	#========
    254 	# RAM
    255 	#========
    256 
    257 #	li	0,SYSCALL_SYSINFO	# sysinfo() syscall
    258 #	addi	3,BSS_BEGIN,(sysinfo_buff-bss_begin)
    259 					# sysinfo_buffer
    260 
    261 #	sc
    262 
    263 	lwz	4,(sysinfo_buff+S_TOTALRAM-data_begin)(DATA_BEGIN)
    264 					# load bytes of RAM into r4
    265 
    266 	srawi	4,4,20		# divide by 2^20 to get MB
    267 	li	5,0
    268 
    269 	bl	num_to_ascii
    270 
    271 	addi	16,DATA_BEGIN,(ram_comma-data_begin)-1
    272 					# print 'M RAM, '
    273 
    274 	bl	strcat
    275 
    276 	#========
    277 	# Bogomips
    278 	#========
    279 
    280 	lis	20,('m'<<8)+'i'		# find 'mips' and grab up to \n
    281 	addi	20,20,('p'<<8)+'s'
    282 	li	23,'\n'
    283 	bl	find_string
    284 
    285 	addi	16,DATA_BEGIN,(bogo_total-data_begin)-1
    286 					# print "Bogomips Total"
    287 	bl	strcat
    288 
    289 	bl	center_and_print	# center it
    290 
    291 
    292 	#=================================
    293 	# Print Host Name
    294 	#=================================
    295 
    296 	mr	14,17			# restore out buffer
    297 
    298 	addi	16,DATA_BEGIN,((uname_info-data_begin)+U_NODENAME)-1
    299 					# hostname
    300 
    301 	bl	strcat
    302 
    303 	bl	center_and_print
    304 
    305 	#================================
    306 	# Exit
    307 	#================================
    308 exit:
    309         li      3,0		# 0 exit value
    310 	li      0,SYSCALL_EXIT  # put the exit syscall number in eax
    311 	sc	             	# and exit
    312 
    313 
    314 
    315 
    316 	#=================================
    317 	# FIND_STRING
    318 	#=================================
    319 	#   r23 is char to end at
    320 	#   r20 is the 4-char ascii string to look for
    321 	#   r14 points at output buffer
    322 	#   r16,r21
    323 
    324 find_string:
    325 
    326 	addi	16,DATA_BEGIN,(disk_buffer-data_begin)-1
    327 					# look in cpuinfo buffer
    328 					# -1 so we can use lbzu
    329 
    330 find_loop:
    331 	lwzu	13,1(16)		# load in 32 bits, incrementing 8bits
    332 	cmpwi	13,0			# ! if null, we are done
    333 	beq	done
    334 	cmpw	13,20			# compare with out 4 char string
    335 	bne	find_loop		# ! if no match, keep looping
    336 
    337 
    338 					# ! if we get this far, we matched
    339 
    340 	li	21,':'
    341 find_colon:
    342 	lbzu	13,1(16)		# repeat till we find colon
    343 	cmpwi	13,0
    344 	beq	done
    345 	cmpw	13,21
    346 	bne	find_colon
    347 
    348 	addi	16,16,1			# skip a char [should be space]
    349 
    350 store_loop:
    351 	 lbzu	13,1(16)
    352 	 cmpwi	13,0
    353 	 beq	done
    354     	 cmpw	13,23			# is it end string?
    355 	 beq 	almost_done		# ! if so, finish
    356 	 stbu	13,1(14)		# ! if not store and continue
    357 	 b	store_loop
    358 
    359 almost_done:
    360 	li	13,0			# replace last value with null
    361 	stb	13,1(14)
    362 
    363 done:
    364 	blr
    365 
    366 	#================================
    367 	# strcat
    368 	#================================
    369 	# r13 = "temp"
    370 	# r16 = "source"
    371        	# r14 = "destination"
    372 strcat:
    373 	lbzu	13,1(16)		# load a byte from [r16]
    374 	stbu	13,1(14)		# store a byte to [r14]
    375 	cmpwi	13,0			# is it zero?
    376 	bne	strcat			# ! if not loop
    377 	subi	14,14,1			# point to one less than null
    378 	blr				# return
    379 
    380 	#==============================
    381 	# center_and_print
    382 	#==============================
    383 	# r14 is end of buffer
    384 	# r17 is start of buffer
    385 	# r29 = saved link register
    386 	# r4-r10, r19-r22, r30 trashed
    387 
    388 center_and_print:
    389 
    390 	mflr 	29			# back up return address
    391 
    392 	subf	5,17,14			# see how long the output
    393 					# buffer is
    394 
    395 	cmpwi	5,80			# see if we are >80
    396         bgt	done_center		# ! if so, bail
    397 
    398 	li	4,80			# 80 column screen
    399 	subf	4,5,4			# subtract strlen
    400 	srawi	23,4,1			# divide by two
    401 
    402 	lis	4,escape@ha
    403 	addi	4,4,escape@l
    404 	bl	write_stdout
    405 
    406 	mr	4,23
    407 	li	5,1			# print to stdout
    408 	bl	num_to_ascii		# print number
    409 
    410 	lis	4,c@ha
    411 	addi	4,4,c@l
    412 	bl	write_stdout
    413 
    414 
    415 done_center:
    416 
    417 	addi	4,17,1			# move string to output+1
    418 	bl	write_stdout		# call write stdout
    419 
    420 	lis	4,linefeed@ha
    421 	addi	4,4,linefeed@l
    422 
    423 	mtlr	29	      		# restore link register
    424 					# and let write_stdout
    425 					# return for us
    426 
    427 
    428 
    429 	#================================
    430 	# WRITE_STDOUT
    431 	#================================
    432 	# r4 has string
    433 	# r0,r3,r4,r5,r6 trashed
    434 
    435 write_stdout:
    436 	li	0,SYSCALL_WRITE		# write syscall
    437 	li	3,STDOUT		# stdout
    438 
    439 	li	5,0			# string length counter
    440 strlen_loop:
    441 	lbzx 	6,4,5			# get byte from (r4+r5)
    442        	addi	5,5,1			# increment counter
    443 	cmpi	0,6,0			# is it zero?
    444 	bne	strlen_loop		# ! if not keep counting
    445 	addi	5,5,-1
    446 	sc				# syscall
    447 
    448 	blr				# return
    449 
    450 
    451 	##############################
    452 	# Num to Ascii
    453 	##############################
    454 	# num is in r4
    455 	# r5 =0 then strcat, otherwise stdout
    456 	# r5-r10,r19,r20,r21,r22,r30 trashed
    457 
    458 num_to_ascii:
    459 
    460 	mflr    30			# save the link register
    461 
    462 	addi	16,BSS_BEGIN,(num_to_ascii_end-bss_begin)
    463 					# the end of a backwards growing
    464 					# 10 byte long buffer.
    465 
    466 	li	20,10			# we will divide by 10
    467 	mr	19,4			# load in the value passed
    468 
    469 div_by_10:
    470 	divw	21,19,20		# divide r19 by r20 put into r21
    471 
    472 	mullw	22,21,20		# find remainder.  1st q*dividend
    473 	subf	22,22,19		# then subtract from original = R
    474 	addi	22,22,0x30		# convert remainder to ascii
    475 
    476 	stbu	22,-1(16)		# Store to backwards buffer
    477 
    478 	mr	19,21			# move Quotient as new dividend
    479 	cmpwi	19,0			# was quotient zero?
    480 	bne    	div_by_10		# ! if not keep dividing
    481 
    482 write_out:
    483 	cmpwi	5,0			# ! if r5 is 0 then skip ahead
    484 	bne 	stdout_num
    485 
    486 	addi	16,16,-1		# point to the beginning
    487 	bl	strcat			# and strcat it
    488 
    489 	mtlr	30			# restore link register
    490 
    491 	blr				# return
    492 
    493 stdout_num:
    494         mr	4,16			# point to our buffer
    495 	mtlr	30			# restore link register
    496 	b	write_stdout		# stdout will return for us
    497 
    498 
    499 #===========================================================================
    500 .data
    501 #===========================================================================
    502 
    503 
    504 data_begin:
    505 
    506 .include "logo.lzss_new"
    507 
    508 ver_string:	.ascii	" Version \0"
    509 compiled_string:	.ascii	", Compiled \0"
    510 megahertz:	.ascii	"MHz PPC \0"
    511 .equ space, ram_comma+6
    512 .equ comma, ram_comma+5
    513 linefeed:   	.ascii  "\n\0"
    514 escape:		.ascii	"\033[\0"
    515 c:		.ascii  "C\0"
    516 ram_comma:	.ascii	"M RAM, \0"
    517 
    518 bogo_total:	.ascii	" Bogomips Total\0"
    519 
    520 default_colors:	.ascii	"\033[0m\n\n\0"
    521 
    522 cpuinfo:	.ascii	"/proc/cpuinfo\0"
    523 
    524 one:	.ascii	"One \0"
    525 
    526 disk_buffer:
    527 .ascii "processor	: 0\n"
    528 .ascii "cpu		: 745/755\n"
    529 .ascii "temperature 	: 22-24 C (uncalibrated)\n"
    530 .ascii "clock		: 600.000000MHz\n"
    531 .ascii "revision	: 51.17 (pvr 0008 3311)\n"
    532 .ascii "bogomips	: 49.79\n"
    533 .ascii "timebase	: 24960000\n"
    534 .ascii "platform	: PowerMac\n"
    535 .ascii "model		: PowerBook4,1\n"
    536 .ascii "machine		: PowerBook4,1\n"
    537 .ascii "motherboard	: PowerBook4,1 MacRISC2 MacRISC Power Macintosh\n"
    538 .ascii "detected as	: 257 (iBook 2)\n"
    539 .ascii "pmac flags	: 0000001b\n"
    540 .ascii "L2 cache	: 256K unified\n"
    541 .ascii "pmac-generation	: NewWorld\n\0"
    542 
    543 uname_info:
    544 .ascii "Linux\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    545 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    546 .ascii "henparma\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    547 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    548 .ascii "2.6.29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    549 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    550 .ascii "#1 Wed May 13 15:51:54 UTC 2009\0"
    551 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    552 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    553 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    554 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    555 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    556 
    557 
    558 sysinfo_buff:
    559 .long 0,0,0,0,512*1024*1024,0,0,0
    560 
    561 #============================================================================
    562 #.bss
    563 #============================================================================
    564 
    565 .lcomm bss_begin,0
    566 .lcomm	num_to_ascii_buff,10
    567 .lcomm num_to_ascii_end,1
    568 .lcomm  text_buf, (N+F-1)	# These buffers must follow each other
    569 .lcomm	out_buffer,16384
    570 
    571 
    572 
    573 
    574 
    575 
    576 
    577 
    578 
    579 
    580