mirror of
https://github.com/Wack0/maciNTosh.git
synced 2025-06-18 18:45:34 -04:00
old world support (gossamer, wallstreet/pdq)
hwdesc: add bit for old world arcloaderold(grackle): initial commit oldworldisobuilder: initial commit pxi(grackle): for cuda, turn off one second timer (TBXI enables it) pxi(grackle): for cuda, clear and disable all interrupts pxi(grackle): for pmu (laptops), change reset to power off, to work around issues with rebooting (and because there's no hard shut down outside of a PMU reset) arcfs(grackle): add partitioning support for old world systems as a different partition layout is needed there
This commit is contained in:
parent
7b073c67d3
commit
c62a413c41
547
OldWorldIsoBuilder/oldiso.c
Normal file
547
OldWorldIsoBuilder/oldiso.c
Normal file
@ -0,0 +1,547 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wscalar-storage-order"
|
||||
|
||||
#define ARC_LE __attribute__((scalar_storage_order("little-endian")))
|
||||
#define ARC_BE __attribute__((scalar_storage_order("big-endian")))
|
||||
#define ARC_PACKED __attribute__((packed))
|
||||
#define ARC_FORCEINLINE inline __attribute__((always_inline))
|
||||
#define ARC_ALIGNED(x) __attribute__((aligned(x)))
|
||||
#define ARC_NORETURN __attribute__((noreturn))
|
||||
#define ARC_NOINLINE __attribute__((noinline))
|
||||
#define ARC_WEAK __attribute__((weak))
|
||||
|
||||
#define ARC_BIT(x) (1 << (x))
|
||||
#define ARC_MB(x) ((x) * 1024 * 1024)
|
||||
#define BIT(x) ARC_BIT(x)
|
||||
|
||||
typedef void* PVOID;
|
||||
typedef char CHAR, * PCHAR;
|
||||
typedef uint8_t UCHAR, * PUCHAR, BYTE, * PBYTE, BOOLEAN, * PBOOLEAN;
|
||||
typedef int16_t CSHORT, * PCSHORT, SHORT, * PSHORT;
|
||||
typedef uint16_t WORD, * PWORD, USHORT, * PUSHORT;
|
||||
typedef int32_t LONG, * PLONG;
|
||||
typedef uint32_t ULONG, * PULONG;
|
||||
|
||||
typedef uint16_t WCHAR, * PWCHAR;
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
|
||||
// Partition table parsing stuff.
|
||||
typedef struct ARC_LE ARC_PACKED _PARTITION_ENTRY {
|
||||
BYTE Active;
|
||||
BYTE StartChs[3];
|
||||
BYTE Type;
|
||||
BYTE EndChs[3];
|
||||
ULONG SectorStart;
|
||||
ULONG SectorCount;
|
||||
} PARTITION_ENTRY, *PPARTITION_ENTRY;
|
||||
|
||||
// Driver descriptor entry
|
||||
typedef struct ARC_BE ARC_PACKED _DDT_DRIVER_ENTRY {
|
||||
ULONG SectorStart;
|
||||
USHORT SectorCount;
|
||||
USHORT OsType; // classic MacOS = 1, ptDR = 0x0701, wiki = 0xF8FF
|
||||
} DDT_DRIVER_ENTRY, *PDDT_DRIVER_ENTRY;
|
||||
|
||||
enum {
|
||||
// This is very specific.
|
||||
// This is: (sizeof(MBR_SECTOR.MbrCode) - offsetof(DDT_ENTRY, Drivers)) / sizeof(DDT_DRIVER_ENTRY).
|
||||
// that is, enough DDT_DRIVER_ENTRY structures such that DDT_ENTRY structure can fit into MBR_SECTOR.MbrCode.
|
||||
DDT_DRIVER_COUNT_FOR_MBR = 0x34
|
||||
};
|
||||
|
||||
// Driver descriptor table for APM, at sector 0.
|
||||
typedef struct ARC_BE ARC_PACKED _DDT_ENTRY {
|
||||
USHORT Signature;
|
||||
USHORT SectorSize;
|
||||
ULONG SectorCount; // of whole disk
|
||||
USHORT DeviceType;
|
||||
USHORT DeviceId;
|
||||
ULONG Data;
|
||||
USHORT DriverCount;
|
||||
DDT_DRIVER_ENTRY Drivers[DDT_DRIVER_COUNT_FOR_MBR];
|
||||
} DDT_ENTRY, *PDDT_ENTRY;
|
||||
|
||||
// Ensure at compile time that DDT_ENTRY can fit into MbrCode.
|
||||
_Static_assert(sizeof(DDT_ENTRY) <= 0x1B8);
|
||||
|
||||
// MBR (sector 0)
|
||||
typedef struct ARC_LE ARC_PACKED _MBR_SECTOR {
|
||||
union {
|
||||
BYTE MbrCode[0x1B8];
|
||||
DDT_ENTRY ApmDdt;
|
||||
};
|
||||
ULONG Signature;
|
||||
USHORT Reserved;
|
||||
PARTITION_ENTRY Partitions[4];
|
||||
USHORT ValidMbr;
|
||||
} MBR_SECTOR, *PMBR_SECTOR;
|
||||
_Static_assert(sizeof(MBR_SECTOR) == 0x200);
|
||||
|
||||
// APM partition table. (each entry starts at sector 1)
|
||||
typedef struct ARC_BE ARC_PACKED _APM_SECTOR {
|
||||
ULONG Signature;
|
||||
ULONG ApmTableSectors; // aka partition count
|
||||
ULONG SectorStart;
|
||||
ULONG SectorCount;
|
||||
char Name[32];
|
||||
char Type[32];
|
||||
ULONG RelativeSectorStartData;
|
||||
ULONG SectorCountData;
|
||||
ULONG Status; // "only used by A/UX"
|
||||
ULONG RelativeSectorStartBoot;
|
||||
ULONG LengthBoot;
|
||||
ULONG BootCodeBaseAddress[2];
|
||||
ULONG BootCodeEntryPoint[2];
|
||||
ULONG BootCodeChecksum;
|
||||
char BootCodeArchitecture[16];
|
||||
BYTE UnusedData[0x178];
|
||||
} APM_SECTOR, *PAPM_SECTOR;
|
||||
_Static_assert(sizeof(APM_SECTOR) == 0x200);
|
||||
|
||||
typedef struct ARC_BE ARC_PACKED _APM_SECTOR2K {
|
||||
APM_SECTOR Sector;
|
||||
BYTE UnusedData[0x600];
|
||||
} APM_SECTOR2K, *PAPM_SECTOR2K;
|
||||
_Static_assert(sizeof(APM_SECTOR2K) == 0x800);
|
||||
|
||||
enum {
|
||||
APM_VALID_SIGNATURE = 0x504D0000,
|
||||
DDT_VALID_SIGNATURE = 0x4552,
|
||||
APM_SECTOR_SIZE = 0x200,
|
||||
APM_SECTOR_SIZE_CD = 0x800,
|
||||
};
|
||||
|
||||
static void ApmpInit(PAPM_SECTOR Apm, ULONG ApmPartitionCount, ULONG SectorStart, ULONG SectorCount, bool BootCode) {
|
||||
Apm->Signature = APM_VALID_SIGNATURE;
|
||||
Apm->ApmTableSectors = ApmPartitionCount;
|
||||
Apm->SectorStart = SectorStart;
|
||||
Apm->SectorCount = SectorCount;
|
||||
Apm->SectorCountData = SectorCount;
|
||||
// osx disk utility does this for some reason??
|
||||
memset(&Apm->UnusedData[0x14C], 0xFF, 4);
|
||||
Apm->Status = 0x7f;
|
||||
if (BootCode) {
|
||||
Apm->Status |= 0x300;
|
||||
}
|
||||
}
|
||||
|
||||
static void ApmpInitVoid(PAPM_SECTOR Apm, ULONG ApmPartitionCount) {
|
||||
Apm->Signature = APM_VALID_SIGNATURE;
|
||||
Apm->ApmTableSectors = ApmPartitionCount;
|
||||
strncpy(Apm->Type, "Apple_Void", sizeof(Apm->Type));
|
||||
}
|
||||
|
||||
static ULONG ApmpRolw1(USHORT Value) {
|
||||
return (Value << 1) | (Value >> 15);
|
||||
}
|
||||
|
||||
// same algorithm as in OSX MediaKit
|
||||
static ULONG ApmpDriverChecksum(PUCHAR Buffer, ULONG Length) {
|
||||
ULONG Checksum = 0;
|
||||
for (ULONG i = 0; i < Length; i++) {
|
||||
Checksum = ApmpRolw1((USHORT)(Checksum + Buffer[i]));
|
||||
}
|
||||
if (Checksum == 0) return 0xFFFF;
|
||||
return (USHORT)Checksum;
|
||||
}
|
||||
|
||||
static void usage(char* arg0) {
|
||||
printf("oldiso: add APM + bootable HFS partition to ISO image\n");
|
||||
printf("usage: %s iso hfsimg Driver43.ptDR Driver43.CDrv DriverATAPI.ptDR DriverATAPI.ATPI Patches\n", arg0);
|
||||
}
|
||||
|
||||
#define BAD_ARGS() do { \
|
||||
usage(argv[0]); \
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
#define READ_FILE(var, i, len) \
|
||||
PUCHAR var = NULL; \
|
||||
do { \
|
||||
FILE* fFile = fopen(argv[i], "rb"); \
|
||||
if (fFile == NULL) { \
|
||||
printf("Could not open %s\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
fseek(fFile, 0, SEEK_END); \
|
||||
\
|
||||
__auto_type lenFile = ftello(fFile); \
|
||||
fseek(fFile, 0, SEEK_SET); \
|
||||
if (lenFile != (len)) { \
|
||||
if (lenFile > 0xFFFFFFFF) lenFile = 0xFFFFFFFF; \
|
||||
printf("%s is %d bytes, expected %d\n", argv[i], lenFile, (len)); \
|
||||
return -2; \
|
||||
} \
|
||||
var = (PUCHAR)malloc((len)); \
|
||||
if (var == NULL) { \
|
||||
printf("Could not allocate memory for %s\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
if (fread( var, 1, (len), fFile) != (len)) { \
|
||||
printf("Could not read %s\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
fclose(fFile); \
|
||||
} while (0)
|
||||
|
||||
#define READ_FILE_UNKLEN(var, varLen, i) \
|
||||
PUCHAR var = NULL; \
|
||||
ULONG varLen = 0; \
|
||||
do { \
|
||||
FILE* fFile = fopen(argv[i], "rb"); \
|
||||
if (fFile == NULL) { \
|
||||
printf("Could not open %s\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
fseek(fFile, 0, SEEK_END); \
|
||||
\
|
||||
__auto_type lenFile = ftello(fFile); \
|
||||
if (varLen > 0xFFFFFFFF) { \
|
||||
printf("%s cannot be over 4GB\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
if ((varLen % APM_SECTOR_SIZE_CD) != 0) { \
|
||||
printf("%s size must be a multiple of 2048 bytes\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
varLen = (ULONG)lenFile; \
|
||||
fseek(fFile, 0, SEEK_SET); \
|
||||
var = (PUCHAR)malloc(varLen); \
|
||||
if (var == NULL) { \
|
||||
printf("Could not allocate memory for %s\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
if (fread( var, 1, varLen, fFile) != varLen) { \
|
||||
printf("Could not read %s\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
fclose(fFile); \
|
||||
} while (0)
|
||||
|
||||
#define READ_FILE_MAXLEN_IMPL(var, varLen, i, len) \
|
||||
PUCHAR var = NULL; \
|
||||
ULONG varLen = 0; \
|
||||
do { \
|
||||
FILE* fFile = fopen(argv[i], "rb"); \
|
||||
if (fFile == NULL) { \
|
||||
printf("Could not open %s\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
fseek(fFile, 0, SEEK_END); \
|
||||
\
|
||||
__auto_type lenFile = ftello(fFile); \
|
||||
if (varLen > len) { \
|
||||
printf("%s cannot be over %d bytes\n", argv[i], len); \
|
||||
return -2; \
|
||||
} \
|
||||
if ((varLen % APM_SECTOR_SIZE_CD) != 0) { \
|
||||
printf("%s size must be a multiple of 2048 bytes\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
varLen = (ULONG)lenFile; \
|
||||
fseek(fFile, 0, SEEK_SET); \
|
||||
var = (PUCHAR)malloc((len)); \
|
||||
if (var == NULL) { \
|
||||
printf("Could not allocate memory for %s\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
memset(var, 0, len); \
|
||||
if (fread( var, 1, varLen, fFile) != varLen) { \
|
||||
printf("Could not read %s\n", argv[i]); \
|
||||
return -2; \
|
||||
} \
|
||||
fclose(fFile); \
|
||||
} while (0)
|
||||
|
||||
#define READ_FILE_MAXLEN(var, i, length) READ_FILE_MAXLEN_IMPL(p##var, len##var, i, length)
|
||||
|
||||
enum {
|
||||
LEN_DRV1 = 0x7000,
|
||||
LEN_DRV2 = 0x11800,
|
||||
LEN_DRV2_CAP = (LEN_DRV2 > 0xF800 ? 0xF800 : LEN_DRV2),
|
||||
LEN_PATCH = 0x40000,
|
||||
LEN_ALL_DRIVERS = LEN_DRV1 + LEN_DRV2 + LEN_DRV1 + LEN_DRV2 + LEN_PATCH,
|
||||
LEN_APM = 63 * APM_SECTOR_SIZE,
|
||||
SECTLEN_APM = 63,
|
||||
SECTLEN_DRV1 = LEN_DRV1 / APM_SECTOR_SIZE,
|
||||
SECTLEN_DRV2 = LEN_DRV2 / APM_SECTOR_SIZE,
|
||||
SECTLEN_PATCH = LEN_PATCH / APM_SECTOR_SIZE,
|
||||
|
||||
SECTLEN_CD_APM = 15,
|
||||
SECTLEN_CD_DRV1 = LEN_DRV1 / APM_SECTOR_SIZE_CD,
|
||||
SECTLEN_CD_DRV2 = LEN_DRV2 / APM_SECTOR_SIZE_CD,
|
||||
SECTLEN_CD_PATCH = LEN_PATCH / APM_SECTOR_SIZE_CD,
|
||||
};
|
||||
|
||||
#define APM_PART_TO_CD_APM_PART(i) ((i) - ((i) / 4))
|
||||
|
||||
#define FOR_EACH_APM(i) for ( \
|
||||
PAPM_SECTOR pApm = &Apm[i]; \
|
||||
pApm != NULL; \
|
||||
pApm = (pApm == &Apm[i] ? &Apm2K[APM_PART_TO_CD_APM_PART(i)].Sector : NULL) \
|
||||
)
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc < 8) {
|
||||
BAD_ARGS();
|
||||
}
|
||||
|
||||
// open the files
|
||||
FILE* fIso = fopen(argv[1], "r+b");
|
||||
if (fIso == NULL) {
|
||||
printf("Could not open %s\n", argv[1]);
|
||||
BAD_ARGS();
|
||||
}
|
||||
|
||||
READ_FILE_UNKLEN(pHfsPart, lenHfsPart, 2);
|
||||
READ_FILE_MAXLEN(43ptDR, 3, LEN_DRV1);
|
||||
READ_FILE_MAXLEN(43CDrv, 4, LEN_DRV2);
|
||||
READ_FILE_MAXLEN(ATAptDR, 5, LEN_DRV1);
|
||||
READ_FILE_MAXLEN(ATAATPI, 6, LEN_DRV2);
|
||||
READ_FILE(pPatches, 7, LEN_PATCH);
|
||||
// if length of the main driver is too large, ptDR will crash
|
||||
// this works around someone passing whole driver partition images
|
||||
if (len43CDrv > LEN_DRV2_CAP) len43CDrv = LEN_DRV2_CAP;
|
||||
if (lenATAATPI > LEN_DRV2_CAP) lenATAATPI = LEN_DRV2_CAP;
|
||||
|
||||
// how big is the ISO(bytes)?
|
||||
fseek(fIso, 0, SEEK_END);
|
||||
__auto_type lenIso = ftello(fIso);
|
||||
if (lenIso < 0x8400) {
|
||||
printf("%s is %d bytes, needs to be more than %d bytes\n", argv[1], lenIso, 0x8400);
|
||||
return -3;
|
||||
}
|
||||
if ((lenIso % APM_SECTOR_SIZE_CD) != 0) {
|
||||
printf("%s size must be a multiple of 2048 bytes\n", argv[1]);
|
||||
return -3;
|
||||
}
|
||||
// make sure there's an iso header here
|
||||
{
|
||||
BYTE hdr[5];
|
||||
fseek(fIso, 0x8001, SEEK_SET);
|
||||
fread(hdr, 5, 1, fIso);
|
||||
fseek(fIso, 0, SEEK_SET);
|
||||
if (memcmp(hdr, "CD001", sizeof(hdr)) != 0) {
|
||||
printf("%s doesn't appear to be an ISO\n", argv[1]);
|
||||
return -3;
|
||||
}
|
||||
fread(hdr, 2, 1, fIso);
|
||||
fseek(fIso, 0, SEEK_SET);
|
||||
if (hdr[0] != 0 || hdr[1] != 0) {
|
||||
printf("%s appears to already be a hybrid ISO\n", argv[1]);
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t TotalLength = (uint64_t)lenIso + lenHfsPart + LEN_ALL_DRIVERS;
|
||||
if ((TotalLength % APM_SECTOR_SIZE_CD) != 0) {
|
||||
TotalLength += APM_SECTOR_SIZE_CD - (TotalLength % APM_SECTOR_SIZE_CD);
|
||||
}
|
||||
ULONG TotalLengthSectors = (ULONG)(TotalLength / APM_SECTOR_SIZE);
|
||||
ULONG TotalLengthSectorsCd = (ULONG)(TotalLength / APM_SECTOR_SIZE_CD);
|
||||
ULONG PartitionLengths[] = {
|
||||
SECTLEN_APM,
|
||||
(lenIso - LEN_APM - APM_SECTOR_SIZE) / APM_SECTOR_SIZE,
|
||||
SECTLEN_DRV1,
|
||||
SECTLEN_DRV2,
|
||||
SECTLEN_DRV1,
|
||||
SECTLEN_DRV2,
|
||||
SECTLEN_PATCH,
|
||||
lenHfsPart / APM_SECTOR_SIZE
|
||||
};
|
||||
ULONG PartitionLengthsCd[] = {
|
||||
SECTLEN_CD_APM,
|
||||
(lenIso - LEN_APM - APM_SECTOR_SIZE) / APM_SECTOR_SIZE_CD,
|
||||
SECTLEN_CD_DRV1,
|
||||
SECTLEN_CD_DRV2,
|
||||
SECTLEN_CD_DRV1,
|
||||
SECTLEN_CD_DRV2,
|
||||
SECTLEN_CD_PATCH,
|
||||
lenHfsPart / APM_SECTOR_SIZE_CD
|
||||
};
|
||||
ULONG PartitionOffsets[8];
|
||||
ULONG PartitionOffsetsCd[8];
|
||||
_Static_assert(sizeof(PartitionOffsets) == sizeof(PartitionLengths));
|
||||
_Static_assert(sizeof(PartitionOffsets) == sizeof(PartitionLengthsCd));
|
||||
_Static_assert(sizeof(PartitionOffsetsCd) == sizeof(PartitionLengthsCd));
|
||||
PartitionOffsets[0] = 1;
|
||||
PartitionOffsetsCd[0] = 1;
|
||||
for (int i = 1; i < 8; i++) {
|
||||
PartitionOffsets[i] = PartitionOffsets[i - 1] + PartitionLengths[i - 1];
|
||||
PartitionOffsetsCd[i] = PartitionOffsetsCd[i - 1] + PartitionLengthsCd[i - 1];
|
||||
}
|
||||
|
||||
|
||||
// init DDT, APM entries
|
||||
UCHAR BlankSector[APM_SECTOR_SIZE] = {0};
|
||||
MBR_SECTOR Mbr;
|
||||
memset((void*)(size_t)&Mbr, 0, sizeof(Mbr));
|
||||
|
||||
// DDT
|
||||
Mbr.ApmDdt.Signature = DDT_VALID_SIGNATURE;
|
||||
Mbr.ApmDdt.SectorSize = APM_SECTOR_SIZE_CD;
|
||||
Mbr.ApmDdt.SectorCount = TotalLengthSectorsCd;
|
||||
Mbr.ApmDdt.DeviceType = 1;
|
||||
Mbr.ApmDdt.DeviceId = 1;
|
||||
Mbr.ApmDdt.DriverCount = 4;
|
||||
Mbr.ApmDdt.Drivers[0].SectorStart = PartitionOffsetsCd[2];
|
||||
Mbr.ApmDdt.Drivers[0].SectorCount = PartitionLengthsCd[2];
|
||||
Mbr.ApmDdt.Drivers[0].OsType = 0x0001;
|
||||
Mbr.ApmDdt.Drivers[1].SectorStart = PartitionOffsetsCd[3];
|
||||
Mbr.ApmDdt.Drivers[1].SectorCount = PartitionLengthsCd[3];
|
||||
Mbr.ApmDdt.Drivers[1].OsType = 0xFFFF;
|
||||
Mbr.ApmDdt.Drivers[2].SectorStart = PartitionOffsetsCd[4];
|
||||
Mbr.ApmDdt.Drivers[2].SectorCount = PartitionLengthsCd[4];
|
||||
Mbr.ApmDdt.Drivers[2].OsType = 0x0701;
|
||||
Mbr.ApmDdt.Drivers[3].SectorStart = PartitionOffsetsCd[5];
|
||||
Mbr.ApmDdt.Drivers[3].SectorCount = PartitionLengthsCd[5];
|
||||
Mbr.ApmDdt.Drivers[3].OsType = 0xF8FF;
|
||||
|
||||
// APM
|
||||
enum {
|
||||
ApmPartitionsCountBeforeFixup = 8,
|
||||
// fixup requires one blank (except for count and type) "Void" partition where 512 and 2048 byte sectors overlap
|
||||
ApmPartitionsCount = ApmPartitionsCountBeforeFixup + (ApmPartitionsCountBeforeFixup / 4),
|
||||
ApmPartitionsWritten512 = (ApmPartitionsCount + (4 - (ApmPartitionsCount & 3))) - 1,
|
||||
};
|
||||
_Static_assert(ApmPartitionsWritten512 >= ApmPartitionsCount);
|
||||
APM_SECTOR Apm[ApmPartitionsWritten512];
|
||||
APM_SECTOR2K Apm2K[ApmPartitionsCountBeforeFixup];
|
||||
memset((void*)(size_t)&Apm, 0, sizeof(Apm));
|
||||
memset((void*)(size_t)&Apm2K, 0, sizeof(Apm2K));
|
||||
_Static_assert((sizeof(Mbr) + sizeof(Apm2K) + sizeof(Apm)) < 0x8000);
|
||||
_Static_assert(((sizeof(Apm) + sizeof(Mbr)) % APM_SECTOR_SIZE_CD) == 0);
|
||||
// Partition 1: partition tables themselves
|
||||
ApmpInit(&Apm[0], ApmPartitionsCount, PartitionOffsets[0], PartitionLengths[0], false);
|
||||
ApmpInit(&Apm2K[0].Sector, ApmPartitionsCount, PartitionOffsetsCd[0], PartitionLengthsCd[0], false);
|
||||
FOR_EACH_APM(0) {
|
||||
strncpy(pApm->Name, "Apple", sizeof(Apm[0].Name));
|
||||
strncpy(pApm->Type, "Apple_partition_map", sizeof(Apm[0].Type));
|
||||
pApm->Status = 3;
|
||||
}
|
||||
// Partition 2: ISO9660
|
||||
ApmpInit(&Apm[1], ApmPartitionsCount, PartitionOffsets[1], PartitionLengths[1], false);
|
||||
ApmpInit(&Apm2K[1].Sector, ApmPartitionsCount, PartitionOffsetsCd[1], PartitionLengthsCd[1], false);
|
||||
FOR_EACH_APM(1) {
|
||||
strncpy(pApm->Name, "Extra", sizeof(Apm[1].Name));
|
||||
strncpy(pApm->Type, "CD_partition_scheme", sizeof(Apm[1].Type));
|
||||
pApm->Status = 0;
|
||||
}
|
||||
// Partition 3: SCSI4.3 ptDR
|
||||
ApmpInit(&Apm[2], ApmPartitionsCount, PartitionOffsets[2], PartitionLengths[2], true);
|
||||
ApmpInit(&Apm2K[2].Sector, ApmPartitionsCount, PartitionOffsetsCd[2], PartitionLengthsCd[2], true);
|
||||
FOR_EACH_APM(2) {
|
||||
strncpy(pApm->Name, "Macintosh", sizeof(Apm[2].Name));
|
||||
strncpy(pApm->Type, "Apple_Driver43", sizeof(Apm[2].Type));
|
||||
memcpy(pApm->UnusedData, "ptDR", sizeof("ptDR"));
|
||||
pApm->LengthBoot = len43ptDR;
|
||||
pApm->BootCodeChecksum = ApmpDriverChecksum(p43ptDR, len43ptDR);
|
||||
}
|
||||
// Partition 4: void
|
||||
ApmpInitVoid(&Apm[3], ApmPartitionsCount);
|
||||
// Partition 5(4): SCSI4.3 CDrv
|
||||
ApmpInit(&Apm[4], ApmPartitionsCount, PartitionOffsets[3], PartitionLengths[3], true);
|
||||
ApmpInit(&Apm2K[3].Sector, ApmPartitionsCount, PartitionOffsetsCd[3], PartitionLengthsCd[3], true);
|
||||
FOR_EACH_APM(4) {
|
||||
strncpy(pApm->Name, "Macintosh", sizeof(Apm[4].Name));
|
||||
strncpy(pApm->Type, "Apple_Driver43_CD", sizeof(Apm[4].Type));
|
||||
memcpy(pApm->UnusedData, "CDrv", sizeof("CDrv"));
|
||||
pApm->LengthBoot = len43CDrv;
|
||||
pApm->BootCodeChecksum = ApmpDriverChecksum(p43CDrv, len43CDrv);
|
||||
}
|
||||
// Partition 6(5): ATAPI ptDR
|
||||
ApmpInit(&Apm[5], ApmPartitionsCount, PartitionOffsets[4], PartitionLengths[4], true);
|
||||
ApmpInit(&Apm2K[4].Sector, ApmPartitionsCount, PartitionOffsetsCd[4], PartitionLengthsCd[4], true);
|
||||
FOR_EACH_APM(5) {
|
||||
strncpy(pApm->Name, "Macintosh", sizeof(Apm[5].Name));
|
||||
strncpy(pApm->Type, "Apple_Driver_ATAPI", sizeof(Apm[5].Type));
|
||||
memcpy(pApm->UnusedData, "ptDR", sizeof("ptDR"));
|
||||
pApm->LengthBoot = lenATAptDR;
|
||||
pApm->BootCodeChecksum = ApmpDriverChecksum(pATAptDR, lenATAptDR);
|
||||
}
|
||||
// Partition 7(6): ATAPI ATPI
|
||||
ApmpInit(&Apm[6], ApmPartitionsCount, PartitionOffsets[5], PartitionLengths[5], true);
|
||||
ApmpInit(&Apm2K[5].Sector, ApmPartitionsCount, PartitionOffsetsCd[5], PartitionLengthsCd[5], true);
|
||||
FOR_EACH_APM(6) {
|
||||
strncpy(pApm->Name, "Macintosh", sizeof(Apm[6].Name));
|
||||
strncpy(pApm->Type, "Apple_Driver_ATAPI", sizeof(Apm[6].Type));
|
||||
memcpy(pApm->UnusedData, "ATPI", sizeof("ATPI"));
|
||||
pApm->LengthBoot = lenATAATPI;
|
||||
pApm->BootCodeChecksum = ApmpDriverChecksum(pATAATPI, lenATAATPI);
|
||||
}
|
||||
// Partition 8: void
|
||||
ApmpInitVoid(&Apm[7], ApmPartitionsCount);
|
||||
// Partition 9(7): Apple Patch partition
|
||||
ApmpInit(&Apm[8], ApmPartitionsCount, PartitionOffsets[6], PartitionLengths[6], false);
|
||||
ApmpInit(&Apm2K[6].Sector, ApmPartitionsCount, PartitionOffsetsCd[6], PartitionLengthsCd[6], false);
|
||||
FOR_EACH_APM(8) {
|
||||
strncpy(pApm->Name, "Patch Partition", sizeof(Apm[8].Name));
|
||||
strncpy(pApm->Type, "Apple_Patches", sizeof(Apm[8].Type));
|
||||
pApm->Status = 1;
|
||||
}
|
||||
// Partition 10(8): HFS boot partition
|
||||
ApmpInit(&Apm[9], ApmPartitionsCount, PartitionOffsets[7], PartitionLengths[7], false);
|
||||
ApmpInit(&Apm2K[7].Sector, ApmPartitionsCount, PartitionOffsetsCd[7], PartitionLengthsCd[7], false);
|
||||
FOR_EACH_APM(9) {
|
||||
strncpy(pApm->Name, "Windows NT", sizeof(Apm[9].Name));
|
||||
strncpy(pApm->Type, "Apple_HFS", sizeof(Apm[9].Type));
|
||||
pApm->Status = 0x40000033;
|
||||
}
|
||||
|
||||
// Write DDT then APM
|
||||
if (fwrite((void*)(size_t)&Mbr, 1, sizeof(Mbr), fIso) != sizeof(Mbr)) {
|
||||
printf("Could not write to %s\n", argv[1]);
|
||||
return -4;
|
||||
}
|
||||
if (fwrite((void*)(size_t)&Apm, 1, sizeof(Apm), fIso) != sizeof(Apm)) {
|
||||
printf("Could not write to %s\n", argv[1]);
|
||||
return -4;
|
||||
}
|
||||
if (fwrite((void*)(size_t)&Apm2K, 1, sizeof(Apm2K), fIso) != sizeof(Apm2K)) {
|
||||
printf("Could not write to %s\n", argv[1]);
|
||||
return -4;
|
||||
}
|
||||
|
||||
// Seek to end, write partition 3+ data out
|
||||
fseek(fIso, 0, SEEK_END);
|
||||
if (fwrite(p43ptDR, 1, LEN_DRV1, fIso) != LEN_DRV1) {
|
||||
printf("Could not write to %s\n", argv[1]);
|
||||
return -4;
|
||||
}
|
||||
if (fwrite(p43CDrv, 1, LEN_DRV2, fIso) != LEN_DRV2) {
|
||||
printf("Could not write to %s\n", argv[1]);
|
||||
return -4;
|
||||
}
|
||||
if (fwrite(pATAptDR, 1, LEN_DRV1, fIso) != LEN_DRV1) {
|
||||
printf("Could not write to %s\n", argv[1]);
|
||||
return -4;
|
||||
}
|
||||
if (fwrite(pATAATPI, 1, LEN_DRV2, fIso) != LEN_DRV2) {
|
||||
printf("Could not write to %s\n", argv[1]);
|
||||
return -4;
|
||||
}
|
||||
if (fwrite(pPatches, 1, LEN_PATCH, fIso) != LEN_PATCH) {
|
||||
printf("Could not write to %s\n", argv[1]);
|
||||
return -4;
|
||||
}
|
||||
if (fwrite(pHfsPart, 1, lenHfsPart, fIso) != lenHfsPart) {
|
||||
printf("Could not write to %s\n", argv[1]);
|
||||
return -4;
|
||||
}
|
||||
|
||||
fflush(fIso);
|
||||
fclose(fIso);
|
||||
return 0;
|
||||
}
|
20
OldWorldIsoBuilder/readme.md
Normal file
20
OldWorldIsoBuilder/readme.md
Normal file
@ -0,0 +1,20 @@
|
||||
## OldWorldIsoBuilder
|
||||
This tool will take a standard ISO file created by your favourite tool and inject the PM partition table, drivers and HFS partition image to make it bootable on an Old World system (assuming the HFS partition is itself bootable).
|
||||
|
||||
You need the driver files for this tool to work, you can extract them from a Mac OS X install media (path is something like `/System/Library/PrivateFrameworks/MediaKit.framework/Versions/A/Resources/MKDrivers.bundle/Contents/Resources`). The files you need are:
|
||||
|
||||
- `Apple_Driver43.ptDR.drvr` (SCSI patch driver)
|
||||
- `Apple_Driver43_CD.CDrv.drvr` (SCSI CD driver)
|
||||
- `Apple_Driver_ATAPI.ptDR.drvr` (ATAPI patch driver)
|
||||
- `Apple_Driver_ATAPI.ATPI.drvr` (ATAPI main driver)
|
||||
|
||||
The tool will also work with raw images of these partitions.
|
||||
|
||||
Additionally this tool needs the raw image of the CD Apple Patch partition (containing patches `mesh / Mesh Itt Patch`, `scsi / CD SCSIMgr` and `snag / CDSnag`), you can extract this from a Mac OS X install media using 7-Zip (v24.09 or higher, this version fixes some bugs in APM parsing), example command line: `7z x -tapm "Apple Mac OS X 10.3.0 - Disk 1.iso" "Patch Partition.Apple_Patches"`
|
||||
|
||||
Command line for this tool is as follows:
|
||||
`oldiso <iso> <hfs_partition.img> Apple_Driver43.ptDR.drvr Apple_Driver43_CD.CDrv.drvr Apple_Driver_ATAPI.ptDR.drvr Apple_Driver_ATAPI.ATPI.drvr Patch Partition.Apple_Patches`
|
||||
|
||||
The iso file provided will be overwritten on disk, so make a backup of the original first.
|
||||
|
||||
Build `oldiso.c` with gcc: `gcc -ooldiso oldiso.c` or `x86_64-w64-mingw32-gcc -ooldiso.exe oldiso.c` (etc). **clang does not work** due to not currently supporting `scalar_storage_order`.
|
@ -1006,3 +1006,6 @@ typedef enum _ARC_SCREEN_COLOUR {
|
||||
// I'm lazy, reimplementing the RVL arc firmware keyboard low level driver based on high level ARC calls:
|
||||
UCHAR IOSKBD_ReadChar(void);
|
||||
bool IOSKBD_CharAvailable(void);
|
||||
|
||||
// true if system is oldworld (and thus had to kexec out of Mac OS)
|
||||
bool IsSystemOldWorld(void);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -33,8 +33,42 @@ enum {
|
||||
REPART_APM_PART5_SIZE = 256 * REPART_KB_SECTORS,
|
||||
REPART_APM_PART6_START = REPART_APM_PART5_START + REPART_APM_PART5_SIZE,
|
||||
REPART_APM_PART6_SIZE = 256 * REPART_KB_SECTORS,
|
||||
REPART_APM_PART7_START = REPART_APM_PART6_START + REPART_APM_PART6_SIZE
|
||||
REPART_APM_PART7_START = REPART_APM_PART6_START + REPART_APM_PART6_SIZE,
|
||||
|
||||
|
||||
REPART_OWR_APM_MINIMUM_PARTITIONS = 10,
|
||||
REPART_OWR_APM_PART1_START = 1,
|
||||
REPART_OWR_APM_PART1_SIZE = REPART_APM_SECTORS - 1,
|
||||
REPART_OWR_APM_PART2_START = REPART_OWR_APM_PART1_START + REPART_OWR_APM_PART1_SIZE,
|
||||
REPART_OWR_APM_PART2_SIZE = 1,
|
||||
REPART_OWR_APM_PART3_START = REPART_OWR_APM_PART2_START + REPART_OWR_APM_PART2_SIZE,
|
||||
REPART_OWR_APM_PART3_SIZE = 0x6C00 / REPART_SECTOR_SIZE,
|
||||
REPART_OWR_APM_PART4_START = REPART_OWR_APM_PART3_START + REPART_OWR_APM_PART3_SIZE,
|
||||
REPART_OWR_APM_PART4_SIZE = 0x9400 / REPART_SECTOR_SIZE,
|
||||
REPART_OWR_APM_PART5_START = REPART_OWR_APM_PART4_START + REPART_OWR_APM_PART4_SIZE,
|
||||
REPART_OWR_APM_PART5_SIZE = 0x6C00 / REPART_SECTOR_SIZE,
|
||||
REPART_OWR_APM_PART6_START = REPART_OWR_APM_PART5_START + REPART_OWR_APM_PART5_SIZE,
|
||||
REPART_OWR_APM_PART6_SIZE = 0x9400 / REPART_SECTOR_SIZE,
|
||||
REPART_OWR_APM_PART7_START = REPART_OWR_APM_PART6_START + REPART_OWR_APM_PART6_SIZE,
|
||||
REPART_OWR_APM_PART7_SIZE = 256 * REPART_KB_SECTORS,
|
||||
REPART_OWR_APM_PART8_START = REPART_OWR_APM_PART7_START + REPART_OWR_APM_PART7_SIZE,
|
||||
REPART_OWR_APM_PART8_SIZE = 256 * REPART_KB_SECTORS,
|
||||
REPART_OWR_APM_PART9_START = REPART_OWR_APM_PART8_START + REPART_OWR_APM_PART8_SIZE,
|
||||
|
||||
REPART_OWR_DRIVER_PTDR_MAX = REPART_OWR_APM_PART3_SIZE * REPART_SECTOR_SIZE,
|
||||
REPART_OWR_DRIVER_MAIN_MAX = REPART_OWR_APM_PART4_SIZE * REPART_SECTOR_SIZE,
|
||||
|
||||
REPART_OWR_APM_PART7_SIZE_BYTES = 256 * 0x400,
|
||||
REPART_OWR_APM_PART8_SIZE_BYTES = 256 * 0x400
|
||||
|
||||
};
|
||||
// Empty space at APM partition 7 (new world) / partition 9 (old world) used to store ARC non-volatile environment variables.
|
||||
// They must be at identical locations on disk.
|
||||
_Static_assert(REPART_APM_PART7_START == REPART_OWR_APM_PART9_START);
|
||||
// Partitions 1 (APM partition table) and 2 (backup MBR) must also be identical.
|
||||
_Static_assert(REPART_APM_PART1_START == REPART_OWR_APM_PART1_START && REPART_APM_PART1_SIZE == REPART_OWR_APM_PART1_SIZE);
|
||||
_Static_assert(REPART_APM_PART2_START == REPART_OWR_APM_PART2_START && REPART_APM_PART2_SIZE == REPART_OWR_APM_PART2_SIZE);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of partitions in the Apple Partition Map.
|
||||
|
@ -3,6 +3,7 @@
|
||||
enum { // MRF = "MacRISC Flag"
|
||||
MRF_IN_EMULATOR = ARC_BIT(0),
|
||||
MRF_VIA_IS_CUDA = ARC_BIT(1),
|
||||
MRF_OLD_WORLD = ARC_BIT(2),
|
||||
};
|
||||
|
||||
typedef struct _HW_DESCRIPTION {
|
||||
|
@ -234,6 +234,9 @@ void ArcInitRamDisk(ULONG ControllerKey, PVOID Pointer, ULONG Length) {
|
||||
s_RamdiskLoaded = true;
|
||||
}
|
||||
|
||||
static bool s_IsOldWorld = false;
|
||||
bool IsSystemOldWorld(void) { return s_IsOldWorld; }
|
||||
|
||||
static void ArcMain() {
|
||||
// Initialise the ARC firmware.
|
||||
PSYSTEM_PARAMETER_BLOCK Spb = ARC_SYSTEM_TABLE();
|
||||
@ -712,6 +715,7 @@ void ARC_NORETURN FwMain(PHW_DESCRIPTION Desc) {
|
||||
HW_DESCRIPTION StackDesc;
|
||||
memcpy(&StackDesc, Desc, sizeof(StackDesc));
|
||||
Desc = &StackDesc;
|
||||
s_IsOldWorld = (Desc->MrFlags & MRF_OLD_WORLD) != 0;
|
||||
|
||||
// Initialise the console. We know where it is. Just convert it from physical address to our BAT mapping.
|
||||
ArcConsoleInit(PciPhysToVirt(Desc->FrameBufferBase), 0, 0, Desc->FrameBufferWidth, Desc->FrameBufferHeight, Desc->FrameBufferStride);
|
||||
|
@ -300,6 +300,14 @@ void PxiInit(PVOID MmioBase, bool IsCuda) {
|
||||
MmioWrite8(&s_PxiRegs->DirB, (s_PxiRegs->DirB & ~PXI_PORT_REQ_CUDA) | PXI_PORT_ACK_CUDA | PXI_PORT_TIP_CUDA);
|
||||
#if 1
|
||||
MmioWrite8(&s_PxiRegs->BufB, s_PxiRegs->BufB | PXI_PORT_RX_CUDA);
|
||||
// Ensure PXI interrupts are all acked and disabled, to prevent an interrupt storm during HAL init.
|
||||
// ack
|
||||
MmioWrite8(&s_PxiRegs->IFR, 0xFF);
|
||||
// disable
|
||||
MmioWrite8(&s_PxiRegs->IER, ~PXI_IE_SET);
|
||||
MmioRead8(&s_PxiRegs->IER);
|
||||
// clear
|
||||
MmioRead8(&s_PxiRegs->SR);
|
||||
#else // following is what openbsd driver does:
|
||||
PxipSetAcrIn();
|
||||
MmioWrite8(&s_PxiRegs->BufB, s_PxiRegs->BufB | PXI_PORT_RX_CUDA);
|
||||
@ -321,6 +329,9 @@ void PxiInit(PVOID MmioBase, bool IsCuda) {
|
||||
UCHAR Out[3];
|
||||
PxiSendSyncRequest(CUDA_TYPE_CMD, Cmd, sizeof(Cmd), false, Out, sizeof(Out), false);
|
||||
|
||||
// turn off one second timer
|
||||
Cmd[0] = 0x1B;
|
||||
PxiSendSyncRequest(CUDA_TYPE_CMD, Cmd, sizeof(Cmd), false, Out, sizeof(Out), false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -400,7 +411,11 @@ void PxiRtcWrite(ULONG Value) {
|
||||
|
||||
void PxiPowerOffSystem(bool Reset) {
|
||||
// Power off or reset system.
|
||||
if (Reset) {
|
||||
// For PMU systems, always power off, because:
|
||||
// - No way to shut down system outside of pmu poweroff
|
||||
// - NT (and ARC) doesn't actually power off system, only reboot
|
||||
// - Some systems won't come up after reset?
|
||||
if (Reset && s_IsCuda) {
|
||||
if (s_PxiIsCuda) {
|
||||
UCHAR Cmd = CUDA_RESET_PPC;
|
||||
UCHAR Out[16];
|
||||
|
@ -3,6 +3,7 @@
|
||||
enum { // MRF = "MacRISC Flag"
|
||||
MRF_IN_EMULATOR = ARC_BIT(0),
|
||||
MRF_VIA_IS_CUDA = ARC_BIT(1),
|
||||
MRF_OLD_WORLD = ARC_BIT(2),
|
||||
};
|
||||
|
||||
typedef struct _HW_DESCRIPTION {
|
||||
|
107
arcloaderold_grackle/Makefile
Normal file
107
arcloaderold_grackle/Makefile
Normal file
@ -0,0 +1,107 @@
|
||||
ifeq ($(strip $(RETRO68)),)
|
||||
$(error "Set RETRO68 in your environment.")
|
||||
endif
|
||||
|
||||
TOOLPATH = $(RETRO68)/bin
|
||||
PREFIX = $(TOOLPATH)/powerpc-apple-macos-
|
||||
|
||||
CFLAGS = -mcpu=603 -Wall -Wextra -Os
|
||||
ASFLAGS =
|
||||
LDFLAGS =
|
||||
LIBS = -lDisplayLib -lNameRegistryLib
|
||||
|
||||
REZFLAGS = -I$(RETRO68)/RIncludes -tzsys -cMACS
|
||||
|
||||
TARGET = stage1
|
||||
|
||||
FILES = $(wildcard source/*.S) $(wildcard source/*.c)
|
||||
OBJSx = $(FILES:source/%.S=build/%.o)
|
||||
OBJS = $(OBJSx:source/%.c=build/%.o)
|
||||
|
||||
AR = $(PREFIX)ar
|
||||
AS = $(PREFIX)as
|
||||
CC = $(PREFIX)gcc
|
||||
CXX = $(PREFIX)g++
|
||||
LD = $(PREFIX)ld
|
||||
OBJCOPY = $(PREFIX)objcopy
|
||||
RANLIB = $(PREFIX)ranlib
|
||||
STRIP = $(PREFIX)strip
|
||||
MAKEPEF = $(TOOLPATH)/MakePEF
|
||||
REZ = $(TOOLPATH)/Rez
|
||||
|
||||
ifeq ($(NOMAPFILE),)
|
||||
LDFLAGS += -Wl,-Map,$(TARGET).map
|
||||
endif
|
||||
|
||||
ifneq ($(LDSCRIPT),)
|
||||
LDFLAGS += -Wl,-T$(LDSCRIPT)
|
||||
endif
|
||||
|
||||
DEPDIR = .deps
|
||||
|
||||
all: $(TARGET).img
|
||||
@[ -d $(DIR_BUILD) ] || mkdir $(DIR_BUILD)
|
||||
|
||||
addstage2: $(TARGET).img
|
||||
@$(TOOLPATH)/hmount $<
|
||||
@$(TOOLPATH)/hcopy -r ../arcgrackle/stage2.elf :stage2.elf
|
||||
@$(TOOLPATH)/humount $<
|
||||
|
||||
$(TARGET).img: $(TARGET).rsrc.bin apple/boot1.bin
|
||||
@echo " IMG $@"
|
||||
@dd if=/dev/zero of=$@ bs=256K count=1
|
||||
@$(TOOLPATH)/hformat -l 'Windows NT' $@
|
||||
@dd conv=notrunc if=apple/boot1.bin of=$@
|
||||
@$(TOOLPATH)/hmount $@
|
||||
@$(TOOLPATH)/hcopy -m $< :System
|
||||
@touch Finder
|
||||
@$(TOOLPATH)/hcopy -r Finder :Finder
|
||||
@rm Finder
|
||||
@$(TOOLPATH)/hattrib -t FNDR -c MACS :Finder
|
||||
@$(TOOLPATH)/hattrib -b :
|
||||
@$(TOOLPATH)/humount $@
|
||||
|
||||
$(TARGET).rsrc.bin: source/$(TARGET).r apple/boot1.bin $(TARGET).bin
|
||||
@echo " REZ $@"
|
||||
@$(REZ) $(REZFLAGS) source/$(TARGET).r -o System.bin
|
||||
@mv System.bin $@
|
||||
|
||||
$(TARGET).bin: $(TARGET).pef apple/boot2stub.bin
|
||||
@echo " MAKEBIN $@"
|
||||
@cat apple/boot2stub.bin $(TARGET).pef > $@
|
||||
|
||||
$(TARGET).pef: $(TARGET).xcoff
|
||||
@echo " MAKEPEF $@"
|
||||
@$(MAKEPEF) $(TARGET).xcoff -o $@
|
||||
|
||||
$(TARGET).xcoff: $(OBJS)
|
||||
@echo " LINK $@"
|
||||
$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
|
||||
|
||||
ifneq ($(LDSCRIPT),)
|
||||
$(TARGET): $(LDSCRIPT)
|
||||
endif
|
||||
|
||||
build/%.o: source/%.c
|
||||
@echo " COMPILE $<"
|
||||
@mkdir -p $(DEPDIR)
|
||||
@mkdir -p build
|
||||
@$(CC) $(CFLAGS) $(DEFINES) -Wp,-MMD,$(DEPDIR)/$(*F).d,-MQ,"$@",-MP -c $< -o $@
|
||||
|
||||
build/%.o: source/%.s
|
||||
@echo " ASSEMBLE $<"
|
||||
@mkdir -p build
|
||||
@$(CC) $(CFLAGS) $(DEFINES) $(ASFLAGS) -c $< -o $@
|
||||
|
||||
build/%.o: source/%.S
|
||||
@echo " ASSEMBLE $<"
|
||||
@mkdir -p build
|
||||
@$(CC) $(CFLAGS) $(DEFINES) $(ASFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -rf $(DEPDIR)
|
||||
rm -f $(TARGET).* $(OBJS)
|
||||
|
||||
-include $(DEPDIR)/*
|
||||
|
||||
.PHONY: clean
|
15
arcloaderold_grackle/Retro68.patch
Normal file
15
arcloaderold_grackle/Retro68.patch
Normal file
@ -0,0 +1,15 @@
|
||||
diff --git a/hfsutils/libhfs/volume.c b/hfsutils/libhfs/volume.c
|
||||
index 37c41d7c3f..8c01b65c14 100644
|
||||
--- a/hfsutils/libhfs/volume.c
|
||||
+++ b/hfsutils/libhfs/volume.c
|
||||
@@ -269,8 +269,8 @@ int v_geometry(hfsvol *vol, int pnum)
|
||||
ERROR(EINVAL, "volume partition is empty");
|
||||
}
|
||||
|
||||
- if (vol->vlen < 800 * (1024 >> HFS_BLOCKSZ_BITS))
|
||||
- ERROR(EINVAL, "volume is smaller than 800K");
|
||||
+ if (vol->vlen < 8 * (1024 >> HFS_BLOCKSZ_BITS))
|
||||
+ ERROR(EINVAL, "volume is smaller than 8K");
|
||||
|
||||
return 0;
|
||||
|
BIN
arcloaderold_grackle/apple/boot1.bin
Normal file
BIN
arcloaderold_grackle/apple/boot1.bin
Normal file
Binary file not shown.
BIN
arcloaderold_grackle/apple/boot2stub.bin
Normal file
BIN
arcloaderold_grackle/apple/boot2stub.bin
Normal file
Binary file not shown.
11
arcloaderold_grackle/readme.md
Normal file
11
arcloaderold_grackle/readme.md
Normal file
@ -0,0 +1,11 @@
|
||||
# ARC firmware Old World bootloader for Gossamer/Wallstreet
|
||||
|
||||
This is the stage 1 ARC firmware bootloader for Old World systems using the MPC106 PCI host controller.
|
||||
|
||||
The toolchain used to build this is [Retro68](https://github.com/autc04/Retro68), with included patch (to change the libhfs 800KB restriction to 8KB which is the actual lower bound for an HFS partition image).
|
||||
|
||||
Included in the `apple` folder is:
|
||||
- `boot1.bin`: m68k HFS boot block with minor patches (to abort boot if Escape button is held, added because I had issues under emulation with boot-time key-combinations not working)
|
||||
- `boot2stub.bin`: second stage bootloader stub, contains a single MixedMode routine descriptor to call into PowerPC code (the built PEF)
|
||||
|
||||
Run `make ; make addstage2` after building `arcgrackle` to create a `stage1.img` HFS partition image used for booting Old World systems, that can be injected into a standard ISO-9660 image using `OldWorldIsoBuilder`.
|
1007
arcloaderold_grackle/source/arc.h
Normal file
1007
arcloaderold_grackle/source/arc.h
Normal file
File diff suppressed because it is too large
Load Diff
342
arcloaderold_grackle/source/asm.h
Normal file
342
arcloaderold_grackle/source/asm.h
Normal file
@ -0,0 +1,342 @@
|
||||
#ifndef __ASM_H__
|
||||
#define __ASM_H__
|
||||
|
||||
#ifdef _LANGUAGE_ASSEMBLY
|
||||
/* Condition Register Bit Fields */
|
||||
|
||||
#define cr0 0
|
||||
#define cr1 1
|
||||
#define cr2 2
|
||||
#define cr3 3
|
||||
#define cr4 4
|
||||
#define cr5 5
|
||||
#define cr6 6
|
||||
#define cr7 7
|
||||
|
||||
|
||||
/* General Purpose Registers (GPRs) */
|
||||
|
||||
#define r0 0
|
||||
#define r1 1
|
||||
#define sp 1
|
||||
#define r2 2
|
||||
#define toc 2
|
||||
#define r3 3
|
||||
#define r4 4
|
||||
#define r5 5
|
||||
#define r6 6
|
||||
#define r7 7
|
||||
#define r8 8
|
||||
#define r9 9
|
||||
#define r10 10
|
||||
#define r11 11
|
||||
#define r12 12
|
||||
#define r13 13
|
||||
#define r14 14
|
||||
#define r15 15
|
||||
#define r16 16
|
||||
#define r17 17
|
||||
#define r18 18
|
||||
#define r19 19
|
||||
#define r20 20
|
||||
#define r21 21
|
||||
#define r22 22
|
||||
#define r23 23
|
||||
#define r24 24
|
||||
#define r25 25
|
||||
#define r26 26
|
||||
#define r27 27
|
||||
#define r28 28
|
||||
#define r29 29
|
||||
#define r30 30
|
||||
#define r31 31
|
||||
|
||||
|
||||
/* Floating Point Registers (FPRs) */
|
||||
|
||||
#define fr0 0
|
||||
#define fr1 1
|
||||
#define fr2 2
|
||||
#define fr3 3
|
||||
#define fr4 4
|
||||
#define fr5 5
|
||||
#define fr6 6
|
||||
#define fr7 7
|
||||
#define fr8 8
|
||||
#define fr9 9
|
||||
#define fr10 10
|
||||
#define fr11 11
|
||||
#define fr12 12
|
||||
#define fr13 13
|
||||
#define fr14 14
|
||||
#define fr15 15
|
||||
#define fr16 16
|
||||
#define fr17 17
|
||||
#define fr18 18
|
||||
#define fr19 19
|
||||
#define fr20 20
|
||||
#define fr21 21
|
||||
#define fr22 22
|
||||
#define fr23 23
|
||||
#define fr24 24
|
||||
#define fr25 25
|
||||
#define fr26 26
|
||||
#define fr27 27
|
||||
#define fr28 28
|
||||
#define fr29 29
|
||||
#define fr30 30
|
||||
#define fr31 31
|
||||
|
||||
#define vr0 0
|
||||
#define vr1 1
|
||||
#define vr2 2
|
||||
#define vr3 3
|
||||
#define vr4 4
|
||||
#define vr5 5
|
||||
#define vr6 6
|
||||
#define vr7 7
|
||||
#define vr8 8
|
||||
#define vr9 9
|
||||
#define vr10 10
|
||||
#define vr11 11
|
||||
#define vr12 12
|
||||
#define vr13 13
|
||||
#define vr14 14
|
||||
#define vr15 15
|
||||
#define vr16 16
|
||||
#define vr17 17
|
||||
#define vr18 18
|
||||
#define vr19 19
|
||||
#define vr20 20
|
||||
#define vr21 21
|
||||
#define vr22 22
|
||||
#define vr23 23
|
||||
#define vr24 24
|
||||
#define vr25 25
|
||||
#define vr26 26
|
||||
#define vr27 27
|
||||
#define vr28 28
|
||||
#define vr29 29
|
||||
#define vr30 30
|
||||
#define vr31 31
|
||||
|
||||
#endif //_LANGUAGE_ASSEMBLY
|
||||
|
||||
#define SPRG0 272
|
||||
#define SPRG1 273
|
||||
#define SPRG2 274
|
||||
#define SPRG3 275
|
||||
|
||||
#define DABR 1013
|
||||
|
||||
#define IABR 1010
|
||||
|
||||
#define PMC1 953
|
||||
#define PMC2 954
|
||||
#define PMC3 957
|
||||
#define PMC4 958
|
||||
|
||||
#define MMCR0 952
|
||||
#define MMCR1 956
|
||||
|
||||
|
||||
#define LINK_REGISTER_CALLEE_UPDATE_ROOM 4
|
||||
#define EXCEPTION_NUMBER 8
|
||||
#define SRR0_OFFSET 12
|
||||
#define SRR1_OFFSET 16
|
||||
#define GPR0_OFFSET 20
|
||||
#define GPR1_OFFSET 24
|
||||
#define GPR2_OFFSET 28
|
||||
#define GPR3_OFFSET 32
|
||||
#define GPR4_OFFSET 36
|
||||
#define GPR5_OFFSET 40
|
||||
#define GPR6_OFFSET 44
|
||||
#define GPR7_OFFSET 48
|
||||
#define GPR8_OFFSET 52
|
||||
#define GPR9_OFFSET 56
|
||||
#define GPR10_OFFSET 60
|
||||
#define GPR11_OFFSET 64
|
||||
#define GPR12_OFFSET 68
|
||||
#define GPR13_OFFSET 72
|
||||
#define GPR14_OFFSET 76
|
||||
#define GPR15_OFFSET 80
|
||||
#define GPR16_OFFSET 84
|
||||
#define GPR17_OFFSET 88
|
||||
#define GPR18_OFFSET 92
|
||||
#define GPR19_OFFSET 96
|
||||
#define GPR20_OFFSET 100
|
||||
#define GPR21_OFFSET 104
|
||||
#define GPR22_OFFSET 108
|
||||
#define GPR23_OFFSET 112
|
||||
#define GPR24_OFFSET 116
|
||||
#define GPR25_OFFSET 120
|
||||
#define GPR26_OFFSET 124
|
||||
#define GPR27_OFFSET 128
|
||||
#define GPR28_OFFSET 132
|
||||
#define GPR29_OFFSET 136
|
||||
#define GPR30_OFFSET 140
|
||||
#define GPR31_OFFSET 144
|
||||
|
||||
#define GQR0_OFFSET 148
|
||||
#define GQR1_OFFSET 152
|
||||
#define GQR2_OFFSET 156
|
||||
#define GQR3_OFFSET 160
|
||||
#define GQR4_OFFSET 164
|
||||
#define GQR5_OFFSET 168
|
||||
#define GQR6_OFFSET 172
|
||||
#define GQR7_OFFSET 176
|
||||
|
||||
#define CR_OFFSET 180
|
||||
#define LR_OFFSET 184
|
||||
#define CTR_OFFSET 188
|
||||
#define XER_OFFSET 192
|
||||
#define MSR_OFFSET 196
|
||||
#define DAR_OFFSET 200
|
||||
|
||||
#define STATE_OFFSET 204
|
||||
#define MODE_OFFSET 206
|
||||
|
||||
#define FPR0_OFFSET 208
|
||||
#define FPR1_OFFSET 216
|
||||
#define FPR2_OFFSET 224
|
||||
#define FPR3_OFFSET 232
|
||||
#define FPR4_OFFSET 240
|
||||
#define FPR5_OFFSET 248
|
||||
#define FPR6_OFFSET 256
|
||||
#define FPR7_OFFSET 264
|
||||
#define FPR8_OFFSET 272
|
||||
#define FPR9_OFFSET 280
|
||||
#define FPR10_OFFSET 288
|
||||
#define FPR11_OFFSET 296
|
||||
#define FPR12_OFFSET 304
|
||||
#define FPR13_OFFSET 312
|
||||
#define FPR14_OFFSET 320
|
||||
#define FPR15_OFFSET 328
|
||||
#define FPR16_OFFSET 336
|
||||
#define FPR17_OFFSET 344
|
||||
#define FPR18_OFFSET 352
|
||||
#define FPR19_OFFSET 360
|
||||
#define FPR20_OFFSET 368
|
||||
#define FPR21_OFFSET 376
|
||||
#define FPR22_OFFSET 384
|
||||
#define FPR23_OFFSET 392
|
||||
#define FPR24_OFFSET 400
|
||||
#define FPR25_OFFSET 408
|
||||
#define FPR26_OFFSET 416
|
||||
#define FPR27_OFFSET 424
|
||||
#define FPR28_OFFSET 432
|
||||
#define FPR29_OFFSET 440
|
||||
#define FPR30_OFFSET 448
|
||||
#define FPR31_OFFSET 456
|
||||
|
||||
#define FPSCR_OFFSET 464
|
||||
|
||||
#define PSR0_OFFSET 472
|
||||
#define PSR1_OFFSET 480
|
||||
#define PSR2_OFFSET 488
|
||||
#define PSR3_OFFSET 496
|
||||
#define PSR4_OFFSET 504
|
||||
#define PSR5_OFFSET 512
|
||||
#define PSR6_OFFSET 520
|
||||
#define PSR7_OFFSET 528
|
||||
#define PSR8_OFFSET 536
|
||||
#define PSR9_OFFSET 544
|
||||
#define PSR10_OFFSET 552
|
||||
#define PSR11_OFFSET 560
|
||||
#define PSR12_OFFSET 568
|
||||
#define PSR13_OFFSET 576
|
||||
#define PSR14_OFFSET 584
|
||||
#define PSR15_OFFSET 592
|
||||
#define PSR16_OFFSET 600
|
||||
#define PSR17_OFFSET 608
|
||||
#define PSR18_OFFSET 616
|
||||
#define PSR19_OFFSET 624
|
||||
#define PSR20_OFFSET 632
|
||||
#define PSR21_OFFSET 640
|
||||
#define PSR22_OFFSET 648
|
||||
#define PSR23_OFFSET 656
|
||||
#define PSR24_OFFSET 664
|
||||
#define PSR25_OFFSET 672
|
||||
#define PSR26_OFFSET 680
|
||||
#define PSR27_OFFSET 688
|
||||
#define PSR28_OFFSET 696
|
||||
#define PSR29_OFFSET 704
|
||||
#define PSR30_OFFSET 712
|
||||
#define PSR31_OFFSET 720
|
||||
/*
|
||||
* maintain the EABI requested 8 bytes aligment
|
||||
* As SVR4 ABI requires 16, make it 16 (as some
|
||||
* exception may need more registers to be processed...)
|
||||
*/
|
||||
#define EXCEPTION_FRAME_END 728
|
||||
|
||||
#define IBAT0U 528
|
||||
#define IBAT0L 529
|
||||
#define IBAT1U 530
|
||||
#define IBAT1L 531
|
||||
#define IBAT2U 532
|
||||
#define IBAT2L 533
|
||||
#define IBAT3U 534
|
||||
#define IBAT3L 535
|
||||
#define IBAT4U 560
|
||||
#define IBAT4L 561
|
||||
#define IBAT5U 562
|
||||
#define IBAT5L 563
|
||||
#define IBAT6U 564
|
||||
#define IBAT6L 565
|
||||
#define IBAT7U 566
|
||||
#define IBAT7L 567
|
||||
|
||||
#define DBAT0U 536
|
||||
#define DBAT0L 537
|
||||
#define DBAT1U 538
|
||||
#define DBAT1L 539
|
||||
#define DBAT2U 540
|
||||
#define DBAT2L 541
|
||||
#define DBAT3U 542
|
||||
#define DBAT3L 543
|
||||
#define DBAT4U 568
|
||||
#define DBAT4L 569
|
||||
#define DBAT5U 570
|
||||
#define DBAT5L 571
|
||||
#define DBAT6U 572
|
||||
#define DBAT6L 573
|
||||
#define DBAT7U 574
|
||||
#define DBAT7L 575
|
||||
|
||||
#define HID0 1008
|
||||
#define HID1 1009
|
||||
#define HID2 920
|
||||
#define HID4 1011
|
||||
|
||||
#define GQR0 912
|
||||
#define GQR1 913
|
||||
#define GQR2 914
|
||||
#define GQR3 915
|
||||
#define GQR4 916
|
||||
#define GQR5 917
|
||||
#define GQR6 918
|
||||
#define GQR7 919
|
||||
|
||||
#define L2CR 1017
|
||||
|
||||
#define WPAR 921
|
||||
|
||||
#define DMAU 922
|
||||
#define DMAL 923
|
||||
|
||||
#define MSR_RI 0x00000002
|
||||
#define MSR_DR 0x00000010
|
||||
#define MSR_IR 0x00000020
|
||||
#define MSR_IP 0x00000040
|
||||
#define MSR_SE 0x00000400
|
||||
#define MSR_ME 0x00001000
|
||||
#define MSR_FP 0x00002000
|
||||
#define MSR_POW 0x00004000
|
||||
#define MSR_EE 0x00008000
|
||||
|
||||
#define PPC_ALIGNMENT 8
|
||||
|
||||
#define PPC_CACHE_ALIGNMENT 32
|
||||
|
||||
#endif //__ASM_H__
|
594
arcloaderold_grackle/source/elf_abi.h
Normal file
594
arcloaderold_grackle/source/elf_abi.h
Normal file
@ -0,0 +1,594 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 1996, 2001, 2002
|
||||
* Erik Theisen. 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. The name of the author 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the ELF ABI header file
|
||||
* formerly known as "elf_abi.h".
|
||||
*/
|
||||
|
||||
#ifndef _ELF_ABI_H
|
||||
#define _ELF_ABI_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* This version doesn't work for 64-bit ABIs - Erik.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These typedefs need to be handled better.
|
||||
*/
|
||||
typedef ULONG Elf32_Addr; /* Unsigned program address */
|
||||
typedef ULONG Elf32_Off; /* Unsigned file offset */
|
||||
typedef LONG Elf32_Sword; /* Signed large integer */
|
||||
typedef ULONG Elf32_Word; /* Unsigned large integer */
|
||||
typedef USHORT Elf32_Half; /* Unsigned medium integer */
|
||||
|
||||
/* e_ident[] identification indexes */
|
||||
#define EI_MAG0 0 /* file ID */
|
||||
#define EI_MAG1 1 /* file ID */
|
||||
#define EI_MAG2 2 /* file ID */
|
||||
#define EI_MAG3 3 /* file ID */
|
||||
#define EI_CLASS 4 /* file class */
|
||||
#define EI_DATA 5 /* data encoding */
|
||||
#define EI_VERSION 6 /* ELF header version */
|
||||
#define EI_OSABI 7 /* OS/ABI specific ELF extensions */
|
||||
#define EI_ABIVERSION 8 /* ABI target version */
|
||||
#define EI_PAD 9 /* start of pad bytes */
|
||||
#define EI_NIDENT 16 /* Size of e_ident[] */
|
||||
|
||||
/* e_ident[] magic number */
|
||||
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
|
||||
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
|
||||
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
|
||||
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
|
||||
#define ELFMAG "\177ELF" /* magic */
|
||||
#define SELFMAG 4 /* size of magic */
|
||||
|
||||
/* e_ident[] file class */
|
||||
#define ELFCLASSNONE 0 /* invalid */
|
||||
#define ELFCLASS32 1 /* 32-bit objs */
|
||||
#define ELFCLASS64 2 /* 64-bit objs */
|
||||
#define ELFCLASSNUM 3 /* number of classes */
|
||||
|
||||
/* e_ident[] data encoding */
|
||||
#define ELFDATANONE 0 /* invalid */
|
||||
#define ELFDATA2LSB 1 /* Little-Endian */
|
||||
#define ELFDATA2MSB 2 /* Big-Endian */
|
||||
#define ELFDATANUM 3 /* number of data encode defines */
|
||||
|
||||
/* e_ident[] OS/ABI specific ELF extensions */
|
||||
#define ELFOSABI_NONE 0 /* No extension specified */
|
||||
#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */
|
||||
#define ELFOSABI_NETBSD 2 /* NetBSD */
|
||||
#define ELFOSABI_LINUX 3 /* Linux */
|
||||
#define ELFOSABI_SOLARIS 6 /* Sun Solaris */
|
||||
#define ELFOSABI_AIX 7 /* AIX */
|
||||
#define ELFOSABI_IRIX 8 /* IRIX */
|
||||
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
|
||||
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */
|
||||
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
|
||||
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
|
||||
/* 64-255 Architecture-specific value range */
|
||||
|
||||
/* e_ident[] ABI Version */
|
||||
#define ELFABIVERSION 0
|
||||
|
||||
/* e_ident */
|
||||
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
|
||||
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
|
||||
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
|
||||
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
|
||||
|
||||
/* ELF Header */
|
||||
typedef struct ARC_LE elfhdr{
|
||||
unsigned char e_ident[EI_NIDENT]; /* ELF Identification */
|
||||
Elf32_Half e_type; /* object file type */
|
||||
Elf32_Half e_machine; /* machine */
|
||||
Elf32_Word e_version; /* object file version */
|
||||
Elf32_Addr e_entry; /* virtual entry point */
|
||||
Elf32_Off e_phoff; /* program header table offset */
|
||||
Elf32_Off e_shoff; /* section header table offset */
|
||||
Elf32_Word e_flags; /* processor-specific flags */
|
||||
Elf32_Half e_ehsize; /* ELF header size */
|
||||
Elf32_Half e_phentsize; /* program header entry size */
|
||||
Elf32_Half e_phnum; /* number of program header entries */
|
||||
Elf32_Half e_shentsize; /* section header entry size */
|
||||
Elf32_Half e_shnum; /* number of section header entries */
|
||||
Elf32_Half e_shstrndx; /* section header table's "section
|
||||
header string table" entry offset */
|
||||
} Elf32_Ehdr;
|
||||
|
||||
/* e_type */
|
||||
#define ET_NONE 0 /* No file type */
|
||||
#define ET_REL 1 /* relocatable file */
|
||||
#define ET_EXEC 2 /* executable file */
|
||||
#define ET_DYN 3 /* shared object file */
|
||||
#define ET_CORE 4 /* core file */
|
||||
#define ET_NUM 5 /* number of types */
|
||||
#define ET_LOOS 0xfe00 /* reserved range for operating */
|
||||
#define ET_HIOS 0xfeff /* system specific e_type */
|
||||
#define ET_LOPROC 0xff00 /* reserved range for processor */
|
||||
#define ET_HIPROC 0xffff /* specific e_type */
|
||||
|
||||
/* e_machine */
|
||||
#define EM_NONE 0 /* No Machine */
|
||||
#define EM_M32 1 /* AT&T WE 32100 */
|
||||
#define EM_SPARC 2 /* SPARC */
|
||||
#define EM_386 3 /* Intel 80386 */
|
||||
#define EM_68K 4 /* Motorola 68000 */
|
||||
#define EM_88K 5 /* Motorola 88000 */
|
||||
#if 0
|
||||
#define EM_486 6 /* RESERVED - was Intel 80486 */
|
||||
#endif
|
||||
#define EM_860 7 /* Intel 80860 */
|
||||
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
|
||||
#define EM_S370 9 /* IBM System/370 Processor */
|
||||
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
|
||||
#if 0
|
||||
#define EM_SPARC64 11 /* RESERVED - was SPARC v9
|
||||
64-bit unoffical */
|
||||
#endif
|
||||
/* RESERVED 11-14 for future use */
|
||||
#define EM_PARISC 15 /* HPPA */
|
||||
/* RESERVED 16 for future use */
|
||||
#define EM_VPP500 17 /* Fujitsu VPP500 */
|
||||
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
|
||||
#define EM_960 19 /* Intel 80960 */
|
||||
#define EM_PPC 20 /* PowerPC */
|
||||
#define EM_PPC64 21 /* 64-bit PowerPC */
|
||||
#define EM_S390 22 /* IBM System/390 Processor */
|
||||
/* RESERVED 23-35 for future use */
|
||||
#define EM_V800 36 /* NEC V800 */
|
||||
#define EM_FR20 37 /* Fujitsu FR20 */
|
||||
#define EM_RH32 38 /* TRW RH-32 */
|
||||
#define EM_RCE 39 /* Motorola RCE */
|
||||
#define EM_ARM 40 /* Advanced Risc Machines ARM */
|
||||
#define EM_ALPHA 41 /* Digital Alpha */
|
||||
#define EM_SH 42 /* Hitachi SH */
|
||||
#define EM_SPARCV9 43 /* SPARC Version 9 */
|
||||
#define EM_TRICORE 44 /* Siemens TriCore embedded processor */
|
||||
#define EM_ARC 45 /* Argonaut RISC Core */
|
||||
#define EM_H8_300 46 /* Hitachi H8/300 */
|
||||
#define EM_H8_300H 47 /* Hitachi H8/300H */
|
||||
#define EM_H8S 48 /* Hitachi H8S */
|
||||
#define EM_H8_500 49 /* Hitachi H8/500 */
|
||||
#define EM_IA_64 50 /* Intel Merced */
|
||||
#define EM_MIPS_X 51 /* Stanford MIPS-X */
|
||||
#define EM_COLDFIRE 52 /* Motorola Coldfire */
|
||||
#define EM_68HC12 53 /* Motorola M68HC12 */
|
||||
#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
|
||||
#define EM_PCP 55 /* Siemens PCP */
|
||||
#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
|
||||
#define EM_NDR1 57 /* Denso NDR1 microprocessor */
|
||||
#define EM_STARCORE 58 /* Motorola Start*Core processor */
|
||||
#define EM_ME16 59 /* Toyota ME16 processor */
|
||||
#define EM_ST100 60 /* STMicroelectronic ST100 processor */
|
||||
#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
|
||||
#define EM_X86_64 62 /* AMD x86-64 */
|
||||
#define EM_PDSP 63 /* Sony DSP Processor */
|
||||
/* RESERVED 64,65 for future use */
|
||||
#define EM_FX66 66 /* Siemens FX66 microcontroller */
|
||||
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
|
||||
#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
|
||||
#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
|
||||
#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
|
||||
#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
|
||||
#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
|
||||
#define EM_SVX 73 /* Silicon Graphics SVx */
|
||||
#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
|
||||
#define EM_VAX 75 /* Digital VAX */
|
||||
#define EM_CHRIS 76 /* Axis Communications embedded proc. */
|
||||
#define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */
|
||||
#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
|
||||
#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
|
||||
#define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */
|
||||
#define EM_HUANY 81 /* Harvard University mach-indep objs */
|
||||
#define EM_PRISM 82 /* SiTera Prism */
|
||||
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
|
||||
#define EM_FR30 84 /* Fujitsu FR30 */
|
||||
#define EM_D10V 85 /* Mitsubishi DV10V */
|
||||
#define EM_D30V 86 /* Mitsubishi DV30V */
|
||||
#define EM_V850 87 /* NEC v850 */
|
||||
#define EM_M32R 88 /* Mitsubishi M32R */
|
||||
#define EM_MN10300 89 /* Matsushita MN10200 */
|
||||
#define EM_MN10200 90 /* Matsushita MN10200 */
|
||||
#define EM_PJ 91 /* picoJava */
|
||||
#define EM_NUM 92 /* number of machine types */
|
||||
|
||||
/* Version */
|
||||
#define EV_NONE 0 /* Invalid */
|
||||
#define EV_CURRENT 1 /* Current */
|
||||
#define EV_NUM 2 /* number of versions */
|
||||
|
||||
/* Section Header */
|
||||
typedef struct ARC_LE {
|
||||
Elf32_Word sh_name; /* name - index into section header
|
||||
string table section */
|
||||
Elf32_Word sh_type; /* type */
|
||||
Elf32_Word sh_flags; /* flags */
|
||||
Elf32_Addr sh_addr; /* address */
|
||||
Elf32_Off sh_offset; /* file offset */
|
||||
Elf32_Word sh_size; /* section size */
|
||||
Elf32_Word sh_link; /* section header table index link */
|
||||
Elf32_Word sh_info; /* extra information */
|
||||
Elf32_Word sh_addralign; /* address alignment */
|
||||
Elf32_Word sh_entsize; /* section entry size */
|
||||
} Elf32_Shdr;
|
||||
|
||||
/* Special Section Indexes */
|
||||
#define SHN_UNDEF 0 /* undefined */
|
||||
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
|
||||
#define SHN_LOPROC 0xff00 /* reserved range for processor */
|
||||
#define SHN_HIPROC 0xff1f /* specific section indexes */
|
||||
#define SHN_LOOS 0xff20 /* reserved range for operating */
|
||||
#define SHN_HIOS 0xff3f /* specific semantics */
|
||||
#define SHN_ABS 0xfff1 /* absolute value */
|
||||
#define SHN_COMMON 0xfff2 /* common symbol */
|
||||
#define SHN_XINDEX 0xffff /* Index is an extra table */
|
||||
#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */
|
||||
|
||||
/* sh_type */
|
||||
#define SHT_NULL 0 /* inactive */
|
||||
#define SHT_PROGBITS 1 /* program defined information */
|
||||
#define SHT_SYMTAB 2 /* symbol table section */
|
||||
#define SHT_STRTAB 3 /* string table section */
|
||||
#define SHT_RELA 4 /* relocation section with addends*/
|
||||
#define SHT_HASH 5 /* symbol hash table section */
|
||||
#define SHT_DYNAMIC 6 /* dynamic section */
|
||||
#define SHT_NOTE 7 /* note section */
|
||||
#define SHT_NOBITS 8 /* no space section */
|
||||
#define SHT_REL 9 /* relation section without addends */
|
||||
#define SHT_SHLIB 10 /* reserved - purpose unknown */
|
||||
#define SHT_DYNSYM 11 /* dynamic symbol table section */
|
||||
#define SHT_INIT_ARRAY 14 /* Array of constructors */
|
||||
#define SHT_FINI_ARRAY 15 /* Array of destructors */
|
||||
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
|
||||
#define SHT_GROUP 17 /* Section group */
|
||||
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
|
||||
#define SHT_NUM 19 /* number of section types */
|
||||
#define SHT_LOOS 0x60000000 /* Start OS-specific */
|
||||
#define SHT_HIOS 0x6fffffff /* End OS-specific */
|
||||
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define SHT_HIPROC 0x7fffffff /* specific section header types */
|
||||
#define SHT_LOUSER 0x80000000 /* reserved range for application */
|
||||
#define SHT_HIUSER 0xffffffff /* specific indexes */
|
||||
|
||||
/* Section names */
|
||||
#define ELF_BSS ".bss" /* uninitialized data */
|
||||
#define ELF_COMMENT ".comment" /* version control information */
|
||||
#define ELF_DATA ".data" /* initialized data */
|
||||
#define ELF_DATA1 ".data1" /* initialized data */
|
||||
#define ELF_DEBUG ".debug" /* debug */
|
||||
#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
|
||||
#define ELF_DYNSTR ".dynstr" /* dynamic string table */
|
||||
#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
|
||||
#define ELF_FINI ".fini" /* termination code */
|
||||
#define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */
|
||||
#define ELF_GOT ".got" /* global offset table */
|
||||
#define ELF_HASH ".hash" /* symbol hash table */
|
||||
#define ELF_INIT ".init" /* initialization code */
|
||||
#define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */
|
||||
#define ELF_INTERP ".interp" /* Pathname of program interpreter */
|
||||
#define ELF_LINE ".line" /* Symbolic line numnber information */
|
||||
#define ELF_NOTE ".note" /* Contains note section */
|
||||
#define ELF_PLT ".plt" /* Procedure linkage table */
|
||||
#define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */
|
||||
#define ELF_REL_DATA ".rel.data" /* relocation data */
|
||||
#define ELF_REL_FINI ".rel.fini" /* relocation termination code */
|
||||
#define ELF_REL_INIT ".rel.init" /* relocation initialization code */
|
||||
#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */
|
||||
#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
|
||||
#define ELF_REL_TEXT ".rel.text" /* relocation code */
|
||||
#define ELF_RODATA ".rodata" /* read-only data */
|
||||
#define ELF_RODATA1 ".rodata1" /* read-only data */
|
||||
#define ELF_SHSTRTAB ".shstrtab" /* section header string table */
|
||||
#define ELF_STRTAB ".strtab" /* string table */
|
||||
#define ELF_SYMTAB ".symtab" /* symbol table */
|
||||
#define ELF_SYMTAB_SHNDX ".symtab_shndx"/* symbol table section index */
|
||||
#define ELF_TBSS ".tbss" /* thread local uninit data */
|
||||
#define ELF_TDATA ".tdata" /* thread local init data */
|
||||
#define ELF_TDATA1 ".tdata1" /* thread local init data */
|
||||
#define ELF_TEXT ".text" /* code */
|
||||
|
||||
/* Section Attribute Flags - sh_flags */
|
||||
#define SHF_WRITE 0x1 /* Writable */
|
||||
#define SHF_ALLOC 0x2 /* occupies memory */
|
||||
#define SHF_EXECINSTR 0x4 /* executable */
|
||||
#define SHF_MERGE 0x10 /* Might be merged */
|
||||
#define SHF_STRINGS 0x20 /* Contains NULL terminated strings */
|
||||
#define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */
|
||||
#define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/
|
||||
#define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */
|
||||
#define SHF_GROUP 0x200 /* Member of section group */
|
||||
#define SHF_TLS 0x400 /* Thread local storage */
|
||||
#define SHF_MASKOS 0x0ff00000 /* OS specific */
|
||||
#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */
|
||||
/* specific section attributes */
|
||||
|
||||
/* Section Group Flags */
|
||||
#define GRP_COMDAT 0x1 /* COMDAT group */
|
||||
#define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */
|
||||
#define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */
|
||||
|
||||
/* Symbol Table Entry */
|
||||
typedef struct ARC_LE elf32_sym {
|
||||
Elf32_Word st_name; /* name - index into string table */
|
||||
Elf32_Addr st_value; /* symbol value */
|
||||
Elf32_Word st_size; /* symbol size */
|
||||
unsigned char st_info; /* type and binding */
|
||||
unsigned char st_other; /* 0 - no defined meaning */
|
||||
Elf32_Half st_shndx; /* section header index */
|
||||
} Elf32_Sym;
|
||||
|
||||
/* Symbol table index */
|
||||
#define STN_UNDEF 0 /* undefined */
|
||||
|
||||
/* Extract symbol info - st_info */
|
||||
#define ELF32_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
|
||||
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
|
||||
#define ELF32_ST_VISIBILITY(x) ((x) & 0x3)
|
||||
|
||||
/* Symbol Binding - ELF32_ST_BIND - st_info */
|
||||
#define STB_LOCAL 0 /* Local symbol */
|
||||
#define STB_GLOBAL 1 /* Global symbol */
|
||||
#define STB_WEAK 2 /* like global - lower precedence */
|
||||
#define STB_NUM 3 /* number of symbol bindings */
|
||||
#define STB_LOOS 10 /* reserved range for operating */
|
||||
#define STB_HIOS 12 /* system specific symbol bindings */
|
||||
#define STB_LOPROC 13 /* reserved range for processor */
|
||||
#define STB_HIPROC 15 /* specific symbol bindings */
|
||||
|
||||
/* Symbol type - ELF32_ST_TYPE - st_info */
|
||||
#define STT_NOTYPE 0 /* not specified */
|
||||
#define STT_OBJECT 1 /* data object */
|
||||
#define STT_FUNC 2 /* function */
|
||||
#define STT_SECTION 3 /* section */
|
||||
#define STT_FILE 4 /* file */
|
||||
#define STT_NUM 5 /* number of symbol types */
|
||||
#define STT_TLS 6 /* Thread local storage symbol */
|
||||
#define STT_LOOS 10 /* reserved range for operating */
|
||||
#define STT_HIOS 12 /* system specific symbol types */
|
||||
#define STT_LOPROC 13 /* reserved range for processor */
|
||||
#define STT_HIPROC 15 /* specific symbol types */
|
||||
|
||||
/* Symbol visibility - ELF32_ST_VISIBILITY - st_other */
|
||||
#define STV_DEFAULT 0 /* Normal visibility rules */
|
||||
#define STV_INTERNAL 1 /* Processor specific hidden class */
|
||||
#define STV_HIDDEN 2 /* Symbol unavailable in other mods */
|
||||
#define STV_PROTECTED 3 /* Not preemptible, not exported */
|
||||
|
||||
|
||||
/* Relocation entry with implicit addend */
|
||||
typedef struct ARC_LE
|
||||
{
|
||||
Elf32_Addr r_offset; /* offset of relocation */
|
||||
Elf32_Word r_info; /* symbol table index and type */
|
||||
} Elf32_Rel;
|
||||
|
||||
/* Relocation entry with explicit addend */
|
||||
typedef struct ARC_LE
|
||||
{
|
||||
Elf32_Addr r_offset; /* offset of relocation */
|
||||
Elf32_Word r_info; /* symbol table index and type */
|
||||
Elf32_Sword r_addend;
|
||||
} Elf32_Rela;
|
||||
|
||||
/* Extract relocation info - r_info */
|
||||
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||
#define ELF32_R_TYPE(i) ((unsigned char) (i))
|
||||
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
|
||||
|
||||
/* Program Header */
|
||||
typedef struct ARC_LE {
|
||||
Elf32_Word p_type; /* segment type */
|
||||
Elf32_Off p_offset; /* segment offset */
|
||||
Elf32_Addr p_vaddr; /* virtual address of segment */
|
||||
Elf32_Addr p_paddr; /* physical address - ignored? */
|
||||
Elf32_Word p_filesz; /* number of bytes in file for seg. */
|
||||
Elf32_Word p_memsz; /* number of bytes in mem. for seg. */
|
||||
Elf32_Word p_flags; /* flags */
|
||||
Elf32_Word p_align; /* memory alignment */
|
||||
} Elf32_Phdr;
|
||||
|
||||
/* Segment types - p_type */
|
||||
#define PT_NULL 0 /* unused */
|
||||
#define PT_LOAD 1 /* loadable segment */
|
||||
#define PT_DYNAMIC 2 /* dynamic linking section */
|
||||
#define PT_INTERP 3 /* the RTLD */
|
||||
#define PT_NOTE 4 /* auxiliary information */
|
||||
#define PT_SHLIB 5 /* reserved - purpose undefined */
|
||||
#define PT_PHDR 6 /* program header */
|
||||
#define PT_TLS 7 /* Thread local storage template */
|
||||
#define PT_NUM 8 /* Number of segment types */
|
||||
#define PT_LOOS 0x60000000 /* reserved range for operating */
|
||||
#define PT_HIOS 0x6fffffff /* system specific segment types */
|
||||
#define PT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define PT_HIPROC 0x7fffffff /* specific segment types */
|
||||
|
||||
/* Segment flags - p_flags */
|
||||
#define PF_X 0x1 /* Executable */
|
||||
#define PF_W 0x2 /* Writable */
|
||||
#define PF_R 0x4 /* Readable */
|
||||
#define PF_MASKOS 0x0ff00000 /* OS specific segment flags */
|
||||
#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */
|
||||
/* specific segment flags */
|
||||
/* Dynamic structure */
|
||||
typedef struct ARC_LE
|
||||
{
|
||||
Elf32_Sword d_tag; /* controls meaning of d_val */
|
||||
union
|
||||
{
|
||||
Elf32_Word d_val; /* Multiple meanings - see d_tag */
|
||||
Elf32_Addr d_ptr; /* program virtual address */
|
||||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
extern Elf32_Dyn _DYNAMIC[];
|
||||
|
||||
/* Dynamic Array Tags - d_tag */
|
||||
#define DT_NULL 0 /* marks end of _DYNAMIC array */
|
||||
#define DT_NEEDED 1 /* string table offset of needed lib */
|
||||
#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */
|
||||
#define DT_PLTGOT 3 /* address PLT/GOT */
|
||||
#define DT_HASH 4 /* address of symbol hash table */
|
||||
#define DT_STRTAB 5 /* address of string table */
|
||||
#define DT_SYMTAB 6 /* address of symbol table */
|
||||
#define DT_RELA 7 /* address of relocation table */
|
||||
#define DT_RELASZ 8 /* size of relocation table */
|
||||
#define DT_RELAENT 9 /* size of relocation entry */
|
||||
#define DT_STRSZ 10 /* size of string table */
|
||||
#define DT_SYMENT 11 /* size of symbol table entry */
|
||||
#define DT_INIT 12 /* address of initialization func. */
|
||||
#define DT_FINI 13 /* address of termination function */
|
||||
#define DT_SONAME 14 /* string table offset of shared obj */
|
||||
#define DT_RPATH 15 /* string table offset of library
|
||||
search path */
|
||||
#define DT_SYMBOLIC 16 /* start sym search in shared obj. */
|
||||
#define DT_REL 17 /* address of rel. tbl. w addends */
|
||||
#define DT_RELSZ 18 /* size of DT_REL relocation table */
|
||||
#define DT_RELENT 19 /* size of DT_REL relocation entry */
|
||||
#define DT_PLTREL 20 /* PLT referenced relocation entry */
|
||||
#define DT_DEBUG 21 /* bugger */
|
||||
#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */
|
||||
#define DT_JMPREL 23 /* add. of PLT's relocation entries */
|
||||
#define DT_BIND_NOW 24 /* Process relocations of object */
|
||||
#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
|
||||
#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
|
||||
#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
|
||||
#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
|
||||
#define DT_RUNPATH 29 /* Library search path */
|
||||
#define DT_FLAGS 30 /* Flags for the object being loaded */
|
||||
#define DT_ENCODING 32 /* Start of encoded range */
|
||||
#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
|
||||
#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
|
||||
#define DT_NUM 34 /* Number used. */
|
||||
#define DT_LOOS 0x60000000 /* reserved range for OS */
|
||||
#define DT_HIOS 0x6fffffff /* specific dynamic array tags */
|
||||
#define DT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */
|
||||
|
||||
/* Dynamic Tag Flags - d_un.d_val */
|
||||
#define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */
|
||||
#define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */
|
||||
#define DF_TEXTREL 0x04 /* Object contains text relocations */
|
||||
#define DF_BIND_NOW 0x08 /* No lazy binding for this object */
|
||||
#define DF_STATIC_TLS 0x10 /* Static thread local storage */
|
||||
|
||||
/* Standard ELF hashing function */
|
||||
unsigned long elf_hash(const unsigned char *name);
|
||||
|
||||
#define ELF_TARG_VER 1 /* The ver for which this code is intended */
|
||||
|
||||
/*
|
||||
* XXX - PowerPC defines really don't belong in here,
|
||||
* but we'll put them in for simplicity.
|
||||
*/
|
||||
|
||||
/* Values for Elf32/64_Ehdr.e_flags. */
|
||||
#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
|
||||
|
||||
/* Cygnus local bits below */
|
||||
#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
|
||||
#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
|
||||
flag */
|
||||
|
||||
/* PowerPC relocations defined by the ABIs */
|
||||
#define R_PPC_NONE 0
|
||||
#define R_PPC_ADDR32 1 /* 32bit absolute address */
|
||||
#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
|
||||
#define R_PPC_ADDR16 3 /* 16bit absolute address */
|
||||
#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
|
||||
#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
|
||||
#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
|
||||
#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
|
||||
#define R_PPC_ADDR14_BRTAKEN 8
|
||||
#define R_PPC_ADDR14_BRNTAKEN 9
|
||||
#define R_PPC_REL24 10 /* PC relative 26 bit */
|
||||
#define R_PPC_REL14 11 /* PC relative 16 bit */
|
||||
#define R_PPC_REL14_BRTAKEN 12
|
||||
#define R_PPC_REL14_BRNTAKEN 13
|
||||
#define R_PPC_GOT16 14
|
||||
#define R_PPC_GOT16_LO 15
|
||||
#define R_PPC_GOT16_HI 16
|
||||
#define R_PPC_GOT16_HA 17
|
||||
#define R_PPC_PLTREL24 18
|
||||
#define R_PPC_COPY 19
|
||||
#define R_PPC_GLOB_DAT 20
|
||||
#define R_PPC_JMP_SLOT 21
|
||||
#define R_PPC_RELATIVE 22
|
||||
#define R_PPC_LOCAL24PC 23
|
||||
#define R_PPC_UADDR32 24
|
||||
#define R_PPC_UADDR16 25
|
||||
#define R_PPC_REL32 26
|
||||
#define R_PPC_PLT32 27
|
||||
#define R_PPC_PLTREL32 28
|
||||
#define R_PPC_PLT16_LO 29
|
||||
#define R_PPC_PLT16_HI 30
|
||||
#define R_PPC_PLT16_HA 31
|
||||
#define R_PPC_SDAREL16 32
|
||||
#define R_PPC_SECTOFF 33
|
||||
#define R_PPC_SECTOFF_LO 34
|
||||
#define R_PPC_SECTOFF_HI 35
|
||||
#define R_PPC_SECTOFF_HA 36
|
||||
/* Keep this the last entry. */
|
||||
#define R_PPC_NUM 37
|
||||
|
||||
/* The remaining relocs are from the Embedded ELF ABI, and are not
|
||||
in the SVR4 ELF ABI. */
|
||||
#define R_PPC_EMB_NADDR32 101
|
||||
#define R_PPC_EMB_NADDR16 102
|
||||
#define R_PPC_EMB_NADDR16_LO 103
|
||||
#define R_PPC_EMB_NADDR16_HI 104
|
||||
#define R_PPC_EMB_NADDR16_HA 105
|
||||
#define R_PPC_EMB_SDAI16 106
|
||||
#define R_PPC_EMB_SDA2I16 107
|
||||
#define R_PPC_EMB_SDA2REL 108
|
||||
#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
|
||||
#define R_PPC_EMB_MRKREF 110
|
||||
#define R_PPC_EMB_RELSEC16 111
|
||||
#define R_PPC_EMB_RELST_LO 112
|
||||
#define R_PPC_EMB_RELST_HI 113
|
||||
#define R_PPC_EMB_RELST_HA 114
|
||||
#define R_PPC_EMB_BIT_FLD 115
|
||||
#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
|
||||
|
||||
/* Diab tool relocations. */
|
||||
#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
|
||||
#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
|
||||
#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
|
||||
#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
|
||||
#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
|
||||
#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
|
||||
|
||||
/* This is a phony reloc to handle any old fashioned TOC16 references
|
||||
that may still be in object files. */
|
||||
#define R_PPC_TOC16 255
|
||||
|
||||
#endif /* _ELF_H */
|
||||
|
1049
arcloaderold_grackle/source/entry.c
Normal file
1049
arcloaderold_grackle/source/entry.c
Normal file
File diff suppressed because it is too large
Load Diff
26
arcloaderold_grackle/source/hwdesc.h
Normal file
26
arcloaderold_grackle/source/hwdesc.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
enum { // MRF = "MacRISC Flag"
|
||||
MRF_IN_EMULATOR = ARC_BIT(0),
|
||||
MRF_VIA_IS_CUDA = ARC_BIT(1),
|
||||
MRF_OLD_WORLD = ARC_BIT(2),
|
||||
};
|
||||
|
||||
typedef struct _HW_DESCRIPTION {
|
||||
ULONG MemoryLength; // Length of physical memory.
|
||||
ULONG MacIoStart; // Base address of Mac I/O controller.
|
||||
ULONG DecrementerFrequency; // Decrementer frequency.
|
||||
ULONG MrFlags; // MRF_* bit flags.
|
||||
ULONG UsbOhciStart[2]; // Base address of USB controller(s).
|
||||
|
||||
// Framebuffer details.
|
||||
ULONG FrameBufferBase; // Base address of frame buffer.
|
||||
//ULONG FrameBufferLength; // Length of frame buffer in video RAM. (unneeded, can be calculated later by height * stride)
|
||||
ULONG FrameBufferWidth; // Display width
|
||||
ULONG FrameBufferHeight; // Display height
|
||||
ULONG FrameBufferStride; // Number of bytes per line.
|
||||
|
||||
// Ramdisk image details if loaded by stage1
|
||||
ULONG DriversImgBase; // Base address of drivers.img
|
||||
ULONG DriversImgSize; // Size of drivers.img
|
||||
} HW_DESCRIPTION, *PHW_DESCRIPTION;
|
80
arcloaderold_grackle/source/modeswitch.S
Normal file
80
arcloaderold_grackle/source/modeswitch.S
Normal file
@ -0,0 +1,80 @@
|
||||
#define _LANGUAGE_ASSEMBLY
|
||||
#include "asm.h"
|
||||
|
||||
.text
|
||||
.global .ModeSwitchEntry
|
||||
.csect .text[PR]
|
||||
.skip 0x800
|
||||
.ModeSwitchEntry: // (ArcFirmEntry Start, PHW_DESCRIPTION HwDesc)
|
||||
|
||||
// save our arguments
|
||||
// r3 (le entrypoint) into srr0
|
||||
mr r29, r3
|
||||
// r4 (argument) into r31
|
||||
mr r31, r4
|
||||
mr r30, r5
|
||||
li r28,-1
|
||||
|
||||
#if 0 // Already done by privesc.
|
||||
// Disable interrupts.
|
||||
mfmsr r7
|
||||
rlwinm r8, r7, 0, 17, 15
|
||||
mtmsr r8
|
||||
isync
|
||||
#endif
|
||||
|
||||
// r4 = CONFIG_ADDR
|
||||
lis r4, 0xFEC0
|
||||
ori r4, r4, 4
|
||||
// r5 = CONFIG_DATA
|
||||
addis r5, r4, 0x20
|
||||
// r6 = PICR1 addr
|
||||
lis r6, 0x8000
|
||||
ori r6, r6, 0x00A8
|
||||
|
||||
// Ensure we can access grackle pci config registers through the MMU:
|
||||
lwbrx r0,0,r4
|
||||
lwbrx r0,0,r5
|
||||
|
||||
// All exceptions lead to infinite loop. No exceptions.
|
||||
li r0,0x10
|
||||
mtctr r0
|
||||
li r7,0
|
||||
lis r8, 0x4800 // b .
|
||||
exception_wipe_loop:
|
||||
stw r8, 4(r7)
|
||||
addi r7, r7, 0x100
|
||||
bdnz+ exception_wipe_loop
|
||||
|
||||
// Set up grackle to r/w PICR1
|
||||
stwbrx r6,0,r4
|
||||
eieio
|
||||
sync
|
||||
lwbrx r0,0,r4
|
||||
sync
|
||||
// Set PICR1_LE_MODE in PICR1
|
||||
lwbrx r7,0,r5
|
||||
sync
|
||||
ori r7,r7,0x20
|
||||
stwbrx r7,0,r5
|
||||
eieio
|
||||
sync
|
||||
|
||||
// Set MSR_ILE now PCI bus is endian swapping and interrupts are disabled
|
||||
mfmsr r7
|
||||
lis r8, 1
|
||||
or r7, r7, r8
|
||||
mtmsr r7
|
||||
isync
|
||||
|
||||
// set up srr1 ready to set MSR_LE, disable MSR_IR|MSR_DR
|
||||
ori r7, r7, 1
|
||||
rlwinm r7, r7, 0, 28, 25
|
||||
mtsrr1 r7
|
||||
mtsrr0 r29
|
||||
|
||||
// srr0 already set up
|
||||
// set the hwdesc arg (vaddr):
|
||||
oris r3, r31, 0x8000
|
||||
// and rfi into le entrypoint
|
||||
rfi
|
31
arcloaderold_grackle/source/stage1.r
Normal file
31
arcloaderold_grackle/source/stage1.r
Normal file
@ -0,0 +1,31 @@
|
||||
#include "MacTypes.r" // for vers type
|
||||
#include "IntlResources.r" // for itlc type
|
||||
|
||||
// boot sector
|
||||
data 'boot' (1, sysHeap, protected) {
|
||||
$$read("apple/boot1.bin")
|
||||
};
|
||||
|
||||
// mixedmode routine descriptor followed by our PEF
|
||||
data 'boot' (2) {
|
||||
$$read("stage1.bin")
|
||||
};
|
||||
|
||||
// version info, needed for Startup Disk to allow this to be selected
|
||||
resource 'vers' (1, purgeable) {
|
||||
0x00, // Major version
|
||||
0x00, // Minor version
|
||||
release, // Release stage
|
||||
0x00, // Non-final release number
|
||||
verUS, // Region code
|
||||
"0.0", // short version string
|
||||
"0.0" // long version string
|
||||
};
|
||||
|
||||
// this is needed or InitResources (called by boot sector) dies
|
||||
resource 'itlc' (0, sysHeap, purgeable) {
|
||||
0, 0x800,
|
||||
noFontForce, intlForce, noOldKeyboard,
|
||||
0, 40, rightOffset, 0, verUS, directionLeftRight,
|
||||
$""
|
||||
};
|
137
arcloaderold_grackle/source/types.h
Normal file
137
arcloaderold_grackle/source/types.h
Normal file
@ -0,0 +1,137 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef _MSC_VER // Microsoft compilers
|
||||
|
||||
#define GET_ARG_COUNT(...) INTERNAL_EXPAND_ARGS_PRIVATE(INTERNAL_ARGS_AUGMENTER(__VA_ARGS__))
|
||||
|
||||
#define INTERNAL_ARGS_AUGMENTER(...) unused, __VA_ARGS__
|
||||
#define INTERNAL_EXPAND(x) x
|
||||
#define INTERNAL_EXPAND_ARGS_PRIVATE(...) INTERNAL_EXPAND(INTERNAL_GET_ARG_COUNT_PRIVATE(__VA_ARGS__, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
|
||||
#define INTERNAL_GET_ARG_COUNT_PRIVATE(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, _10_, _11_, _12_, _13_, _14_, _15_, _16_, _17_, _18_, _19_, _20_, _21_, _22_, _23_, _24_, _25_, _26_, _27_, _28_, _29_, _30_, _31_, _32_, _33_, _34_, _35_, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, count, ...) count
|
||||
|
||||
#else // Non-Microsoft compilers
|
||||
|
||||
#define GET_ARG_COUNT(...) INTERNAL_GET_ARG_COUNT_PRIVATE(0, ## __VA_ARGS__, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||
#define INTERNAL_GET_ARG_COUNT_PRIVATE(_0, _1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, _10_, _11_, _12_, _13_, _14_, _15_, _16_, _17_, _18_, _19_, _20_, _21_, _22_, _23_, _24_, _25_, _26_, _27_, _28_, _29_, _30_, _31_, _32_, _33_, _34_, _35_, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, count, ...) count
|
||||
|
||||
#endif
|
||||
|
||||
#define IN
|
||||
#define OUT
|
||||
#define INOUT
|
||||
#define OPTIONAL
|
||||
|
||||
#define VOID void
|
||||
|
||||
#define ARC_BIT(x) (1 << (x))
|
||||
#define ARC_MB(x) ((x) * 1024 * 1024)
|
||||
|
||||
#ifdef __INTELLISENSE__
|
||||
#define ARC_LE
|
||||
#define ARC_BE
|
||||
#define ARC_PACKED
|
||||
#define ARC_FORCEINLINE
|
||||
#define ARC_ALIGNED(x)
|
||||
#define ARC_NORETURN
|
||||
#define ARC_NOINLINE
|
||||
#else
|
||||
#define ARC_LE __attribute__((scalar_storage_order("little-endian")))
|
||||
#define ARC_BE
|
||||
#define ARC_PACKED __attribute__((packed))
|
||||
#define ARC_FORCEINLINE __attribute__((always_inline))
|
||||
#define ARC_ALIGNED(x) __attribute__((aligned(x)))
|
||||
#define ARC_NORETURN __attribute__((noreturn))
|
||||
#define ARC_NOINLINE __attribute__((noinline))
|
||||
#endif
|
||||
|
||||
typedef void* PVOID;
|
||||
typedef char CHAR, * PCHAR;
|
||||
typedef uint8_t UCHAR, * PUCHAR, BYTE, * PBYTE, BOOLEAN, * PBOOLEAN;
|
||||
typedef int16_t CSHORT, * PCSHORT, SHORT, * PSHORT;
|
||||
typedef uint16_t WORD, * PWORD, USHORT, * PUSHORT;
|
||||
typedef int32_t LONG, * PLONG;
|
||||
typedef uint32_t ULONG, * PULONG;
|
||||
|
||||
typedef uint16_t WCHAR, * PWCHAR;
|
||||
|
||||
typedef uint8_t u8;
|
||||
|
||||
// Specify LARGE_INTEGER as 64-bit values are word-swapped by callers
|
||||
typedef union ARC_LE _LARGE_INTEGER {
|
||||
struct ARC_LE {
|
||||
ULONG LowPart;
|
||||
LONG HighPart;
|
||||
};
|
||||
int64_t QuadPart;
|
||||
} LARGE_INTEGER, * PLARGE_INTEGER;
|
||||
|
||||
typedef union ARC_BE _LARGE_INTEGER_BIG {
|
||||
struct ARC_BE {
|
||||
LONG HighPart;
|
||||
ULONG LowPart;
|
||||
};
|
||||
int64_t QuadPart;
|
||||
} LARGE_INTEGER_BIG, * PLARGE_INTEGER_BIG;
|
||||
|
||||
typedef LARGE_INTEGER PHYSICAL_ADDRESS, * PPHYSICAL_ADDRESS;
|
||||
|
||||
static inline ARC_FORCEINLINE int64_t LargeIntegerToInt64(LARGE_INTEGER li) {
|
||||
return li.QuadPart;
|
||||
}
|
||||
|
||||
#define INT32_TO_LARGE_INTEGER(i32) { .LowPart = (i32), .HighPart = 0 }
|
||||
//#define INT64_TO_LARGE_INTEGER(i64) (LARGE_INTEGER){ .LowPart = ((int64_t)(i64) & 0xffffffff), .HighPart = (((int64_t)(i64) >> 32) & 0xffffffff) }
|
||||
#define INT64_TO_LARGE_INTEGER(i64) (LARGE_INTEGER){ .QuadPart = (i64) }
|
||||
|
||||
static inline ARC_FORCEINLINE LARGE_INTEGER Int64ToLargeInteger(int64_t i64) {
|
||||
LARGE_INTEGER little;
|
||||
little.QuadPart = i64;
|
||||
return little;
|
||||
}
|
||||
|
||||
typedef struct ARC_LE {
|
||||
LONG v;
|
||||
} S32LE, * PS32LE;
|
||||
|
||||
typedef struct {
|
||||
LONG v;
|
||||
} S32BE, * PS32BE;
|
||||
|
||||
typedef struct ARC_LE {
|
||||
uint64_t v;
|
||||
} U64LE, * PU64LE;
|
||||
|
||||
typedef struct {
|
||||
uint64_t v;
|
||||
} U64BE, * PU64BE;
|
||||
|
||||
typedef struct ARC_LE {
|
||||
ULONG v;
|
||||
} U32LE, * PU32LE;
|
||||
|
||||
typedef struct {
|
||||
ULONG v;
|
||||
} U32BE, * PU32BE;
|
||||
|
||||
typedef struct ARC_LE {
|
||||
USHORT v;
|
||||
} U16LE, * PU16LE;
|
||||
|
||||
typedef struct {
|
||||
USHORT v;
|
||||
} U16BE, * PU16BE;
|
||||
|
||||
typedef struct ARC_LE {
|
||||
SHORT v;
|
||||
} S16LE, * PS16LE;
|
||||
|
||||
typedef struct {
|
||||
SHORT v;
|
||||
} S16BE, * PS16BE;
|
||||
|
||||
static inline ARC_FORCEINLINE ULONG SwapEndianness32(ULONG value) {
|
||||
return __builtin_bswap32(value);
|
||||
}
|
Loading…
Reference in New Issue
Block a user