Skip to content

Commit 0e416c8

Browse files
committed
boot: Add 1BL initialization for ROM less southbridges
1 parent bf9dc2a commit 0e416c8

File tree

11 files changed

+633
-379
lines changed

11 files changed

+633
-379
lines changed

boot_rom/2bBootStartBios.c

+199-46
Original file line numberDiff line numberDiff line change
@@ -22,55 +22,213 @@ int BufferINlen;
2222
unsigned char *BufferOUT;
2323
int BufferOUTPos;
2424

25-
extern int decompress_kernel(char*out, char *data, int len);
25+
extern int decompress_kernel(char *out, char *data, int len);
2626

27-
u32 PciWriteDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned int dw)
27+
void BootSystemInitialization(void)
2828
{
29-
30-
u32 base_addr = 0x80000000;
31-
base_addr |= ((bus & 0xFF) << 16); // bus #
32-
base_addr |= ((dev & 0x1F) << 11); // device #
33-
base_addr |= ((func & 0x07) << 8); // func #
34-
base_addr |= ((reg_off & 0xff));
35-
36-
IoOutputDword(0xcf8, base_addr );
37-
IoOutputDword(0xcfc ,dw);
38-
39-
return 0;
40-
}
41-
42-
u32 PciReadDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off)
43-
{
44-
u32 base_addr = 0x80000000;
45-
base_addr |= ((bus & 0xFF) << 16); // bus #
46-
base_addr |= ((dev & 0x1F) << 11); // device #
47-
base_addr |= ((func & 0x07) << 8); // func #
48-
base_addr |= ((func & 0x07) << 8);
49-
base_addr |= ((reg_off & 0xff));
50-
51-
IoOutputDword(0xcf8, base_addr);
52-
return IoInputDword(0xcfc);
29+
const u32 base = NV2A_MMIO_BASE;
30+
register u32 res;
31+
32+
/* check to see if we're an Original Xbox first */
33+
if (PciReadDword(BUS_0, DEV_0, FUNC_0, 0x00) == 0x02a510de) { /* Original Xbox PCI 0:0.0 ID [10de:02a5] */
34+
outb(0x02, 0x00ee); /* Turn LED green on OpenXenium, if connected */
35+
} else {
36+
/* do something else if we're not */
37+
outb(0x03, 0x00ee); /* Turn LED yellow on OpenXenium, if connected */
38+
outb(0x90, 0x0080);
39+
while (1);
40+
}
41+
42+
/* translated to C from Xcodes.h */
43+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x84, 0x00008001); /* AMD-768 System Management (PM) IO BAR0 */
44+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x10, 0x00008001); /* AMD-768 System Management (PM) IO BAR0 */
45+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x04, 0x00000003);
46+
outb(0x08, 0x8049); /* PM49 - TCO timer halt */
47+
outb(0x00, 0x80d9); /* PMD9 - GPIO25 input mode */
48+
outb(0x01, 0x8026); /* PM26 */
49+
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x4c, 0x00000001);
50+
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x18, 0x00010100);
51+
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x84, 0x07ffffff);
52+
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x20, base | 0x00f00000 | (base >> 16)); /* was 0x0ff00f00 */
53+
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x24, 0xf7f0f000);
54+
PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x10, base); /* was 0x0f000000; set NV2A MMIO BAR0 higher, since we're not X-codes */
55+
PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x14, 0xf0000000);
56+
PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x04, 0x00000007);
57+
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x04, 0x00000007);
58+
#ifndef MCPXREVD5
59+
writel(0x07633461, base + 0x0010b0);
60+
#else
61+
writel(0x01000010, base + 0x0010b0);
62+
#endif
63+
writel(0x66660000, base + 0x0010cc);
64+
res = readl(base + 0x101000);
65+
res &= 0x000c0000;
66+
if (!res) {
67+
res = readl(base + 0x101000);
68+
res &= 0xe1f3ffff;
69+
res |= 0x80000000;
70+
writel(res, base + 0x101000);
71+
writel(0xeeee0000, base + 0x0010b8);
72+
} else if (res == 0x000c0000) {
73+
res = readl(base + 0x101000);
74+
res &= 0xe1f3ffff;
75+
res |= 0x860c0000;
76+
writel(res, base + 0x101000);
77+
writel(0xffff0000, base + 0x0010b8);
78+
} else {
79+
res = readl(base + 0x101000);
80+
res &= 0xe1f3ffff;
81+
res |= 0x820c0000;
82+
writel(res, base + 0x101000);
83+
writel(0x11110000, base + 0x0010b8);
84+
}
85+
writel(0x00000009, base + 0x0010d4);
86+
writel(0x00000000, base + 0x0010b4);
87+
writel(0x00005866, base + 0x0010bc);
88+
writel(0x0351c858, base + 0x0010c4);
89+
writel(0x30007d67, base + 0x0010c8);
90+
writel(0x00000000, base + 0x0010d8);
91+
writel(0xa0423635, base + 0x0010dc);
92+
writel(0x0c6558c6, base + 0x0010e8);
93+
writel(0x03070103, base + 0x100200);
94+
writel(0x11000016, base + 0x100410);
95+
writel(0x84848888, base + 0x100330);
96+
writel(0xffffcfff, base + 0x10032c);
97+
writel(0x00000001, base + 0x100328);
98+
writel(0x000000df, base + 0x100338);
99+
100+
/* initialize SMBus controller */
101+
PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x04, 0x00000001);
102+
PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x14, SMBUS | 1);
103+
PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x18, SMBUS+0x200 | 1);
104+
outb(0x70, SMBUS+0x200);
105+
106+
/* initialize video encoder */
107+
/*
108+
* It is necessary to write to the video encoder, as the PIC
109+
* snoops the I2C traffic and will reset us if it doesn't see what
110+
* it judges as 'appropriate' traffic. Conexant is the most urgent,
111+
* as on v1.0 Xboxes, the PIC was very strict and reset us earlier
112+
* than later models.
113+
*/
114+
do {
115+
/* Conexant (CX25871) video encoder */
116+
smbus_set_addr(0x8a);
117+
smbus_write_start(0xba, 0x3f); /* SLAVER | DACOFF | DACDIS{D,C,B,A} */
118+
if (smbus_cycle_completed()) {
119+
smbus_write(0x6c, 0x46); /* EN_REG_RD | EACTIVE | FLD_MODE[1] */
120+
smbus_write(0xb8, 0x00); /* autoconfiguration register */
121+
smbus_write(0xce, 0x19); /* OUT_MUXC[0] | OUT_MUXB[1] | OUT_MUXA[0] */
122+
smbus_write(0xc6, 0x9c); /* EN_BLANKO | {V,H}SYNCI | IN_MODE[2] */
123+
smbus_write(0x32, 0x08); /* IN_MODE[3] */
124+
smbus_write(0xc4, 0x01); /* EN_OUT */
125+
break;
126+
}
127+
128+
/* Focus (FS454) video encoder */
129+
smbus_set_addr(0xd4);
130+
smbus_write_start(0x0c, 0x00);
131+
if (smbus_cycle_completed()) {
132+
smbus_write(0x0d, 0x20);
133+
break;
134+
}
135+
136+
/* Xcalibur video encoder */
137+
smbus_set_addr(0xe0);
138+
smbus_write_start(0x00, 0x00);
139+
if (smbus_cycle_completed()) {
140+
smbus_write(0xb8, 0x00);
141+
break;
142+
}
143+
} while (0);
144+
145+
smbus_set_addr(0x20); /* set PIC address; write command */
146+
smbus_write(0x01, 0x00);
147+
smbus_set_addr(0x21); /* set PIC address; read command */
148+
res = smbus_read(0x01); /* if SMC version does not match ... ????? */
149+
150+
writel(0x00011c01, base + 0x680500);
151+
writel(0x000a0400, base + 0x68050c);
152+
writel(0x00000000, base + 0x001220);
153+
writel(0x00000000, base + 0x001228);
154+
writel(0x00000000, base + 0x001264);
155+
writel(0x00000010, base + 0x001210);
156+
res = readl(base + 0x101000);
157+
res &= 0x06000000;
158+
if (!res) {
159+
writel(0x48480848, base + 0x001214);
160+
writel(0x88888888, base + 0x00122c);
161+
} else {
162+
writel(0x09090909, base + 0x001214);
163+
writel(0xaaaaaaaa, base + 0x00122c);
164+
}
165+
writel(0xffffffff, base + 0x001230);
166+
writel(0xaaaaaaaa, base + 0x001234);
167+
writel(0xaaaaaaaa, base + 0x001238);
168+
writel(0x8b8b8b8b, base + 0x00123c);
169+
writel(0xffffffff, base + 0x001240);
170+
writel(0x8b8b8b8b, base + 0x001244);
171+
writel(0x8b8b8b8b, base + 0x001248);
172+
writel(0x00000001, base + 0x1002d4);
173+
writel(0x00100042, base + 0x1002c4);
174+
writel(0x00100042, base + 0x1002cc);
175+
writel(0x00000011, base + 0x1002c0);
176+
writel(0x00000011, base + 0x1002c8);
177+
writel(0x00000032, base + 0x1002c0);
178+
writel(0x00000032, base + 0x1002c8);
179+
writel(0x00000132, base + 0x1002c0);
180+
writel(0x00000132, base + 0x1002c8);
181+
writel(0x00000001, base + 0x1002d0);
182+
writel(0x00000001, base + 0x1002d0);
183+
writel(0x80000000, base + 0x100210);
184+
writel(0xaa8baa8b, base + 0x00124c);
185+
writel(0x0000aa8b, base + 0x001250);
186+
writel(0x081205ff, base + 0x100228);
187+
writel(0x00010000, base + 0x001218);
188+
res = PciReadDword(BUS_0, DEV_1, FUNC_0, 0x60);
189+
res |= 0x00000400;
190+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x60, res);
191+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x4c, 0x0000fdde);
192+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x9c, 0x871cc707);
193+
res = PciReadDword(BUS_0, DEV_1, FUNC_0, 0xb4);
194+
res |= 0x00000f00;
195+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0xb4, res);
196+
PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x40, 0xf0f0c0c0);
197+
PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x44, 0x00c00000);
198+
PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x5c, 0x04070000);
199+
PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x6c, 0x00230801); /* FSB clock speed == 133 MHz; no override */
200+
PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x6c, 0x01230801); /* FSB clock speed == 133 MHz; override */
201+
writel(0x03070103, base + 0x100200);
202+
writel(0x11448000, base + 0x100204);
203+
PciWriteDword(BUS_0, DEV_2, FUNC_0, 0x3c, 0x00000000);
204+
205+
/* report memory size to PIC scratch register */
206+
smbus_set_addr(0x20); /* set PIC address; write command */
207+
smbus_write(0x13, 0x0f);
208+
smbus_write(0x12, 0xf0);
209+
210+
/* execution continues in 2bBootStartup.S */
211+
goto *0xfffc1000;
53212
}
54213

