HEADER_PATHS = -I$(SRCROOT)/bootx.tproj/include.subproj
NEXTSTEP_PB_CFLAGS = -static
-NEXTSTEP_PB_LDFLAGS = -nostdlib -e _StartTVector -seg1addr 01C00000
+NEXTSTEP_PB_LDFLAGS = -nostdlib -e _StartTVector -seg1addr 05600000
NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
# To include a version string, project source must exist in a directory named
# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
-# OTHER_GENERATED_OFILES = $(VERS_OFILE)
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
# This definition will suppress stripping of debug symbols when an executable
# is installed. By default it is YES.
NEXTSTEP_COMPILEROPTIONS = "-static";
NEXTSTEP_INSTALLDIR = /bin;
NEXTSTEP_JAVA_COMPILER = /usr/bin/javac;
- NEXTSTEP_LINKEROPTIONS = "-nostdlib -e _StartTVector -seg1addr 01C00000";
+ NEXTSTEP_LINKEROPTIONS = "-nostdlib -e _StartTVector -seg1addr 05600000";
NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc;
PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make;
PDO_UNIX_INSTALLDIR = /bin;
<CHRP-BOOT>
<COMPATIBLE>
-MacRISC MacRISC3
+MacRISC MacRISC3 MacRISC4
</COMPATIBLE>
<DESCRIPTION>
Boot Loader for Mac OS X.
/*
* cache.c - A simple cache for file systems meta-data.
*
- * Copyright (c) 2000 Apple Computer, Inc.
+ * Copyright (c) 2000 - 2003 Apple Computer, Inc.
*
* DRI: Josh de Cesare
*/
};
typedef struct CacheEntry CacheEntry;
-#define kCacheSize (0x80000)
+#define kCacheSize (kFSCacheSize)
#define kCacheMinBlockSize (0x200)
#define kCacheMaxBlockSize (0x4000)
#define kCacheMaxEntries (kCacheSize / kCacheMinBlockSize)
static long gCacheNumEntries;
static long gCacheTime;
static CacheEntry gCacheEntries[kCacheMaxEntries];
-static char gCacheBuffer[kCacheSize];
+static char *gCacheBuffer = (char *)kFSCacheAddr;
unsigned long gCacheHits;
unsigned long gCacheMisses;
static long ReadFile(InodePtr fileInode, long *length);
-#define kDevBlockSize (0x200) // Size of each disk block.
-#define kDiskLableBlock (15) // Block the DL is in.
-
static CICell gCurrentIH;
static long long gPartitionBase;
-static char gDLBuf[8192];
static char gFSBuf[SBSIZE];
static struct fs *gFS;
static long gBlockSize;
long UFSInitPartition(CICell ih)
{
- disk_label_t *dl;
- partition_t *part;
-
if (ih == gCurrentIH) return 0;
printf("UFSInitPartition: %x\n", ih);
gFS = (struct fs *)gFSBuf;
if (gFS->fs_magic != FS_MAGIC) {
- // Did not find it... Look for the Disk Label.
- // Look for the Disk Label
- Seek(ih, 1ULL * kDevBlockSize * kDiskLableBlock);
- Read(ih, (long)gDLBuf, 8192);
-
- dl = (disk_label_t *)gDLBuf;
- byte_swap_disklabel_in(dl);
-
- if (dl->dl_version != DL_VERSION) {
- return -1;
- }
-
- part = &dl->dl_part[0];
- gPartitionBase = (1ULL * (dl->dl_front + part->p_base) * dl->dl_secsize) -
- (1ULL * (dl->dl_label_blkno - kDiskLableBlock) * kDevBlockSize);
-
- // Re-read the Super Block.
- Seek(ih, gPartitionBase + SBOFF);
- Read(ih, (long)gFSBuf, SBSIZE);
-
- gFS = (struct fs *)gFSBuf;
- if (gFS->fs_magic != FS_MAGIC) {
- return -1;
- }
+ return -1;
}
// Calculate the block size and set up the block cache.
}
-static inline void
-byte_swap_disklabel_common(disk_label_t *dl)
-{
-
- swapBigLongToHost(dl->dl_version); /* ditto */
- swapBigLongToHost(dl->dl_label_blkno);
- swapBigLongToHost(dl->dl_size);
- swapBigLongToHost(dl->dl_flags);
- swapBigLongToHost(dl->dl_tag);
-// swapBigShortToHost(dl->dl_checksum);
-// if (dl->dl_version >= DL_V3)
-// swapBigShortToHost(dl->dl_un.DL_v3_checksum);
-// else
-// swapBigIntsToHost(dl->dl_un.DL_bad, NBAD);
-
-}
-
-
-void
-byte_swap_disklabel_in(disk_label_t *dl)
-{
-
- byte_swap_disklabel_common(dl);
- byte_swap_disktab_in(&dl->dl_dt);
-
-}
-
-
-static inline void
-byte_swap_disktab_common(struct disktab *dt)
-{
-
- register unsigned int i;
-
- swapBigLongToHost(dt->d_secsize);
- swapBigLongToHost(dt->d_ntracks);
- swapBigLongToHost(dt->d_nsectors);
- swapBigLongToHost(dt->d_ncylinders);
-// swapBigLongToHost(dt->d_rpm);
- swapBigShortToHost(dt->d_front);
- swapBigShortToHost(dt->d_back);
-// swapBigShortToHost(dt->d_ngroups);
-// swapBigShortToHost(dt->d_ag_size);
-// swapBigShortToHost(dt->d_ag_alts);
-// swapBigShortToHost(dt->d_ag_off);
-// swapBigIntsToHost(dt->d_boot0_blkno, NBOOTS);
-
- for (i=0; i < NPART; i++)
- byte_swap_partition(&dt->d_partitions[i]);
-
-}
-
-/*
- * This is particularly grody. The beginning of the partition array is two
- * bytes low on the 68 wrt natural alignment rules. Furthermore, each
- * element of the partition table is two bytes smaller on 68k due to padding
- * at the end of the struct.
- */
-void
-byte_swap_disktab_in(struct disktab *dt)
-{
-
- struct partition *pp;
- int i;
-
- /*
- * Shift each struct partition up in memory by 2 + 2 * offset bytes.
- * Do it backwards so we don't overwrite anything.
- */
- for (i=NPART - 1; i >=0; i--) {
- struct partition temp;
- pp = &dt->d_partitions[i];
- /* beware: compiler doesn't do overlapping struct assignment */
- temp = *(struct partition *)(((char *) pp) - 2 * (i + 1));
- *pp = temp;
- }
-
- byte_swap_disktab_common(dt);
-
-}
-
-
-void
-byte_swap_partition(struct partition *part)
-{
-
- swapBigLongToHost(part->p_base);
- swapBigLongToHost(part->p_size);
- swapBigShortToHost(part->p_bsize);
- swapBigShortToHost(part->p_fsize);
- swapBigShortToHost(part->p_cpg);
- swapBigShortToHost(part->p_density);
-
-}
-
-
void
byte_swap_inode_in(struct dinode *dc, struct dinode *ic)
{
#include <sys/param.h>
#include <sys/types.h>
-#include <sys/disktab.h>
#include <sys/vnode.h>
#include <sys/buf.h>
-#include <dev/disk.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ffs/fs.h>
void byte_swap_ints(int *array, int count);
void byte_swap_shorts(short *array, int count);
-void byte_swap_disklabel_in(disk_label_t *dl);
-void byte_swap_disktab_in(struct disktab *dt);
-void byte_swap_partition(struct partition *part);
void byte_swap_inode_in(struct dinode *dc, struct dinode *ic);
void byte_swap_dir_block_in(char *addr, int count);
/*
* boot_args.h - Data stuctures for the information passed to the kernel.
*
- * Copyright (c) 1998-2000 Apple Computer, Inc.
+ * Copyright (c) 1998-2003 Apple Computer, Inc.
*
* DRI: Josh de Cesare
*/
// Boot argument structure - passed into kernel at boot time.
#define kBootArgsRevision (1)
-#define kBootArgsVersion (1)
+#define kBootArgsVersion1 (1)
+#define kBootArgsVersion2 (2)
#define BOOT_LINE_LENGTH (256)
/*
* sl.h - Headers for configuring the Secondary Loader
*
- * Copyright (c) 1998-2002 Apple Computer, Inc.
+ * Copyright (c) 1998-2003 Apple Computer, Inc.
*
* DRI: Josh de Cesare
*/
/*
-Memory Map... Assumes 32 MB
+Memory Map: assumes 96 MB
Physical Address
-Open Firmware Version 1x, 2x 3x
-00000000 - 00003FFF : Exception Vectors
-00004000 - 002FFFFF : Free Memory
-00300000 - 004FFFFF : OF Image / Free Memory
-00500000 - 01DFFFFF : Free Memory
-01E00000 - 01FFFFFF : Free Memory / OF Image
+Open Firmware Version 3x, 4x, ...
+00000000 - 00003FFF : Exception Vectors
+00004000 - 057FFFFF : Free Memory
+05800000 - 05FFFFFF : OF Image
Logical Address
00000000 - 00003FFF : Exception Vectors
-00004000 - 013FFFFF : Kernel Image, Boot Struct and Drivers
-01400000 - 01BFFFFF : File Load Area
-01C00000 - 01CFFFFF : Secondary Loader Image
-01D00000 - 01DFFFFF : Malloc Area
-01E00000 - 01FFFFFF : Unused
-
-To provide a consistant Logical Memory Usage between OF 1,2 and OF 3
-the Logical Addresses 0x00300000 - 0x004FFFFF will be mapped to
-Physical Address 0x01E00000 - 0x01FFFFFF and will be copied back
-just before the kernel is loaded.
-
+00004000 - 03FFFFFF : Kernel Image, Boot Struct and Drivers
+04000000 - 04FFFFFF : File Load Area
+05000000 - 053FFFFF : FS Cache
+05400000 - 055FFFFF : Malloc Zone
+05600000 - 057FFFFF : BootX Image
+05800000 - 05FFFFFF : Unused
*/
// OF 3.x
#define kImageAddr (0x00004000)
-#define kImageSize (0x013FC000)
+#define kImageSize (0x03FFC000)
// OF 1.x 2.x
#define kImageAddr0 (0x00004000)
#define kImageSize0 (0x002FC000)
#define kImageAddr1 (0x00300000)
#define kImageSize1 (0x00200000)
-#define kImageAddr1Phys (0x01E00000)
+#define kImageAddr1Phys (0x05800000)
#define kImageAddr2 (0x00500000)
-#define kImageSize2 (0x00F00000)
+#define kImageSize2 (0x03B00000)
-#define kLoadAddr (0x01400000)
-#define kLoadSize (0x00800000)
+#define kLoadAddr (0x04000000)
+#define kLoadSize (0x01000000)
-#define kMallocAddr (0x01D00000)
-#define kMallocSize (0x00100000)
+#define kFSCacheAddr (0x05000000)
+#define kFSCacheSize (0x00400000)
+
+#define kMallocAddr (0x05400000)
+#define kMallocSize (0x00200000)
// Default Output Level
#define kOutputLevelOff (0)
#define kOFVersion1x (0x01000000)
#define kOFVersion2x (0x02000000)
#define kOFVersion3x (0x03000000)
+#define kOFVersion4x (0x04000000)
// Device Types
enum {
extern char *gKeyMap;
+extern long gRootAddrCells;
+extern long gRootSizeCells;
+
extern CICell gChosenPH;
extern CICell gOptionsPH;
extern CICell gScreenPH;
extern CICell gStdOutIH;
extern CICell gKeyboardIH;
+extern long ThinFatBinary(void **binary, unsigned long *length);
extern long GetDeviceType(char *devSpec);
extern long ConvertFileSpec(char *fileSpec, char *devSpec, char **filePath);
extern long MatchThis(CICell phandle, char *string);
extern unsigned long Alder32(unsigned char *buffer, long length);
// Externs for macho.c
-extern long DecodeMachO(void);
+extern long ThinFatBinaryMachO(void **binary, unsigned long *length);
+extern long DecodeMachO(void *binary);
// Externs for elf.c
-extern long DecodeElf(void);
+extern long ThinFatBinaryElf(void **binary, unsigned long *length);
+extern long DecodeElf(void *binary);
// Externs for device_tree.c
extern long FlattenDeviceTree(void);
/*
* zalloc.c - malloc functions.
*
- * Copyright (c) 1998-2000 Apple Computer, Inc.
+ * Copyright (c) 1998-2003 Apple Computer, Inc.
*
* DRI: Josh de Cesare
*/
#include <libclite.h>
-#define ZALLOC_NODES 384
+#define ZALLOC_NODES 768
#define ZDEBUG 0
#include <sl.h>
+#define DRIVER_DEBUG 0
+
enum {
kTagTypeNone = 0,
kTagTypeDict,
static void FreeTag(TagPtr tag);
static char *NewSymbol(char *string);
static void FreeSymbol(char *string);
+#if DRIVER_DEBUG
static void DumpTag(TagPtr tag, long depth);
+#endif
static ModulePtr gModuleHead, gModuleTail;
static TagPtr gPersonalityHead, gPersonalityTail;
static long LoadDriverMKext(char *fileSpec)
{
- long driversAddr, driversLength;
+ unsigned long driversAddr, driversLength, length;
char segName[32];
DriversPackage *package = (DriversPackage *)kLoadAddr;
// Load the MKext.
- if (LoadFile(fileSpec) == -1) return -1;
+ length = LoadFile(fileSpec);
+ if (length == -1) return -1;
+
+ ThinFatBinary((void **)&package, &length);
// Verify the MKext.
if ((package->signature1 != kDriverPackageSignature1) ||
driversAddr = AllocateKernelMemory(driversLength);
// Copy the MKext.
- memcpy((void *)driversAddr, (void *)kLoadAddr, driversLength);
+ memcpy((void *)driversAddr, (void *)package, driversLength);
// Add the MKext to the memory map.
sprintf(segName, "DriversPackage-%x", driversAddr);
ModulePtr module;
char *fileName, segName[32];
DriverInfoPtr driver;
- long length, driverAddr, driverLength;
+ unsigned long length, driverAddr, driverLength;
+ void *driverModuleAddr;
module = gModuleHead;
while (module != 0) {
length = LoadFile(gFileSpec);
} else length = 0;
if (length != -1) {
+ if (length != 0) {
+ driverModuleAddr = (void *)kLoadAddr;
+ ThinFatBinary(&driverModuleAddr, &length);
+ }
+
// Make make in the image area.
driverLength = sizeof(DriverInfo) + module->plistLength + length;
driverAddr = AllocateKernelMemory(driverLength);
// Save the plist and module.
strcpy(driver->plistAddr, module->plistAddr);
if (length != 0) {
- memcpy(driver->moduleAddr, (void *)kLoadAddr, driver->moduleLength);
+ memcpy(driver->moduleAddr, driverModuleAddr, driver->moduleLength);
}
// Add an entry to the memory map.
return symbol;
}
-#if 0
+#if DRIVER_DEBUG
static void DumpTagDict(TagPtr tag, long depth);
static void DumpTagKey(TagPtr tag, long depth);
static void DumpTagString(TagPtr tag, long depth);
// Public Functions
-long DecodeElf(void)
+long ThinFatBinaryElf(void **binary, unsigned long *length)
+{
+ return -1;
+}
+
+long DecodeElf(void *binary)
{
ElfHeaderPtr ehPtr;
ProgramHeaderPtr phPtr;
long cnt, paddr, offset, memsz, filesz, entry, *tmp;
- ehPtr = (ElfHeaderPtr)kLoadAddr;
+ ehPtr = (ElfHeaderPtr)binary;
if (ehPtr->signature != kElfSignature) return 0;
entry = ehPtr->entry & kElfAddressMask;
for (cnt = 0; cnt < ehPtr->phnum; cnt++) {
- phPtr = (ProgramHeaderPtr)(kLoadAddr+ehPtr->phoff+cnt*ehPtr->phentsize);
+ phPtr = (ProgramHeaderPtr)((unsigned long)binary + ehPtr->phoff + cnt * ehPtr->phentsize);
if (phPtr->type == kElfProgramTypeLoad) {
paddr = phPtr->paddr & kElfAddressMask;
// Get the actual entry if it is in this program.
if ((entry >= paddr) && (entry < (paddr + filesz))) {
- tmp = (long *)(kLoadAddr + offset + entry);
+ tmp = (long *)((unsigned long)binary + offset + entry);
if (tmp[2] == 0) entry += tmp[0];
}
if (paddr < kImageAddr) {
// Copy the Vectors out of the way.
- bcopy((char *)(kLoadAddr + offset), gVectorSaveAddr,
+ bcopy((char *)((unsigned long)binary + offset), gVectorSaveAddr,
kVectorSize - paddr);
offset += kImageAddr - paddr;
}
// Move the program.
- bcopy((char *)(kLoadAddr + offset), (char *)paddr, filesz);
+ bcopy((char *)((unsigned long)binary + offset), (char *)paddr, filesz);
}
}
/*
* macho.c - Functions for decoding a Mach-o Kernel.
*
- * Copyright (c) 1998-2000 Apple Computer, Inc.
+ * Copyright (c) 1998-2003 Apple Computer, Inc.
*
* DRI: Josh de Cesare
*/
static long DecodeUnixThread(long cmdBase);
static long DecodeSymbolTable(long cmdBase);
-static long gPPCOffset;
+static unsigned long gPPCAddress;
// Public Functions
-long DecodeMachO(void)
+long ThinFatBinaryMachO(void **binary, unsigned long *length)
+{
+ unsigned long nfat, swapped, size;
+ struct fat_header *fhp = (struct fat_header *)*binary;
+ struct fat_arch *fap =
+ (struct fat_arch *)((unsigned long)*binary + sizeof(struct fat_header));
+
+ if (fhp->magic == FAT_MAGIC) {
+ nfat = fhp->nfat_arch;
+ swapped = 0;
+ } else if (fhp->magic == FAT_CIGAM) {
+ nfat = NXSwapInt(fhp->nfat_arch);
+ swapped = 1;
+ } else {
+ return -1;
+ }
+
+ for (; nfat > 0; nfat--, fap++) {
+ if (swapped) {
+ fap->cputype = NXSwapInt(fap->cputype);
+ fap->offset = NXSwapInt(fap->offset);
+ fap->size = NXSwapInt(fap->size);
+ }
+
+ if (fap->cputype == CPU_TYPE_POWERPC) {
+ *binary = (void *) ((unsigned long)*binary + fap->offset);
+ size = fap->size;
+ break;
+ }
+ }
+
+ if (length != 0) *length = size;
+
+ return 0;
+}
+
+long DecodeMachO(void *binary)
{
- struct fat_header *fH;
- struct fat_arch *fA;
struct mach_header *mH;
long ncmds, cmdBase, cmd, cmdsize, headerBase, headerAddr, headerSize;
long cnt, ret;
- // Test for a fat header.
- fH = (struct fat_header *)kLoadAddr;
- if (fH->magic == FAT_MAGIC) {
- fA = (struct fat_arch *)(kLoadAddr + sizeof(struct fat_header));
- // see if the there is one for PPC.
- for (cnt = 0; cnt < fH->nfat_arch; cnt++) {
- if (fA[cnt].cputype == CPU_TYPE_POWERPC) {
- gPPCOffset = fA[cnt].offset;
- }
- }
- }
+ gPPCAddress = (unsigned long)binary;
- // offset will be the start of the
- headerBase = kLoadAddr + gPPCOffset;
- cmdBase = headerBase+ sizeof(struct mach_header);
+ headerBase = gPPCAddress;
+ cmdBase = headerBase + sizeof(struct mach_header);
mH = (struct mach_header *)(headerBase);
if (mH->magic != MH_MAGIC) return -1;
vmaddr = (char *)segCmd->vmaddr;
vmsize = segCmd->vmsize;
- fileaddr = (char *)(kLoadAddr + gPPCOffset + segCmd->fileoff);
+ fileaddr = (char *)(gPPCAddress + segCmd->fileoff);
filesize = segCmd->filesize;
#if 0
symTableSave->stroff = tmpAddr + symsSize;
symTableSave->strsize = symTab->strsize;
- bcopy((char *)(kLoadAddr + gPPCOffset + symTab->symoff),
+ bcopy((char *)(gPPCAddress + symTab->symoff),
(char *)tmpAddr, totalSize);
return 0;
/*
* main.c - Main functions for BootX.
*
- * Copyright (c) 1998-2002 Apple Computer, Inc.
+ * Copyright (c) 1998-2003 Apple Computer, Inc.
*
* DRI: Josh de Cesare
*/
char *gKeyMap;
+long gRootAddrCells;
+long gRootSizeCells;
+
CICell gChosenPH;
CICell gOptionsPH;
CICell gScreenPH;
CICell gStdOutIH;
CICell gKeyboardIH;
+static char gOFVectorSave[kVectorSize];
+static unsigned long gOFMSRSave;
+static unsigned long gOFSPRG0Save;
+static unsigned long gOFSPRG1Save;
+static unsigned long gOFSPRG2Save;
+static unsigned long gOFSPRG3Save;
+
// Private Functions
static void Start(void *unused1, void *unused2, ClientInterfacePtr ciPtr)
gOFVersion = GetOFVersion();
if (gOFVersion == 0) return -1;
+ // Get the address and size cells for the root.
+ GetProp(Peer(0), "#address-cells", (char *)&gRootAddrCells, 4);
+ GetProp(Peer(0), "#size-cells", (char *)&gRootSizeCells, 4);
+ if ((gRootAddrCells > 2) || (gRootAddrCells > 2)) return -1;
+
// Init the SL Words package.
ret = InitSLWords();
if (ret != 0) return -1;
gBootMode |= kBootModeSafe;
}
+ // Claim memory for the FS Cache.
+ if (Claim(kFSCacheAddr, kFSCacheSize, 0) == 0) {
+ printf("Claim for fs cache failed.\n");
+ return -1;
+ }
+
+ // Claim memory for malloc.
if (Claim(kMallocAddr, kMallocSize, 0) == 0) {
printf("Claim for malloc failed.\n");
return -1;
}
malloc_init((char *)kMallocAddr, kMallocSize);
- // malloc now works.
-
- // Claim the memory for the Load Addr
+ // Claim memory for the Load Addr.
mem_base = Claim(kLoadAddr, kLoadSize, 0);
if (mem_base == 0) {
printf("Claim for Load Area failed.\n");
}
+long ThinFatBinary(void **binary, unsigned long *length)
+{
+ long ret;
+
+ ret = ThinFatBinaryMachO(binary, length);
+ if (ret == -1) ret = ThinFatBinaryElf(binary, length);
+
+ return ret;
+}
+
+
static long DecodeKernel(void)
{
+ void *binary = (void *)kLoadAddr;
long ret;
- ret = DecodeMachO();
- if (ret == -1) ret = DecodeElf();
+ ThinFatBinary(&binary, 0);
+
+ ret = DecodeMachO(binary);
+ if (ret == -1) ret = DecodeElf(binary);
return ret;
}
static long SetUpBootArgs(void)
{
- boot_args_ptr args;
- CICell memoryPH;
- long graphicsBoot = 1;
- long ret, cnt, mem_size, size, dash;
- long sKey, vKey, keyPos;
- char ofBootArgs[128], *ofArgs, tc, keyStr[8];
+ boot_args_ptr args;
+ CICell memoryPH;
+ long graphicsBoot = 1;
+ long ret, cnt, size, dash;
+ long sKey, vKey, keyPos;
+ char ofBootArgs[128], *ofArgs, tc, keyStr[8];
+ unsigned char mem_regs[kMaxDRAMBanks*16];
+ unsigned long mem_banks, bank_shift;
// Save file system cache statistics.
SetProp(gChosenPH, "BootXCacheHits", (char *)&gCacheHits, 4);
args = (boot_args_ptr)gBootArgsAddr;
args->Revision = kBootArgsRevision;
- args->Version = kBootArgsVersion;
+ args->Version = kBootArgsVersion1;
args->machineType = 0;
// Check the Keyboard for 'cmd-s' and 'cmd-v'
sprintf(args->CommandLine, "%s%s", keyStr, ofBootArgs);
- // Get the memory info
+ // If the address or size cells are larger than 1, use page numbers
+ // and signify Boot Args Version 2.
+ if ((gRootAddrCells == 1) && (gRootSizeCells == 1)) bank_shift = 0;
+ else {
+ bank_shift = 12;
+ args->Version = kBootArgsVersion2;
+ }
+
+ // Get the information about the memory banks
memoryPH = FindDevice("/memory");
if (memoryPH == -1) return -1;
- size = GetProp(memoryPH, "reg", (char *)(args->PhysicalDRAM),
- kMaxDRAMBanks * sizeof(DRAMBank));
+ size = GetProp(memoryPH, "reg", mem_regs, kMaxDRAMBanks * 16);
if (size == 0) return -1;
+ mem_banks = size / (4 * (gRootAddrCells + gRootSizeCells));
+ if (mem_banks > kMaxDRAMBanks) mem_banks = kMaxDRAMBanks;
+
+ // Convert the reg properties to 32 bit values
+ for (cnt = 0; cnt < mem_banks; cnt++) {
+ if (gRootAddrCells == 1) {
+ args->PhysicalDRAM[cnt].base =
+ *(unsigned long *)(mem_regs + cnt * 4 * (gRootAddrCells + gRootSizeCells)) >> bank_shift;
+ } else {
+ args->PhysicalDRAM[cnt].base =
+ *(unsigned long long *)(mem_regs + cnt * 4 * (gRootAddrCells + gRootSizeCells)) >> bank_shift;
+
+ }
+
+ if (gRootSizeCells == 1) {
+ args->PhysicalDRAM[cnt].size =
+ *(unsigned long *)(mem_regs + cnt * 4 * (gRootAddrCells + gRootSizeCells) + 4 * gRootAddrCells) >> bank_shift;
+ } else {
+ args->PhysicalDRAM[cnt].size =
+ *(unsigned long long *)(mem_regs + cnt * 4 * (gRootAddrCells + gRootSizeCells) + 4 * gRootAddrCells) >> bank_shift;
+
+ }
+ }
- // This is a hack to make the memory look like its all
- // in one big bank.
- mem_size = 0;
- for (cnt = 0; cnt < kMaxDRAMBanks; cnt++) {
- mem_size += args->PhysicalDRAM[cnt].size;
- args->PhysicalDRAM[cnt].base = 0;
- args->PhysicalDRAM[cnt].size = 0;
+ // Collapse the memory banks into contiguous chunks
+ for (cnt = 0; cnt < mem_banks - 1; cnt++) {
+ if ((args->PhysicalDRAM[cnt + 1].base != 0) &&
+ ((args->PhysicalDRAM[cnt].base + args->PhysicalDRAM[cnt].size) !=
+ args->PhysicalDRAM[cnt + 1].base)) continue;
+
+ args->PhysicalDRAM[cnt].size += args->PhysicalDRAM[cnt + 1].size;
+ bcopy(args->PhysicalDRAM + cnt + 2, args->PhysicalDRAM + cnt + 1, (mem_banks - cnt - 2) * sizeof(DRAMBank));
+ mem_banks--;
+ cnt--;
}
- args->PhysicalDRAM[0].size = mem_size;
+ bzero(args->PhysicalDRAM + mem_banks, (kMaxDRAMBanks - mem_banks) * sizeof(DRAMBank));
// Get the video info
GetMainScreenPH(&args->Video);
static long CallKernel(void)
{
- long msr, cnt;
+ unsigned long msr, cnt;
Quiesce();
printf("\nCall Kernel!\n");
+ // Save SPRs for OF
+ __asm__ volatile("mfmsr %0" : "=r" (gOFMSRSave));
+ __asm__ volatile("mfsprg %0, 0" : "=r" (gOFSPRG0Save));
+ __asm__ volatile("mfsprg %0, 1" : "=r" (gOFSPRG1Save));
+ __asm__ volatile("mfsprg %0, 2" : "=r" (gOFSPRG2Save));
+ __asm__ volatile("mfsprg %0, 3" : "=r" (gOFSPRG3Save));
+
+ // Turn off translations
msr = 0x00001000;
+ __asm__ volatile("sync");
__asm__ volatile("mtmsr %0" : : "r" (msr));
__asm__ volatile("isync");
- // Move the Execption Vectors
+ // Save the OF's Exceptions Vectors
+ bcopy(0x0, gOFVectorSave, kVectorSize);
+
+ // Move the Exception Vectors
bcopy(gVectorSaveAddr, 0x0, kVectorSize);
for (cnt = 0; cnt < kVectorSize; cnt += 0x20) {
__asm__ volatile("dcbf 0, %0" : : "r" (cnt));
__asm__ volatile("sync");
__asm__ volatile("eieio");
+ // Call the Kernel's entry point
(*(void (*)())gKernelEntryPoint)(gBootArgsAddr, kMacOSXSignature);
+ // Restore OF's Exception Vectors
+ bcopy(gOFVectorSave, 0x0, 0x3000);
+ for (cnt = 0; cnt < kVectorSize; cnt += 0x20) {
+ __asm__ volatile("dcbf 0, %0" : : "r" (cnt));
+ __asm__ volatile("icbi 0, %0" : : "r" (cnt));
+ }
+
+ // Restore SPRs for OF
+ __asm__ volatile("mtsprg 0, %0" : : "r" (gOFSPRG0Save));
+ __asm__ volatile("mtsprg 1, %0" : : "r" (gOFSPRG1Save));
+ __asm__ volatile("mtsprg 2, %0" : : "r" (gOFSPRG2Save));
+ __asm__ volatile("mtsprg 3, %0" : : "r" (gOFSPRG3Save));
+
+ // Restore translations
+ __asm__ volatile("sync");
+ __asm__ volatile("mtmsr %0" : : "r" (gOFMSRSave));
+ __asm__ volatile("isync");
+
return -1;
}
vers = kOFVersion3x;
break;
+ case '4' :
+ vers = kOFVersion4x;
+ break;
+
default :
vers = 0;
break;
#define kNetBootFPS (10)
const unsigned char gNetBootPict[] = {
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x01,0x2b,0x2b,0x01,0x01,0x01,0x01,0x01,0x01,0x2b,0x2b,0x01,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x01,0x2b,0x01,0x10,0x2f,0x40,0x4c,0x54,0x54,0x4c,0x41,0x30,0x11,0x01,0x2b,0x01,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x2b,0x01,0x22,0x4f,0x63,0x66,0x63,0x5c,0x56,0x54,0x56,0x5a,0x8c,0x8c,0x4e,0x24,0x2b,0x2b,0x02,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x2b,0x0c,0x51,0x68,0x60,0x42,0x2d,0x31,0x4b,0x58,0x54,0x54,0x53,0x53,0x55,0x5a,0x5f,0x4b,0x0a,0x2b,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x03,0x06,0x0d,0x13,0x13,0x1b,0x2f,0x43,0x4c,0x52,0x57,0x57,0x52,0x4c,0x42,0x2e,0x19,0x11,0x10,0x0b,0xf7,0x02,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x02,0x02,0xf7,0x09,0x11,0x14,0x14,0x15,0x19,0x1c,0x1c,0x1c,0x1c,0x17,0x13,0x12,0x12,0x0d,0x08,0x04,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0xf7,0x09,0x0d,0x12,0x12,0x12,0x13,0x14,0x12,0x12,0x0e,0x0a,0x07,0xf7,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
- 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x04,0x06,0x07,0x08,0x0a,0x08,0x08,0x07,0xf7,0x04,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
- 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x03,0x03,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x04,0x06,0x07,0x08,0x0a,0x08,0x08,0x07,0xf7,0x04,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01
};