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 Aug 9, 2022
1 parent bf9dc2a commit e276f11
Show file tree
Hide file tree
Showing 10 changed files with 579 additions and 277 deletions.
233 changes: 196 additions & 37 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 (PciReadDword(BUS_0, DEV_0, FUNC_0, 0x00) == 0x02a510de) { /* Original Xbox PCI 0:0.0 ID [10de:02a5] */
outb(0x02, 0x00ee); /* Turn LED green on OpenXenium, if connected */
} else {
/* do something else if we're not */
outb(0x90, 0x0080);
outb(0x03, 0x00ee); /* Turn LED yellow on OpenXenium, if connected */
while (1);
}

/* translated to C from Xcodes.h */
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x84, 0x00008001); /* AMD-768 System Management (PM) IO BAR0 */
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x10, 0x00008001); /* AMD-768 System Management (PM) IO BAR0 */
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 BAR0 higher */
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); /* NV_PBUS_DEBUG_CTRIM_0 */
#else
writel(0x01000010, base + 0x0010b0); /* NV_PBUS_DEBUG_CTRIM_0 */
#endif
writel(0x66660000, base + 0x0010cc); /* NV_PBUS_DEBUG_CTRIM_6 */
res = readl(base + 0x101000); /* NV_PEXTDEV_BOOT_0 */
res &= 0x000c0000; /* NV_PEXTDEV_BOOT_0_STRAP_EMRS */
if (!res) { /* NV_PEXTDEV_BOOT_0_STRAP_EMRS_MICRON */
res = readl(base + 0x101000); /* NV_PEXTDEV_BOOT_0 */
res &= 0xe1f3ffff;
res |= 0x80000000; /* NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE */
writel(res, base + 0x101000); /* NV_PEXTDEV_BOOT_0 */
writel(0xeeee0000, base + 0x0010b8); /* NV_PBUS_DEBUG_CTRIM_2 */
} else if (res == 0x000c0000) { /* NV_PEXTDEV_BOOT_0_STRAP_EMRS_REDUCED_DRIVE */
res = readl(base + 0x101000); /* NV_PEXTDEV_BOOT_0 */
res &= 0xe1f3ffff;
res |= 0x860c0000; /* NV_PEXTDEV_BOOT_0_STRAP_{EMRS_REDUCED_DRIVE,OVERWRITE} | 0x06000000 */
writel(res, base + 0x101000); /* NV_PEXTDEV_BOOT_0 */
writel(0xffff0000, base + 0x0010b8); /* NV_PBUS_DEBUG_CTRIM_2 */
} else {
res = readl(base + 0x101000); /* NV_PEXTDEV_BOOT_0 */
res &= 0xe1f3ffff;
res |= 0x820c0000; /* NV_PEXTDEV_BOOT_0_STRAP_{EMRS_REDUCED_DRIVE,OVERWRITE} | 0x02000000 */
writel(res, base + 0x101000); /* NV_PEXTDEV_BOOT_0 */
writel(0x11110000, base + 0x0010b8); /* NV_PBUS_DEBUG_CTRIM_2 */
}
writel(0x00000009, base + 0x0010d4); /* NV_PBUS_DEBUG_CTRIM_7_CCDP_TRIM */
writel(0x00000000, base + 0x0010b4); /* NV_PBUS_DEBUG_CTRIM_1_INIT */
writel(0x00005866, base + 0x0010bc); /* NV_PBUS_DEBUG_CTRIM_3_C[0-3]_DELAY */
writel(0x0351c858, base + 0x0010c4); /* NV_PBUS_DEBUG_CTRIM_4_C[0-6]_DELAY */
writel(0x30007d67, base + 0x0010c8); /* NV_PBUS_DEBUG_CTRIM_5_C{0,1,2,3,7}_DELAY */
writel(0x00000000, base + 0x0010d8); /* NV_PBUS_DEBUG_CTRIM_8_DQSOB_[0-7]_INIT */
writel(0xa0423635, base + 0x0010dc); /* NV_PBUS_DEBUG_CTRIM_9_NV_{PA0,PA1,PA2,PA3,CM,TM,NB}_TRIM */
writel(0x0c6558c6, base + 0x0010e8); /* NV_PBUS_DEBUG_CTRIM_10_M_{NW,FB,PA0,PA1,PA2,PA3,NB}_TRIM */
writel(0x03070103, base + 0x100200); /* NV_PFB_CFG0_{PART_4,EXTBANK_1,BURST_INT_{RD2RD,WR2WR,RD2PRE},AUTO_PRE_{RD,WR}} */
writel(0x11000016, base + 0x100410); /* NV_PFB_WBC_{HWM_22,ATOMIC_CPU_READS,32B_WRITE_BLOCKS_READS} */
writel(0x84848888, base + 0x100330); /* NV_PFB_ARB_XFER_SZ */
writel(0xffffcfff, base + 0x10032c); /* NV_PFB_ARB_TIMEOUT */
writel(0x00000001, base + 0x100328); /* NV_PFB_ARB_PREDIVIDER_DIV_1 */
writel(0x000000df, base + 0x100338); /* NV_PFB_ARB_DIFF_BANK_{EXT,LP,ZO,TX,ZR,CR,CW} */

/* 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_set_addr(0x8a);
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_set_addr(0xd4);
smbus_write_start(0x0c, 0x00);
if (smbus_cycle_completed()) {
smbus_write(0x0d, 0x20);
break;
}

/* Xcalibur video encoder */
smbus_set_addr(0xe0);
smbus_write_start(0x00, 0x00);
if (smbus_cycle_completed()) {
smbus_write(0xb8, 0x00);
break;
}
} while (0);

