1996-11-30 02:36:29 +03:00
|
|
|
/*
|
2002-01-26 16:18:57 +03:00
|
|
|
* $NetBSD: main.c,v 1.15 2002/01/26 13:18:58 aymeric Exp $
|
1996-11-30 02:36:29 +03:00
|
|
|
*
|
|
|
|
*
|
1999-11-29 01:10:47 +03:00
|
|
|
* Copyright (c) 1996,1999 Ignatios Souvatzis
|
1996-11-30 02:36:29 +03:00
|
|
|
* Copyright (c) 1994 Michael L. Hitch
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by Michael L. Hitch.
|
|
|
|
* 4. The name of the authors may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/cdefs.h>
|
|
|
|
#include <sys/reboot.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#include <sys/exec_aout.h>
|
|
|
|
|
|
|
|
#include <amiga/cfdev.h>
|
|
|
|
#include <amiga/memlist.h>
|
|
|
|
#include <include/cpu.h>
|
|
|
|
|
1997-01-21 21:26:07 +03:00
|
|
|
#include <saerrno.h>
|
|
|
|
#include <stand.h>
|
1996-11-30 02:36:29 +03:00
|
|
|
|
|
|
|
#include "libstubs.h"
|
|
|
|
#include "samachdep.h"
|
2001-12-17 08:40:40 +03:00
|
|
|
#include "loadfile.h"
|
1996-11-30 02:36:29 +03:00
|
|
|
|
1997-03-24 21:52:46 +03:00
|
|
|
#undef __LDPGSZ
|
1996-11-30 02:36:29 +03:00
|
|
|
#define __LDPGSZ 8192
|
|
|
|
#define __PGSZ 8192
|
|
|
|
|
|
|
|
#define DRACOREVISION (*(u_int8_t *)0x02000009)
|
|
|
|
#define DRACOMMUMARGIN 0x200000
|
|
|
|
#define DRACOZ2OFFSET 0x3000000
|
|
|
|
#define DRACOZ2MAX 0x1000000
|
|
|
|
|
|
|
|
#define EXECMIN 36
|
|
|
|
|
2001-12-17 08:40:40 +03:00
|
|
|
/*
|
|
|
|
* vers.c (generated by newvers.sh)
|
|
|
|
*/
|
|
|
|
extern const char bootprog_rev[];
|
|
|
|
extern const char bootprog_date[];
|
|
|
|
extern const char bootprog_maker[];
|
|
|
|
|
2002-01-26 16:18:57 +03:00
|
|
|
void startit(void *, u_long, u_long, void *, u_long, u_long, int, void *,
|
|
|
|
int, int, u_long, u_long, u_long, int);
|
|
|
|
int get_cpuid(u_int32_t *);
|
1999-11-29 01:10:47 +03:00
|
|
|
#ifdef PPCBOOTER
|
|
|
|
u_int16_t kickstart[];
|
|
|
|
size_t kicksize;
|
|
|
|
#else
|
2002-01-26 16:18:57 +03:00
|
|
|
void startit_end(void);
|
1999-11-29 01:10:47 +03:00
|
|
|
#endif
|
1996-11-30 02:36:29 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Kernel startup interface version
|
|
|
|
* 1: first version of loadbsd
|
|
|
|
* 2: needs esym location passed in a4
|
|
|
|
* 3: load kernel image into fastmem rather than chipmem
|
|
|
|
* MAX: highest version with backward compatibility.
|
2002-01-26 16:18:57 +03:00
|
|
|
*/
|
1996-11-30 02:36:29 +03:00
|
|
|
|
|
|
|
#define KERNEL_STARTUP_VERSION 3
|
|
|
|
#define KERNEL_STARTUP_VERSION_MAX 9
|
|
|
|
|
|
|
|
static long get_number(char **);
|
|
|
|
|
2001-09-25 00:27:08 +04:00
|
|
|
extern char default_command[];
|
1996-11-30 02:36:29 +03:00
|
|
|
|
|
|
|
int
|
2002-01-26 16:18:57 +03:00
|
|
|
pain(void *aio, void *cons)
|
1996-11-30 02:36:29 +03:00
|
|
|
{
|
|
|
|
char linebuf[128];
|
|
|
|
char *kernel_name = default_command;
|
|
|
|
char *path = default_command;
|
|
|
|
int boothowto = RB_AUTOBOOT;
|
|
|
|
u_int32_t cpuid = 0;
|
|
|
|
int amiga_flags = 0;
|
|
|
|
u_int32_t I_flag = 0;
|
|
|
|
int k_flag = 0;
|
|
|
|
int p_flag = 0;
|
|
|
|
int m_value = 0;
|
|
|
|
int S_flag = 0;
|
|
|
|
int t_flag = 0;
|
|
|
|
|
|
|
|
u_int32_t fmem = 0x0;
|
|
|
|
int fmemsz = 0x0;
|
|
|
|
int cmemsz = 0x0;
|
|
|
|
int eclock = SysBase->EClockFreq;
|
|
|
|
/* int skip_chipmem = 0; */
|
|
|
|
|
|
|
|
void (*start_it)(void *, u_long, u_long, void *, u_long, u_long, int,
|
1999-11-29 01:10:47 +03:00
|
|
|
void *, int, int, u_long, u_long, u_long, int);
|
1996-11-30 02:36:29 +03:00
|
|
|
|
|
|
|
caddr_t kp;
|
|
|
|
u_int16_t *kvers;
|
2001-12-17 08:40:40 +03:00
|
|
|
int ksize;
|
1996-11-30 02:36:29 +03:00
|
|
|
void *esym = 0;
|
|
|
|
int32_t *nkcd;
|
|
|
|
struct cfdev *cd, *kcd;
|
|
|
|
struct boot_memseg *kmemseg;
|
|
|
|
struct boot_memseg *memseg;
|
|
|
|
struct MemHead *mh;
|
|
|
|
u_int32_t from, size, vfrom, vsize;
|
|
|
|
int contflag, mapped1to1;
|
|
|
|
|
|
|
|
int ncd, nseg;
|
|
|
|
char c;
|
|
|
|
|
2001-12-17 08:40:40 +03:00
|
|
|
u_long marks[MARK_MAX];
|
|
|
|
|
1996-11-30 02:36:29 +03:00
|
|
|
extern u_int16_t timelimit;
|
|
|
|
|
1997-02-01 04:46:26 +03:00
|
|
|
extern u_int32_t aio_base;
|
|
|
|
|
1998-11-14 01:12:35 +03:00
|
|
|
xdinit(aio);
|
|
|
|
|
2001-12-17 08:40:40 +03:00
|
|
|
if (consinit(cons))
|
1998-11-14 01:12:35 +03:00
|
|
|
return(1);
|
|
|
|
|
1996-11-30 02:36:29 +03:00
|
|
|
/*
|
|
|
|
* we need V36 for: EClock, RDB Bootblocks, CacheClearU
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (SysBase->LibNode.Version < EXECMIN) {
|
|
|
|
printf("Exec V%ld, need V%ld\n",
|
|
|
|
(long)SysBase->LibNode.Version, (long)EXECMIN);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2001-12-17 08:40:40 +03:00
|
|
|
/*
|
|
|
|
* XXX Do this differently; default boot will attempt to load a list of
|
|
|
|
* XXX kernels until one of them succeeds.
|
|
|
|
*/
|
|
|
|
timelimit = 3;
|
|
|
|
again:
|
1999-11-29 01:10:47 +03:00
|
|
|
#ifdef PPCBOOTER
|
2001-12-17 08:40:40 +03:00
|
|
|
printf("\nNetBSD/AmigaPPC " NETBSD_VERS " Bootstrap, Revision %s\n",
|
|
|
|
bootprog_rev);
|
1999-11-29 01:10:47 +03:00
|
|
|
#else
|
2001-12-17 08:40:40 +03:00
|
|
|
printf("\nNetBSD/Amiga " NETBSD_VERS " Bootstrap, Revision %s\n",
|
|
|
|
bootprog_rev);
|
1999-11-29 01:10:47 +03:00
|
|
|
#endif
|
2001-12-17 08:40:40 +03:00
|
|
|
printf("(%s, %s)\n", bootprog_maker, bootprog_date);
|
|
|
|
printf("\n");
|
|
|
|
printf("Boot: [%s] ", kernel_name);
|
1996-11-30 02:36:29 +03:00
|
|
|
|
|
|
|
gets(linebuf);
|
|
|
|
|
|
|
|
if (*linebuf == 'q')
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (*linebuf)
|
|
|
|
path = linebuf;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* parse boot command for path name and process any options
|
|
|
|
*/
|
|
|
|
while ((c = *path)) {
|
|
|
|
while (c == ' ')
|
|
|
|
c = *++path;
|
|
|
|
if (c == '-') {
|
|
|
|
while ((c = *++path) && c != ' ') {
|
|
|
|
switch (c) {
|
|
|
|
case 'a': /* multi-user state */
|
|
|
|
boothowto &= ~RB_SINGLE;
|
|
|
|
break;
|
|
|
|
case 'b': /* ask for root device */
|
|
|
|
boothowto |= RB_ASKNAME;
|
|
|
|
break;
|
|
|
|
case 'c': /* force machine model */
|
|
|
|
cpuid = get_number(&path) << 16;
|
|
|
|
break;
|
|
|
|
case 'k': /* Reserve first 4M fastmem */
|
|
|
|
k_flag++;
|
|
|
|
break;
|
|
|
|
case 'm': /* Force fastmem size */
|
|
|
|
m_value = get_number(&path) * 1024;
|
|
|
|
break;
|
|
|
|
case 'n': /* non-contiguous memory */
|
2002-01-26 16:18:57 +03:00
|
|
|
amiga_flags |=
|
1996-11-30 02:36:29 +03:00
|
|
|
(get_number(&path) & 3) << 1;
|
|
|
|
break;
|
|
|
|
case 'p': /* Select fastmem by priority */
|
|
|
|
p_flag++;
|
|
|
|
break;
|
2000-09-25 00:56:04 +04:00
|
|
|
case 'q':
|
|
|
|
boothowto |= AB_QUIET;
|
|
|
|
break;
|
1996-11-30 02:36:29 +03:00
|
|
|
case 's': /* single-user state */
|
|
|
|
boothowto |= RB_SINGLE;
|
|
|
|
break;
|
|
|
|
case 't': /* test flag */
|
|
|
|
t_flag = 1;
|
|
|
|
break;
|
2000-09-25 00:56:04 +04:00
|
|
|
case 'v':
|
|
|
|
boothowto |= AB_VERBOSE;
|
|
|
|
break;
|
1996-11-30 02:36:29 +03:00
|
|
|
case 'A': /* enable AGA modes */
|
|
|
|
amiga_flags |= 1;
|
|
|
|
break;
|
|
|
|
case 'D': /* enter Debugger */
|
|
|
|
boothowto |= RB_KDB;
|
|
|
|
break;
|
|
|
|
case 'I': /* inhibit sync negotiation */
|
|
|
|
I_flag = get_number(&path);
|
|
|
|
break;
|
|
|
|
case 'K': /* remove 1st 4MB fastmem */
|
|
|
|
break;
|
|
|
|
case 'S': /* include debug symbols */
|
|
|
|
S_flag = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2001-12-17 08:40:40 +03:00
|
|
|
/* XXX Handle kernel_name differently */
|
1996-11-30 02:36:29 +03:00
|
|
|
kernel_name = path;
|
|
|
|
while ((c = *++path) && c != ' ')
|
|
|
|
;
|
|
|
|
if (c)
|
|
|
|
*path++ = 0;
|
|
|
|
}
|
|
|
|
}
|
2001-12-17 08:40:40 +03:00
|
|
|
/* XXX Handle kernel_name differently */
|
1996-11-30 02:36:29 +03:00
|
|
|
while ((c = *kernel_name) && c == ' ')
|
|
|
|
++kernel_name;
|
|
|
|
path = kernel_name;
|
|
|
|
while ((c = *path) && c != ' ')
|
|
|
|
++path;
|
|
|
|
if (c)
|
|
|
|
*path = 0;
|
|
|
|
|
|
|
|
if (get_cpuid(&cpuid))
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
ExpansionBase = OpenLibrary("expansion.library", 0);
|
|
|
|
if (!ExpansionBase) {
|
|
|
|
printf("can't open %s\n", "expansion.library");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (ncd=0, cd=0; (cd = FindConfigDev(cd, -1, -1)); ncd++)
|
|
|
|
/* nothing */;
|
|
|
|
|
|
|
|
/* find memory list */
|
|
|
|
|
|
|
|
memseg = (struct boot_memseg *)alloc(16*sizeof(struct boot_memseg));
|
|
|
|
|
|
|
|
/* Forbid(); */
|
|
|
|
|
|
|
|
nseg = 0;
|
|
|
|
mh = SysBase->MemLst;
|
|
|
|
vfrom = mh->Lower & -__PGSZ;
|
2002-01-26 16:18:57 +03:00
|
|
|
vsize = (mh->Upper & -__PGSZ) - vfrom;
|
1996-11-30 02:36:29 +03:00
|
|
|
contflag = mapped1to1 = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
size = vsize;
|
|
|
|
|
|
|
|
if (SysBase->LibNode.Version > 36) {
|
|
|
|
from = CachePreDMA(vfrom, &size, contflag);
|
|
|
|
contflag = DMAF_Continue;
|
|
|
|
mapped1to1 = (from == vfrom);
|
|
|
|
vsize -= size;
|
|
|
|
vfrom += size;
|
|
|
|
} else {
|
|
|
|
from = vfrom;
|
1997-03-24 22:51:28 +03:00
|
|
|
mapped1to1 = 1;
|
1996-11-30 02:36:29 +03:00
|
|
|
vsize = 0;
|
|
|
|
}
|
|
|
|
|
1997-03-24 21:56:26 +03:00
|
|
|
#ifdef DEBUG_MEMORY_LIST
|
1996-11-30 02:36:29 +03:00
|
|
|
printf("%lx %lx %lx %ld/%lx %lx\n",
|
2002-01-26 16:18:57 +03:00
|
|
|
(long)from, (long)size,
|
1996-11-30 02:36:29 +03:00
|
|
|
(long)mh->Attribs, (long)mh->Pri,
|
|
|
|
(long)vfrom, (long)vsize);
|
|
|
|
#endif
|
|
|
|
/* Insert The Evergrowing Kludge List Here: */
|
|
|
|
|
|
|
|
/* a) dont load kernel over DraCo MMU table */
|
|
|
|
|
|
|
|
if (((cpuid >> 24) == 0x7D) &&
|
2002-01-26 16:18:57 +03:00
|
|
|
((from & -DRACOMMUMARGIN) == 0x40000000) &&
|
1996-11-30 02:36:29 +03:00
|
|
|
(size >= DRACOMMUMARGIN)) {
|
|
|
|
|
|
|
|
memseg[nseg].ms_start = from & -DRACOMMUMARGIN;
|
|
|
|
memseg[nseg].ms_size = DRACOMMUMARGIN;
|
|
|
|
memseg[nseg].ms_attrib = mh->Attribs;
|
|
|
|
memseg[nseg].ms_pri = mh->Pri;
|
|
|
|
|
|
|
|
size -= DRACOMMUMARGIN - (from & (DRACOMMUMARGIN - 1));
|
|
|
|
from += DRACOMMUMARGIN - (from & (DRACOMMUMARGIN - 1));
|
|
|
|
++nseg;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((mh->Attribs & (MEMF_CHIP|MEMF_FAST)) == MEMF_CHIP) {
|
|
|
|
size += from;
|
|
|
|
cmemsz = size;;
|
|
|
|
from = 0;
|
|
|
|
} else if ((fmemsz < size) && mapped1to1) {
|
|
|
|
fmem = from;
|
|
|
|
fmemsz = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
memseg[nseg].ms_start = from;
|
|
|
|
memseg[nseg].ms_size = size;
|
|
|
|
memseg[nseg].ms_attrib = mh->Attribs;
|
|
|
|
memseg[nseg].ms_pri = mh->Pri;
|
|
|
|
|
|
|
|
if (vsize == 0) {
|
|
|
|
mh = mh->next;
|
|
|
|
contflag = 0;
|
|
|
|
if (mh->next) {
|
|
|
|
vfrom = mh->Lower & -__PGSZ;
|
2002-01-26 16:18:57 +03:00
|
|
|
vsize = (mh->Upper & -__PGSZ) - vfrom;
|
1996-11-30 02:36:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} while ((++nseg <= 16) && vsize);
|
|
|
|
|
|
|
|
/* Permit(); */
|
|
|
|
|
1998-05-09 03:03:49 +04:00
|
|
|
if (k_flag) {
|
|
|
|
fmem += 4*1024*1024;
|
|
|
|
fmemsz -= 4*1024*1024;
|
|
|
|
}
|
|
|
|
if (m_value && m_value < fmemsz)
|
|
|
|
fmemsz = m_value;
|
|
|
|
|
2001-12-17 08:40:40 +03:00
|
|
|
/* XXX Loop through list of kernels */
|
1996-11-30 02:36:29 +03:00
|
|
|
printf("Loading %s: ", kernel_name);
|
2001-12-17 08:40:40 +03:00
|
|
|
/*
|
|
|
|
* XXX Call loadfile with COUNT* options to get size
|
|
|
|
* XXX Allocate memory for kernel + additional data
|
|
|
|
* XXX Call loadfile with LOAD* options to load text/data/symbols
|
|
|
|
*/
|
|
|
|
marks[MARK_START] = 0;
|
|
|
|
if (loadfile(kernel_name, marks,
|
|
|
|
COUNT_TEXT|COUNT_TEXTA|COUNT_DATA|COUNT_BSS |
|
|
|
|
(S_flag ? (COUNT_SYM|COUNT_HDR) : 0)) == -1) {
|
1996-11-30 02:36:29 +03:00
|
|
|
goto err;
|
|
|
|
}
|
2001-12-17 08:40:40 +03:00
|
|
|
ksize = ((marks[MARK_END] + 3) & ~3)
|
1996-11-30 02:36:29 +03:00
|
|
|
+ sizeof(*nkcd) + ncd*sizeof(*cd)
|
|
|
|
+ sizeof(*nkcd) + nseg * sizeof(struct boot_memseg);
|
2001-12-17 08:40:40 +03:00
|
|
|
|
1999-11-29 01:10:47 +03:00
|
|
|
#ifdef PPCBOOTER
|
|
|
|
kp = alloc(ksize);
|
|
|
|
#else
|
1996-11-30 02:36:29 +03:00
|
|
|
kp = alloc(ksize + 256 + ((u_char *)startit_end - (u_char *)startit));
|
1999-11-29 01:10:47 +03:00
|
|
|
#endif
|
1996-11-30 02:36:29 +03:00
|
|
|
if (kp == 0) {
|
|
|
|
errno = ENOMEM;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2001-12-17 08:40:40 +03:00
|
|
|
marks[MARK_START] = (u_long)kp;
|
|
|
|
if (loadfile(kernel_name, marks,
|
|
|
|
LOAD_TEXT|LOAD_TEXTA|LOAD_DATA|LOAD_BSS|
|
|
|
|
(S_flag ? (LOAD_SYM|LOAD_HDR) : 0)) == -1) {
|
|
|
|
printf("Kernel load failed\n");
|
1996-11-30 02:36:29 +03:00
|
|
|
goto err;
|
2001-12-17 08:40:40 +03:00
|
|
|
}
|
|
|
|
marks[MARK_END] = (marks[MARK_END] + 3) & ~3;
|
|
|
|
nkcd = (int *)marks[MARK_END];
|
|
|
|
if (S_flag)
|
|
|
|
esym = (void*)(marks[MARK_END] - marks[MARK_START]);
|
|
|
|
/* #ifndef PPCBOOTER*/
|
|
|
|
kvers = (u_short *)(marks[MARK_ENTRY] - 2);
|
1996-11-30 02:36:29 +03:00
|
|
|
|
|
|
|
if (*kvers > KERNEL_STARTUP_VERSION_MAX && *kvers != 0x4e73) {
|
|
|
|
printf("\nnewer bootblock required: %ld\n", (long)*kvers);
|
|
|
|
goto freeall;
|
|
|
|
}
|
1998-05-08 23:08:18 +04:00
|
|
|
if (*kvers < KERNEL_STARTUP_VERSION || *kvers == 0x4e73) {
|
|
|
|
printf("\nkernel too old for bootblock\n");
|
|
|
|
goto freeall;
|
|
|
|
}
|
1996-11-30 02:36:29 +03:00
|
|
|
#if 0
|
|
|
|
if (*kvers > KERNEL_STARTUP_VERSION)
|
|
|
|
printf("\nKernel V%ld newer than bootblock V%ld\n",
|
|
|
|
(long)*kvers, (long)KERNEL_STARTUP_VERSION);
|
|
|
|
#endif
|
2001-12-17 08:40:40 +03:00
|
|
|
if (marks[MARK_NSYM] && (*kvers == 0x4e73 || *kvers <= 1)) {
|
|
|
|
nkcd = (int *)marks[MARK_SYM];
|
|
|
|
esym = 0;
|
|
|
|
printf("Supressing %ld kernel symbols\n", marks[MARK_NSYM]);
|
|
|
|
timelimit = 60;
|
|
|
|
(void)getchar();
|
|
|
|
}
|
|
|
|
/* version checks */
|
1996-11-30 02:36:29 +03:00
|
|
|
putchar('\n');
|
|
|
|
|
|
|
|
*nkcd = ncd;
|
|
|
|
kcd = (struct cfdev *)(nkcd + 1);
|
|
|
|
|
|
|
|
while ((cd = FindConfigDev(cd, -1, -1))) {
|
|
|
|
*kcd = *cd;
|
1999-11-29 01:10:47 +03:00
|
|
|
#ifndef PPCBOOTER
|
1996-11-30 02:36:29 +03:00
|
|
|
if (((cpuid >> 24) == 0x7D) &&
|
|
|
|
((u_long)kcd->addr < 0x1000000)) {
|
|
|
|
kcd->addr += 0x3000000;
|
|
|
|
}
|
1999-11-29 01:10:47 +03:00
|
|
|
#endif
|
1996-11-30 02:36:29 +03:00
|
|
|
++kcd;
|
|
|
|
}
|
|
|
|
|
|
|
|
nkcd = (u_int32_t *)kcd;
|
|
|
|
*nkcd = nseg;
|
|
|
|
|
|
|
|
kmemseg = (struct boot_memseg *)(nkcd + 1);
|
|
|
|
|
|
|
|
while (nseg-- > 0)
|
|
|
|
*kmemseg++ = *memseg++;
|
|
|
|
|
1999-11-29 01:10:47 +03:00
|
|
|
#ifdef PPCBOOTER
|
|
|
|
/*
|
|
|
|
* we use the ppc starter...
|
|
|
|
*/
|
|
|
|
start_it = startit;
|
|
|
|
#else
|
1998-05-08 23:08:18 +04:00
|
|
|
/*
|
1998-05-09 03:03:49 +04:00
|
|
|
* Copy startup code to end of kernel image and set start_it.
|
1998-05-08 23:08:18 +04:00
|
|
|
*/
|
|
|
|
memcpy(kp + ksize + 256, (char *)startit,
|
|
|
|
(char *)startit_end - (char *)startit);
|
|
|
|
CacheClearU();
|
|
|
|
(caddr_t)start_it = kp + ksize + 256;
|
1999-11-29 01:10:47 +03:00
|
|
|
#endif
|
1998-05-08 23:08:18 +04:00
|
|
|
printf("*** Loading from %08lx to Fastmem %08lx ***\n",
|
|
|
|
(u_long)kp, (u_long)fmem);
|
|
|
|
/* sleep(2); */
|
1996-11-30 02:36:29 +03:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
printf("would start(kp=0x%lx, ksize=%ld, entry=0x%lx,\n"
|
|
|
|
"fmem=0x%lx, fmemsz=%ld, cmemsz=%ld\n"
|
|
|
|
"boothow=0x%lx, esym=0x%lx, cpuid=0x%lx, eclock=%ld\n"
|
1998-05-08 23:08:18 +04:00
|
|
|
"amigaflags=0x%lx, I_flags=0x%lx, ok?\n",
|
2001-12-17 08:40:40 +03:00
|
|
|
(u_long)kp, (u_long)ksize, marks[MARK_ENTRY] - marks[MARK_START],
|
1996-11-30 02:36:29 +03:00
|
|
|
(u_long)fmem, (u_long)fmemsz, (u_long)cmemsz,
|
|
|
|
(u_long)boothowto, (u_long)esym, (u_long)cpuid, (u_long)eclock,
|
1998-05-08 23:08:18 +04:00
|
|
|
(u_long)amiga_flags, (u_long)I_flag);
|
2001-12-17 08:40:40 +03:00
|
|
|
timelimit = 60;
|
|
|
|
(void)getchar();
|
1996-11-30 02:36:29 +03:00
|
|
|
#endif
|
1997-03-24 21:56:26 +03:00
|
|
|
#ifdef DEBUG_MEMORY_LIST
|
|
|
|
timelimit = 0;
|
|
|
|
#else
|
1996-11-30 02:36:29 +03:00
|
|
|
timelimit = 2;
|
1997-03-24 21:56:26 +03:00
|
|
|
#endif
|
1996-11-30 02:36:29 +03:00
|
|
|
(void)getchar();
|
|
|
|
|
1999-11-29 01:10:47 +03:00
|
|
|
#ifdef PPCBOOTER
|
|
|
|
startit
|
|
|
|
#else
|
|
|
|
start_it
|
|
|
|
#endif
|
2001-12-17 08:40:40 +03:00
|
|
|
(kp, ksize, marks[MARK_ENTRY] - marks[MARK_START], (void *)fmem, fmemsz, cmemsz,
|
1997-02-01 04:46:26 +03:00
|
|
|
boothowto, esym, cpuid, eclock, amiga_flags, I_flag,
|
1998-05-08 23:08:18 +04:00
|
|
|
aio_base >> 9, 1);
|
1996-11-30 02:36:29 +03:00
|
|
|
/*NOTREACHED*/
|
|
|
|
|
|
|
|
freeall:
|
|
|
|
free(kp, ksize);
|
|
|
|
err:
|
|
|
|
printf("\nError %ld\n", (long)errno);
|
2001-12-17 08:40:40 +03:00
|
|
|
goto again;
|
1996-11-30 02:36:29 +03:00
|
|
|
out:
|
|
|
|
timelimit = 10;
|
|
|
|
(void)getchar();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
2002-01-26 16:18:57 +03:00
|
|
|
long get_number(char **ptr)
|
1996-11-30 02:36:29 +03:00
|
|
|
{
|
|
|
|
long value = 0;
|
|
|
|
int base = 10;
|
|
|
|
char *p = *ptr;
|
|
|
|
char c;
|
|
|
|
char sign = 0;
|
|
|
|
|
|
|
|
c = *++p;
|
|
|
|
while (c == ' ')
|
|
|
|
c = *++p;
|
|
|
|
if (c == '-') {
|
|
|
|
sign = -1;
|
|
|
|
c = *++p;
|
|
|
|
}
|
|
|
|
if (c == '$') {
|
|
|
|
base = 16;
|
|
|
|
c = *++p;
|
|
|
|
} else if (c == '0') {
|
|
|
|
c = *++p;
|
|
|
|
if ((c & 0xdf) == 'X') {
|
|
|
|
base = 16;
|
|
|
|
c = *++p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (c) {
|
|
|
|
if (c >= '0' && c <= '9')
|
|
|
|
c -= '0';
|
|
|
|
else {
|
|
|
|
c = (c & 0xdf) - 'A' + 10;
|
|
|
|
if (base != 16 || c < 10 || c > 15)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
value = value * base + c;
|
|
|
|
c = *++p;
|
|
|
|
}
|
|
|
|
*ptr = p - 1;
|
|
|
|
#ifdef TEST
|
2002-01-26 16:18:57 +03:00
|
|
|
fprintf(stderr, "get_number: got %c0x%x",
|
1996-11-30 02:36:29 +03:00
|
|
|
sign ? '-' : '+', value);
|
|
|
|
#endif
|
|
|
|
return (sign ? -value : value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Try to determine the machine ID by searching the resident module list
|
|
|
|
* for modules only present on specific machines. (Thanks, Bill!)
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
2002-01-26 16:18:57 +03:00
|
|
|
get_cpuid(u_int32_t *cpuid)
|
1996-11-30 02:36:29 +03:00
|
|
|
{
|
|
|
|
*cpuid |= SysBase->AttnFlags; /* get FPU and CPU flags */
|
|
|
|
if (*cpuid & 0xffff0000) {
|
|
|
|
if ((*cpuid >> 24) == 0x7D)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch (*cpuid >> 16) {
|
|
|
|
case 500:
|
|
|
|
case 600:
|
|
|
|
case 1000:
|
|
|
|
case 1200:
|
|
|
|
case 2000:
|
|
|
|
case 3000:
|
|
|
|
case 4000:
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
printf("Amiga %ld ???\n",
|
|
|
|
(long)(*cpuid >> 16));
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (FindResident("A4000 Bonus") || FindResident("A4000 bonus")
|
|
|
|
|| FindResident("A1000 Bonus"))
|
|
|
|
*cpuid |= 4000 << 16;
|
|
|
|
else if (FindResident("A3000 Bonus") || FindResident("A3000 bonus")
|
|
|
|
|| (SysBase->LibNode.Version == 36))
|
|
|
|
*cpuid |= 3000 << 16;
|
|
|
|
else if (OpenResource("card.resource")) {
|
|
|
|
/* Test for AGA? */
|
|
|
|
*cpuid |= 1200 << 16;
|
|
|
|
} else if (OpenResource("draco.resource")) {
|
|
|
|
*cpuid |= (32000 | DRACOREVISION) << 16;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Nothing found, it's probably an A2000 or A500
|
|
|
|
*/
|
|
|
|
if ((*cpuid >> 16) == 0)
|
|
|
|
*cpuid |= 2000 << 16;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|