From f78730c106b7b2bc29e0ff763548f6d4964dc465 Mon Sep 17 00:00:00 2001 From: haxar Date: Sat, 22 Oct 2022 14:58:58 -0700 Subject: [PATCH] boot: Add 1BL initialization for ROM less southbridges --- boot_rom/2bBootStartBios.c | 245 ++++++++++++++++++++++++++------- boot_rom/2bBootStartup.S | 156 +++++++++++++++------ boot_rom/2bPicResponseAction.c | 89 ++++-------- boot_rom/2bconsts.h | 71 ---------- boot_rom/2bload.h | 189 ++++++++++++++++++------- boot_rom/Xcodes.h | 30 +++- boot_rom/bootrom.ld | 63 +++++---- drivers/pci/pci.c | 1 - include/consts.h | 54 +++++++- lib/imagebld/imagebld.c | 92 +++++-------- scripts/ldscript-crom.ld | 42 +++--- 11 files changed, 653 insertions(+), 379 deletions(-) delete mode 100644 boot_rom/2bconsts.h diff --git a/boot_rom/2bBootStartBios.c b/boot_rom/2bBootStartBios.c index 3443d6b5..a099cfdf 100644 --- a/boot_rom/2bBootStartBios.c +++ b/boot_rom/2bBootStartBios.c @@ -22,55 +22,213 @@ int BufferINlen; unsigned char *BufferOUT; int BufferOUTPos; -extern int decompress_kernel(char*out, char *data, int len); +extern int decompress_kernel(char *out, char *data, int len); -u32 PciWriteDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned int dw) +void BootSystemInitialization(void) { - - u32 base_addr = 0x80000000; - base_addr |= ((bus & 0xFF) << 16); // bus # - base_addr |= ((dev & 0x1F) << 11); // device # - base_addr |= ((func & 0x07) << 8); // func # - base_addr |= ((reg_off & 0xff)); - - IoOutputDword(0xcf8, base_addr ); - IoOutputDword(0xcfc ,dw); - - return 0; -} - -u32 PciReadDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off) -{ - u32 base_addr = 0x80000000; - base_addr |= ((bus & 0xFF) << 16); // bus # - base_addr |= ((dev & 0x1F) << 11); // device # - base_addr |= ((func & 0x07) << 8); // func # - base_addr |= ((func & 0x07) << 8); - base_addr |= ((reg_off & 0xff)); - - IoOutputDword(0xcf8, base_addr); - return IoInputDword(0xcfc); + const u32 base = NV2A_MMIO_BASE; + register u32 res; + + /* check to see if we're an Original Xbox first */ + if (machine_is_xbox()) { + outb(0x02, 0x00ee); /* Turn LED green on OpenXenium, if connected */ + } else { + /* do something else if we're not */ + outb(0x03, 0x00ee); /* Turn LED yellow on OpenXenium, if connected */ + outb(0x90, 0x0080); + while (1); + } + + /* translated to C from Xcodes.h */ + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x84, 0x00008001); /* AMD-768 System Management (PM) IO BAR */ + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x10, 0x00008001); /* AMD-768 System Management (PM) IO BAR */ + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x04, 0x00000003); + outb(0x08, 0x8049); /* PM49 - TCO timer halt */ + outb(0x00, 0x80d9); /* PMD9 - GPIO25 input mode */ + outb(0x01, 0x8026); /* PM26 */ + PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x4c, 0x00000001); + PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x18, 0x00010100); + PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x84, 0x07ffffff); + PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x20, base | 0x00f00000 | (base >> 16)); /* was 0x0ff00f00 */ + PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x24, 0xf7f0f000); + PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x10, base); /* was 0x0f000000; set NV2A MMIO BAR higher, since we're not X-codes */ + PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x14, 0xf0000000); + PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x04, 0x00000007); + PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x04, 0x00000007); +#ifndef MCPXREVD5 + writel(0x07633461, base + 0x0010b0); +#else + writel(0x01000010, base + 0x0010b0); +#endif + writel(0x66660000, base + 0x0010cc); + res = readl(base + 0x101000); + res &= 0x000c0000; + if (!res) { + res = readl(base + 0x101000); + res &= 0xe1f3ffff; + res |= 0x80000000; + writel(res, base + 0x101000); + writel(0xeeee0000, base + 0x0010b8); + } else if (res == 0x000c0000) { + res = readl(base + 0x101000); + res &= 0xe1f3ffff; + res |= 0x860c0000; + writel(res, base + 0x101000); + writel(0xffff0000, base + 0x0010b8); + } else { + res = readl(base + 0x101000); + res &= 0xe1f3ffff; + res |= 0x820c0000; + writel(res, base + 0x101000); + writel(0x11110000, base + 0x0010b8); + } + writel(0x00000009, base + 0x0010d4); + writel(0x00000000, base + 0x0010b4); + writel(0x00005866, base + 0x0010bc); + writel(0x0351c858, base + 0x0010c4); + writel(0x30007d67, base + 0x0010c8); + writel(0x00000000, base + 0x0010d8); + writel(0xa0423635, base + 0x0010dc); + writel(0x0c6558c6, base + 0x0010e8); + writel(0x03070103, base + 0x100200); + writel(0x11000016, base + 0x100410); + writel(0x84848888, base + 0x100330); + writel(0xffffcfff, base + 0x10032c); + writel(0x00000001, base + 0x100328); + writel(0x000000df, base + 0x100338); + + /* initialize SMBus controller */ + PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x04, 0x00000001); + PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x14, SMBUS | 1); + PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x18, SMBUS+0x200 | 1); + outb(0x70, SMBUS+0x200); + + /* initialize video encoder */ + /* + * It is necessary to write to the video encoder, as the PIC + * snoops the I2C traffic and will reset us if it doesn't see what + * it judges as 'appropriate' traffic. Conexant is the most urgent, + * as on v1.0 Xboxes, the PIC was very strict and reset us earlier + * than later models. + */ + do { + /* Conexant (CX25871) video encoder */ + smbus_write_addr(SMBUS_CONEXANT_ADDR); + smbus_write_start(0xba, 0x3f); /* SLAVER | DACOFF | DACDIS{D,C,B,A} */ + if (smbus_cycle_completed()) { + smbus_write(0x6c, 0x46); /* EN_REG_RD | EACTIVE | FLD_MODE[1] */ + smbus_write(0xb8, 0x00); /* autoconfiguration register */ + smbus_write(0xce, 0x19); /* OUT_MUXC[0] | OUT_MUXB[1] | OUT_MUXA[0] */ + smbus_write(0xc6, 0x9c); /* EN_BLANKO | {V,H}SYNCI | IN_MODE[2] */ + smbus_write(0x32, 0x08); /* IN_MODE[3] */ + smbus_write(0xc4, 0x01); /* EN_OUT */ + break; + } + + /* Focus (FS454) video encoder */ + smbus_write_addr(SMBUS_FOCUS_ADDR); + smbus_write_start(0x0c, 0x00); + if (smbus_cycle_completed()) { + smbus_write(0x0d, 0x20); + break; + } + + /* Xcalibur video encoder */ + smbus_write_addr(SMBUS_XCALIBUR_ADDR); + smbus_write_start(0x00, 0x00); + if (smbus_cycle_completed()) { + smbus_write(0xb8, 0x00); + break; + } + } while (0); + + smbus_write_addr(SMBUS_SMC_ADDR); + smbus_write(0x01, 0x00); + smbus_read_addr(SMBUS_SMC_ADDR); + res = smbus_read(0x01); /* if SMC version does not match ... ????? */ + + writel(0x00011c01, base + 0x680500); + writel(0x000a0400, base + 0x68050c); + writel(0x00000000, base + 0x001220); + writel(0x00000000, base + 0x001228); + writel(0x00000000, base + 0x001264); + writel(0x00000010, base + 0x001210); + res = readl(base + 0x101000); + res &= 0x06000000; + if (!res) { + writel(0x48480848, base + 0x001214); + writel(0x88888888, base + 0x00122c); + } else { + writel(0x09090909, base + 0x001214); + writel(0xaaaaaaaa, base + 0x00122c); + } + writel(0xffffffff, base + 0x001230); + writel(0xaaaaaaaa, base + 0x001234); + writel(0xaaaaaaaa, base + 0x001238); + writel(0x8b8b8b8b, base + 0x00123c); + writel(0xffffffff, base + 0x001240); + writel(0x8b8b8b8b, base + 0x001244); + writel(0x8b8b8b8b, base + 0x001248); + writel(0x00000001, base + 0x1002d4); + writel(0x00100042, base + 0x1002c4); + writel(0x00100042, base + 0x1002cc); + writel(0x00000011, base + 0x1002c0); + writel(0x00000011, base + 0x1002c8); + writel(0x00000032, base + 0x1002c0); + writel(0x00000032, base + 0x1002c8); + writel(0x00000132, base + 0x1002c0); + writel(0x00000132, base + 0x1002c8); + writel(0x00000001, base + 0x1002d0); + writel(0x00000001, base + 0x1002d0); + writel(0x80000000, base + 0x100210); + writel(0xaa8baa8b, base + 0x00124c); + writel(0x0000aa8b, base + 0x001250); + writel(0x081205ff, base + 0x100228); + writel(0x00010000, base + 0x001218); + res = PciReadDword(BUS_0, DEV_1, FUNC_0, 0x60); + res |= 0x00000400; + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x60, res); + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x4c, 0x0000fdde); + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x9c, 0x871cc707); + res = PciReadDword(BUS_0, DEV_1, FUNC_0, 0xb4); + res |= 0x00000f00; + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0xb4, res); + PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x40, 0xf0f0c0c0); + PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x44, 0x00c00000); + PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x5c, 0x04070000); + PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x6c, 0x00230801); /* FSB clock speed == 133 MHz; no override */ + PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x6c, 0x01230801); /* FSB clock speed == 133 MHz; override */ + writel(0x03070103, base + 0x100200); + writel(0x11448000, base + 0x100204); + PciWriteDword(BUS_0, DEV_2, FUNC_0, 0x3c, 0x00000000); + + /* report memory size to SMC scratch register */ + smbus_write_addr(SMBUS_SMC_ADDR); + smbus_write(0x13, 0x0f); + smbus_write(0x12, 0xf0); + + /* execution continues in 2bBootStartup.S */ + goto *0xfffc1000; } -void BootAGPBUSInitialization(void) +static INLINE void BootAGPBUSInitialization(void) { - u32 temp; - PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x54, PciReadDword(BUS_0, DEV_1, FUNC_0, 0x54) | 0x88000000 ); + register u32 res; - PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x64, (PciReadDword(BUS_0, DEV_0, FUNC_0, 0x64))| 0x88000000 ); + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x54, PciReadDword(BUS_0, DEV_1, FUNC_0, 0x54) | 0x88000000); + PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x64, PciReadDword(BUS_0, DEV_0, FUNC_0, 0x64) | 0x88000000); - temp = PciReadDword(BUS_0, DEV_0, FUNC_0, 0x6C); - IoOutputDword(0xcfc , temp & 0xFFFFFFFE); - IoOutputDword(0xcfc , temp ); - - PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x80, 0x00000100); + res = PciReadDword(BUS_0, DEV_0, FUNC_0, 0x6c); + outl(res & 0xfffffffe, PCI_CFG_DATA); + outl(res, PCI_CFG_DATA); + PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x80, 0x00000100); } /* ------------------------- Main Entry for after the ASM sequences ------------------------ */ -extern void BootStartBiosLoader ( void ) { - +void BootStartBiosLoader(void) +{ // do not change this, this is linked to many many scipts unsigned int PROGRAMM_Memory_2bl = 0x00100000; unsigned int CROMWELL_Memory_pos = 0x03A00000; @@ -103,12 +261,9 @@ extern void BootStartBiosLoader ( void ) { SHA1Input(&context,(void*)(PROGRAMM_Memory_2bl+20),bootloadersize-20); SHA1Result(&context,SHA1_result); - if (memcmp(&bootloaderChecksum[0],&SHA1_result[0],20)==0) { - // HEHE, the Image we copy'd into ram is SHA-1 hash identical, this is Optimum - BootPerformPicChallengeResponseAction(); - - } else { - // Bad, the checksum does not match, but we can nothing do now, we wait until PIC kills us + if (memcmp(&bootloaderChecksum[0],&SHA1_result[0],20)) { + // Bad, the checksum does not match, we did not get a valid image copied to RAM, so we stop and display an error. + setLED("rrrr"); while(1); } @@ -200,9 +355,6 @@ extern void BootStartBiosLoader ( void ) { // We are not Longer here } - // Bad, we did not get a valid im age to RAM, we stop and display a error - //setLED("rrrr"); - setLED("oooo"); // I2CTransmitWord(0x10, 0x1901); // no reset on eject @@ -210,3 +362,4 @@ extern void BootStartBiosLoader ( void ) { while(1); } + diff --git a/boot_rom/2bBootStartup.S b/boot_rom/2bBootStartup.S index defbd26f..ade74012 100644 --- a/boot_rom/2bBootStartup.S +++ b/boot_rom/2bBootStartup.S @@ -23,37 +23,7 @@ Xcalibur support by Lehner Franz (franz@caos.at) */ -#include "2bconsts.h" - -#define xcode_peek(val1) .byte 0x2; .long val1 ; .long 0x0 ; -#define xcode_poke(val1,val2) .byte 0x3; .long val1 ; .long val2 ; -#define xcode_pciout(val1,val2) .byte 0x4; .long val1 ; .long val2 ; -#define xcode_pciin_a(val1) .byte 0x5; .long val1 ; .long 0x0 ; - -#define xcode_bittoggle(val1,val2) .byte 0x6; .long val1 ; .long val2 ; - -#define xcode_ifgoto(val1,val2) .byte 0x8; .long val1 ; .long (9*(val2-1)) ; - -#define xcode_outb(val1,val2) .byte 0x11; .long val1 ; .long val2 ; -#define xcode_inb(val1) .byte 0x12; .long val1 ; .long 0x0 ; - -#define xcode_poke_a(val1) .byte 0x7; .long 0x3; .long val1 ; -#define xcode_pciout_a(val1) .byte 0x7; .long 0x4; .long val1 ; -#define xcode_outb_a(val1) .byte 0x7; .long 0x11; .long val1 ; - -#define xcode_goto(val1) .byte 0x9; .long 0x0; .long (9*(val1-1)); - -#define xcode_END(val1) .byte 0xEE; .long val1 ; .long 0x0; - -#define SMBUS 0x0000c000 - - -#define SMB_xcode_Write(val1,val2); xcode_outb(SMBUS+8, val1); \ - xcode_outb(SMBUS+6, val2); \ - xcode_outb(SMBUS+2, 0x0000000a); \ - xcode_inb(SMBUS); \ - xcode_ifgoto(0x00000010,-1); \ - xcode_outb(SMBUS, 0x00000010); +#include "consts.h" .code32 @@ -85,9 +55,9 @@ .long 0xffffffff .long 0xffffffff - .org 0x40 - .long _start_checksum // This number will be overwritten - // With imagebld, but we need a temp value + .org 0x40 // imagebld temporary values + .long _start_checksum + .long _reset_vector_base .org 0x6c .long 0x00000107 @@ -141,8 +111,8 @@ mov %eax, %cr0 wbinvd - // We clear the cr3 register - mov %eax, %eax + // Invalidate TLB + xor %eax, %eax mov %eax, %cr3 // Clear Memory Type register @@ -241,8 +211,13 @@ cld - // copy everything into RAM + // Set the stack pointer to give us a valid stack + movl $0x1ffff0, %esp + // Perform SMC challenge response + call smbus_smc_challenge_response + + // Copy 2BL to RAM mov $_ram_location, %edi mov $_start_ramcopy, %esi mov $(_size_ramcopy + 100), %ecx @@ -288,13 +263,13 @@ tableGdtDescriptor: .word 0x30 .long tableGdt - .word 0x0 // fill Word, so we get alliged again + .word 0 // fill word for alignment tableIdtDescriptor: .word 2048 .long 0x400000 - .word 0x0 // fill Word, so we get alliged again + .word 0 // fill word for alignment initaftermemcpy: /* @@ -339,9 +314,6 @@ reload_cs: mov %eax, %fs mov %eax, %gs - // Set the stack pointer to give us a valid stack - movl $0x1ffff0, %esp - // Clear out .bss xor %eax, %eax mov $BSS_SIZE_L, %ecx @@ -360,7 +332,6 @@ reload_cs: movl $0x40000000, %eax outl %eax, %dx - // CPU Whoami ? sesless ? mov $0x80000080, %eax movw $0xcf8, %dx @@ -369,7 +340,102 @@ reload_cs: movl $0x100, %eax outl %eax, %dx - - // this can be found in BootResetAction.c + // this can be found in 2bBootStartBios.c jmp BootStartBiosLoader + +/* Initial 16-bit x86 Reset Vector Block */ +.section .reset_vector_base, "ax" + +/* + * This is where the nForce specific table resides & is needed + * on nForce boards to start execution at the reset vector. + * Called "nVMB" in vendor BIOS. Structure is not known. + */ + + .byte 0x65, 0xd0, 0x16, 0x2b, 0x3c, 0x34, 0x33, 0x33, 0x03, 0x03, 0x03, 0x03, 0x0e, 0x1c, 0x1c, 0x1c + .byte 0x03, 0x1c, 0xe0, 0x00, 0x8a, 0x70, 0xe4, 0xf8, 0x31, 0xd3, 0x67, 0x65, 0xd0, 0x0d, 0xe3, 0x00 + .byte 0xc0, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x03, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0xd9, 0x40, 0x24, 0x00, 0x00, 0xdb, 0x17, 0x1d, 0xd9, 0x40, 0x25, 0x00, 0x00, 0xdb, 0x17, 0x1d + .byte 0xd9, 0x40, 0x25, 0x00, 0x00, 0xdb, 0x17, 0x1d, 0xd9, 0x40, 0x26, 0x00, 0x00, 0xdb, 0x17, 0x1d + .byte 0xd9, 0x40, 0x23, 0x00, 0x00, 0xe4, 0x27, 0x25, 0xd9, 0x40, 0x24, 0x00, 0x00, 0xe4, 0x27, 0x25 + .byte 0xd9, 0x40, 0x25, 0x00, 0x00, 0xe4, 0x27, 0x25, 0xd9, 0x40, 0x26, 0x00, 0x00, 0xe4, 0x27, 0x25 + .byte 0xd9, 0x40, 0x20, 0x00, 0x00, 0xe4, 0x17, 0x25, 0xd9, 0x40, 0x21, 0x00, 0x00, 0xe4, 0x17, 0x25 + .byte 0xd9, 0x40, 0x21, 0x00, 0x00, 0xe4, 0x17, 0x25, 0xd9, 0x40, 0x22, 0x00, 0x00, 0xe4, 0x17, 0x25 + .byte 0xd9, 0x40, 0x22, 0x00, 0x00, 0xdb, 0x17, 0x1d, 0xd9, 0x40, 0x23, 0x00, 0x00, 0xdb, 0x17, 0x1d + .byte 0xd9, 0x40, 0x23, 0x00, 0x00, 0xdb, 0x17, 0x1d, 0xd9, 0x40, 0x24, 0x00, 0x00, 0xdb, 0x17, 0x1d + +.section .reset_vector.start, "ax" + +.align 16 + +gdt: + + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 0x00 dummy + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9b, 0xcf, 0x00 // 0x08 code32 + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9b, 0xcf, 0x00 // 0x10 code32 + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00 // 0x18 data32 + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9b, 0x8f, 0x00 // 0x20 code16 (8f indicates 4K granularity, ie, huge limit) + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0x8f, 0x00 // 0x28 data16 + +gdt_end: + +.align 16 + +gdt_desc: + + .word gdt_end - gdt + .long gdt + .word 0 // fill word for alignment + +idt_desc: + + .word 0 + .long 0 + .word 0 // fill word for alignment + +.align 16 + +start_32: + + xor %eax, %eax + mov $0x18, %al // Set SS, DS, and ES to a data32 segment with maximum limit. + mov %eax, %ds + mov %eax, %es + mov %eax, %ss + xor %eax, %eax // Clear FS and GS + mov %eax, %fs + mov %eax, %gs + + // Use function attribute "naked" if jumping to C, + // as RAM is not yet available to set a valid stack. + + // this can be found in 2bBootStartBios.c + jmp BootSystemInitialization + +.align 16 + +.code16 + +start_16: + + cli // Disable interrupts + in $0xee, %al // Enable A20 (pull A20M# high via OpenXenium QPI, if connected) + xor %eax, %eax + mov %eax, %cr3 // Invalidate TLB + lgdtl %cs:gdt_desc // Load GDT + lidtl %cs:idt_desc // Load null IDT + mov %cr0, %eax // Enable "Protected Mode" + or $0x1, %al // - Bit 0: Protected Mode Enable + mov %eax, %cr0 + ljmpl $0x10, $start_32 + +.section .reset_vector, "ax" + + jmp start_16 + diff --git a/boot_rom/2bPicResponseAction.c b/boot_rom/2bPicResponseAction.c index 8149240f..0a87831b 100644 --- a/boot_rom/2bPicResponseAction.c +++ b/boot_rom/2bPicResponseAction.c @@ -14,6 +14,36 @@ #include "2bload.h" +void smbus_smc_challenge_response(void) +{ + register u8 x1c, x1d, x1e, x1f; + register u8 b1, b2, b3, b4; + register int i; + + smbus_read_addr(SMBUS_SMC_ADDR); + smbus_read_start(0x1c); + if (!smbus_cycle_completed()) return; + x1c = smbus_read_data(); + x1d = smbus_read(0x1d); + x1e = smbus_read(0x1e); + x1f = smbus_read(0x1f); + + b1 = 0x33; + b2 = 0xed; + b3 = x1c << 2; + b3 ^= x1d + 0x39; + b3 ^= x1e >> 2; + b3 ^= x1f + 0x63; + b4 = x1c + 0x0b; + b4 ^= x1d >> 2; + b4 ^= x1e + 0x1b; + + for (i = 0; i < 4; b1 += b2 ^ b3, b2 += b1 ^ b4, ++i); + + smbus_write_addr(SMBUS_SMC_ADDR); + smbus_write(0x20, b1); + smbus_write(0x21, b2); +} // ---------------------------- I2C ----------------------------------------------------------- // @@ -85,65 +115,6 @@ int I2CTransmitWord(u8 bPicAddressI2cFormat, u16 wDataToWrite) return ERR_I2C_ERROR_BUS; } -// ---------------------------- PIC challenge/response ----------------------------------------------------------- -// -// given four bytes, returns a u16 -// LSB of return is the 'first' byte, MSB is the 'second' response byte - -u16 BootPicManipulation( - u8 bC, - u8 bD, - u8 bE, - u8 bF -) { - int n=4; - u8 - b1 = 0x33, - b2 = 0xed, - b3 = ((bC<<2) ^ (bD +0x39) ^ (bE >>2) ^ (bF +0x63)), - b4 = ((bC+0x0b) ^ (bD>>2) ^ (bE +0x1b)) - ; - - while(n--) { - b1 += b2 ^ b3; - b2 += b1 ^ b4; - } - - return (u16) ((((u16)b2)<<8) | b1); -} - -// actual business of getting I2C data from PIC and reissuing munged version -// returns zero if all okay, else error code - -int BootPerformPicChallengeResponseAction() -{ - u8 bC, bD, bE, bF; - int n; - - n=I2CTransmitByteGetReturn( 0x10, 0x1c ); - if(n<0) return n; - bC=n; - n=I2CTransmitByteGetReturn( 0x10, 0x1d ); - if(n<0) return n; - bD=n; - n=I2CTransmitByteGetReturn( 0x10, 0x1e ); - if(n<0) return n; - bE=n; - n=I2CTransmitByteGetReturn( 0x10, 0x1f ); - if(n<0) return n; - bF=n; - - { - u16 w=BootPicManipulation(bC, bD, bE, bF); - - I2CTransmitWord( 0x10, 0x2000 | (w&0xff)); - I2CTransmitWord( 0x10, 0x2100 | (w>>8) ); - } - - // continues as part of video setup.... - return ERR_SUCCESS; -} - extern int I2cSetFrontpanelLed(u8 b) { I2CTransmitWord( 0x10, 0x800 | b); // sequencing thanks to Jarin the Penguin! diff --git a/boot_rom/2bconsts.h b/boot_rom/2bconsts.h deleted file mode 100644 index 763f6a71..00000000 --- a/boot_rom/2bconsts.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * - * includes for startup code in a form usable by the .S files - * - */ - - /*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#define PCI_CFG_ADDR 0x0CF8 -#define PCI_CFG_DATA 0x0CFC - -#define MTRR_DEF 0x2ff -#define MTRR_DEF_TYPE 0x800 -#define MTRR_PHYSBASE 0x200 -#define MTRR_LAST 0x20F -#define WB_CACHE 6 -#define BASE0_H 0 -#define BASE0_L WB_CACHE -#define MASK0_H 0x0F -#define MASK0_L 0xFC000800 -#define BASE1_H 0 -#define BASE1_L 0xFFF80005 -#define MASK1_H 0x0F -#define MASK1_L 0x0FFF80800 - -#define I2C_IO_BASE 0xc000 - -#define BUS_0 0 -#define BUS_1 1 - -#define DEV_0 0 -#define DEV_1 1 -#define DEV_2 2 -#define DEV_3 3 -#define DEV_4 4 -#define DEV_5 5 -#define DEV_6 6 -#define DEV_7 7 -#define DEV_8 8 -#define DEV_9 9 -#define DEV_a 0xa -#define DEV_b 0xb -#define DEV_c 0xc -#define DEV_d 0xd -#define DEV_e 0xe -#define DEV_f 0xf -#define DEV_10 0x10 -#define DEV_11 0x11 -#define DEV_12 0x12 -#define DEV_13 0x13 -#define DEV_14 0x14 -#define DEV_15 0x15 -#define DEV_16 0x16 -#define DEV_17 0x17 -#define DEV_18 0x18 -#define DEV_19 0x19 -#define DEV_1a 0x1a -#define DEV_1b 0x1b -#define DEV_1c 0x1c -#define DEV_1d 0x1d -#define DEV_1e 0x1e -#define DEV_1f 0x1f - -#define FUNC_0 0 diff --git a/boot_rom/2bload.h b/boot_rom/2bload.h index a7a48137..4bc23b4b 100644 --- a/boot_rom/2bload.h +++ b/boot_rom/2bload.h @@ -10,27 +10,10 @@ * * ***************************************************************************/ -#include "2bconsts.h" +#include "consts.h" #include "stdint.h" #include "cromwell_types.h" - -///////////////////////////////// -// LED-flashing codes -// or these together as argument to I2cSetFrontpanelLed - -enum { - I2C_LED_RED0 = 0x80, - I2C_LED_RED1 = 0x40, - I2C_LED_RED2 = 0x20, - I2C_LED_RED3 = 0x10, - I2C_LED_GREEN0 = 0x08, - I2C_LED_GREEN1 = 0x04, - I2C_LED_GREEN2 = 0x02, - I2C_LED_GREEN3 = 0x01 -}; - -/////////////////////////////// /* BIOS-wide error codes all have b31 set */ enum { @@ -42,55 +25,164 @@ enum { ERR_BOOT_PIC_ALG_BROKEN = 0x80000101 // PIC algorithm did not pass its self-test }; -//////// BootPerformPicChallengeResponseAction.c +// ---------------------------- IO primitives ----------------------------------------------------------- + +static INLINE void IoOutputByte(u16 wAds, u8 bValue) +{ + __asm__ __volatile__ ("outb %b0,%w1" : : "a" (bValue), "Nd" (wAds)); +} + +static INLINE void IoOutputWord(u16 wAds, u16 wValue) +{ + __asm__ __volatile__ ("outw %0,%w1" : : "a" (wValue), "Nd" (wAds)); +} + +static INLINE void IoOutputDword(u16 wAds, u32 dwValue) +{ + __asm__ __volatile__ ("outl %0,%w1" : : "a" (dwValue), "Nd" (wAds)); +} + +static INLINE u8 IoInputByte(u16 wAds) +{ + register u8 ret; -/* ---------------------------- IO primitives ----------------------------------------------------------- -*/ + __asm__ __volatile__ ("inb %w1,%0" : "=a" (ret) : "Nd" (wAds)); -static __inline void IoOutputByte(u16 wAds, u8 bValue) { - __asm__ __volatile__ ("outb %b0,%w1": :"a" (bValue), "Nd" (wAds)); + return ret; } -static __inline void IoOutputWord(u16 wAds, u16 wValue) { - __asm__ __volatile__ ("outw %0,%w1": :"a" (wValue), "Nd" (wAds)); - } +static INLINE u16 IoInputWord(u16 wAds) +{ + register u16 ret; -static __inline void IoOutputDword(u16 wAds, u32 dwValue) { - __asm__ __volatile__ ("outl %0,%w1": :"a" (dwValue), "Nd" (wAds)); + __asm__ __volatile__ ("inw %w1,%0" : "=a" (ret) : "Nd" (wAds)); + + return ret; } -static __inline u8 IoInputByte(u16 wAds) { - unsigned char _v; - __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (wAds)); - return _v; +static INLINE u32 IoInputDword(u16 wAds) +{ + register u32 ret; + + __asm__ __volatile__ ("inl %w1,%0" : "=a" (ret) : "Nd" (wAds)); + + return ret; } -static __inline u16 IoInputWord(u16 wAds) { - u16 _v; - __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (wAds)); - return _v; +static INLINE void PciWriteDword(u32 bus, u32 dev, u32 func, u32 off, u32 data) +{ + register u32 addr = 0x80000000; + + addr |= (bus & 0xff) << 16; // bus # + addr |= (dev & 0x1f) << 11; // device # + addr |= (func & 0x07) << 8; // func # + addr |= (off & 0xff); // reg offset + + outl(addr, PCI_CFG_ADDR); + outl(data, PCI_CFG_DATA); } -static __inline u32 IoInputDword(u16 wAds) { - u32 _v; - __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (wAds)); - return _v; +static INLINE u32 PciReadDword(u32 bus, u32 dev, u32 func, u32 off) +{ + register u32 addr = 0x80000000; + + addr |= (bus & 0xff) << 16; // bus # + addr |= (dev & 0x1f) << 11; // device # + addr |= (func & 0x07) << 8; // func # + addr |= (off & 0xff); // reg offset + + outl(addr, PCI_CFG_ADDR); + return inl(PCI_CFG_DATA); } -// boot process -int BootPerformPicChallengeResponseAction(void); -// LED control (see associated enum above) -int I2cSetFrontpanelLed(u8 b); -int I2cResetFrontpanelLed(void); +static INLINE void smbus_write_addr(u8 addr) +{ + outb(0xff, SMBUS); /* clear any status */ + addr <<= 1; + outb(addr, SMBUS + 4); /* set host address; write command */ +} -////////// BootResetActions.c +static INLINE void smbus_read_addr(u8 addr) +{ + outb(0xff, SMBUS); /* clear any status */ + addr <<= 1; + addr |= 1; + outb(addr, SMBUS + 4); /* set host address; read command */ +} -void BootStartBiosLoader(void); +static INLINE u8 smbus_wait(void) +{ + register u8 ret; -///////// BootPerformPicChallengeResponseAction.c + while ((ret = inb(SMBUS)) & SMBUS_HST_BSY); /* host controller busy loop */ + outb(SMBUS_HCYC_STS, SMBUS); /* clear host cycle complete status */ + return ret; +} + +static INLINE int smbus_cycle_completed(void) +{ + return smbus_wait() == SMBUS_HCYC_STS; +} + +static INLINE void smbus_write_start(u8 cmd, u8 data) +{ + outb(cmd, SMBUS + 8); /* set host command */ + outb(data, SMBUS + 6); /* set host data */ + outb(0x0a, SMBUS + 2); /* set host start; CYCTYPE == read or write byte | HOSTST */ +} + +static INLINE void smbus_write(u8 cmd, u8 data) +{ + smbus_write_start(cmd, data); + smbus_wait(); +} + +static INLINE void smbus_read_start(u8 cmd) +{ + outb(cmd, SMBUS + 8); /* set host command */ + outb(0x0a, SMBUS + 2); /* set host start; CYCTYPE == read or write byte | HOSTST */ +} + +static INLINE u8 smbus_read_data(void) +{ + return inb(SMBUS + 6); /* get host data */ +} + +static INLINE u8 smbus_read(u8 cmd) +{ + smbus_read_start(cmd); + smbus_wait(); + return smbus_read_data(); +} + +static INLINE int machine_is_xbox(void) +{ + /* Original Xbox PCI 0:0.0 ID [10de:02a5] */ + return PciReadDword(BUS_0, DEV_0, FUNC_0, 0x00) == 0x02a510de; +} + +/* 2bBootStartBios.c */ +void BootSystemInitialization(void) __attribute__((section(".reset_vector.1bl"),naked)); +void BootStartBiosLoader(void); + +/* 2bPicResponseAction.c */ +void smbus_smc_challenge_response(void) __attribute__((section(".low_rom"))); int I2CTransmitWord(u8 bPicAddressI2cFormat, u16 wDataToWrite); int I2CTransmitByteGetReturn(u8 bPicAddressI2cFormat, u8 bDataToWrite); +/* LED control; see associated enum as argument to I2cSetFrontpanelLed */ +enum { + I2C_LED_RED0 = 0x80, + I2C_LED_RED1 = 0x40, + I2C_LED_RED2 = 0x20, + I2C_LED_RED3 = 0x10, + I2C_LED_GREEN0 = 0x08, + I2C_LED_GREEN1 = 0x04, + I2C_LED_GREEN2 = 0x02, + I2C_LED_GREEN3 = 0x01 +}; +int I2cSetFrontpanelLed(u8 b); +int I2cResetFrontpanelLed(void); void *memcpy(void *dest, const void *src, size_t size); void *memset(void *dest, int data, size_t size); @@ -100,3 +192,4 @@ extern unsigned char *BufferIN; extern int BufferINlen; extern unsigned char *BufferOUT; extern int BufferOUTPos; + diff --git a/boot_rom/Xcodes.h b/boot_rom/Xcodes.h index e6574438..437c7769 100644 --- a/boot_rom/Xcodes.h +++ b/boot_rom/Xcodes.h @@ -23,6 +23,34 @@ Xcalibur support by Lehner Franz (franz@caos.at) */ +#define xcode_peek(val1) .byte 0x2; .long val1 ; .long 0x0 ; +#define xcode_poke(val1,val2) .byte 0x3; .long val1 ; .long val2 ; +#define xcode_pciout(val1,val2) .byte 0x4; .long val1 ; .long val2 ; +#define xcode_pciin_a(val1) .byte 0x5; .long val1 ; .long 0x0 ; + +#define xcode_bittoggle(val1,val2) .byte 0x6; .long val1 ; .long val2 ; + +#define xcode_ifgoto(val1,val2) .byte 0x8; .long val1 ; .long (9*(val2-1)) ; + +#define xcode_outb(val1,val2) .byte 0x11; .long val1 ; .long val2 ; +#define xcode_inb(val1) .byte 0x12; .long val1 ; .long 0x0 ; + +#define xcode_poke_a(val1) .byte 0x7; .long 0x3; .long val1 ; +#define xcode_pciout_a(val1) .byte 0x7; .long 0x4; .long val1 ; +#define xcode_outb_a(val1) .byte 0x7; .long 0x11; .long val1 ; + +#define xcode_goto(val1) .byte 0x9; .long 0x0; .long (9*(val1-1)); + +#define xcode_END(val1) .byte 0xEE; .long val1 ; .long 0x0; + +#define SMB_xcode_Write(val1,val2) \ + xcode_outb(SMBUS+8, val1); \ + xcode_outb(SMBUS+6, val2); \ + xcode_outb(SMBUS+2, 0x0000000a); \ + xcode_inb(SMBUS); \ + xcode_ifgoto(0x00000010,-1); \ + xcode_outb(SMBUS, 0x00000010); + //The bytecode interpreter begins here xcode_pciout(0x80000884, 0x00008001); xcode_pciout(0x80000810, 0x00008001); @@ -291,7 +319,7 @@ // mov eax, 0xfffc1000 // jmp eax // nop - xcode_poke(0x00000000, 0xfc1000B8); + xcode_poke(0x00000000, 0xfc1000b8); xcode_poke(0x00000004, 0x90e0ffff); diff --git a/boot_rom/bootrom.ld b/boot_rom/bootrom.ld index a60ca1fa..69f799e3 100644 --- a/boot_rom/bootrom.ld +++ b/boot_rom/bootrom.ld @@ -1,33 +1,39 @@ OUTPUT_FORMAT ("elf32-i386"); OUTPUT_ARCH(i386); + MEMORY { - ram (rwx) : ORIGIN = 0, LENGTH = 64M - rom (rx) : ORIGIN = 0xFFFC0000, LENGTH = 256K + RAM (RW) : ORIGIN = 0, LENGTH = 64M + ROM (RX) : ORIGIN = 0xfffc0000, LENGTH = 256K /* this should be changed depending on the actual size of the ROM */ } - RAM_CODE = 0x00100000; -/* this should be changed depending the actual size of the rom */ -ROM_SIZE = 256K; -LOW_ROM = 0xfffc0000; - - -TOP_ROM = ( LOW_ROM + ROM_SIZE - 512 ); -TOP_ROM_LOAD = ( ROM_SIZE - 512 ); +ROM_BASE = ORIGIN(ROM); +ROM_SIZE = LENGTH(ROM); +ROM_END = ROM_BASE + ROM_SIZE; -SECTIONS { - /DISCARD/ : { *(.note.gnu.property) } +RESET_VECTOR_BLOCK_SIZE = 4K; +RESET_VECTOR_BLOCK_BASE = ROM_END - RESET_VECTOR_BLOCK_SIZE; - /* ROM Part of the programm */ +SECTIONS +{ + /* ROM allocations */ - .low_rom LOW_ROM : AT ( 0x0 ){ + .low_rom ROM_BASE : AT ( 0 ) { *(.low_rom); _end_rom = . ; } - /* RAM Part of the programm */ + .reset_vector (RESET_VECTOR_BLOCK_BASE) : AT (RESET_VECTOR_BLOCK_BASE - ROM_BASE) { + _reset_vector_base = .; + *(.reset_vector_base) + *(.reset_vector.*) + . = ALIGN(RESET_VECTOR_BLOCK_SIZE) - 16; + *(.reset_vector) + } >ROM = 0x00 + + /* RAM allocations */ .text (RAM_CODE) : AT( SIZEOF(.low_rom) ) { _ram_location = .; @@ -35,7 +41,7 @@ SECTIONS { *(.text); *(.text.*) *(.eh_frame) - _start_checksum = _start_ramcopy - LOW_ROM; + _start_checksum = _start_ramcopy - ROM_BASE; } .data (RAM_CODE + SIZEOF(.text)) : AT( SIZEOF(.low_rom) + SIZEOF(.text)) { @@ -47,7 +53,7 @@ SECTIONS { *(.got.*); } - .rodata ( RAM_CODE + SIZEOF(.text) + SIZEOF(.data) ) : AT ( SIZEOF(.low_rom) + SIZEOF(.text) + SIZEOF(.data)) { + .rodata ( RAM_CODE + SIZEOF(.text) + SIZEOF(.data) ) : AT ( SIZEOF(.low_rom) + SIZEOF(.text) + SIZEOF(.data)) { *(.rodata); *(.rodata.str1.1); *(.rodata.str1.4); @@ -67,19 +73,22 @@ SECTIONS { BSS_END = .; } - /* We need to copy the .data section to to upper memory */ + /* We need to copy the .data section to upper memory */ - _size_ramcopy = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata) + SIZEOF(.bss); + _size_ramcopy = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata) + SIZEOF(.bss); _size_sha1hash = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata); -/* - .high_rom TOP_ROM : AT (TOP_ROM_LOAD) { - _start_top_rom = . ; - . = . + ( 512 - sizeof_top ); - *(.high_rom); - _end_top_rom = . ; - } = 0x90909090 -*/ + /DISCARD/ : { + *(.note.gnu.property) + *(.comment) + *(.note.GNU-stack) + *(.eh_frame) + *(.rela.eh_frame) + *(.shstrtab) + *(.symtab) + *(.strtab) + *(.got.plt) + } } BSS_SIZE = BSS_END - BSS_BASE; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cd63a41e..74100ca5 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -329,7 +329,6 @@ void BootPciPeripheralInitialization(void) { __asm__ __volatile__ ( "cli" ); - PciWriteDword(BUS_0, DEV_1, 0, 0x80, 2); // v1.1 2BL kill ROM area if(PciReadByte(BUS_0, DEV_1, 0, 0x8)>=0xd1) { // check revision PciWriteDword(BUS_0, DEV_1, 0, 0xc8, 0x8f00); // v1.1 2BL <-- death } diff --git a/include/consts.h b/include/consts.h index 3f44816c..ca1851b6 100644 --- a/include/consts.h +++ b/include/consts.h @@ -16,20 +16,59 @@ * * ***************************************************************************/ +#define INLINE __inline__ __attribute__((always_inline)) +#define PACKED __attribute__((packed)) + +#define inb(addr) IoInputByte((addr)) +#define inw(addr) IoInputWord((addr)) +#define inl(addr) IoInputDword((addr)) +#define outb(val,addr) IoOutputByte((addr), (val)) +#define outw(val,addr) IoOutputWord((addr), (val)) +#define outl(val,addr) IoOutputDword((addr), (val)) +#define readb(addr) (*(volatile u8 *)(addr)) +#define readw(addr) (*(volatile u16 *)(addr)) +#define readl(addr) (*(volatile u32 *)(addr)) +#define writeb(val,addr) ((*(volatile u8 *)(addr)) = (val)) +#define writew(val,addr) ((*(volatile u16 *)(addr)) = (val)) +#define writel(val,addr) ((*(volatile u32 *)(addr)) = (val)) + #define PCI_CFG_ADDR 0x0CF8 #define PCI_CFG_DATA 0x0CFC +#define MTRR_DEF 0x2ff +#define MTRR_DEF_TYPE 0x800 +#define MTRR_PHYSBASE 0x200 +#define MTRR_LAST 0x20F +#define WB_CACHE 6 +#define BASE0_H 0 +#define BASE0_L WB_CACHE +#define MASK0_H 0x0F +#define MASK0_L 0xFC000800 +#define BASE1_H 0 +#define BASE1_L 0xFFF80005 +#define MASK1_H 0x0F +#define MASK1_L 0x0FFF80800 #define TIMER_IO 0x8008 #define TIMER_FREQ 0x369E99 -#define I2C_IO_BASE 0xC000 +#define I2C_IO_BASE 0xc000 +#define SMBUS I2C_IO_BASE /* PME0 */ +#define SMBUS_HST_BSY 0x08 /* PME0 - host controller busy */ +#define SMBUS_HCYC_STS 0x10 /* PME0 - host cycle complete status */ +#define SMBUS_SMC_ADDR 0x10 /* PIC16 (PIC16LC63A-04/SO) system management controller */ +#define SMBUS_CONEXANT_ADDR 0x45 /* Conexant (CX25871) video encoder */ +#define SMBUS_ADM1032_ADDR 0x54 /* Analog Devices temperature sensor (National Semiconductor LM90 compatible) */ +#define SMBUS_FOCUS_ADDR 0x6a /* Focus (FS454) video encoder */ +#define SMBUS_XCALIBUR_ADDR 0x70 /* Xcalibur video encoder */ #define SERIAL_PORT 0x3F8 #define SERIAL_IRQ 4 #define SERIAL_THR 0 #define SERIAL_LSR 5 +#define NV2A_MMIO_BASE 0xfd000000 + #define BUS_0 0 #define BUS_1 1 @@ -67,12 +106,13 @@ #define DEV_1f 0x1f #define FUNC_0 0 -/* -#define boot_post_macro(value) \ - movb $(value), %al ;\ - outb %al, $0x80 -*/ +#define FUNC_1 1 +#define FUNC_2 2 +#define FUNC_3 3 +#define FUNC_4 4 +#define FUNC_5 5 +#define FUNC_6 6 +#define FUNC_7 7 #endif // _Consts_H_ - diff --git a/lib/imagebld/imagebld.c b/lib/imagebld/imagebld.c index a695e000..4ee15574 100644 --- a/lib/imagebld/imagebld.c +++ b/lib/imagebld/imagebld.c @@ -11,6 +11,7 @@ #include #include +#include #include "sha1.h" #include "md5.h" @@ -43,7 +44,6 @@ struct Checksumstruct { struct BiosIdentifier { - unsigned char Magic[4]; // AUTO unsigned char HeaderVersion; unsigned char XboxVersion; // Which Xbox Version does it Work ? (Options) @@ -52,10 +52,18 @@ struct BiosIdentifier { unsigned char Option1; unsigned char Option2; unsigned char Option3; + unsigned char Padding1; unsigned int BiosSize; // in Bytes +#if 0 // disabled to make use of the reset vector with MCPX X2 southbridges char Name[32]; unsigned char MD5Hash[16]; -}; +#else + char Name[20]; + unsigned int nForceTableOffset; // nForce boards read this table before executing at the reset vector + unsigned char Padding2[8]; + unsigned char ResetVector[16]; +#endif +} __attribute__((packed)); void showUsage(); @@ -69,14 +77,14 @@ void shax(unsigned char *result, unsigned char *data, unsigned int len) } -void writeBiosIdentifier(unsigned char *cromimage, int biosSize) { +void writeBiosIdentifier(unsigned char *cromimage, int biosSize, unsigned int resetvectorbase) { struct BiosIdentifier *BiosHeader = (struct BiosIdentifier *)&cromimage[biosSize-sizeof(struct BiosIdentifier)]; - MD5_CTX hashcontext; - unsigned char digest[16]; +// MD5_CTX hashcontext; + memset(BiosHeader, 0, offsetof(typeof(*BiosHeader), ResetVector)); memcpy(BiosHeader->Magic,"AUTO",4); BiosHeader->HeaderVersion=1; BiosHeader->BiosSize= biosSize; - sprintf(BiosHeader->Name,"Cromwell %s",CROMWELL_VERSION); + snprintf(BiosHeader->Name, sizeof(BiosHeader->Name), "Cromwell %s", CROMWELL_VERSION); BiosHeader->XboxVersion = BiosID_Version10 | BiosID_Version11 | @@ -89,9 +97,11 @@ void writeBiosIdentifier(unsigned char *cromimage, int biosSize) { BiosHeader->VideoEncoder = BiosID_VideoEncoder_Conexant | BiosID_VideoEncoder_Focus; - MD5Init(&hashcontext); - MD5Update(&hashcontext, cromimage, biosSize-16); - MD5Final(BiosHeader->MD5Hash, &hashcontext); +// MD5Init(&hashcontext); +// MD5Update(&hashcontext, cromimage, biosSize-16); +// MD5Final(BiosHeader->MD5Hash, &hashcontext); + + BiosHeader->nForceTableOffset = resetvectorbase; } int xberepair ( const char * xbeimage, @@ -289,13 +299,14 @@ int romcopy ( unsigned char *flash256; unsigned char *flash1024; unsigned char *crom; - unsigned int freeflashspace = 256*1024; - unsigned int romsize=0; - unsigned int a=0; + signed int freeflashspace = 256*1024; + unsigned int romsize=0; + unsigned int a=0; struct Checksumstruct bootloaderstruct ; - unsigned int bootloaderpos; - unsigned int temp; - struct stat fileinfo; + unsigned int bootloaderpos; + unsigned int resetvectorbase; + unsigned int temp; + struct stat fileinfo; loaderimage = malloc(256*1024); flash256 = malloc(256*1024); @@ -334,40 +345,15 @@ int romcopy ( // Ok, we have loaded both images, we can continue - // this is very nasty, but simple , we Dump a GDT to the TOP rom - - memset(&loaderimage[0x3fe00],0x90,512); - memset(&loaderimage[0x3ffd0],0x00,32); - loaderimage[0x3ffcf] = 0xfc; - loaderimage[0x3ffd0] = 0xea; - loaderimage[0x3ffd2] = 0x10; - loaderimage[0x3ffd3] = 0xfc; - loaderimage[0x3ffd4] = 0xff; - loaderimage[0x3ffd5] = 0x08; - loaderimage[0x3ffd7] = 0x90; - - loaderimage[0x3ffe0] = 0xff; - loaderimage[0x3ffe1] = 0xff; - loaderimage[0x3ffe5] = 0x9b; - loaderimage[0x3ffe6] = 0xcf; - loaderimage[0x3ffe8] = 0xff; - loaderimage[0x3ffe9] = 0xff; - loaderimage[0x3ffed] = 0x93; - loaderimage[0x3ffee] = 0xcf; - - loaderimage[0x3fff4] = 0x18; - loaderimage[0x3fff5] = 0x00; - loaderimage[0x3fff6] = 0xd8; - loaderimage[0x3fff7] = 0xff; - loaderimage[0x3fff8] = 0xff; - loaderimage[0x3fff9] = 0xff; - - // We have dumped the GDT now, we continue - - memcpy(&bootloaderpos,&loaderimage[0x40],4); // This can be foun in the 2bBootStartup.S - memset(&loaderimage[0x40],0x0,4); // We do not need this helper sum anymore + bootloaderpos = *(unsigned int *)&loaderimage[0x40]; // This can be found in 2bBootStartup.S + resetvectorbase = *(unsigned int *)&loaderimage[0x44]; + *(unsigned int *)&loaderimage[0x40] = 0; // Not needed anymore + *(unsigned int *)&loaderimage[0x44] = 0; memcpy(&bootloaderstruct,&loaderimage[bootloaderpos],sizeof(struct Checksumstruct)); + // Apply the SmartXX bios identifier data + writeBiosIdentifier(loaderimage, 256*1024, resetvectorbase); + memcpy(flash256,loaderimage,256*1024); memcpy(flash1024,loaderimage,256*1024); @@ -381,9 +367,8 @@ int romcopy ( bootloaderstruct.compressed_image_start = temp; bootloaderstruct.compressed_image_size = romsize; - //freeflashspace = freeflashspace - 512; // We decrement the TOP ROM - // We have no TOP ROM anymore - freeflashspace = freeflashspace - bootloaderstruct.compressed_image_start; + freeflashspace -= 4*1024; // decrement for the Reset Vector Block at the top of ROM + freeflashspace -= bootloaderstruct.compressed_image_start; bootloaderstruct.Biossize_type = 0; // Means it is a 256 kbyte Image memcpy(&flash256[bootloaderpos],&bootloaderstruct,sizeof(struct Checksumstruct)); @@ -435,12 +420,10 @@ int romcopy ( #endif // In 1MB flash we need the Image 2 times, as ... you know - memset(&flash1024[(0*256*1024)+bootloaderstruct.compressed_image_start],0xff,256*1024-bootloaderstruct.compressed_image_start-512); memcpy(&flash1024[3*256*1024],&flash1024[0],256*1024); // Ok, the 2BL loader is ready, we now go to the "Kernel" - memset(&flash256[bootloaderstruct.compressed_image_start+20+romsize],0xff,256*1024-(bootloaderstruct.compressed_image_start+20+romsize)-512); - // The first 20 bytes of the compressed image are the checksum + // The first 20 bytes of the compressed image are the checksum memcpy(&flash256[bootloaderstruct.compressed_image_start+20],&crom[0],romsize); SHA1Reset(&context); SHA1Input(&context,&flash256[bootloaderstruct.compressed_image_start+20],romsize); @@ -461,9 +444,6 @@ int romcopy ( printf("\n"); #endif - //Apply the SmartXX bios identifier data - writeBiosIdentifier(flash256, 256*1024); - writeBiosIdentifier(flash1024, 1024*1024); // Write the 256 /1024 Kbyte Image Back f = fopen(binname256, "w"); fwrite(flash256, 1, 256*1024, f); diff --git a/scripts/ldscript-crom.ld b/scripts/ldscript-crom.ld index 470aa81c..86d46a0c 100644 --- a/scripts/ldscript-crom.ld +++ b/scripts/ldscript-crom.ld @@ -1,33 +1,27 @@ -/* - * loader script - */ - OUTPUT_FORMAT ("elf32-i386"); OUTPUT_ARCH(i386); + MEMORY { - ram (rwx) : ORIGIN = 0, LENGTH = 64M - rom (rx) : ORIGIN = 0x03A00000, LENGTH = 2M + RAM (RW) : ORIGIN = 0, LENGTH = 64M + ROM (RX) : ORIGIN = 0x03a00000 /* 58MiB */, LENGTH = 256K /* this should be changed depending on the actual size of the ROM */ } -/* this should be changed depending the actual size of the rom */ -ROM_SIZE = 256K; -LOW_ROM = 0x03A00000; /* 58MB */ - -SECTIONS { - /DISCARD/ : { *(.note.gnu.property) } +ROM_BASE = ORIGIN(ROM); +ROM_SIZE = LENGTH(ROM); +ROM_END = ROM_BASE + ROM_SIZE; +SECTIONS +{ /* ROM allocations */ - .text LOW_ROM : AT ( 0 ){ - _start_low_rom = . ; + .text ROM_BASE : AT ( 0 ) { *(.text); *(.text.*) *(.eh_frame) - _end_low_rom = . ; } - .rodata (LOW_ROM + SIZEOF(.text)) : AT (SIZEOF(.text)) { + .rodata (ROM_BASE + SIZEOF(.text)) : AT (SIZEOF(.text)) { *(.rodata); *(.rodata.str1.1); *(.rodata.str1.32); @@ -45,7 +39,7 @@ SECTIONS { /* RAM allocations */ - .data (LOW_ROM + SIZEOF(.text) + SIZEOF(.rodata)) : AT( SIZEOF(.text) + SIZEOF(.rodata) ) { + .data (ROM_BASE + SIZEOF(.text) + SIZEOF(.rodata)) : AT( SIZEOF(.text) + SIZEOF(.rodata) ) { _start_data = .; *(.data); *(.data.*); @@ -58,7 +52,7 @@ SECTIONS { /* the data (initialized globals) is moved to ram by the startup code */ - .bss (LOW_ROM + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.data)) : AT( SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.data)) { + .bss (ROM_BASE + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.data)) : AT( SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.data)) { BSS_BASE = .; _bss = .; *(.bss) @@ -70,6 +64,18 @@ SECTIONS { } _end_complete_rom = SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.data) + SIZEOF(.bss); + + /DISCARD/ : { + *(.note.gnu.property) + *(.comment) + *(.note.GNU-stack) + *(.eh_frame) + *(.rela.eh_frame) + *(.shstrtab) + *(.symtab) + *(.strtab) + *(.got.plt) + } } BSS_SIZE = BSS_END - BSS_BASE;