55-
void BootAGPBUSInitialization(void)
214+
static INLINE void BootAGPBUSInitialization(void)
56215
{
57-
u32 temp;
58-
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x54, PciReadDword(BUS_0, DEV_1, FUNC_0, 0x54) | 0x88000000 );
216+
register u32 res;
59217

60-
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x64, (PciReadDword(BUS_0, DEV_0, FUNC_0, 0x64))| 0x88000000 );
218+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x54, PciReadDword(BUS_0, DEV_1, FUNC_0, 0x54) | 0x88000000);
219+
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x64, PciReadDword(BUS_0, DEV_0, FUNC_0, 0x64) | 0x88000000);
61220

62-
temp = PciReadDword(BUS_0, DEV_0, FUNC_0, 0x6C);
63-
IoOutputDword(0xcfc , temp & 0xFFFFFFFE);
64-
IoOutputDword(0xcfc , temp );
65-
66-
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x80, 0x00000100);
221+
res = PciReadDword(BUS_0, DEV_0, FUNC_0, 0x6c);
222+
outl(res & 0xfffffffe, PCI_CFG_DATA);
223+
outl(res, PCI_CFG_DATA);
67224

225+
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x80, 0x00000100);
68226
}
69227

70228
/* ------------------------- Main Entry for after the ASM sequences ------------------------ */
71229

