Skip to content

Commit c0a0115

Browse files
committed
boot: Translate X-codes to C in BootSystemInitialization()
Drop using proprietary X-code interpreter for basic system initialization. This makes it possible to use a southbridge (e.g. MCPX X2) that does not contain such interpreter.
1 parent b5e315e commit c0a0115

File tree

5 files changed

+293
-84
lines changed

5 files changed

+293
-84
lines changed

boot_rom/2bBootStartBios.c

+255-7
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@
1616
#include "2bload.h"
1717
#include "sha1.h"
1818

19-
extern int decompress_kernel(char*out, char *data, int len);
19+
extern int decompress_kernel(char *out, char *data, int len);
2020

2121
u32 PciWriteDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned int dw)
2222
{
23-
2423
u32 base_addr = 0x80000000;
2524
base_addr |= ((bus & 0xFF) << 16); // bus #
2625
base_addr |= ((dev & 0x1F) << 11); // device #
@@ -39,9 +38,8 @@ u32 PciReadDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned
3938
base_addr |= ((bus & 0xFF) << 16); // bus #
4039
base_addr |= ((dev & 0x1F) << 11); // device #
4140
base_addr |= ((func & 0x07) << 8); // func #
42-
base_addr |= ((func & 0x07) << 8);
43-
base_addr |= ((reg_off & 0xff));
44-
41+
base_addr |= ((reg_off & 0xff));
42+
4543
IoOutputDword(0xcf8, base_addr);
4644
return IoInputDword(0xcfc);
4745
}
@@ -58,9 +56,259 @@ void BootAGPBUSInitialization(void)
5856
IoOutputDword(0xcfc , temp );
5957

