From 99909f0e2a5b6440c3e78d08ec994e197ee7d52f Mon Sep 17 00:00:00 2001 From: jmcmullan Date: Mon, 10 Oct 2011 18:47:03 +0000 Subject: [PATCH] arch/m68k-amiga: Perform multiple passes over KickMemPtr This should fix up the last remaining issues with AROSBootstrap. I hope. Signed-off-by: Jason S. McMullan git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@41815 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- arch/m68k-amiga/boot/start.c | 99 ++++++++++++++++++++++++++++++++++----- arch/m68k-amiga/c/AROSBootstrap.c | 15 ++---- 2 files changed, 91 insertions(+), 23 deletions(-) diff --git a/arch/m68k-amiga/boot/start.c b/arch/m68k-amiga/boot/start.c index b1156017e0..05e6218439 100644 --- a/arch/m68k-amiga/boot/start.c +++ b/arch/m68k-amiga/boot/start.c @@ -34,6 +34,8 @@ extern const struct Resident Exec_resident; extern void __clear_bss(const struct KernelBSS *bss); +static void protectKick(struct MemHeader *mh, struct MemList *ml); + extern void __attribute__((interrupt)) Exec_Supervisor_Trap (void); #define _AS_STRING(x) #x @@ -187,13 +189,11 @@ static void protectROM(struct MemHeader *mh) DEBUGPUTHEX(("Protect", (IPTR)mh)); protectAlloc(mh, &_ss, &_ss_end, "SS", FALSE); protectAlloc(mh, &_bss, &_bss_end, "BSS", FALSE); - protectAlloc(mh, &_rom_start, &_rom_end, "ROM", TRUE); - protectAlloc(mh, &_ext_start, &_ext_end, "EXT", TRUE); DEBUGPUTHEX(("First ", (IPTR)mh->mh_First)); DEBUGPUTHEX(("Bytes ", (IPTR)mh->mh_First->mc_Bytes)); } -static struct MemHeader *addmemoryregion(ULONG startaddr, ULONG size) +static struct MemHeader *addmemoryregion(ULONG startaddr, ULONG size, struct MemList *ml) { if (size < 65536) return NULL; @@ -208,6 +208,9 @@ static struct MemHeader *addmemoryregion(ULONG startaddr, ULONG size) MEMF_FAST | MEMF_KICK | MEMF_PUBLIC | MEMF_LOCAL | (startaddr < 0x01000000 ? MEMF_24BITDMA : 0)); } + /* Must be done first, in case BSS and SS are in it */ + protectKick((struct MemHeader*)startaddr, ml); + protectROM((struct MemHeader*)startaddr); return (struct MemHeader*)startaddr; } @@ -221,18 +224,88 @@ static BOOL IsSysBaseValidNoVersion(struct ExecBase *sysbase) return GetSysBaseChkSum(sysbase) == 0xffff; } +/* In the following functions, we use bit 0 of the + * MemEntry->me_Addr to indicate whether or not + * that MemEntry in the MemList has been 'locked down' + * + * (addr & 1) = unallocated + * !(addr & 1) = allocated + */ + +/* Remove all bit 0 marks + */ +/* We support up to 32 KickMemPtr tags in pre-expansion.library RAM */ +static ULONG protectKickBits; + +static void markKick(struct MemList *ml) +{ + int ndx; + for (ndx = 0; ml ; ml = (struct MemList*)ml->ml_Node.ln_Succ) { + int i; + for (i = 0; i < ml->ml_NumEntries; i++, ndx++) { + if (ndx < 32) + protectKickBits |= (1 << ndx); + } + } +} + +static void protectKick(struct MemHeader *mh, struct MemList *ml) +{ + int ndx = 0; + + DEBUGPUTHEX(("protectKick", (IPTR)ml)); + + if (!mh) + return; + + while (ml) { + int i; + DEBUGPUTHEX(("NumEntries", ml->ml_NumEntries)); + for (i = 0; i < ml->ml_NumEntries; i++, ndx++) { + APTR start = (APTR)((IPTR)ml->ml_ME[i].me_Addr & ~1); + APTR end = start + ml->ml_ME[i].me_Length; + + /* Already allocated? */ + if (ndx >= 32 || !(protectKickBits & (1 << ndx))) + continue; + + if ((mh->mh_Lower > start) || + (mh->mh_Upper < end)) + continue; + + if (protectAlloc(mh, start, end, ml->ml_Node.ln_Name, FALSE)) { + protectKickBits &= ~(1 << ndx); + } + } + ml = (struct MemList*)ml->ml_Node.ln_Succ; + } + + return; +} + static BOOL InitKickMem(struct ExecBase *SysBase) { + int ndx = 0; struct MemList *ml = SysBase->KickMemPtr; + DEBUGPUTHEX(("KickMemPtr", (IPTR)ml)); + while (ml) { int i; DEBUGPUTHEX(("NumEntries", ml->ml_NumEntries)); - for (i = 0; i < ml->ml_NumEntries; i++) { - DEBUGPUTHEX((" Addr", (IPTR)ml->ml_ME[i].me_Addr)); - DEBUGPUTHEX((" Len", ml->ml_ME[i].me_Length)); + for (i = 0; i < ml->ml_NumEntries; i++,ndx++) { + APTR start = ml->ml_ME[i].me_Addr; + ULONG len = ml->ml_ME[i].me_Length; + + /* Already allocated? */ + if (ndx < 32 && !(protectKickBits & (1 << ndx))) + continue; + + DEBUGPUTHEX((" Addr", (IPTR)start)); + DEBUGPUTHEX((" Len", len)); + /* Use the non-mungwalling AllocAbs */ - if (!InternalAllocAbs(ml->ml_ME[i].me_Addr, ml->ml_ME[i].me_Length, SysBase)) + if (!InternalAllocAbs(start, len, SysBase)) return FALSE; } ml = (struct MemList*)ml->ml_Node.ln_Succ; @@ -543,14 +616,18 @@ void exec_boot(ULONG *membanks, ULONG *cpupcr) Early_ScreenCode(CODE_RAM_CHECK); - mh = addmemoryregion(membanks[0], membanks[1]); + /* Clear the BSS. */ + __clear_bss(&kbss[0]); + + /* Mark all the kick memory as 'unprotected' */ + markKick(KickMemPtr); + + mh = addmemoryregion(membanks[0], membanks[1], KickMemPtr); if (mh == NULL) { DEBUGPUTS(("Can't create initial memory header!\n")); Early_Alert(AT_DeadEnd | AG_NoMemory); } - /* Clear the BSS. */ - __clear_bss(&kbss[0]); BootMsg = bootmsgptr; /* @@ -625,7 +702,7 @@ void exec_boot(ULONG *membanks, ULONG *cpupcr) DEBUGPUTHEX(("RAM Addr: ", addr)); DEBUGPUTHEX(("RAM Size: ", size)); - mh = addmemoryregion(addr, size); + mh = addmemoryregion(addr, size, KickMemPtr); Enqueue(&SysBase->MemList, &mh->mh_Node); /* Adjust MaxLocMem and MaxExtMem as needed */ diff --git a/arch/m68k-amiga/c/AROSBootstrap.c b/arch/m68k-amiga/c/AROSBootstrap.c index 04ae0754dd..498f513efb 100644 --- a/arch/m68k-amiga/c/AROSBootstrap.c +++ b/arch/m68k-amiga/c/AROSBootstrap.c @@ -468,18 +468,9 @@ static AROS_UFH3(APTR, elfAlloc, ml->ml_ME[0].me_Addr = (APTR)mem; ml->ml_ME[0].me_Length = size; - /* If we're loading the ROM, it will automatically protect - * memory in the MEMF_CHIP and MEMF_LOCAL regions. - */ - if (ROM_Loaded || ((TypeOfMem(mem) & (MEMF_CHIP | MEMF_LOCAL)) == 0)) { - AddTail(&mlist, (struct Node*)ml); - D(WriteF("ELF: Got KICK memory at %X8, size %N\n", (IPTR)(&ml[1]), size)); - } else { - /* Dummy node, so that we can unconditionally call Remove() on it */ - ml->ml_Node.ln_Pred = &ml->ml_Node; - ml->ml_Node.ln_Succ = &ml->ml_Node; - D(WriteF("ELF: Got LOCAL memory at %X8, size %N\n", (IPTR)(&ml[1]), size)); - } + /* Add to the KickMem list */ + AddTail(&mlist, (struct Node*)ml); + D(WriteF("ELF: Got memory at %X8, size %N\n", (IPTR)(&ml[1]), size)); return &ml[1]; -- 2.11.4.GIT