72-
extern void BootStartBiosLoader ( void ) {
73-
230+
void BootStartBiosLoader(void)
231+
{
74232
// do not change this, this is linked to many many scipts
75233
unsigned int PROGRAMM_Memory_2bl = 0x00100000;
76234
unsigned int CROMWELL_Memory_pos = 0x03A00000;
@@ -103,12 +261,9 @@ extern void BootStartBiosLoader ( void ) {
103261
SHA1Input(&context,(void*)(PROGRAMM_Memory_2bl+20),bootloadersize-20);
104262
SHA1Result(&context,SHA1_result);
105263

106-
if (memcmp(&bootloaderChecksum[0],&SHA1_result[0],20)==0) {
107-
// HEHE, the Image we copy'd into ram is SHA-1 hash identical, this is Optimum
108-
BootPerformPicChallengeResponseAction();
109-
110-
} else {
111-
// Bad, the checksum does not match, but we can nothing do now, we wait until PIC kills us
264+
if (memcmp(&bootloaderChecksum[0],&SHA1_result[0],20)) {
265+
// Bad, the checksum does not match, we did not get a valid image copied to RAM, so we stop and display an error.
266+
setLED("rrrr");
112267
while(1);
113268
}
114269

@@ -200,13 +355,11 @@ extern void BootStartBiosLoader ( void ) {
200355
// We are not Longer here
201356
}
202357

203-
// Bad, we did not get a valid im age to RAM, we stop and display a error
204-
//setLED("rrrr");
205-
206358
setLED("oooo");
207359

208360
// I2CTransmitWord(0x10, 0x1901); // no reset on eject
209361
// I2CTransmitWord(0x10, 0x0c00); // eject DVD tray
210362

211363
while(1);
212364
}
365+

0 commit comments

Comments
 (0)