smbus_set_addr(0x20); /* set PIC address; write command */
smbus_write(0x01, 0x00);
smbus_set_addr(0x21); /* set PIC address; read command */
res = smbus_read(0x01); /* if SMC version does not match ... ????? */

writel(0x00011c01, base + 0x680500); /* NV_PRAMDAC_NVPLL_COEFF - NVCLK clock speed == 233 MHz */
writel(0x000a0400, base + 0x68050c); /* NV_PRAMDAC_PLL_COEFF_SELECT_{NVSOURCE_PROG,VS_PCLK{,2}_TV_PCLK */
writel(0x00000000, base + 0x001220); /* NV_PBUS_FBIO_CALEN */
writel(0x00000000, base + 0x001228); /* NV_PBUS_FBIO_CALSEL */
writel(0x00000000, base + 0x001264); /* NV_PBUS_TVDIO_CALEN */
writel(0x00000010, base + 0x001210); /* NV_PBUS_FBIO_CFG_CLK_EDGE_EARLY */
res = readl(base + 0x101000); /* NV_PEXTDEV_BOOT_0 */
res &= 0x06000000; /* NV_PEXTDEV_BOOT_0_STRAP_USER */
if (!res) { /* NV_PEXTDEV_BOOT_0_STRAP_EMRS_MICRON */
writel(0x48480848, base + 0x001214); /* NV_PBUS_FBIO_DLY */
writel(0x88888888, base + 0x00122c); /* NV_PBUS_FBIO_ADRDRV */
} else { /* NV_PEXTDEV_BOOT_0_STRAP_EMRS_REDUCED_DRIVE */
writel(0x09090909, base + 0x001214); /* NV_PBUS_FBIO_DLY */
writel(0xaaaaaaaa, base + 0x00122c); /* NV_PBUS_FBIO_ADRDRV */
}
writel(0xffffffff, base + 0x001230); /* NV_PBUS_FBIO_CLKDRV */
writel(0xaaaaaaaa, base + 0x001234); /* NV_PBUS_FBIO_DATDRV */
writel(0xaaaaaaaa, base + 0x001238); /* NV_PBUS_FBIO_DQSDRV */
writel(0x8b8b8b8b, base + 0x00123c); /* NV_PBUS_FBIO_ADRSLW */
writel(0xffffffff, base + 0x001240); /* NV_PBUS_FBIO_CLKSLW */
writel(0x8b8b8b8b, base + 0x001244); /* NV_PBUS_FBIO_DATSLW */
writel(0x8b8b8b8b, base + 0x001248); /* NV_PBUS_FBIO_DQSSLW */
writel(0x00000001, base + 0x1002d4); /* NV_PFB_PRE_CMD_PRECHARGE_1 */
writel(0x00100042, base + 0x1002c4); /* NV_PFB_EMRS_{A{1,6},BA0}_1 */
writel(0x00100042, base + 0x1002cc); /* NV_PFB_EMRS_EXT_{A{1,6},BA0}_1 */
writel(0x00000011, base + 0x1002c0); /* NV_PFB_MRS_A{0,4}_1 */
writel(0x00000011, base + 0x1002c8); /* NV_PFB_MRS_EXT_A{0,4}_1 */
writel(0x00000032, base + 0x1002c0); /* NV_PFB_MRS_A{1,4,5}_1 */
writel(0x00000032, base + 0x1002c8); /* NV_PFB_MRS_EXT_A{1,4,5}_1 */
writel(0x00000132, base + 0x1002c0); /* NV_PFB_MRS_A{1,4,5,8}_1 */
writel(0x00000132, base + 0x1002c8); /* NV_PFB_MRS_EXT_A{1,4,5,8}_1 */
writel(0x00000001, base + 0x1002d0); /* NV_PFB_REF_CMD_REFRESH_1 */
writel(0x00000001, base + 0x1002d0); /* NV_PFB_REF_CMD_REFRESH_1 */
writel(0x80000000, base + 0x100210); /* NV_PFB_REFCTRL_VALID_1 */
writel(0xaa8baa8b, base + 0x00124c); /* NV_PBUS_DISPIO_PADCTL */
writel(0x0000aa8b, base + 0x001250); /* NV_PBUS_TVDIO_PADCTL */
writel(0x081205ff, base + 0x100228); /* NV_PFB_TIMING2 */
writel(0x00010000, base + 0x001218); /* NV_PBUS_FBIO_RAM_VREF_ENABLED */
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); /* NV_PFB_CFG0_{PART_4,EXTBANK_1,BURST_INT_{RD2RD,WR2WR,RD2PRE},AUTO_PRE_{RD,WR}} */
writel(0x11448000, base + 0x100204); /* NV_PFB_CFG1_{COL_8,ROW{A,B}_12,BANK{A,B}_2} */
PciWriteDword(BUS_0, DEV_2, FUNC_0, 0x3c, 0x00000000);

/* report memory size to PIC scratch register */
smbus_set_addr(0x20); /* set PIC address; write command */
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 );

PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x64, (PciReadDword(BUS_0, DEV_0, FUNC_0, 0x64))| 0x88000000 );
register u32 res;

temp = PciReadDword(BUS_0, DEV_0, FUNC_0, 0x6C);
IoOutputDword(0xcfc , temp & 0xFFFFFFFE);
IoOutputDword(0xcfc , temp );
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);

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 @@ -210,3 +368,4 @@ extern void BootStartBiosLoader ( void ) {

while(1);
}

Loading

0 comments on commit e276f11

Please sign in to comment.