6058
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x80, 0x00000100);
61-
6259
}
63-
60+
61+
extern void BootSystemInitialization(void)
62+
{
63+
register u32 res;
64+
65+
/* translated to C from Xcodes.h */
66+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x84, 0x00008001);
67+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x10, 0x00008001);
68+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x04, 0x00000003);
69+
IoOutputByte(0x8049, 0x08);
70+
IoOutputByte(0x80d9, 0x00);
71+
IoOutputByte(0x8026, 0x01);
72+
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x4c, 0x00000001);
73+
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x18, 0x00010100);
74+
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x84, 0x07ffffff);
75+
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x20, 0x0ff00f00);
76+
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x24, 0xf7f0f000);
77+
PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x10, 0x0f000000);
78+
PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x14, 0xf0000000);
79+
PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x04, 0x00000007);
80+
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x04, 0x00000007);
81+
#ifndef MCPXREVD5
82+
writel(0x07633461, 0x0f0010b0);
83+
#else
84+
writel(0x01000010, 0x0f0010b0);
85+
#endif
86+
writel(0x66660000, 0x0f0010cc);
87+
res = readl(0x0f101000);
88+
res &= 0x000c0000;
89+
if (res == 0x00000000) {
90+
res = readl(0x0f101000);
91+
res &= 0xe1f3ffff;
92+
res |= 0x80000000;
93+
writel(res, 0x0f101000);
94+
writel(0xeeee0000, 0x0f0010b8);
95+
} else if (res == 0x000c0000) {
96+
res = readl(0x0f101000);
97+
res &= 0xe1f3ffff;
98+
res |= 0x860c0000;
99+
writel(res, 0x0f101000);
100+
writel(0xffff0000, 0x0f0010b8);
101+
} else {
102+
res = readl(0x0f101000);
103+
res &= 0xe1f3ffff;
104+
res |= 0x820c0000;
105+
writel(res, 0x0f101000);
106+
writel(0x11110000, 0x0f0010b8);
107+
}
108+
writel(0x00000009, 0x0f0010d4);
109+
writel(0x00000000, 0x0f0010b4);
110+
writel(0x00005866, 0x0f0010bc);
111+
writel(0x0351c858, 0x0f0010c4);
112+
writel(0x30007d67, 0x0f0010c8);
113+
writel(0x00000000, 0x0f0010d8);
114+
writel(0xa0423635, 0x0f0010dc);
115+
writel(0x0c6558c6, 0x0f0010e8);
116+
writel(0x03070103, 0x0f100200);
117+
writel(0x11000016, 0x0f100410);
118+
writel(0x84848888, 0x0f100330);
119+
writel(0xffffcfff, 0x0f10032c);
120+
writel(0x00000001, 0x0f100328);
121+
writel(0x000000df, 0x0f100338);
122+
123+
/* initialize SMBus controller */
124+
PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x04, 0x00000001);
125+
PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x14, 0x0000c001);
126+
PciWriteDword(BUS_0, DEV_1, FUNC_1, 0x18, 0x0000c201);
127+
IoOutputByte(SMBUS+0x200, 0x70);
128+
129+
/* initialize video encoder */
130+
/*
131+
* It is necessary to write to the video encoder, as the PIC
132+
* snoops the I2C traffic and will reset us if it doesn't see what
133+
* it judges as 'appropriate' traffic. Conexant is the most urgent,
134+
* as on v1.0 Xboxes, the PIC was very strict and reset us earlier
135+
* than later models.
136+
*/
137+
do {
138+
/* Conexant video encoder */
139+
IoOutputByte(SMBUS+4, 0x8a); /* set Conexant address */
140+
IoOutputByte(SMBUS+8, 0xba);
141+
IoOutputByte(SMBUS+6, 0x3f);
142+
IoOutputByte(SMBUS+2, 0x0a);
143+
do {
144+
res = IoInputByte(SMBUS);
145+
if (res == 0x10) {
146+
IoOutputByte(SMBUS, 0x10);
147+
IoOutputByte(SMBUS+8, 0x6c);
148+
IoOutputByte(SMBUS+6, 0x46);
149+
IoOutputByte(SMBUS+2, 0x0a);
150+
while (IoInputByte(SMBUS) != 0x10);
151+
IoOutputByte(SMBUS, 0x10);
152+
IoOutputByte(SMBUS+8, 0xb8);
153+
IoOutputByte(SMBUS+6, 0x00);
154+
IoOutputByte(SMBUS+2, 0x0a);
155+
while (IoInputByte(SMBUS) != 0x10);
156+
IoOutputByte(SMBUS, 0x10);
157+
IoOutputByte(SMBUS+8, 0xce);
158+
IoOutputByte(SMBUS+6, 0x19);
159+
IoOutputByte(SMBUS+2, 0x0a);
160+
while (IoInputByte(SMBUS) != 0x10);
161+
IoOutputByte(SMBUS, 0x10);
162+
IoOutputByte(SMBUS+8, 0xc6);
163+
IoOutputByte(SMBUS+6, 0x9c);
164+
IoOutputByte(SMBUS+2, 0x0a);
165+
while (IoInputByte(SMBUS) != 0x10);
166+
IoOutputByte(SMBUS, 0x10);
167+
IoOutputByte(SMBUS+8, 0x32);
168+
IoOutputByte(SMBUS+6, 0x08);
169+
IoOutputByte(SMBUS+2, 0x0a);
170+
while (IoInputByte(SMBUS) != 0x10);
171+
IoOutputByte(SMBUS, 0x10);
172+
IoOutputByte(SMBUS+8, 0xc4);
173+
IoOutputByte(SMBUS+6, 0x01);
174+
IoOutputByte(SMBUS+2, 0x0a);
175+
while (IoInputByte(SMBUS) != 0x10);
176+
IoOutputByte(SMBUS, 0x10);
177+
break;
178+
}
179+
} while (res & 0x08);
180+
181+
if (res == 0x10) break;
182+
183+
/* Focus video encoder */
184+
IoOutputByte(SMBUS, 0xff); /* clear any error */
185+
IoOutputByte(SMBUS, 0x10);
186+
IoOutputByte(SMBUS+4, 0xd4); /* set Focus address */
187+
IoOutputByte(SMBUS+8, 0x0c);
188+
IoOutputByte(SMBUS+6, 0x00);
189+
IoOutputByte(SMBUS+2, 0x0a);
190+
do {
191+
res = IoInputByte(SMBUS);
192+
if (res == 0x10) {
193+
IoOutputByte(SMBUS, 0x10);
194+
IoOutputByte(SMBUS+8, 0x0d);
195+
IoOutputByte(SMBUS+6, 0x20);
196+
IoOutputByte(SMBUS+2, 0x0a);
197+
while (IoInputByte(SMBUS) != 0x10);
198+
IoOutputByte(SMBUS, 0x10);
199+
break;
200+
}
201+
} while (res & 0x08);
202+
203+
if (res == 0x10) break;
204+
205+
/* Xcalibur video encoder */
206+
/*
207+
* We don't check to see if these writes fail, as
208+
* we've already tried Conexant and Focus - Oh dear,
209+
* not another encoder... :(
210+
*/
211+
IoOutputByte(SMBUS, 0xff); /* clear any error */
212+
IoOutputByte(SMBUS, 0x10);
213+
IoOutputByte(SMBUS+4, 0xe0); /* set Xcalibur address */
214+
IoOutputByte(SMBUS+8, 0x00);
215+
IoOutputByte(SMBUS+6, 0x00);
216+
IoOutputByte(SMBUS+2, 0x0a);
217+
while (IoInputByte(SMBUS) != 0x10);
218+
IoOutputByte(SMBUS, 0x10);
219+
IoOutputByte(SMBUS+8, 0xb8);
220+
IoOutputByte(SMBUS+6, 0x00);
221+
IoOutputByte(SMBUS+2, 0x0a);
222+
while (IoInputByte(SMBUS) != 0x10);
223+
IoOutputByte(SMBUS, 0x10);
224+
} while (0);
225+
226+
IoOutputByte(SMBUS+4, 0x20); /* set PIC write address */
227+
IoOutputByte(SMBUS+8, 0x01);
228+
IoOutputByte(SMBUS+6, 0x00);
229+
IoOutputByte(SMBUS+2, 0x0a);
230+
while (IoInputByte(SMBUS) != 0x10);
231+
IoOutputByte(SMBUS, 0x10);
232+
IoOutputByte(SMBUS+4, 0x21); /* set PIC read address */
233+
IoOutputByte(SMBUS+8, 0x01);
234+
IoOutputByte(SMBUS+2, 0x0a);
235+
while (IoInputByte(SMBUS) != 0x10);
236+
IoOutputByte(SMBUS, 0x10);
237+
res = IoInputByte(SMBUS+6); /* if SMC version does not match ... ????? */
238+
writel(0x00011c01, 0x0f680500);
239+
writel(0x000a0400, 0x0f68050c);
240+
writel(0x00000000, 0x0f001220);
241+
writel(0x00000000, 0x0f001228);
242+
writel(0x00000000, 0x0f001264);
243+
writel(0x00000010, 0x0f001210);
244+
res = readl(0x0f101000);
245+
res &= 0x06000000;
246+
if (res == 0x00000000) {
247+
writel(0x48480848, 0x0f001214);
248+
writel(0x88888888, 0x0f00122c);
249+
} else {
250+
writel(0x09090909, 0x0f001214);
251+
writel(0xaaaaaaaa, 0x0f00122c);
252+
}
253+
writel(0xffffffff, 0x0f001230);
254+
writel(0xaaaaaaaa, 0x0f001234);
255+
writel(0xaaaaaaaa, 0x0f001238);
256+
writel(0x8b8b8b8b, 0x0f00123c);
257+
writel(0xffffffff, 0x0f001240);
258+
writel(0x8b8b8b8b, 0x0f001244);
259+
writel(0x8b8b8b8b, 0x0f001248);
260+
writel(0x00000001, 0x0f1002d4);
261+
writel(0x00100042, 0x0f1002c4);
262+
writel(0x00100042, 0x0f1002cc);
263+
writel(0x00000011, 0x0f1002c0);
264+
writel(0x00000011, 0x0f1002c8);
265+
writel(0x00000032, 0x0f1002c0);
266+
writel(0x00000032, 0x0f1002c8);
267+
writel(0x00000132, 0x0f1002c0);
268+
writel(0x00000132, 0x0f1002c8);
269+
writel(0x00000001, 0x0f1002d0);
270+
writel(0x00000001, 0x0f1002d0);
271+
writel(0x80000000, 0x0f100210);
272+
writel(0xaa8baa8b, 0x0f00124c);
273+
writel(0x0000aa8b, 0x0f001250);
274+
writel(0x081205ff, 0x0f100228);
275+
writel(0x00010000, 0x0f001218);
276+
res = PciReadDword(BUS_0, DEV_1, FUNC_0, 0x60);
277+
res |= 0x00000400;
278+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x60, res);
279+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x4c, 0x0000fdde);
280+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x9c, 0x871cc707);
281+
res = PciReadDword(BUS_0, DEV_1, FUNC_0, 0xb4);
282+
res |= 0x00000f00;
283+
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0xb4, res);
284+
PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x40, 0xf0f0c0c0);
285+
PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x44, 0x00c00000);
286+
PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x5c, 0x04070000);
287+
PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x6c, 0x00230801);
288+
PciWriteDword(BUS_0, DEV_0, FUNC_3, 0x6c, 0x01230801);
289+
writel(0x03070103, 0x0f100200);
290+
writel(0x11448000, 0x0f100204);
291+
PciWriteDword(BUS_0, DEV_2, FUNC_0, 0x3c, 0x00000000);
292+
IoOutputByte(SMBUS, 0x10);
293+
294+
/* report memory size to PIC scratch register */
295+
IoOutputByte(SMBUS+4, 0x20); /* set PIC write address */
296+
IoOutputByte(SMBUS+8, 0x13);
297+
IoOutputByte(SMBUS+6, 0x0f);
298+
IoOutputByte(SMBUS+2, 0x0a);
299+
while (IoInputByte(SMBUS) != 0x10);
300+
IoOutputByte(SMBUS, 0x10);
301+
IoOutputByte(SMBUS+8, 0x12);
302+
IoOutputByte(SMBUS+6, 0xf0);
303+
IoOutputByte(SMBUS+2, 0x0a);
304+
while (IoInputByte(SMBUS) != 0x10);
305+
IoOutputByte(SMBUS, 0x10);
306+
307+
/* reload NV2A registers */
308+
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x20, 0xfdf0fd00);
309+
PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x10, 0xfd000000);
310+
}
311+
64312
/* ------------------------- Main Entry for after the ASM sequences ------------------------ */
65313

