diff --git a/boot_rom/2bBootStartBios.c b/boot_rom/2bBootStartBios.c index e35a6432..6449ba8b 100644 --- a/boot_rom/2bBootStartBios.c +++ b/boot_rom/2bBootStartBios.c @@ -16,11 +16,10 @@ #include "2bload.h" #include "sha1.h" -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) { - u32 base_addr = 0x80000000; base_addr |= ((bus & 0xFF) << 16); // bus # base_addr |= ((dev & 0x1F) << 11); // device # @@ -39,13 +38,271 @@ u32 PciReadDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned 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)); - + base_addr |= ((reg_off & 0xff)); + IoOutputDword(0xcf8, base_addr); return IoInputDword(0xcfc); } +void BootSystemInitialization(void) +{ + register u32 res; + + /* translated to C from Xcodes.h */ + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x84, 0x00008001); + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x10, 0x00008001); + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x04, 0x00000003); + IoOutputByte(0x8049, 0x08); + IoOutputByte(0x80d9, 0x00); + IoOutputByte(0x8026, 0x01); + 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, 0x0ff00f00); + PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x24, 0xf7f0f000); + PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x10, 0x0f000000); + 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, 0x0f0010b0); +#else + writel(0x01000010, 0x0f0010b0); +#endif + writel(0x66660000, 0x0f0010cc); + res = readl(0x0f101000); + res &= 0x000c0000; + if (res == 0x00000000) { + res = readl(0x0f101000); + res &= 0xe1f3ffff; + res |= 0x80000000; + writel(res, 0x0f101000); + writel(0xeeee0000, 0x0f0010b8); + } else if (res == 0x000c0000) { + res = readl(0x0f101000); + res &= 0xe1f3ffff; + res |= 0x860c0000; + writel(res, 0x0f101000); + writel(0xffff0000, 0x0f0010b8); + } else { + res = readl(0x0f101000); + res &= 0xe1f3ffff; + res |= 0x820c0000; + writel(res, 0x0f101000); + writel(0x11110000, 0x0f0010b8); + } + writel(0x00000009, 0x0f0010d4); + writel(0x00000000, 0x0f0010b4); + writel(0x00005866, 0x0f0010bc); + writel(0x0351c858, 0x0f0010c4); + writel(0x30007d67, 0x0f0010c8); + writel(0x00000000, 0x0f0010d8); + writel(0xa0423635, 0x0f0010dc); + writel(0x0c6558c6, 0x0f0010e8); + writel(0x03070103, 0x0f100200); + writel(0x11000016, 0x0f100410); + writel(0x84848888, 0x0f100330); + writel(0xffffcfff, 0x0f10032c); + writel(0x00000001, 0x0f100328); + writel(0x000000df, 0x0f100338); + + /* initialize SMBus controller */ + PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x04, 0x00000001); + PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x14, 0x0000c001); + PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x18, 0x0000c201); + IoOutputByte(SMBUS+0x200, 0x70); + + /* 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 video encoder */ + IoOutputByte(SMBUS+4, 0x8a); /* set Conexant address */ + IoOutputByte(SMBUS+8, 0xba); + IoOutputByte(SMBUS+6, 0x3f); + IoOutputByte(SMBUS+2, 0x0a); + do { + res = IoInputByte(SMBUS); + if (res == 0x10) { + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+8, 0x6c); + IoOutputByte(SMBUS+6, 0x46); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+8, 0xb8); + IoOutputByte(SMBUS+6, 0x00); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+8, 0xce); + IoOutputByte(SMBUS+6, 0x19); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+8, 0xc6); + IoOutputByte(SMBUS+6, 0x9c); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+8, 0x32); + IoOutputByte(SMBUS+6, 0x08); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+8, 0xc4); + IoOutputByte(SMBUS+6, 0x01); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + break; + } + } while (res & 0x08); + + if (res == 0x10) break; + + /* Focus video encoder */ + IoOutputByte(SMBUS, 0xff); /* clear any error */ + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+4, 0xd4); /* set Focus address */ + IoOutputByte(SMBUS+8, 0x0c); + IoOutputByte(SMBUS+6, 0x00); + IoOutputByte(SMBUS+2, 0x0a); + do { + res = IoInputByte(SMBUS); + if (res == 0x10) { + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+8, 0x0d); + IoOutputByte(SMBUS+6, 0x20); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + break; + } + } while (res & 0x08); + + if (res == 0x10) break; + + /* Xcalibur video encoder */ + /* + * We don't check to see if these writes fail, as + * we've already tried Conexant and Focus - Oh dear, + * not another encoder... :( + */ + IoOutputByte(SMBUS, 0xff); /* clear any error */ + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+4, 0xe0); /* set Xcalibur address */ + IoOutputByte(SMBUS+8, 0x00); + IoOutputByte(SMBUS+6, 0x00); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+8, 0xb8); + IoOutputByte(SMBUS+6, 0x00); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + } while (0); + + IoOutputByte(SMBUS+4, 0x20); /* set PIC write address */ + IoOutputByte(SMBUS+8, 0x01); + IoOutputByte(SMBUS+6, 0x00); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+4, 0x21); /* set PIC read address */ + IoOutputByte(SMBUS+8, 0x01); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + res = IoInputByte(SMBUS+6); /* if SMC version does not match ... ????? */ + writel(0x00011c01, 0x0f680500); + writel(0x000a0400, 0x0f68050c); + writel(0x00000000, 0x0f001220); + writel(0x00000000, 0x0f001228); + writel(0x00000000, 0x0f001264); + writel(0x00000010, 0x0f001210); + res = readl(0x0f101000); + res &= 0x06000000; + if (res == 0x00000000) { + writel(0x48480848, 0x0f001214); + writel(0x88888888, 0x0f00122c); + } else { + writel(0x09090909, 0x0f001214); + writel(0xaaaaaaaa, 0x0f00122c); + } + writel(0xffffffff, 0x0f001230); + writel(0xaaaaaaaa, 0x0f001234); + writel(0xaaaaaaaa, 0x0f001238); + writel(0x8b8b8b8b, 0x0f00123c); + writel(0xffffffff, 0x0f001240); + writel(0x8b8b8b8b, 0x0f001244); + writel(0x8b8b8b8b, 0x0f001248); + writel(0x00000001, 0x0f1002d4); + writel(0x00100042, 0x0f1002c4); + writel(0x00100042, 0x0f1002cc); + writel(0x00000011, 0x0f1002c0); + writel(0x00000011, 0x0f1002c8); + writel(0x00000032, 0x0f1002c0); + writel(0x00000032, 0x0f1002c8); + writel(0x00000132, 0x0f1002c0); + writel(0x00000132, 0x0f1002c8); + writel(0x00000001, 0x0f1002d0); + writel(0x00000001, 0x0f1002d0); + writel(0x80000000, 0x0f100210); + writel(0xaa8baa8b, 0x0f00124c); + writel(0x0000aa8b, 0x0f001250); + writel(0x081205ff, 0x0f100228); + writel(0x00010000, 0x0f001218); + 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); + PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x6c, 0x01230801); + writel(0x03070103, 0x0f100200); + writel(0x11448000, 0x0f100204); + PciWriteDword(BUS_0, DEV_2, FUNC_0, 0x3c, 0x00000000); + IoOutputByte(SMBUS, 0x10); + + /* report memory size to PIC scratch register */ + IoOutputByte(SMBUS+4, 0x20); /* set PIC write address */ + IoOutputByte(SMBUS+8, 0x13); + IoOutputByte(SMBUS+6, 0x0f); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + IoOutputByte(SMBUS+8, 0x12); + IoOutputByte(SMBUS+6, 0xf0); + IoOutputByte(SMBUS+2, 0x0a); + while (IoInputByte(SMBUS) != 0x10); + IoOutputByte(SMBUS, 0x10); + + /* reload NV2A registers */ + PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x20, 0xfdf0fd00); + PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x10, 0xfd000000); + + IoOutputByte(0x0061, 0x08); + + /* enable IDE and NIC */ + PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x8c, 0x40000000); + + /* CPU whoami ? sesless ? */ + PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x80, 0x00000100); +} + void BootAGPBUSInitialization(void) { u32 temp; @@ -58,9 +315,8 @@ void BootAGPBUSInitialization(void) IoOutputDword(0xcfc , temp ); PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x80, 0x00000100); - } - + /* ------------------------- Main Entry for after the ASM sequences ------------------------ */ extern void BootStartBiosLoader ( void ) { @@ -86,7 +342,10 @@ extern void BootStartBiosLoader ( void ) { unsigned int Biossize_type; int validimage; - + + // Perform basic system initialization (formerly from X-codes) + BootSystemInitialization(); + memcpy(&bootloaderChecksum[0],(void*)PROGRAMM_Memory_2bl,20); memcpy(&bootloadersize,(void*)(PROGRAMM_Memory_2bl+20),4); memcpy(&compressed_image_start,(void*)(PROGRAMM_Memory_2bl+24),4); diff --git a/boot_rom/2bBootStartup.S b/boot_rom/2bBootStartup.S index a9627104..e92d9b0e 100644 --- a/boot_rom/2bBootStartup.S +++ b/boot_rom/2bBootStartup.S @@ -23,7 +23,7 @@ Xcalibur support by Lehner Franz (franz@caos.at) */ -#include "2bconsts.h" +#include "consts.h" #define xcode_peek(val1) .byte 0x2; .long val1 ; .long 0x0 ; #define xcode_poke(val1,val2) .byte 0x3; .long val1 ; .long val2 ; @@ -45,9 +45,6 @@ #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); \ @@ -106,7 +103,14 @@ //The bytecode interpreter begins here .org 0x80 -#include "Xcodes.h" + + // Note: X-codes are now translated to C code in BootSystemInitialization() + + // overflow trick + xcode_poke(0x00000000, 0xfc1000ea); + xcode_poke(0x00000004, 0x000008ff); + + xcode_END(0x806); // Note: never change this from offset 0x1000 .... // This is the Main Entry point .... @@ -338,31 +342,9 @@ reload_cs: xor %eax, %eax mov %eax, %fs mov %eax, %gs - - movl $ 0x1ffff0,%esp - - mov $0x8, %al - mov $0x61, %dx - out %al, %dx - - // Enable IDE and NIC - mov $0x8000088C, %eax - movw $0xcf8, %dx - outl %eax, %dx - movw $0xcfc, %dx - movl $0x40000000, %eax - outl %eax, %dx - - - // CPU Whoami ? sesless ? - mov $0x80000080, %eax - movw $0xcf8, %dx - outl %eax, %dx - movw $0xcfc, %dx - movl $0x100, %eax - outl %eax, %dx - + movl $0x1ffff0, %esp + // this can be found in BootResetAction.c - jmp BootStartBiosLoader - + jmp BootStartBiosLoader + 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 7888e402..1bd84ede 100644 --- a/boot_rom/2bload.h +++ b/boot_rom/2bload.h @@ -10,7 +10,7 @@ * * ***************************************************************************/ -#include "2bconsts.h" +#include "consts.h" #include "stdint.h" #include "cromwell_types.h" @@ -85,6 +85,10 @@ int I2cResetFrontpanelLed(void); ////////// BootResetActions.c +#define readl(addr) (*(volatile unsigned int *) (addr)) +#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b)) + +void BootSystemInitialization(void); void BootStartBiosLoader(void); ///////// BootPerformPicChallengeResponseAction.c diff --git a/include/consts.h b/include/consts.h index 0b356eca..13f8f6bc 100644 --- a/include/consts.h +++ b/include/consts.h @@ -19,11 +19,25 @@ #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 SMBUS I2C_IO_BASE #define SERIAL_PORT 0x3F8 #define SERIAL_IRQ 4 @@ -67,6 +81,13 @@ #define DEV_1f 0x1f #define FUNC_0 0 +#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 /* #define boot_post_macro(value) \ movb $(value), %al ;\