1 /* $NetBSD: boot26.c,v 1.4 2005/12/11 12:16:05 christos Exp $ */
4 * Copyright (c) 1998, 1999, 2000, 2001 Ben Harris
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <lib/libkern/libkern.h>
31 #include <lib/libsa/stand.h>
32 #include <lib/libsa/loadfile.h>
33 #include <riscoscalls.h>
34 #include <sys/boot_flag.h>
35 #include <machine/boot.h>
36 #include <machine/memcreg.h>
38 extern const char bootprog_rev
[];
39 extern const char bootprog_name
[];
40 extern const char bootprog_date
[];
41 extern const char bootprog_maker
[];
45 enum pgstatus
{ FREE
, USED_RISCOS
, USED_KERNEL
, USED_BOOT
};
48 struct os_mem_map_request
*pginfo
;
49 enum pgstatus
*pgstatus
;
51 u_long marks
[MARK_MAX
];
55 void get_mem_map(struct os_mem_map_request
*, enum pgstatus
*, int);
58 extern void start_kernel(struct bootconfig
*, u_int
, u_int
);
61 main(int argc
, char **argv
)
66 struct bootconfig bootconfig
;
70 printf(">> %s, Revision %s\n", bootprog_name
, bootprog_rev
);
71 printf(">> (%s, %s)\n", bootprog_maker
, bootprog_date
);
73 os_read_mem_map_info(&nbpp
, &npages
);
75 printf("Machine has %d pages of %d KB each. "
76 "Total RAM: %d MB\n", npages
, nbpp
>> 10,
77 (npages
* nbpp
) >> 20);
79 /* Need one extra for teminator in OS_ReadMemMapEntries. */
80 pginfo
= alloc((npages
+ 1) * sizeof(*pginfo
));
82 panic("cannot alloc pginfo array");
83 memset(pginfo
, 0, npages
* sizeof(*pginfo
));
84 pgstatus
= alloc(npages
* sizeof(*pgstatus
));
86 panic("cannot alloc pgstatus array");
87 memset(pgstatus
, 0, npages
* sizeof(*pgstatus
));
89 get_mem_map(pginfo
, pgstatus
, npages
);
93 for (i
= 1; i
< argc
; i
++)
94 if (argv
[i
][0] == '-')
95 for (j
= 1; argv
[i
][j
]; j
++)
96 BOOT_FLAG(argv
[i
][j
], howto
);
99 panic("Too many files!");
103 if (howto
& RB_ASKNAME
) {
110 printf("Booting %s (howto = 0x%x)\n", file
, howto
);
112 ret
= loadfile(file
, marks
, LOAD_KERNEL
);
114 panic("Kernel load failed");
117 printf("Starting at 0x%lx\n", marks
[MARK_ENTRY
]);
119 memset(&bootconfig
, 0, sizeof(bootconfig
));
120 bootconfig
.magic
= BOOT_MAGIC
;
121 bootconfig
.version
= 0;
122 bootconfig
.boothowto
= howto
;
123 bootconfig
.bootdev
= -1;
124 bootconfig
.ssym
= (void *)marks
[MARK_SYM
] - MEMC_PHYS_BASE
;
125 bootconfig
.esym
= (void *)marks
[MARK_END
] - MEMC_PHYS_BASE
;
126 bootconfig
.nbpp
= nbpp
;
127 bootconfig
.npages
= npages
;
128 bootconfig
.freebase
= (void *)marks
[MARK_END
] - MEMC_PHYS_BASE
;
129 bootconfig
.xpixels
= vdu_var(os_MODEVAR_XWIND_LIMIT
) + 1;
130 bootconfig
.ypixels
= vdu_var(os_MODEVAR_YWIND_LIMIT
) + 1;
131 bootconfig
.bpp
= 1 << vdu_var(os_MODEVAR_LOG2_BPP
);
132 bootconfig
.screenbase
= (void *)vdu_var(os_VDUVAR_DISPLAY_START
) +
133 vdu_var(os_VDUVAR_TOTAL_SCREEN_SIZE
) - MEMC_PHYS_BASE
;
134 bootconfig
.screensize
= vdu_var(os_VDUVAR_TOTAL_SCREEN_SIZE
);
135 os_byte(osbyte_OUTPUT_CURSOR_POSITION
, 0, 0, NULL
, &crow
);
136 bootconfig
.cpixelrow
= crow
* vdu_var(os_VDUVAR_TCHAR_SPACEY
);
138 if (bootconfig
.bpp
< 8)
139 printf("WARNING: Current screen mode has fewer than eight "
141 " Console display may not work correctly "
143 /* Tear down RISC OS... */
145 /* NetBSD will want the cache off initially. */
146 xcache_control(0, 0, NULL
);
148 /* Dismount all filesystems. */
149 xosfscontrol_shutdown();
151 /* Ask device drivers to reset devices. */
154 /* Disable interrupts. */
157 start_kernel(&bootconfig
, marks
[MARK_ENTRY
], 0x02090000);
163 get_mem_map(struct os_mem_map_request
*pginfo
, enum pgstatus
*pgstatus
,
168 for (i
= 0; i
< npages
; i
++)
169 pginfo
[i
].page_no
= i
;
170 pginfo
[npages
].page_no
= -1;
171 os_read_mem_map_entries(pginfo
);
174 printf("--------/-------/-------/-------\n");
175 for (i
= 0; i
< npages
; i
++) {
176 pgstatus
[i
] = USED_RISCOS
;
177 if (pginfo
[i
].access
== os_AREA_ACCESS_NONE
) {
178 if (debug
) printf(".");
180 if (pginfo
[i
].map
< (void *)0x0008000) {
181 if (debug
) printf("0");
182 } else if (pginfo
[i
].map
< (void *)HIMEM
) {
183 pgstatus
[i
] = USED_BOOT
;
184 if (debug
) printf("+");
185 } else if (pginfo
[i
].map
< (void *)0x1000000) {
186 if (pginfo
[i
].access
==
187 os_AREA_ACCESS_READ_WRITE
) {
189 if (debug
) printf("*");
191 if (debug
) printf("a");
193 } else if (pginfo
[i
].map
< (void *)0x1400000) {
194 if (debug
) printf("d");
195 } else if (pginfo
[i
].map
< (void *)0x1800000) {
196 if (debug
) printf("s");
197 } else if (pginfo
[i
].map
< (void *)0x1c00000) {
198 if (debug
) printf("m");
199 } else if (pginfo
[i
].map
< (void *)0x1e00000) {
200 if (debug
) printf("h");
201 } else if (pginfo
[i
].map
< (void *)0x1f00000) {
202 if (debug
) printf("f");
203 } else if (pginfo
[i
].map
< (void *)0x2000000) {
204 if (debug
) printf("S");
207 if (i
% 32 == 31 && debug
)
213 * Return the address of a page that will end up corresponding to the
214 * target address when the kernel boots. "target" is expected to be
215 * in the MEMC physical RAM area (0x02000000--0x02ffffff). It need
216 * not be page-aligned. The return value is in the logical RAM area,
217 * and either points to a mapping of the requested page or to a
218 * mapping of another page which will be copied to the requested page
219 * after RISC OS is shut down.
221 * At present, there's no relocation mechanism, so we panic if its use
225 get_page(void *target
)
229 ppn
= ((void *)target
- MEMC_PHYS_BASE
) / nbpp
;
230 if (pgstatus
[ppn
] != FREE
)
231 panic("Page %d not free", ppn
);
232 return pginfo
[ppn
].map
;
236 boot26_read(int f
, void *addr
, size_t size
)
240 ssize_t retval
, total
;
244 fragaddr
= get_page(addr
) + ((u_int
)addr
% nbpp
);
245 fragsize
= nbpp
- ((u_int
)addr
% nbpp
);
248 retval
= read(f
, fragaddr
, fragsize
);
252 if (retval
< fragsize
)
261 boot26_memcpy(void *dst
, const void *src
, size_t size
)
268 fragaddr
= get_page(addr
) + ((u_int
)addr
% nbpp
);
269 fragsize
= nbpp
- ((u_int
)addr
% nbpp
);
272 memcpy(fragaddr
, src
, fragsize
);
281 boot26_memset(void *dst
, int c
, size_t size
)
288 fragaddr
= get_page(addr
) + ((u_int
)addr
% nbpp
);
289 fragsize
= nbpp
- ((u_int
)addr
% nbpp
);
292 memset(fragaddr
, c
, fragsize
);
302 int varlist
[2], vallist
[2];
306 os_read_vdu_variables(varlist
, vallist
);