Skip to content

Commit

Permalink
boot: Add 1BL initialization for ROM less southbridges
Browse files Browse the repository at this point in the history
  • Loading branch information
haxar committed Oct 22, 2022
1 parent bf9dc2a commit f78730c
Show file tree
Hide file tree
Showing 11 changed files with 653 additions and 379 deletions.
245 changes: 199 additions & 46 deletions boot_rom/2bBootStartBios.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -200,13 +355,11 @@ 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
// I2CTransmitWord(0x10, 0x0c00); // eject DVD tray

while(1);
}

Loading

0 comments on commit f78730c

Please sign in to comment.