diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1996-10-04 23:34:59 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1996-10-04 23:34:59 +0000 |
commit | 336aa88c94f8c10484b22ec84f1178d0dc52e8c3 (patch) | |
tree | a78db61d41a3df6c542783c4ab4fcb3e57d9ac0e /sys/arch/amiga/stand/loadbsd/loadbsd.c | |
parent | 6844facfb2d8171043e78487574361a8fd1bbd43 (diff) |
Merge of NetBSD 1.2 (961004)
Diffstat (limited to 'sys/arch/amiga/stand/loadbsd/loadbsd.c')
-rw-r--r-- | sys/arch/amiga/stand/loadbsd/loadbsd.c | 375 |
1 files changed, 282 insertions, 93 deletions
diff --git a/sys/arch/amiga/stand/loadbsd/loadbsd.c b/sys/arch/amiga/stand/loadbsd/loadbsd.c index 5669b1f0bfb..65676af4df6 100644 --- a/sys/arch/amiga/stand/loadbsd/loadbsd.c +++ b/sys/arch/amiga/stand/loadbsd/loadbsd.c @@ -1,5 +1,5 @@ -/* $OpenBSD: loadbsd.c,v 1.6 1996/08/15 13:00:37 niklas Exp $ */ -/* $NetBSD: loadbsd.c,v 1.19 1996/05/04 01:23:37 mhitch Exp $ */ +/* $OpenBSD: loadbsd.c,v 1.7 1996/10/04 23:34:58 niklas Exp $ */ +/* $NetBSD: loadbsd.c,v 1.19.4.2 1996/08/03 00:51:46 jtc Exp $ */ /* * Copyright (c) 1994 Michael L. Hitch @@ -109,11 +109,19 @@ void warnx __P((const char *, ...)); * Add -s flag for compatibility to bootblock loader. * 05/02/96 - Add a maximum startup interface version level * to allow future kernel compatibility. + * 2.14 06/26/96 is - Add first version of kludges needed to + * boot on DraCos. This can probably be done a bit more cleanly + * using TTRs, but it works for now. + * 2.15 07/28/96 is - Add first version of kludges needed to + * get FusionForty kickrom'd memory back. Hope this doesn't + * break anything else. + * * 2.13.1 OpenBSD branch: changed old -c to -C so new -c can be the * architecture-independent bootflag for user-controlled * startup configuration. + * 2.15.1 Merge of changes from 2.13 -> 2.15 */ -static const char _version[] = "$VER: LoadBSD 2.13.1 (OpenBSD 15.8.96)"; +static const char _version[] = "$VER: LoadBSD 2.15.1 (OpenBSD 04.10.96)"; /* * Kernel startup interface version @@ -125,6 +133,9 @@ static const char _version[] = "$VER: LoadBSD 2.13.1 (OpenBSD 15.8.96)"; #define KERNEL_STARTUP_VERSION 3 #define KERNEL_STARTUP_VERSION_MAX 9 +#define DRACOREVISION (*(UBYTE *)0x02000009) +#define DRACOMMUMARGIN 0x200000 + #define MAXMEMSEG 16 struct boot_memlist { u_int m_nseg; /* num_mem; */ @@ -168,7 +179,8 @@ char *program_name; char *kname; struct ExpansionBase *ExpansionBase; struct GfxBase *GfxBase; - +u_char *kp; +int ksize; int main(argc, argv) @@ -178,10 +190,9 @@ main(argc, argv) struct exec e; struct ConfigDev *cd, *kcd; u_long fmemsz, cmemsz; - int fd, boothowto, ksize, textsz, stringsz, ncd, i, mem_ix, ch; + int fd, boothowto, textsz, stringsz, ncd, i, mem_ix, ch; u_short *kvers; int *nkcd; - u_char *kp; void *fmem; char *esym; void (*start_it) __P((void *, u_long, u_long, void *, u_long, u_long, @@ -275,8 +286,8 @@ main(argc, argv) for (cd = 0, ncd = 0; cd = FindConfigDev(cd, -1, -1); ncd++) ; - get_mem_config(&fmem, &fmemsz, &cmemsz); get_cpuid(); + get_mem_config(&fmem, &fmemsz, &cmemsz); get_eclock(); get_AGA(); @@ -297,7 +308,8 @@ main(argc, argv) ksize += e.a_syms + 4 + ((stringsz + 3) & ~3); } - kp = (u_char *)malloc(ksize + ((char *)startit_end - (char *)startit) + 256); + kp = (u_char *)AllocMem(ksize + ((char *)startit_end - (char *)startit) + 256, + MEMF_FAST|MEMF_REVERSE); if (t_flag) { for (i = 0; i < memlist.m_nseg; ++i) { printf("mem segment %d: start=%08lx size=%08lx" @@ -368,8 +380,20 @@ main(argc, argv) *nkcd = ncd; kcd = (struct ConfigDev *)(nkcd + 1); - while(cd = FindConfigDev(cd, -1, -1)) - *kcd++ = *cd; + while(cd = FindConfigDev(cd, -1, -1)) { + *kcd = *cd; + if (((cpuid >> 24) == 0x7d) && + ((u_long)kcd->cd_BoardAddr < 0x1000000)) { + if (t_flag) + printf("Transformed Z2 device from %08lx ", + kcd->cd_BoardAddr); + kcd->cd_BoardAddr += 0x3000000; + + if (t_flag) + printf("to %08lx\n", kcd->cd_BoardAddr); + } + ++kcd; + } kmemlist = (struct boot_memlist *)kcd; kmemlist->m_nseg = memlist.m_nseg; @@ -382,6 +406,11 @@ main(argc, argv) * option was not specified. Copy startup code to end * of kernel image and set start_it. */ + if ((void *)kp < fmem) { + printf("Kernel at %08lx, Fastmem used at %08lx\n", + kp, fmem); + errx(20, "Can't copy downwards yet."); + } memcpy(kp + ksize + 256, (char *)startit, (char *)startit_end - (char *)startit); CacheClearU(); @@ -407,8 +436,12 @@ main(argc, argv) /* * if test option set, done */ - if (t_flag) + if (t_flag) { + if (kp) + FreeMem(kp, ksize + ((char *)startit_end + - (char *)startit) + 256); exit(0); + } /* * XXX AGA startup - may need more @@ -425,7 +458,8 @@ get_mem_config(fmem, fmemsz, cmemsz) u_long *fmemsz, *cmemsz; { struct MemHeader *mh, *nmh; - u_int segsz, seg, eseg, nmem; + u_int segsz, seg, eseg, nmem, nseg, nsegsz; + u_int tseg, tsegsz; char mempri; nmem = 0; @@ -437,70 +471,129 @@ get_mem_config(fmem, fmemsz, cmemsz) * walk thru the exec memory list */ Forbid(); - for (mh = (void *) SysBase->MemList.lh_Head; - nmh = (void *) mh->mh_Node.ln_Succ; mh = nmh, nmem++) { - memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes; - memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri; - seg = (u_int)mh->mh_Lower; - eseg = (u_int)mh->mh_Upper; - segsz = eseg - seg; - memlist.m_seg[nmem].ms_size = segsz; - memlist.m_seg[nmem].ms_start = seg; - - if (mh->mh_Attributes & MEMF_CHIP) { + for (mh = (void *) SysBase->MemList.lh_Head; + nmh = (void *) mh->mh_Node.ln_Succ; mh = nmh) { + + nseg = (u_int)mh->mh_Lower; + nsegsz = (u_int)mh->mh_Upper - nseg; + + segsz = nsegsz; + seg = (u_int)CachePreDMA((APTR)nseg, (LONG *)&segsz, 0L); + nsegsz -= segsz, nseg += segsz; + for (;segsz; + segsz = nsegsz, + seg = (u_int)CachePreDMA((APTR)nseg, (LONG *)&segsz, DMA_Continue), + nsegsz -= segsz, nseg += segsz, ++nmem) { + + if (t_flag) + printf("Translated %08x sz %08x to %08x sz %08x\n", + nseg - segsz, nsegsz + segsz, seg, segsz); + + eseg = seg + segsz; + + + if ((cpuid >> 24) == 0x7D) { + /* DraCo MMU table kludge */ + + segsz = ((segsz -1) | 0xfffff) + 1; + seg = eseg - segsz; + + /* + * Only use first SIMM to boot; we know it is VA==PA. + * Enter into table and continue. Yes, + * this is ugly. + */ + if (seg != 0x40000000) { + memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes; + memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri; + memlist.m_seg[nmem].ms_size = segsz; + memlist.m_seg[nmem].ms_start = seg; + ++nmem; + continue; + } + + memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes; + memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri; + memlist.m_seg[nmem].ms_size = DRACOMMUMARGIN; + memlist.m_seg[nmem].ms_start = seg; + + ++nmem; + seg += DRACOMMUMARGIN; + segsz -= DRACOMMUMARGIN; + } + + memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes; + memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri; + memlist.m_seg[nmem].ms_size = segsz; + memlist.m_seg[nmem].ms_start = seg; + + if ((mh->mh_Attributes & (MEMF_CHIP|MEMF_FAST)) == MEMF_CHIP) { + /* + * there should hardly be more than one entry for + * chip mem, but handle it the same nevertheless + * cmem always starts at 0, so include vector area + */ + memlist.m_seg[nmem].ms_start = seg = 0; + /* + * round to multiple of 512K + */ + segsz = (segsz + 512 * 1024 - 1) & -(512 * 1024); + memlist.m_seg[nmem].ms_size = segsz; + if (segsz > *cmemsz) + *cmemsz = segsz; + continue; + } /* - * there should hardly be more than one entry for - * chip mem, but handle it the same nevertheless - * cmem always starts at 0, so include vector area + * some heuristics.. */ - memlist.m_seg[nmem].ms_start = seg = 0; + seg &= -__LDPGSZ; + eseg = (eseg + __LDPGSZ - 1) & -__LDPGSZ; + + /* + * get the mem back stolen by incore kickstart on + * A3000 with V36 bootrom. + */ + if (eseg == 0x07f80000) + eseg = 0x08000000; + /* - * round to multiple of 512K + * or by zkick on a A2000. */ - segsz = (segsz + 512 * 1024 - 1) & -(512 * 1024); + if (seg == 0x280000 && + strcmp(mh->mh_Node.ln_Name, "zkick memory") == 0) + seg = 0x200000; + /* + * or by Fusion Forty fastrom + */ + if ((seg & ~(1024*1024-1)) == 0x11000000) { + /* + * XXX we should test the name. + * Unfortunately, the memory is just called + * "32 bit memory" which isn't very specific. + */ + seg = 0x11000000; + } + + segsz = eseg - seg; + memlist.m_seg[nmem].ms_start = seg; memlist.m_seg[nmem].ms_size = segsz; - if (segsz > *cmemsz) - *cmemsz = segsz; - continue; - } - /* - * some heuristics.. - */ - seg &= -__LDPGSZ; - eseg = (eseg + __LDPGSZ - 1) & -__LDPGSZ; - - /* - * get the mem back stolen by incore kickstart on - * A3000 with V36 bootrom. - */ - if (eseg == 0x07f80000) - eseg = 0x08000000; - - /* - * or by zkick on a A2000. - */ - if (seg == 0x280000 && - strcmp(mh->mh_Node.ln_Name, "zkick memory") == 0) - seg = 0x200000; + /* + * If this segment is smaller than 2M, + * don't use it to load the kernel + */ + if (segsz < 2 * 1024 * 1024) + continue; + /* + * if p_flag is set, select memory by priority + * instead of size + */ + if ((!p_flag && segsz > *fmemsz) || (p_flag && + mempri <= mh->mh_Node.ln_Pri && segsz > *fmemsz)) { + *fmemsz = segsz; + *fmem = (void *)seg; + mempri = mh->mh_Node.ln_Pri; + } - segsz = eseg - seg; - memlist.m_seg[nmem].ms_start = seg; - memlist.m_seg[nmem].ms_size = segsz; - /* - * If this segment is smaller than 2M, - * don't use it to load the kernel - */ - if (segsz < 2 * 1024 * 1024) - continue; - /* - * if p_flag is set, select memory by priority - * instead of size - */ - if ((!p_flag && segsz > *fmemsz) || (p_flag && - mempri <= mh->mh_Node.ln_Pri && segsz > *fmemsz)) { - *fmemsz = segsz; - *fmem = (void *)seg; - mempri = mh->mh_Node.ln_Pri; } } memlist.m_nseg = nmem; @@ -520,6 +613,9 @@ get_cpuid() cpuid |= SysBase->AttnFlags; /* get FPU and CPU flags */ if (cpuid & 0xffff0000) { + if ((cpuid & 0xff000000) == 0x7D) + return; + switch (cpuid >> 16) { case 500: case 600: @@ -543,6 +639,8 @@ get_cpuid() 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 @@ -580,7 +678,7 @@ asm(" _startit: movel sp,a3 movel 4:w,a6 - lea pc@(start_super-.+2),a5 + lea pc@(start_super),a5 jmp a6@(-0x1e) | supervisor-call start_super: @@ -598,11 +696,12 @@ start_super: | a2: Inhibit sync flags | All other registers zeroed for possible future requirements. - lea pc@(_startit-.+2),sp | make sure we have a good stack *** + lea pc@(_startit),sp | make sure we have a good stack *** + movel a3@(4),a1 | loaded kernel movel a3@(8),d2 | length of loaded kernel | movel a3@(12),sp | entry point in stack pointer - movel a3@(12),sp@- | push entry point *** + movel a3@(12),a6 | push entry point *** movel a3@(16),a0 | fastmem-start movel a3@(20),d0 | fastmem-size movel a3@(24),d1 | chipmem-size @@ -615,57 +714,132 @@ start_super: movel a3@(52),d6 | Load to fastmem flag subl a5,a5 | target, load to 0 - btst #3,(ABSEXECBASE)@(0x129) | AFB_68040,SysBase->AttnFlags + cmpb #0x7D,a3@(36) | is it DraCo? + beq nott | yes, switch off MMU later + + | no, it is an Amiga: + +| movew #0xf00,0xdff180 |red +| moveb #0,0x200003c8 +| moveb #63,0x200003c9 +| moveb #0,0x200003c9 +| moveb #0,0x200003c9 + + movew #(1<<9),0xdff096 | disable DMA on Amigas. + +| ------ mmu off start ----- + + btst #3,d5 | AFB_68040,SysBase->AttnFlags beq not040 -| Turn off 68040 MMU +| Turn off 68040/060 MMU - .word 0x4e7b,0xd003 | movec a5,tc - .word 0x4e7b,0xd806 | movec a5,urp - .word 0x4e7b,0xd807 | movec a5,srp - .word 0x4e7b,0xd004 | movec a5,itt0 - .word 0x4e7b,0xd005 | movec a5,itt1 - .word 0x4e7b,0xd006 | movec a5,dtt0 - .word 0x4e7b,0xd007 | movec a5,dtt1 + subl a3,a3 + .word 0x4e7b,0xb003 | movec a3,tc + .word 0x4e7b,0xb806 | movec a3,urp + .word 0x4e7b,0xb807 | movec a3,srp + .word 0x4e7b,0xb004 | movec a3,itt0 + .word 0x4e7b,0xb005 | movec a3,itt1 + .word 0x4e7b,0xb006 | movec a3,dtt0 + .word 0x4e7b,0xb007 | movec a3,dtt1 bra nott not040: - lea pc@(zero-.+2),a3 + lea pc@(zero),a3 pmove a3@,tc | Turn off MMU - lea pc@(nullrp-.+2),a3 + lea pc@(nullrp),a3 pmove a3@,crp | Turn off MMU some more pmove a3@,srp | Really, really, turn off MMU | Turn off 68030 TT registers - btst #2,(ABSEXECBASE)@(0x129) | AFB_68030,SysBase->AttnFlags + btst #2,d5 | AFB_68030,SysBase->AttnFlags beq nott | Skip TT registers if not 68030 - lea pc@(zero-.+2),a3 + lea pc@(zero),a3 .word 0xf013,0x0800 | pmove a3@,tt0 (gas only knows about 68851 ops..) .word 0xf013,0x0c00 | pmove a3@,tt1 (gas only knows about 68851 ops..) nott: +| ---- mmu off end ---- +| movew #0xf60,0xdff180 | orange +| moveb #0,0x200003c8 +| moveb #63,0x200003c9 +| moveb #24,0x200003c9 +| moveb #0,0x200003c9 - movew #(1<<9),0xdff096 | disable DMA +| ---- copy kernel start ---- tstl d6 | Can we load to fastmem? beq L0 | No, leave destination at 0 movl a0,a5 | Move to start of fastmem chunk - movl a0,d6 | and relocate kernel entry - addl d6,sp@ | address (on top of stack) + addl a0,a6 | relocate kernel entry point L0: movl a1@+,a5@+ subl #4,d2 bcc L0 + lea pc@(ckend:w),a1 + movl a5,sp@- + movl #_startit_end - ckend,d2 +L2: + movl a1@+,a5@+ + subl #4,d2 + bcc L2 + + btst #3,d5 + jeq L1 + .word 0xf4f8 +L1: movql #0,d2 | switch off cache to ensure we use + movec d2,cacr | valid kernel data + +| movew #0xFF0,0xdff180 | yellow +| moveb #0,0x200003c8 +| moveb #63,0x200003c9 +| moveb #0,0x200003c9 +| moveb #0,0x200003c9 + rts + +| ---- copy kernel end ---- + +ckend: +| movew #0x0ff,0xdff180 | petrol +| moveb #0,0x200003c8 +| moveb #0,0x200003c9 +| moveb #63,0x200003c9 +| moveb #63,0x200003c9 + + movl d5,d2 + roll #8,d2 + cmpb #0x7D,d2 + jne noDraCo + +| DraCo: switch off MMU now: + + subl a3,a3 + .word 0x4e7b,0xb003 | movec a3,tc + .word 0x4e7b,0xb806 | movec a3,urp + .word 0x4e7b,0xb807 | movec a3,srp + .word 0x4e7b,0xb004 | movec a3,itt0 + .word 0x4e7b,0xb005 | movec a3,itt1 + .word 0x4e7b,0xb006 | movec a3,dtt0 + .word 0x4e7b,0xb007 | movec a3,dtt1 + +noDraCo: moveq #0,d2 | zero out unused registers moveq #0,d6 | (might make future compatibility movel d6,a1 | would have known contents) movel d6,a3 movel d6,a5 + movel a6,sp | entry point into stack pointer movel d6,a6 -| jmp sp@ | jump to kernel entry point - rts | enter kernel at address on stack *** + +| movew #0x0F0,0xdff180 | green +| moveb #0,0x200003c8 +| moveb #0,0x200003c9 +| moveb #63,0x200003c9 +| moveb #0,0x200003c9 + + jmp sp@ | jump to kernel entry point | A do-nothing MMU root pointer (includes the following long as well) @@ -700,7 +874,7 @@ OPTIONS \t-b Ask for which root device. \t Its possible to have multiple roots and choose between them. \t-c Enter user-controlled startup-configuration mode. -\t-C Set machine type. [e.g 3000] +\t-C Set machine type. [e.g 3000; use 32000+N for DraCo rev. N] \t-D Enter debugger \t-h This help message. \t-I Inhibit sync negotiation. Option value is bit-encoded targets. @@ -742,15 +916,21 @@ _Vdomessage(doexit, eval, doerrno, fmt, args) } if (doerrno && errno < sys_nerr) { fprintf(stderr, "%s", strerror(errno)); +#if 0 if (errno == EINTR || errno == 0) { int sigs; sigpending((sigset_t *)&sigs); printf("%x\n", sigs); } +#endif } fprintf(stderr, "\n"); - if (doexit) + if (doexit) { + if (kp) + FreeMem(kp, ksize + ((char *)startit_end + - (char *)startit) + 256); exit(eval); + } } void @@ -788,3 +968,12 @@ warnx(const char *fmt, ...) _Vdomessage(0, 0, 0, fmt, ap); va_end(ap); } + + +u_int +sleep(u_int n) +{ + (void)TimeDelay(0L, n, 0L); +} + + |