start.S revision 1.1 1 1.1 skrll ; $NetBSD: start.S,v 1.1 2014/02/24 07:23:43 skrll Exp $
2 1.1 skrll
3 1.1 skrll ; Copyright (c) 2003 ITOH Yasufumi.
4 1.1 skrll ; All rights reserved.
5 1.1 skrll ;
6 1.1 skrll ; Redistribution and use in source and binary forms, with or without
7 1.1 skrll ; modification, are permitted provided that the following conditions
8 1.1 skrll ; are met:
9 1.1 skrll ; 1. Redistributions of source code must retain the above copyright
10 1.1 skrll ; notice, this list of conditions and the following disclaimer.
11 1.1 skrll ; 2. Redistributions in binary forms are unlimited.
12 1.1 skrll ;
13 1.1 skrll ; THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS''
14 1.1 skrll ; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 1.1 skrll ; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 1.1 skrll ; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS
17 1.1 skrll ; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 1.1 skrll ; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 1.1 skrll ; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 1.1 skrll ; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 1.1 skrll ; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 1.1 skrll ; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 1.1 skrll ; THE POSSIBILITY OF SUCH DAMAGE.
24 1.1 skrll
25 1.1 skrll .level 1.0
26 1.1 skrll
27 1.1 skrll .code
28 1.1 skrll .origin 0
29 1.1 skrll ;
30 1.1 skrll ; LIF (Logical Interchange Format) header
31 1.1 skrll ;
32 1.1 skrll lifhdr: .byte 0x80,0x00 ; LIF magic
33 1.1 skrll .string "NetBSD" ; volume label (6 chars, fill with space)
34 1.1 skrll .origin 0xf0
35 1.1 skrll ; 0xf0
36 1.1 skrll lif_ipl_addr:
37 1.1 skrll .word top-lifhdr ; start at 4KB (must be 2KB aligned)
38 1.1 skrll lif_ipl_size:
39 1.1 skrll .word 0x00001000 ; size 4KB (must be 2KB aligned)
40 1.1 skrll lif_ipl_entry:
41 1.1 skrll .word $START$-top ; entry offset
42 1.1 skrll
43 1.1 skrll ; ipl part 1 starts here
44 1.1 skrll .origin 4096
45 1.1 skrll top:
46 1.1 skrll ;
47 1.1 skrll ; IPL startup
48 1.1 skrll ;
49 1.1 skrll ; arg0 = interact flag (1: interactive, 0: otherwise)
50 1.1 skrll ; arg1 = address of first doubleword past the end of ipl part 1
51 1.1 skrll ;
52 1.1 skrll .export $START$,entry
53 1.1 skrll $START$:
54 1.1 skrll b,n start ; 0: entry address
55 1.1 skrll
56 1.1 skrll ; version of interface of primary to secondary boot
57 1.1 skrll BOOT_IF_VERSION: .equ 0
58 1.1 skrll ; version 0: arg0 = interact flag, arg1 = version (0),
59 1.1 skrll ; arg2 = end addr, arg3 = selected boot partition
60 1.1 skrll ; r1, r3 - r22, r28, r29, r31 = cleared to zeros
61 1.1 skrll
62 1.1 skrll cksum: .word 0 ; 4: checksum will be stored here
63 1.1 skrll version: .word BOOT_IF_VERSION ; 8: version of interface
64 1.1 skrll rsvd1: .word 0 ; 12: future use
65 1.1 skrll rsvd2: .word 0 ; 16: future use
66 1.1 skrll rsvd3: .word 0 ; 20: future use
67 1.1 skrll
68 1.1 skrll start:
69 1.1 skrll ; set data pointer for relocatable data access
70 1.1 skrll blr %r0,%r27
71 1.1 skrll ; get PSW at entry
72 1.1 skrll ssm 0,%r4
73 1.1 skrll .export $global$,data
74 1.1 skrll $global$:
75 1.1 skrll
76 1.1 skrll ; save parameters for main
77 1.1 skrll copy %arg0,%r3
78 1.1 skrll
79 1.1 skrll tmpdiskbufsz: .equ 0x1000 ; 4KB
80 1.1 skrll tmpdiskbuf_labelsec: .equ 0x0200 ; dbtob(LABELSECTOR)
81 1.1 skrll tmpdiskbuf_labelsecsz: .equ 512
82 1.1 skrll tmpdiskbuf_part2: .equ 0x0400
83 1.1 skrll tmpdiskbuf_part2sz: .equ 0x0400
84 1.1 skrll tmpdiskbuf_part3: .equ 0x0A00
85 1.1 skrll tmpdiskbuf_part3sz: .equ 0x0600
86 1.1 skrll
87 1.1 skrll part1sz: .equ 0x1000
88 1.1 skrll
89 1.1 skrll ; get next free address
90 1.1 skrll .import _end,data
91 1.1 skrll addil L%_end-$global$,%r27;%r1
92 1.1 skrll ldo R%_end-$global$(%r1),%r1
93 1.1 skrll
94 1.1 skrll ; 32bit environment (and this code) requires stack is 64byte aligned.
95 1.1 skrll ldi 64-1,%r2
96 1.1 skrll add %r1,%r2,%r1
97 1.1 skrll andcm %r1,%r2,%r6 ; r6 = tmp disk buffer
98 1.1 skrll ldo tmpdiskbufsz+64(%r6),%sp ; tmp stack
99 1.1 skrll
100 1.1 skrll bl print,%rp
101 1.1 skrll ldo str_startup-$global$(%r27),%arg0
102 1.1 skrll
103 1.1 skrll ;
104 1.1 skrll ; read part 2 and 3 of ipl (see README.ipl)
105 1.1 skrll ;
106 1.1 skrll
107 1.1 skrll ; read disk blocks which contains ipl part 2 and part 3
108 1.1 skrll copy %r6,%arg0
109 1.1 skrll ldi 0,%arg2 ; offset = 0
110 1.1 skrll bl boot_input,%rp
111 1.1 skrll ldi tmpdiskbufsz,%arg1 ; read size
112 1.1 skrll
113 1.1 skrll ; part 2 address
114 1.1 skrll ldo top-$global$+part1sz(%r27),%r19
115 1.1 skrll
116 1.1 skrll ; copy part 2
117 1.1 skrll ldo tmpdiskbuf_part2(%r6),%r20
118 1.1 skrll addi,tr tmpdiskbuf_part2sz/4,%r0,%r2 ; loop count, skip next
119 1.1 skrll cpipl2: stws,ma %r1,4(0,%r19) ; write to dst
120 1.1 skrll addib,uv,n -1,%r2,cpipl2 ; check loop condition
121 1.1 skrll ldws,ma 4(0,%r20),%r1 ; read from src
122 1.1 skrll
123 1.1 skrll ; copy part 3
124 1.1 skrll ; (r19 already has destination address of part 3)
125 1.1 skrll ldo tmpdiskbuf_part3(%r6),%r20
126 1.1 skrll addi,tr tmpdiskbuf_part3sz/4,%r0,%r2 ; loop count, skip next
127 1.1 skrll cpipl3: stws,ma %r1,4(0,%r19) ; write to dst
128 1.1 skrll addib,uv,n -1,%r2,cpipl3 ; check loop condition
129 1.1 skrll ldws,ma 4(0,%r20),%r1 ; read from src
130 1.1 skrll
131 1.1 skrll ; flush data cache / invalidate instruction cache
132 1.1 skrll ldo top-$global$+part1sz(%r27),%r1 ; part 2 address
133 1.1 skrll ldi 16,%r20 ; 16: cache line size
134 1.1 skrll flipl: fdc 0(0,%r1) ; flush data cache line at r1
135 1.1 skrll comb,< %r1,%r19,flipl
136 1.1 skrll fic,m %r20(0,%r1) ; flush instruction cache line at r1, r1 += 16
137 1.1 skrll sync ; I/O operation is guaranteed to finish
138 1.1 skrll ; in eight instructions after sync
139 1.1 skrll ;
140 1.1 skrll ; Now, whole the IPL is loaded
141 1.1 skrll ;
142 1.1 skrll
143 1.1 skrll ; clear BSS
144 1.1 skrll .import _edata,data
145 1.1 skrll addil L%_edata-$global$,%r27;%r1
146 1.1 skrll ldo R%_edata-$global$(%r1),%r1
147 1.1 skrll clrbss: comb,< %r1,%r6,clrbss
148 1.1 skrll stws,ma %r0,4(0,%r1)
149 1.1 skrll
150 1.1 skrll ; we have read disklabel -- save it for later use
151 1.1 skrll .import labelsector,data
152 1.1 skrll addil L%labelsector-$global$,%r27;%r1
153 1.1 skrll ldo R%labelsector-$global$(%r1),%r20
154 1.1 skrll ldo tmpdiskbuf_labelsec(%r6),%r21
155 1.1 skrll addi,tr tmpdiskbuf_labelsecsz/4,%r0,%r2 ; loop count, skip next
156 1.1 skrll cplbl: stws,ma %r1,4(0,%r20) ; write to dst
157 1.1 skrll addib,uv,n -1,%r2,cplbl ; check loop condition
158 1.1 skrll ldws,ma 4(0,%r21),%r1 ; read from src
159 1.1 skrll
160 1.1 skrll ; set stack
161 1.1 skrll ; (r6 points at free space, 64byte aligned)
162 1.1 skrll ; 32bit environment (and this code) requires stack is 64byte aligned.
163 1.1 skrll ldo 64(%r6),%sp ; 64 > 48: frame marker (32) + args(up to 4)
164 1.1 skrll
165 1.1 skrll ; stack usage
166 1.1 skrll ; 12bytes arguments
167 1.1 skrll ; 32 frame marker
168 1.1 skrll
169 1.1 skrll ; parameters for main
170 1.1 skrll copy %r3,%arg0
171 1.1 skrll copy %r4,%arg2
172 1.1 skrll
173 1.1 skrll .import ipl_main,entry
174 1.1 skrll bl ipl_main,%rp
175 1.1 skrll copy %sp,%arg1
176 1.1 skrll
177 1.1 skrll ; main returned --- perform reset
178 1.1 skrll bl print,%rp
179 1.1 skrll ldo str_reset-$global$(%r27),%arg0
180 1.1 skrll ; FALLTHROUGH
181 1.1 skrll
182 1.1 skrll IOMOD_CMD: .equ 0xFFFC0000 + (4*12)
183 1.1 skrll IOMOD_CMD_STOP: .equ 0
184 1.1 skrll IOMOD_CMD_RESET: .equ 5
185 1.1 skrll
186 1.1 skrll ; void reboot(void)
187 1.1 skrll ; void halt(void)
188 1.1 skrll .export reboot,entry
189 1.1 skrll .export halt,entry
190 1.1 skrll reboot:
191 1.1 skrll addi,tr IOMOD_CMD_RESET,%r0,%r1 ; %r1 = IOMOD_CMD_RESET, skip next
192 1.1 skrll halt: ldi IOMOD_CMD_STOP,%r1
193 1.1 skrll iomcmd: ldil L%IOMOD_CMD,%r2
194 1.1 skrll ldo R%IOMOD_CMD(%r2),%r2
195 1.1 skrll stwas %r1,0(%r2)
196 1.1 skrll b,n .
197 1.1 skrll
198 1.1 skrll str_startup:
199 1.1 skrll .string "\r\n\n"
200 1.1 skrll .stringz "NetBSD/hppa FFS/LFS Primary Bootstrap\r\n\n"
201 1.1 skrll str_reset:
202 1.1 skrll .stringz "\r\nresetting..."
203 1.1 skrll .align 4
204 1.1 skrll
205 1.1 skrll ; void dispatch(unsigned interactive, unsigned top, unsigned end, int part,
206 1.1 skrll ; unsigned entry)
207 1.1 skrll .export dispatch,entry
208 1.1 skrll dispatch:
209 1.1 skrll ; flush data cache / invalidate instruction cache
210 1.1 skrll ldi 16,%r20 ; 16: cache line size
211 1.1 skrll flush: fdc 0(0,%arg1) ; flush data cache line at arg1
212 1.1 skrll comb,< %arg1,%arg2,flush
213 1.1 skrll fic,m %r20(0,%arg1) ; flush instruction cache line at arg1, arg1+=16
214 1.1 skrll sync
215 1.1 skrll copy %r0,%r1 ; I/O operation is guaranteed to finish
216 1.1 skrll copy %r0,%r3 ; in eight instructions after sync
217 1.1 skrll copy %r0,%r4
218 1.1 skrll copy %r0,%r5 ; while waiting, clear unused registers
219 1.1 skrll copy %r0,%r6 ; for future compatibility
220 1.1 skrll copy %r0,%r7
221 1.1 skrll copy %r0,%r8
222 1.1 skrll copy %r0,%r9
223 1.1 skrll copy %r0,%r10
224 1.1 skrll copy %r0,%r11
225 1.1 skrll copy %r0,%r12
226 1.1 skrll copy %r0,%r13
227 1.1 skrll copy %r0,%r14
228 1.1 skrll copy %r0,%r15
229 1.1 skrll copy %r0,%r16
230 1.1 skrll copy %r0,%r17
231 1.1 skrll copy %r0,%r18
232 1.1 skrll copy %r0,%r19
233 1.1 skrll copy %r0,%r20
234 1.1 skrll copy %r0,%r21
235 1.1 skrll copy %r0,%r22
236 1.1 skrll copy %r0,%r28 ; r23-r26: arg3-arg0, r27: dp
237 1.1 skrll copy %r0,%r29 ; r30: sp
238 1.1 skrll copy %r0,%r31
239 1.1 skrll ldw -52(%sp),%arg1 ; arg4: exec address
240 1.1 skrll ldo reboot-$global$(%r27),%rp ; reboot if returns
241 1.1 skrll bv %r0(%arg1) ; execute
242 1.1 skrll ldi BOOT_IF_VERSION,%arg1
243 1.1 skrll
244 1.1 skrll ;
245 1.1 skrll ; IODC subroutines
246 1.1 skrll ;
247 1.1 skrll PZ_MEM_CONSOLE: .equ 0x3a0
248 1.1 skrll PZ_MEM_BOOT: .equ 0x3d0
249 1.1 skrll PZ_MEM_KEYBOARD: .equ 0x400
250 1.1 skrll
251 1.1 skrll DEV_PATH: .equ 0x00
252 1.1 skrll DEV_LAYERS: .equ 0x08
253 1.1 skrll DEV_HPA: .equ 0x20 ; hard physical address space
254 1.1 skrll DEV_SPA: .equ 0x24 ; soft physical address space
255 1.1 skrll DEV_IODC_ENTRY: .equ 0x28
256 1.1 skrll DEV_CLASS: .equ 0x2c
257 1.1 skrll DEV_CL_DUPLEX: .equ 0x7 ; full-duplex console class
258 1.1 skrll
259 1.1 skrll IODC_ENTRY_IO_BOOTIN: .equ 0
260 1.1 skrll IODC_ENTRY_IO_CONSOLEIN: .equ 2
261 1.1 skrll IODC_ENTRY_IO_CONSOLEOUT: .equ 3
262 1.1 skrll
263 1.1 skrll ; call_iodc
264 1.1 skrll ; inputs:
265 1.1 skrll ; %ret0 IODC base in page zero
266 1.1 skrll ; %rp return address
267 1.1 skrll ; %r29 arg 8
268 1.1 skrll ; %r19 arg 7
269 1.1 skrll ; %r20 arg 6
270 1.1 skrll ; %r21 arg 5
271 1.1 skrll ; %r25 arg 1
272 1.1 skrll ; outputs
273 1.1 skrll ; all scratch regs undefined, unless defined by the IODC call
274 1.1 skrll call_iodc:
275 1.1 skrll ; set common arguments in registers
276 1.1 skrll addil L%retbuf-$global$,%r27;%r1
277 1.1 skrll ldo R%retbuf-$global$(%r1),%r22 ; arg4: return buffer
278 1.1 skrll ldo DEV_LAYERS(%ret0),%arg3 ; arg3: layer
279 1.1 skrll ldw DEV_SPA(%ret0),%arg2 ; arg2: spa
280 1.1 skrll ldw DEV_HPA(%ret0),%arg0 ; arg0: hpa
281 1.1 skrll ; check if narrow or wide mode
282 1.1 skrll ssm 0,%r1 ; get PSW
283 1.1 skrll bb,< %r1,4,call_iodc_64 ; if W, call in 64bit mode
284 1.1 skrll ldw DEV_IODC_ENTRY(%ret0),%r1 ; ENTRY_IO address
285 1.1 skrll
286 1.1 skrll ; narrow mode
287 1.1 skrll stw %r29,-68(%sp) ; arg8: maxsize / lang
288 1.1 skrll stw %r19,-64(%sp) ; arg7: size
289 1.1 skrll stw %r20,-60(%sp) ; arg6: buf
290 1.1 skrll stw %r21,-56(%sp) ; arg5: devaddr / unused
291 1.1 skrll bv %r0(%r1) ; call ENTRY_IO
292 1.1 skrll stw %r22,-52(%sp) ; arg4: return buffer
293 1.1 skrll
294 1.1 skrll call_iodc_64:
295 1.1 skrll .allow 2.0
296 1.1 skrll ; On PA64 convention, arg0 - arg7 are passed in registers.
297 1.1 skrll ; Parameters are placed in INCREASING order.
298 1.1 skrll ; The argument pointer points at the first stack parameter.
299 1.1 skrll ; stack usage:
300 1.1 skrll ; 64bytes allocated for register arguments arg0-arg7
301 1.1 skrll ; 8 arg8 (argument pointer points here)
302 1.1 skrll ; 16 frame marker
303 1.1 skrll std %r29,-16-8(%sp) ; arg8: maxsize / lang
304 1.1 skrll ; std %sp,-8(%sp) ; psp in frame marker
305 1.1 skrll bv %r0(%r1) ; call ENTRY_IO
306 1.1 skrll ldo -16-8(%sp),%r29 ; argument pointer
307 1.1 skrll .allow
308 1.1 skrll
309 1.1 skrll ;
310 1.1 skrll ; console output
311 1.1 skrll ;
312 1.1 skrll ; void putch(int)
313 1.1 skrll ; void print(const char *string)
314 1.1 skrll .align 4
315 1.1 skrll .export putch,entry
316 1.1 skrll .export print,entry
317 1.1 skrll putch:
318 1.1 skrll stwm %arg0,128(%sp) ; fake up a string on the stack
319 1.1 skrll stb %r0,-124(%sp) ; (see stack usage below)
320 1.1 skrll addi,tr -125,%sp,%arg0 ; string address, skip next
321 1.1 skrll print:
322 1.1 skrll .proc
323 1.1 skrll .callinfo frame=128,save_rp,no_unwind
324 1.1 skrll .entry
325 1.1 skrll ldo 128(%sp),%sp
326 1.1 skrll stw %rp,-128-20(%sp)
327 1.1 skrll
328 1.1 skrll ; stack usage:
329 1.1 skrll ; 36byte IODC buffer (assume %sp was 64byte aligned)
330 1.1 skrll ; 4 saved reg
331 1.1 skrll ; 88 arguments, frame marker
332 1.1 skrll ; 32bit: 36 (arguments) + 32 (frame marker)
333 1.1 skrll ; 64bit: 72 (arguments) + 16 (frame marker)
334 1.1 skrll prbufsiz: .equ 36
335 1.1 skrll
336 1.1 skrll ; save callee-saves
337 1.1 skrll stw %r3,-92(%sp)
338 1.1 skrll
339 1.1 skrll copy %arg0,%r3
340 1.1 skrll
341 1.1 skrll prloop:
342 1.1 skrll copy %r0,%r19
343 1.1 skrll ldi prbufsiz,%r20
344 1.1 skrll ldo -128(%sp),%r1
345 1.1 skrll
346 1.1 skrll strloop:
347 1.1 skrll ldb 0(%r3),%r2
348 1.1 skrll comb,= %r2,%r0,endstr
349 1.1 skrll stbs,ma %r2,1(0,%r1)
350 1.1 skrll ldo 1(%r19),%r19
351 1.1 skrll comb,<> %r19,%r20,strloop
352 1.1 skrll ldo 1(%r3),%r3
353 1.1 skrll
354 1.1 skrll endstr:
355 1.1 skrll comb,=,n %r19,%r0,endpr
356 1.1 skrll
357 1.1 skrll ; see IODC 3-51
358 1.1 skrll ; arg0 hpa
359 1.1 skrll ; arg1 option (ENTRY_IO_CONSOLEOUT (3))
360 1.1 skrll ; arg2 spa
361 1.1 skrll ; arg3 ID_addr (pointer to LAYER)
362 1.1 skrll ; arg4 R_addr (pointer to return buffer (64word?))
363 1.1 skrll ; arg5 unused (0)
364 1.1 skrll ; arg6 memaddr (64byte-aligned) string buffer
365 1.1 skrll ; arg7 reqsize
366 1.1 skrll ; arg8 lang (0)
367 1.1 skrll ldi PZ_MEM_CONSOLE,%ret0 ; IODC base in page zero
368 1.1 skrll copy %r0,%r29 ; arg8: lang
369 1.1 skrll ; copy %r19,%r19 ; arg7: size
370 1.1 skrll ldo -128(%sp),%r20 ; arg6: buf
371 1.1 skrll ; copy %r0,%r21 ; arg5: unused
372 1.1 skrll bl call_iodc,%rp
373 1.1 skrll ldi IODC_ENTRY_IO_CONSOLEOUT,%arg1 ; arg1: option
374 1.1 skrll b,n prloop
375 1.1 skrll
376 1.1 skrll endpr:
377 1.1 skrll ; restore callee-saves
378 1.1 skrll ldw -92(%sp),%r3
379 1.1 skrll
380 1.1 skrll ; return subroutine
381 1.1 skrll ldw -128-20(%sp),%rp
382 1.1 skrll bv %r0(%rp)
383 1.1 skrll .exit
384 1.1 skrll ldo -128(%sp),%sp
385 1.1 skrll .procend
386 1.1 skrll
387 1.1 skrll ;
388 1.1 skrll ; console input
389 1.1 skrll ;
390 1.1 skrll ; int getch(void)
391 1.1 skrll .align 4
392 1.1 skrll .export getch,entry
393 1.1 skrll getch:
394 1.1 skrll .proc
395 1.1 skrll .callinfo frame=192,save_rp,no_unwind
396 1.1 skrll .entry
397 1.1 skrll stw %rp,-20(%sp)
398 1.1 skrll ldo 192(%sp),%sp
399 1.1 skrll
400 1.1 skrll ; stack usage:
401 1.1 skrll ; 64byte IODC buffer (assume %sp was 64byte aligned)
402 1.1 skrll ; 40 unused
403 1.1 skrll ; 88 arguments, frame marker
404 1.1 skrll ; 32bit: 36 (arguments) + 32 (frame marker)
405 1.1 skrll ; 64bit: 72 (arguments) + 16 (frame marker)
406 1.1 skrll
407 1.1 skrll ; check if console is full or half duplex
408 1.1 skrll ldw PZ_MEM_CONSOLE+DEV_CLASS(%r0),%r1 ; device class
409 1.1 skrll extru %r1,31,4,%r1 ; right 4bits are valid
410 1.1 skrll ldi PZ_MEM_CONSOLE,%ret0
411 1.1 skrll comib,=,n DEV_CL_DUPLEX,%r1,getch_console ; use CONSOLE if full
412 1.1 skrll ldi PZ_MEM_KEYBOARD,%ret0 ; otherwise KEYBOARD
413 1.1 skrll getch_console:
414 1.1 skrll
415 1.1 skrll ; see IODC 3-50
416 1.1 skrll ; arg0 hpa
417 1.1 skrll ; arg1 option (ENTRY_IO_CONSOLEIN (2))
418 1.1 skrll ; arg2 spa
419 1.1 skrll ; arg3 ID_addr (pointer to LAYER)
420 1.1 skrll ; arg4 R_addr (pointer to return buffer (64word?))
421 1.1 skrll ; arg5 unused (0)
422 1.1 skrll ; arg6 memaddr (64byte-aligned, must have 64byte) data buffer
423 1.1 skrll ; arg7 reqsize
424 1.1 skrll ; arg8 lang (0)
425 1.1 skrll ; copy %rp,%rp ; IODC base in page zero
426 1.1 skrll copy %r0,%r29 ; arg8: lang
427 1.1 skrll ldi 1,%r19 ; arg7: size (1)
428 1.1 skrll ldo -192(%sp),%r20 ; arg6: buf
429 1.1 skrll ; copy %r0,%r21 ; arg5: unused
430 1.1 skrll bl call_iodc,%rp
431 1.1 skrll ldi IODC_ENTRY_IO_CONSOLEIN,%arg1 ; arg1: option
432 1.1 skrll
433 1.1 skrll ; make return value
434 1.1 skrll comb,<> %ret0,%r0,getch_ret ; return -1 on error
435 1.1 skrll ldi -1,%ret0
436 1.1 skrll ldi 1,%r19
437 1.1 skrll
438 1.1 skrll ; check if narrow or wide mode
439 1.1 skrll ssm 0,%r1 ; get PSW
440 1.1 skrll bb,< %r1,4,getch_64
441 1.1 skrll addil L%retbuf-$global$,%r27;%r1
442 1.1 skrll ldw R%retbuf-$global$(%r1),%r2 ; ret[0]
443 1.1 skrll comclr,<> %r19,%r2,%ret0 ; return 0 if no char available
444 1.1 skrll getch_retc:
445 1.1 skrll ldb -192(%sp),%ret0 ; otherwise return the char
446 1.1 skrll
447 1.1 skrll getch_ret:
448 1.1 skrll ; return subroutine
449 1.1 skrll ldw -192-20(%sp),%rp
450 1.1 skrll bv %r0(%rp)
451 1.1 skrll .exit
452 1.1 skrll ldo -192(%sp),%sp
453 1.1 skrll
454 1.1 skrll getch_64:
455 1.1 skrll .allow 2.0
456 1.1 skrll ldd R%retbuf-$global$(%r1),%r2 ; ret[0] (64bit)
457 1.1 skrll b getch_retc
458 1.1 skrll cmpclr,*<> %r19,%r2,%ret0 ; return 0 if no char available
459 1.1 skrll .allow
460 1.1 skrll .procend
461 1.1 skrll
462 1.1 skrll ;
463 1.1 skrll ; read boot device
464 1.1 skrll ;
465 1.1 skrll ; void boot_input(void *buf, unsigned len, unsigned pos)
466 1.1 skrll .align 4
467 1.1 skrll .export boot_input,entry
468 1.1 skrll boot_input:
469 1.1 skrll .proc
470 1.1 skrll .callinfo frame=128,save_rp,no_unwind
471 1.1 skrll .entry
472 1.1 skrll stw %rp,-20(%sp)
473 1.1 skrll ldo 128(%sp),%sp
474 1.1 skrll
475 1.1 skrll ; stack usage:
476 1.1 skrll ; 40byte unused (alignment)
477 1.1 skrll ; 88 arguments, frame marker
478 1.1 skrll ; 32bit: 36 (arguments) + 32 (frame marker)
479 1.1 skrll ; 64bit: 72 (arguments) + 16 (frame marker)
480 1.1 skrll
481 1.1 skrll ; see IODC 3-46
482 1.1 skrll ; arg0 hpa
483 1.1 skrll ; arg1 option (ENTRY_IO_BOOTIN (0))
484 1.1 skrll ; arg2 spa
485 1.1 skrll ; arg3 ID_addr (pointer to LAYER)
486 1.1 skrll ; arg4 R_addr (pointer to return buffer (64word?))
487 1.1 skrll ; arg5 devaddr
488 1.1 skrll ; arg6 memaddr (64byte-aligned) string buffer
489 1.1 skrll ; arg7 reqsize
490 1.1 skrll ; arg8 maxsize
491 1.1 skrll ldi PZ_MEM_BOOT,%ret0 ; IODC base in page zero
492 1.1 skrll copy %arg1,%r29 ; arg8: maxsize
493 1.1 skrll copy %arg1,%r19 ; arg7: size
494 1.1 skrll copy %arg0,%r20 ; arg6: buf
495 1.1 skrll copy %arg2,%r21 ; arg5: devaddr
496 1.1 skrll bl call_iodc,%rp
497 1.1 skrll ldi IODC_ENTRY_IO_BOOTIN,%arg1 ; arg1: option
498 1.1 skrll
499 1.1 skrll ; return subroutine
500 1.1 skrll ldw -128-20(%sp),%rp
501 1.1 skrll bv %r0(%rp)
502 1.1 skrll .exit
503 1.1 skrll ldo -128(%sp),%sp
504 1.1 skrll .procend
505 1.1 skrll
506 1.1 skrll ;
507 1.1 skrll ; utilities
508 1.1 skrll ; optimized for size
509 1.1 skrll ;
510 1.1 skrll
511 1.1 skrll ; int strcmp(const char *str1, const char *str2)
512 1.1 skrll .align 4
513 1.1 skrll .export strcmp,entry
514 1.1 skrll strcmp:
515 1.1 skrll .proc
516 1.1 skrll .callinfo frame=0,no_calls
517 1.1 skrll .entry
518 1.1 skrll ldbs,ma 1(0,%arg0),%r1
519 1.1 skrll strcmp_loop:
520 1.1 skrll comb,= %r1,%r0,strcmp_eos
521 1.1 skrll ldbs,ma 1(0,%arg1),%r19
522 1.1 skrll comb,=,n %r1,%r19,strcmp_loop
523 1.1 skrll ldbs,ma 1(0,%arg0),%r1
524 1.1 skrll strcmp_eos:
525 1.1 skrll bv %r0(%rp)
526 1.1 skrll .exit
527 1.1 skrll sub %r1,%r19,%ret0
528 1.1 skrll .procend
529 1.1 skrll
530 1.1 skrll ; void memcpy(void *dst, const void *src, unsigned len)
531 1.1 skrll .align 4
532 1.1 skrll .export memcpy,entry
533 1.1 skrll .export memmove,entry
534 1.1 skrll memcpy:
535 1.1 skrll memmove:
536 1.1 skrll .proc
537 1.1 skrll .callinfo no_unwind ; multiple exit points
538 1.1 skrll .entry
539 1.1 skrll ; copy %arg0,%ret0 ; uncomment this to conform ANSI
540 1.1 skrll comb,<<,n %arg0,%arg1,memcpy0 ; copy forward or backward?
541 1.1 skrll add %arg0,%arg2,%arg0 ; dst end address
542 1.1 skrll add,tr %arg1,%arg2,%arg1 ; src end address, skip next
543 1.1 skrll memcpy_bwd:
544 1.1 skrll stbs,mb %r1,-1(0,%arg0) ; write to dst
545 1.1 skrll addib,uv,n -1,%arg2,memcpy_bwd ; check loop condition
546 1.1 skrll ldbs,mb -1(0,%arg1),%r1 ; read from src
547 1.1 skrll bv,n %r0(%rp) ; return subroutine
548 1.1 skrll memcpy_fwd:
549 1.1 skrll stbs,ma %r1,1(0,%arg0) ; write to dst
550 1.1 skrll memcpy0:
551 1.1 skrll addib,uv,n -1,%arg2,memcpy_fwd ; check loop condition
552 1.1 skrll ldbs,ma 1(0,%arg1),%r1 ; read from src
553 1.1 skrll .exit
554 1.1 skrll bv,n %r0(%rp) ; return subroutine
555 1.1 skrll .procend
556 1.1 skrll
557 1.1 skrll ;
558 1.1 skrll ; string table
559 1.1 skrll ; placed here to save space
560 1.1 skrll ;
561 1.1 skrll .export str_seekseq, data
562 1.1 skrll .export str_startup, data
563 1.1 skrll .export str_bit_firmware, data
564 1.1 skrll .export str_crlf, data
565 1.1 skrll .export str_space, data
566 1.1 skrll .export str_rubout, data
567 1.1 skrll str_seekseq:
568 1.1 skrll .stringz "repositioning media...\r\n"
569 1.1 skrll str_bit_firmware:
570 1.1 skrll .stringz "bit firmware\r\n"
571 1.1 skrll str_rubout:
572 1.1 skrll .byte 0x08, 0x20, 0x08, 0x00 ; "\b \b"
573 1.1 skrll
574 1.1 skrll .export str_bootpart, data
575 1.1 skrll str_bootpart:
576 1.1 skrll .string "boot partition (a-p, ! to reboot) [a]:"
577 1.1 skrll str_space:
578 1.1 skrll .stringz " "
579 1.1 skrll .export str_booting_part, data
580 1.1 skrll str_booting_part:
581 1.1 skrll .string "\r\nbooting from partition _"
582 1.1 skrll str_crlf:
583 1.1 skrll .stringz "\r\n"
584 1.1 skrll .export str_warn_2GB, data
585 1.1 skrll str_warn_2GB:
586 1.1 skrll .stringz "boot partition exceeds 2GB boundary\r\n"
587 1.1 skrll .export str_warn_unused, data
588 1.1 skrll str_warn_unused:
589 1.1 skrll .stringz "unused partition\r\n"
590 1.1 skrll .export str_nolabel, data
591 1.1 skrll str_nolabel:
592 1.1 skrll .stringz "no disklabel\r\n"
593 1.1 skrll
594 1.1 skrll .export str_filesystem, data
595 1.1 skrll str_filesystem:
596 1.1 skrll .stringz "filesystem: _FS\r\n"
597 1.1 skrll .export str_nofs, data
598 1.1 skrll str_nofs:
599 1.1 skrll .stringz "no filesystem found\r\n"
600 1.1 skrll .export str_lookup, data
601 1.1 skrll .export str_loading, data
602 1.1 skrll .export str_at, data
603 1.1 skrll .export str_dddot, data
604 1.1 skrll .export str_done, data
605 1.1 skrll str_lookup:
606 1.1 skrll .stringz "looking up "
607 1.1 skrll str_loading:
608 1.1 skrll .stringz "loading "
609 1.1 skrll str_at:
610 1.1 skrll .stringz " at 0x"
611 1.1 skrll str_dddot:
612 1.1 skrll .stringz "..."
613 1.1 skrll str_done:
614 1.1 skrll .stringz "done\r\n"
615 1.1 skrll
616 1.1 skrll .export str_boot1, data
617 1.1 skrll .export str_boot2, data
618 1.1 skrll .export str_boot3, data
619 1.1 skrll str_boot1:
620 1.1 skrll .stringz "boot.hp700"
621 1.1 skrll str_boot2:
622 1.1 skrll .stringz "boot"
623 1.1 skrll str_boot3:
624 1.1 skrll .stringz "usr/mdec/boot"
625 1.1 skrll
626 1.1 skrll .export str_noboot, data
627 1.1 skrll str_noboot:
628 1.1 skrll .stringz "no secondary boot found\r\n"
629 1.1 skrll
630 1.1 skrll .export str_ukfmt, data
631 1.1 skrll str_ukfmt:
632 1.1 skrll .stringz ": unknown format -- exec from top\r\n"
633 1.1 skrll
634 1.1 skrll .bss
635 1.1 skrll .align 64
636 1.1 skrll retbuf: .block 32*8 ; *4 for narrow mode / *8 for wide mode
637 1.1 skrll
638 1.1 skrll .export diskbuf,data
639 1.1 skrll .align 64
640 1.1 skrll diskbuf:
641 1.1 skrll .block 2048
642