Skip to content

Commit 6efa5d6

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

File tree

5 files changed

+306
-111
lines changed

5 files changed

+306
-111
lines changed

boot_rom/2bBootStartBios.c

+267-8
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,13 +38,271 @@ 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
}
4846

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

60317
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x80, 0x00000100);
61-
62318
}
63-
319+
64320
/* ------------------------- Main Entry for after the ASM sequences ------------------------ */
65321

66322
extern void BootStartBiosLoader ( void ) {
@@ -86,7 +342,10 @@ extern void BootStartBiosLoader ( void ) {
86342
unsigned int Biossize_type;
87343

88344
int validimage;
89-
345+
346+
// Perform basic system initialization (formerly from X-codes)
347+
BootSystemInitialization();
348+
90349
memcpy(&bootloaderChecksum[0],(void*)PROGRAMM_Memory_2bl,20);
91350
memcpy(&bootloadersize,(void*)(PROGRAMM_Memory_2bl+20),4);
92351
memcpy(&compressed_image_start,(void*)(PROGRAMM_Memory_2bl+24),4);

boot_rom/2bBootStartup.S

+13-31
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 code 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 ....
@@ -338,31 +342,9 @@ reload_cs:
338342
xor %eax, %eax
339343
mov %eax, %fs
340344
mov %eax, %gs
341-
342-
movl $ 0x1ffff0,%esp
343-
344-
mov $0x8, %al
345-
mov $0x61, %dx
346-
out %al, %dx
347-
348-
// Enable IDE and NIC
349-
mov $0x8000088C, %eax
350-
movw $0xcf8, %dx
351-
outl %eax, %dx
352-
movw $0xcfc, %dx
353-
movl $0x40000000, %eax
354-
outl %eax, %dx
355-
356-
357-
// CPU Whoami ? sesless ?
358-
mov $0x80000080, %eax
359-
movw $0xcf8, %dx
360-
outl %eax, %dx
361-
movw $0xcfc, %dx
362-
movl $0x100, %eax
363-
outl %eax, %dx
364345

365-
346+
movl $0x1ffff0, %esp
347+
366348
// this can be found in BootResetAction.c
367-
jmp BootStartBiosLoader
368-
349+
jmp BootStartBiosLoader
350+

0 commit comments

Comments
 (0)