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