1/* $NetBSD: bbstart.s,v 1.15 2022/04/29 07:12:41 rin Exp $ */
2
3/*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Ignatios Souvatzis.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <machine/asm.h>
33#include "elf2bb.h"
34
35#define LVOAllocMem -0x0c6
36#define LVODoIO               -0x1c8
37#define LVOCacheClearU        -0x27c
38
39#define IOcmd       28
40#define IOerr       31
41#define IOlen       36
42#define IObuf       40
43#define IOoff       44
44
45#define Cmd_Rd      2
46
47          .text
48#if defined(_PRIMARY_BOOT) || defined(AUTOLOAD)
49Lzero:    .asciz "DOS"                            | "DOS type"
50#else
51Lzero:    .ascii    "BOOT"                        | Secondary Boot
52#endif
53          /*
54           * We put the relocator version here, for elf2bb, which replaces
55           * it with the bootblock checksum.
56           */
57Chksum:   .long RELVER_RELATIVE_BYTES_FORWARD
58Filesz:   .long 8192                              | dummy
59
60/*
61 * Entry point from Kickstart.
62 * A1 points to an IOrequest, A6 points to ExecBase, we have a stack.
63 * _must_ be at offset 12.
64 */
65ENTRY_NOPROFILE(start)
66#ifdef AUTOLOAD
67          jra       Lautoload
68#else
69          jra       Lrelocate
70#endif
71
72Lreltab:
73          .word 0                       | elf2bb puts the reloc table address here
74
75          .globl _C_LABEL(default_command)
76_C_LABEL(default_command):
77          .asciz    "netbsd -ASn2"
78          .org      (_C_LABEL(default_command)+32)
79
80#ifdef AUTOLOAD
81/*
82 * autoload
83 */
84Lautoload:
85          movl      %a6,%sp@-                     |SysBase
86          movl      %a1,%sp@-                     |IORequest
87
88          movl      #AUTOLOAD,%d0                 |Howmuch
89          movl      %d0,%a1@(IOlen)               | for the actual read...
90          movl      #0x10001,%d1                  |MEMF_CLEAR|MEMF_PUBLIC
91          jsr       %a6@(LVOAllocMem)
92          movl      %sp@+,%a1                     |IORequest
93          movl      %sp@+,%a6                     |SysBase
94          orl       %d0,%d0
95          jne       Lgotmem
96          movql     #1,%d0
97          rts
98
99Lgotmem:
100          movl      %d0,%sp@-                     |Address
101          movl      %a1@(IOoff),%sp@-             |Old offset
102          movl      %a1,%sp@-
103          movl      %a6,%sp@-
104
105/* we've set IOlen above */
106          movl      %d0,%a1@(IObuf)
107          movw      #Cmd_Rd,%a1@(IOcmd)
108          jsr       %a6@(LVODoIO)
109
110          movl      %sp@+,%a6
111          movl      %sp@+,%a1
112          movl      %sp@+,%a1@(IOoff)
113
114          tstb      %a1@(IOerr)
115          jne       Lioerr
116          addl      #Lrelocate-Lzero,%sp@
117
118          movl      %a6,%sp@-
119          jsr       %a6@(LVOCacheClearU)
120          movl      %sp@+,%a6
121          rts
122Lioerr:
123          movql     #1,%d0
124          addql     #4,%sp
125          rts
126#endif
127
128/*
129 * Relocate ourselves, at the same time clearing the relocation table
130 * (in case it overlaps with BSS).
131 *
132 * Register usage:
133 * A2: points into the reloc table, located at our end.
134 * A0: pointer to the longword to relocate.
135 * D0: word offset of longword to relocate
136 * D1: points to our start.
137 *
138 * Table has relative byte offsets, if a byte offset is zero, it is
139 * followed by an absolute word offset. If this is zero, too, table
140 * end is reached.
141 */
142
143Lrelocate:
144          lea       %pc@(Lzero),%a0
145          movl      %a0,%d1
146
147          /*
148           * Here, we cannot use
149           *        movw      %pc@(Lreltab),%a2
150           * "movw" against An is synonym for "movea.w", which carries out
151           * sign extension. This breaks things when reltab >= 0x8000.
152           */
153          movq      #0,%d0
154          movw      %pc@(Lreltab),%d0
155          movl      %d0,%a2
156
157          addl      %d1,%a2
158          jra       Loopend
159
160Loopw:
161          clrw      %a2@+
162Loopb:
163          addl      %d0,%a0
164          addl      %d1,%a0@
165Loopend:
166          movq      #0,%d0
167          movb      %a2@,%d0
168          clrb      %a2@+     | bfclr %a2@+{0:8} is still two shorts
169          tstb      %d0       | we could save one short by using casb %d0,d0,%a2@+
170          jne       Loopb
171
172          movw      %a2@,%d0
173          jne       Loopw
174
175Lendtab:
176          movl      %a6,%sp@-
177          jsr       %a6@(LVOCacheClearU)
178          movl      %sp@+,%a6
179
180/* We are relocated. Now it is safe to initialize _SysBase: */
181
182          movl      %a6,_C_LABEL(SysBase)
183
184#ifndef _PRIMARY_BOOT
185          movl      %a5,%sp@-           | Console info
186#endif
187          movl      %a1,%sp@-
188          bsr       _C_LABEL(pain)
189#ifdef _PRIMARY_BOOT
190          addql     #4,%sp
191#else
192          addql     #8,%sp
193#endif
194
195Lerr:
196          movq      #1,%d0
197          rts
198
199          .comm _C_LABEL(SysBase),4
200