66314
extern void BootStartBiosLoader ( void ) {

boot_rom/2bBootStartup.S

+12-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
Xcalibur support by Lehner Franz ([email protected])
2424
*/
2525

26-
#include "2bconsts.h"
26+
#include "consts.h"
2727

2828
#define xcode_peek(val1) .byte 0x2; .long val1 ; .long 0x0 ;
2929
#define xcode_poke(val1,val2) .byte 0x3; .long val1 ; .long val2 ;
@@ -45,9 +45,6 @@
4545

4646
#define xcode_END(val1) .byte 0xEE; .long val1 ; .long 0x0;
4747

48-
#define SMBUS 0x0000c000
49-
50-
5148
#define SMB_xcode_Write(val1,val2); xcode_outb(SMBUS+8, val1); \
5249
xcode_outb(SMBUS+6, val2); \
5350
xcode_outb(SMBUS+2, 0x0000000a); \
@@ -106,7 +103,14 @@
106103

107104
//The bytecode interpreter begins here
108105
.org 0x80
109-
#include "Xcodes.h"
106+
107+
// Note: X-codes are now translated to C in BootSystemInitialization()
108+
109+
// overflow trick
110+
xcode_poke(0x00000000, 0xfc1000ea);
111+
xcode_poke(0x00000004, 0x000008ff);
112+
113+
xcode_END(0x806);
110114

111115
// Note: never change this from offset 0x1000 ....
112116
// This is the Main Entry point ....
@@ -341,6 +345,9 @@ reload_cs:
341345

342346
movl $ 0x1ffff0,%esp
343347

348+
// Perform basic system initialization (formerly from X-codes)
349+
call BootSystemInitialization
350+
344351
mov $0x8, %al
345352
mov $0x61, %dx
346353
out %al, %dx

0 commit comments

Comments
 (0)