Simplify a few code chunks, fix whitespace and indentation.
[coreboot.git] / src / northbridge / via / vx800 / examples / romstage.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2009 One Laptop per Child, Association, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20
21 #define ASSEMBLY 1
22 #define __PRE_RAM__
23
24 #include <stdint.h>
25 #include <device/pci_def.h>
26 #include <device/pci_ids.h>
27 #include <arch/io.h>
28 #include <device/pnp_def.h>
29 #include <arch/romcc_io.h>
30 #include <arch/hlt.h>
31 #include "pc80/serial.c"
32 #include "console/console.c"
33 #include "lib/ramtest.c"
34 #include "northbridge/via/vx800/vx800.h"
35 #include "cpu/x86/mtrr/earlymtrr.c"
36 #include "cpu/x86/bist.h"
37 #include "pc80/udelay_io.c"
38 #include "lib/delay.c"
39 #include "lib/memcpy.c"
40 #include "cpu/x86/lapic/boot_cpu.c"
41 #include "driving_clk_phase_data.c"
42 #include "northbridge/via/vx800/raminit.h"
43 #include "northbridge/via/vx800/raminit.c"
44
45 static int acpi_is_wakeup_early_via_vx800(void)
46 {
47         device_t dev;
48         u16 tmp, result;
49
50         print_debug("In acpi_is_wakeup_early_via_vx800\n");
51         /* Power management controller */
52         dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
53                                        PCI_DEVICE_ID_VIA_VX855_LPC), 0);
54
55         if (dev == PCI_DEV_INVALID)
56                 die("Power management controller not found\n");
57
58         /* Set ACPI base address to I/O VX800_ACPI_IO_BASE. */
59         pci_write_config16(dev, 0x88, VX800_ACPI_IO_BASE | 0x1);
60
61         /* Enable ACPI accessm RTC signal gated with PSON. */
62         pci_write_config8(dev, 0x81, 0x84);
63
64         tmp = inw(VX800_ACPI_IO_BASE + 0x04);
65         result = ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0;
66         print_debug("         boot_mode=");
67         print_debug_hex16(result);
68         print_debug("\n");
69         return result;
70 }
71
72 static inline int spd_read_byte(unsigned device, unsigned address)
73 {
74         return smbus_read_byte(device, address);
75 }
76
77 static void enable_mainboard_devices(void)
78 {
79         device_t dev;
80         uint16_t values;
81
82         print_debug("In enable_mainboard_devices \n");
83
84         /* Enable P2P bridge Header for external PCI bus. */
85         dev = pci_locate_device(PCI_ID(0x1106, 0xa353), 0);
86         pci_write_config8(dev, 0x4f, 0x41);
87 }
88
89 static void enable_shadow_ram(void)
90 {
91         uint8_t shadowreg;
92
93         pci_write_config8(PCI_DEV(0, 0, 3), 0x80, 0xff);
94         /* 0xf0000-0xfffff - ACPI tables */
95         shadowreg = pci_read_config8(PCI_DEV(0, 0, 3), 0x83);
96         shadowreg |= 0x30;
97         pci_write_config8(PCI_DEV(0, 0, 3), 0x83, shadowreg);
98         /* 0xe0000-0xeffff - elfload? */
99
100         pci_write_config8(PCI_DEV(0, 0, 3), 0x82, 0xff);
101 }
102
103 /*
104 this table contains the value needed to be set before begin to init dram.
105 Note: REV_Bx should be cared when porting a new board!!!!! */
106 static const struct VIA_PCI_REG_INIT_TABLE mNbStage1InitTbl[] = {
107         //VT3409 no pcie
108         0x00, 0xFF, NB_APIC_REG(0x61), 0xFF, 0x0E,      // Set Exxxxxxx as pcie mmio config range
109         0x00, 0xFF, NB_APIC_REG(0x60), 0xF4, 0x0B,      // Support extended cfg address of pcie
110         //0x00, 0xFF, NB_APIC_REG(0x42), 0xF9, 0x02, // APIC Interrupt((BT_INTR)) Control
111         // Set ROMSIP value by software
112
113         /*0x00, 0xFF, NB_HOST_REG(0x70), 0x77, 0x33, // 2x Host Adr Strobe/Pad Pullup Driving = 3
114            0x00, 0xFF, NB_HOST_REG(0x71), 0x77, 0x33, // 2x Host Adr Strobe/Pad Pulldown Driving = 3
115            0x00, 0xFF, NB_HOST_REG(0x72), 0x77, 0x33, // 4x Host Dat Strobe/Pad Pullup Driving = 3
116            0x00, 0xFF, NB_HOST_REG(0x73), 0x77, 0x33, // 4x Host Dat Strobe/Pad Pulldown Driving = 3
117            0x00, 0xFF, NB_HOST_REG(0x74), 0xFF, 0x21, // Memory I/F timing ctrl
118            0x00, 0xFF, NB_HOST_REG(0x74), 0xFF, 0xE1, // Memory I/F timing ctrl
119            0x00, 0xFF, NB_HOST_REG(0x75), 0xFF, 0x18, // AGTL+ I/O Circuit
120            0x00, 0xFF, NB_HOST_REG(0x76), 0xFB, 0x0C, // AGTL+ Compensation Status
121            0x00, 0xFF, NB_HOST_REG(0x78), 0xFF, 0x33, // 2X AGTL+ Auto Compensation Offset
122            0x00, 0xFF, NB_HOST_REG(0x79), 0xFF, 0x33, // 4X AGTL+ Auto Compensation Offset
123            0x00, 0xFF, NB_HOST_REG(0x7A), 0x3F, 0x72, // AGTL Compensation Status
124            0x00, 0xFF, NB_HOST_REG(0x7A), 0x3F, 0x77, // AGTL Compensation Status
125            0x00, 0xFF, NB_HOST_REG(0x7B), 0xFF, 0x44, // Input Host Address / Host Strobe Delay Control for HA Group
126            0x00, 0xFF, NB_HOST_REG(0x7B), 0xFF, 0x22, // Input Host Address / Host Strobe Delay Control for HA Group
127            0x00, 0xFF, NB_HOST_REG(0x7C), 0xFF, 0x00, // Output Delay Control of PAD for HA Group
128            0x00, 0xFF, NB_HOST_REG(0x7D), 0xFF, 0xAA, // Host Address / Address Clock Output Delay Control (Only for P4 Bus)
129            0x00, 0xFF, NB_HOST_REG(0x7E), 0xFF, 0x10, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
130            0x00, 0xFF, NB_HOST_REG(0x7E), 0xFF, 0x40, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
131            0x00, 0xFF, NB_HOST_REG(0x7F), 0xFF, 0x10, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
132            0x00, 0xFF, NB_HOST_REG(0x7F), 0xFF, 0x40, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
133            0x00, 0xFF, NB_HOST_REG(0x80), 0x3F, 0x44, // Host Data Receiving Strobe Delay Ctrl 1
134            0x00, 0xFF, NB_HOST_REG(0x81), 0xFF, 0x44, // Host Data Receiving Strobe Delay Ctrl 2
135            0x00, 0xFF, NB_HOST_REG(0x82), 0xFF, 0x00, // Output Delay of PAD for HDSTB
136            0x00, 0xFF, NB_HOST_REG(0x83), 0xFF, 0x00, // Output Delay of PAD for HD
137            0x00, 0xFF, NB_HOST_REG(0x84), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 0)
138            0x00, 0xFF, NB_HOST_REG(0x85), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 1)
139            0x00, 0xFF, NB_HOST_REG(0x86), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 2)
140            0x00, 0xFF, NB_HOST_REG(0x87), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 3) */
141
142
143         // CPU Host Bus Control
144         0x00, 0xFF, NB_HOST_REG(0x50), 0x1F, 0x08,      // Request phase ctrl: Dynamic Defer Snoop Stall Count = 8
145         //0x00, 0xFF, NB_HOST_REG(0x51), 0xFF, 0x7F, // CPU I/F Ctrl-1: Disable Fast DRDY and RAW
146         0x00, 0xFF, NB_HOST_REG(0x51), 0xFF, 0x7C,      // CPU I/F Ctrl-1: Disable Fast DRDY and RAW
147         0x00, 0xFF, NB_HOST_REG(0x52), 0xCB, 0xCB,      // CPU I/F Ctrl-2: Enable all for performance
148         //0x00, 0xFF, NB_HOST_REG(0x53), 0xFF, 0x88, // Arbitration: Host/Master Occupancy timer = 8*4 HCLK
149         0x00, 0xFF, NB_HOST_REG(0x53), 0xFF, 0x44,      // Arbitration: Host/Master Occupancy timer = 4*4 HCLK
150         0x00, 0xFF, NB_HOST_REG(0x54), 0x1E, 0x1C,      // Misc Ctrl: Enable 8QW burst Mem Access
151         //0x00, 0xFF, NB_HOST_REG(0x55), 0x06, 0x06, // Miscellaneous Control 2
152         0x00, 0xFF, NB_HOST_REG(0x55), 0x06, 0x04,      // Miscellaneous Control 2
153         0x00, 0xFF, NB_HOST_REG(0x56), 0xF7, 0x63,      // Write Policy 1
154         //0x00, 0xFF, NB_HOST_REG(0x59), 0x3D, 0x01, // CPU Miscellaneous Control 1, enable Lowest-Priority IPL
155         //0x00, 0xFF, NB_HOST_REG(0x5c), 0xFF, 0x00, // CPU Miscellaneous Control 2
156         0x00, 0xFF, NB_HOST_REG(0x5D), 0xFF, 0xA2,      // Write Policy
157         0x00, 0xFF, NB_HOST_REG(0x5E), 0xFF, 0x88,      // Bandwidth Timer
158         0x00, 0xFF, NB_HOST_REG(0x5F), 0x46, 0x46,      // CPU Misc Ctrl
159         // 0x00, 0xFF, NB_HOST_REG(0x90), 0xFF, 0x0B, // CPU Miscellaneous Control 3
160         //0x00, 0xFF, NB_HOST_REG(0x96), 0x0B, 0x0B, // CPU Miscellaneous Control 2
161         0x00, 0xFF, NB_HOST_REG(0x96), 0x0B, 0x0A,      // CPU Miscellaneous Control 2
162         0x00, 0xFF, NB_HOST_REG(0x98), 0xC1, 0x41,      // CPU Miscellaneous Control 3
163         0x00, 0xFF, NB_HOST_REG(0x99), 0x0E, 0x06,      // CPU Miscellaneous Control 4
164
165
166         // Set APIC and SMRAM
167         0x00, 0xFF, NB_HOST_REG(0x97), 0xFF, 0x00,      // APIC Related Control
168         0x00, 0xFF, NB_DRAMC_REG(0x86), 0xD6, 0x29,     // SMM and APIC Decoding: enable APIC, MSI and SMRAM A-Seg
169         0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // End of the table
170 };
171
172 #define USE_VCP     1           //0 means use DVP
173 #define USE_COM1    1
174 #define USE_COM2    0
175
176 #define gCom1Base   0x3f8
177 #define gCom2Base   0x2f8
178
179 void EmbedComInit(void)
180 {
181         u8 ByteVal;
182         u16 ComBase;
183
184         //enable NB multiple function control
185         ByteVal = pci_read_config8(PCI_DEV(0, 0, 0), 0x4f);
186         ByteVal = ByteVal | 0x01;
187         pci_write_config8(PCI_DEV(0, 0, 0), 0x4f, ByteVal);
188
189         //VGA Enable
190         ByteVal = pci_read_config8(PCI_DEV(0, 0, 3), 0xA1);
191         ByteVal = ByteVal | 0x80;
192         pci_write_config8(PCI_DEV(0, 0, 3), 0xA1, ByteVal);
193
194         ByteVal = pci_read_config8(PCI_DEV(0, 0, 3), 0xA7);
195         ByteVal = ByteVal | 0x08;
196         pci_write_config8(PCI_DEV(0, 0, 3), 0xA7, ByteVal);
197
198         //Enable p2p  IO/mem
199         ByteVal = pci_read_config8(PCI_DEV(0, 1, 0), 0x4);
200         ByteVal = ByteVal | 0x07;
201         pci_write_config8(PCI_DEV(0, 1, 0), 0x4, ByteVal);
202
203         //Turn on Graphic chip IO port port access
204         ByteVal = inb(0x3C3);
205         ByteVal = ByteVal | 0x01;
206         outb(ByteVal, 0x3C3);
207
208         //Turn off Graphic chip Register protection
209         outb(0x10, 0x3C4);
210         ByteVal = inb(0x3C5);
211         ByteVal = ByteVal | 0x01;
212         outb(ByteVal, 0x3C5);
213
214         //south module pad share enable 0x3C5.78[7]
215         outb(0x78, 0x3C4);
216         ByteVal = inb(0x3C5);
217         ByteVal = ByteVal | 0x80;
218         outb(ByteVal, 0x3C5);
219
220         //enable  UART Function multiplex with DVP or VCP pad D17F0Rx46[7,6]
221         ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0x46);
222         //multiplex with VCP
223         if (USE_VCP == 1)
224                 ByteVal = (ByteVal & 0x3F) | 0x40;
225         //multiplex with DVP
226         else
227                 ByteVal = (ByteVal & 0x3F) | 0xC0;
228         pci_write_config8(PCI_DEV(0, 17, 0), 0x46, ByteVal);
229
230         //enable embeded com1 and com2 D17F0RxB0[5,4]
231         ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xB0);
232         ByteVal = ByteVal & 0xcf;
233         //multiplex with VCP
234         if (USE_COM1 == 1)
235                 ByteVal = ByteVal | 0x10;
236         if (USE_COM2 == 1)
237                 ByteVal = ByteVal | 0x20;
238         pci_write_config8(PCI_DEV(0, 17, 0), 0xB0, ByteVal);
239
240         if (USE_COM1 == 1)
241                 ComBase = gCom1Base;
242         else
243                 ComBase = gCom2Base;
244
245 //noharddrive
246
247         //set embeded com1 IO base = 0x3E8
248         //D17F0RB4
249         //ByteVal = 0xFD;
250         if (USE_COM1 == 1) {
251                 ByteVal = (u8) ((gCom1Base >> 3) | 0x80);
252                 pci_write_config8(PCI_DEV(0, 17, 0), 0xB4, ByteVal);
253                 ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xb2);
254                 ByteVal = (ByteVal & 0xf0) | 0x04;
255                 pci_write_config8(PCI_DEV(0, 17, 0), 0xB2, ByteVal);
256         }
257         //set embeded com2 IO base = 0x2E8
258         //D17F0RB5
259         //ByteVal = 0xDD;
260         if (USE_COM2 == 1) {
261                 ByteVal = (u8) ((gCom2Base >> 3) | 0x80);
262                 pci_write_config8(PCI_DEV(0, 17, 0), 0xB5, ByteVal);
263                 ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xb2);
264                 ByteVal = (ByteVal & 0x0f) | 0x30;
265                 pci_write_config8(PCI_DEV(0, 17, 0), 0xB2, ByteVal);
266         }
267         //no port 80 biger then 0x10
268
269         //disable interrupt
270         ByteVal = inb(ComBase + 3);
271         outb(ByteVal & 0x7F, ComBase + 3);
272         outb(0x00, ComBase + 1);
273
274         //set baudrate
275         ByteVal = inb(ComBase + 3);
276         outb(ByteVal | 0x80, ComBase + 3);
277         outb(0x01, ComBase);
278         outb(0x00, ComBase + 1);
279
280         //set  frame  fromat
281         ByteVal = inb(ComBase + 3);
282         outb(ByteVal & 0x3F, ComBase + 3);
283         outb(0x03, ComBase + 3);
284         outb(0x00, ComBase + 2);
285         outb(0x00, ComBase + 4);
286
287         //SOutput("Embeded com output\n");
288         //while(1);
289 }
290
291 void main(unsigned long bist)
292 {
293         unsigned cpu_reset = 0;
294         u16 boot_mode;
295         u8 rambits;
296
297         //device_t dev;
298         /* Enable multifunction for northbridge. */
299         pci_write_config8(PCI_DEV(0, 0, 0), 0x4f, 0x01);
300         EmbedComInit();
301         //enable_vx800_serial();
302         //uart_init();
303
304 /*      1.    D15F0
305
306 a)      RxBAh = 71h
307
308 b)      RxBBh = 05h
309
310 c)      RxBEh = 71h
311
312 d)      RxBFh = 05h
313
314 2.    D17F0
315
316 a)      RxA0h = 06h
317
318 b)      RxA1h = 11h
319
320 c)      RxA2h = 27h
321
322 d)      RxA3h = 32h
323
324 e)      Rx79h = 40h
325
326 f)      Rx72h = 27h
327
328 g)      Rx73h = 32h
329 */
330
331         u8 Data8;
332
333         pci_write_config16(PCI_DEV(0, 0xf, 0), 0xBA,
334                            PCI_DEVICE_ID_VIA_VX855_IDE);
335         pci_write_config16(PCI_DEV(0, 0xf, 0), 0xBE,
336                            PCI_DEVICE_ID_VIA_VX855_IDE);
337         pci_write_config16(PCI_DEV(0, 0x11, 0), 0xA0, PCI_VENDOR_ID_VIA);
338         pci_write_config16(PCI_DEV(0, 0x11, 0), 0xA2,
339                            PCI_DEVICE_ID_VIA_VX855_LPC);
340         Data8 = pci_read_config8(PCI_DEV(0, 0x11, 0), 0x79);
341         Data8 &= ~0x40;
342         Data8 |= 0x40;
343         pci_write_config8(PCI_DEV(0, 0x11, 0), 0x79, Data8);
344         pci_write_config16(PCI_DEV(0, 0x11, 0), 0x72,
345                            PCI_DEVICE_ID_VIA_VX855_LPC);
346
347         console_init();         //there are to function defination of console_init(), while the src/archi386/lib is the right one
348
349         /* decide if this is a s3 wakeup or a normal boot */
350         boot_mode = acpi_is_wakeup_early_via_vx800();
351         /*add this, to transfer "cpu restart" to "cold boot"
352            When this boot is not a S3 resume, and PCI registers had been written,
353            then this must be a cpu restart(result of os reboot cmd). so we need a real "cold boot". */
354         if ((boot_mode != 3)
355             && (pci_read_config8(PCI_DEV(0, 0, 3), 0x80) != 0)) {
356                 outb(6, 0xcf9);
357         }
358
359         /*x86 cold boot I/O cmd */
360         enable_smbus();
361         //smbus_fixup(&ctrl);// this fix does help vx800!, but vx855 no need this
362
363         if (bist == 0) {
364                 // CAR need mtrr untill mem is ok, so i disable this early_mtrr_init();
365                 //print_debug("doing early_mtrr\n");
366                 //early_mtrr_init();
367         }
368
369         /* Halt if there was a built-in self test failure. */
370         report_bist_failure(bist);
371
372         print_debug("Enabling mainboard devices\n");
373         enable_mainboard_devices();
374
375         u8 Data;
376         device_t device;
377         /* Get NB Chip revision from D0F4RxF6, revision will be used in via_pci_inittable */
378         device = PCI_DEV(0, 0, 4);
379         Data = pci_read_config8(device, 0xf6);
380         print_debug("NB chip revision =");
381         print_debug_hex8(Data);
382         print_debug("\n");
383         /* make NB ready before draminit */
384         via_pci_inittable(Data, mNbStage1InitTbl);
385
386         /*add this.
387            When resume from s3, draminit is skiped, so need to recovery any PCI register related to draminit.
388            and d0f3 didnt lost its Power during whole s3 time, so any register not belongs to d0f3 need to be recoveried . */
389 #if 1
390         if (boot_mode == 3) {
391                 u8 i;
392                 u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
393                 DRAM_SYS_ATTR DramAttr;
394
395                 print_debug("This is a S3 wakeup\n");
396
397                 memset(&DramAttr, 0, sizeof(DRAM_SYS_ATTR));
398                 /*Step1 DRAM Detection; DDR1 or DDR2; Get SPD Data; Rank Presence;64 or 128bit; Unbuffered or registered; 1T or 2T */
399                 DRAMDetect(&DramAttr);
400
401                 /*begin to get ram size, 43,42 41 40 contains the end address of last rank in ddr2-slot */
402                 device = PCI_DEV(0, 0, 3);
403                 for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
404                         rambits = pci_read_config8(device, ramregs[i]);
405                         if (rambits != 0)
406                                 break;
407                 }
408
409                 DRAMDRDYSetting(&DramAttr);
410
411                 Data = 0x80;    // this value is same with dev_init.c
412                 pci_write_config8(PCI_DEV(0, 0, 4), 0xa3, Data);
413                 pci_write_config8(PCI_DEV(0, 17, 7), 0x60, rambits << 2);
414                 Data = pci_read_config8(MEMCTRL, 0x88);
415                 pci_write_config8(PCI_DEV(0, 17, 7), 0xE5, Data);
416
417                 DRAMRegFinalValue(&DramAttr);   // I just copy this function from draminit to here!
418                 SetUMARam();    // I just copy this function from draminit to here!
419                 print_debug("Resume from S3, RAM init was ignored\n");
420         } else {
421                 ddr2_ram_setup();
422                 ram_check(0, 640 * 1024);
423         }
424 #endif
425         //ddr2_ram_setup();
426         /*this line is the same with cx700 port . */
427         enable_shadow_ram();
428
429         /*
430            For coreboot most time of S3 resume is the same as normal boot, so some memory area under 1M become dirty,
431            so before this happen, I need to backup the content of mem to top-mem.
432            I will reserve the 1M top-men in LBIO table in coreboot_table.c and recovery the content of 1M-mem in wakeup.c
433          */
434 #if PAYLOAD_IS_SEABIOS==1       //
435         if (boot_mode == 3) {
436                 /*   some idea of Libo.Feng at amd.com in  http://www.coreboot.org/pipermail/coreboot/2008-December/043111.html
437                    I want move the 1M data, I have to set some MTRRs myself. */
438                 /* seting mtrr before back memoy save s3 resume time about 0.14 seconds */
439                 /*because CAR stack use cache, and here to use cache , must be careful,
440                    1 during these mtrr code, must no function call, (after this mtrr, I think it should be ok to use function)
441                    2 before stack switch, no use variable that have value set before this
442                    3 due to 2, take care of "cpu_reset", I directlly set it to ZERO.
443                  */
444                 u32 memtop = *(u32 *) WAKE_MEM_INFO;
445                 u32 memtop1 = *(u32 *) WAKE_MEM_INFO - 0x100000;
446                 u32 memtop2 = *(u32 *) WAKE_MEM_INFO - 0x200000;
447                 u32 memtop3 =
448                     *(u32 *) WAKE_MEM_INFO - 64 * 1024 - 0x100000;
449                 u32 memtop4 =
450                     *(u32 *) WAKE_MEM_INFO - 64 * 1024 - 0x100000 +
451                     0xe0000;
452                 /*      __asm__ volatile (
453                    "movl    $0x204, %%ecx\n\t"
454                    "xorl    %%edx, %%edx\n\t"
455                    "movl     %0,%%eax\n\t"
456                    "orl     $(0 | 6), %%eax\n\t"
457                    "wrmsr\n\t"
458
459                    "movl    $0x205, %%ecx\n\t"
460                    "xorl    %%edx, %%edx\n\t"
461                    "movl   $0x100000,%%eax\n\t"
462                    "decl                %%eax\n\t"
463                    "notl                %%eax\n\t"
464                    "orl    $(0 | 0x800), %%eax\n\t"
465                    "wrmsr\n\t"
466                    ::"g"(memtop2)
467                    );
468                    __asm__ volatile (
469                    "movl    $0x206, %%ecx\n\t"
470                    "xorl    %%edx, %%edx\n\t"
471                    "movl     %0,%%eax\n\t"
472                    "orl     $(0 | 6), %%eax\n\t"
473                    "wrmsr\n\t"
474
475                    "movl    $0x207, %%ecx\n\t"
476                    "xorl    %%edx, %%edx\n\t"
477                    "movl   $0x100000,%%eax\n\t"
478                    "decl                %%eax\n\t"
479                    "notl                %%eax\n\t"
480                    "orl    $(0 | 0x800), %%eax\n\t"
481                    "wrmsr\n\t"
482                    ::"g"(memtop1)
483                    );
484                    __asm__ volatile (
485                    "movl    $0x208, %ecx\n\t"
486                    "xorl    %edx, %edx\n\t"
487                    "movl    $0,%eax\n\t"
488                    "orl     $(0 | 6), %eax\n\t"
489                    "wrmsr\n\t"
490
491                    "movl    $0x209, %ecx\n\t"
492                    "xorl    %edx, %edx\n\t"
493                    "movl     $0x100000,%eax\n\t"
494                    "decl                %eax\n\t"
495                    "notl                %eax\n\t"
496                    "orl     $(0 | 0x800), %eax\n\t"
497                    "wrmsr\n\t"
498                    );
499                  */
500                 // WAKE_MEM_INFO is  inited in get_set_top_available_mem in tables.c
501                 // these two memcpy not not be enabled if set the MTRR around this two lines.
502                 /*__asm__ volatile (
503                                 "movl    $0, %%esi\n\t"
504         "movl    %0, %%edi\n\t"
505         "movl    $0xa0000, %%ecx\n\t"
506         "shrl    $2, %%ecx\n\t"
507         "rep movsd\n\t"
508         ::"g"(memtop3)
509         );
510         __asm__ volatile (
511                                 "movl    $0xe0000, %%esi\n\t"
512         "movl    %0, %%edi\n\t"
513         "movl    $0x20000, %%ecx\n\t"
514         "shrl    $2, %%ecx\n\t"
515         "rep movsd\n\t"
516         ::"g"(memtop4)
517         );*/
518                 print_debug("copy memory to high memory to protect s3 wakeup vector code \n");  //this can have function call, because no variable used before this
519                 memcpy((unsigned char *) ((*(u32 *) WAKE_MEM_INFO) -
520                                           64 * 1024 - 0x100000),
521                        (unsigned char *) 0, 0xa0000);
522                 memcpy((unsigned char *) ((*(u32 *) WAKE_MEM_INFO) -
523                                           64 * 1024 - 0x100000 + 0xe0000),
524                        (unsigned char *) 0xe0000, 0x20000);
525
526                 /* restore the MTRR previously modified. */
527 /*              __asm__ volatile (
528         "wbinvd\n\t"
529         "xorl    %edx, %edx\n\t"
530         "xorl    %eax, %eax\n\t"
531         "movl    $0x204, %ecx\n\t"
532         "wrmsr\n\t"
533                                 "movl    $0x205, %ecx\n\t"
534         "wrmsr\n\t"
535                                 "movl    $0x206, %ecx\n\t"
536         "wrmsr\n\t"
537                                 "movl    $0x207, %ecx\n\t"
538         "wrmsr\n\t"
539                                 "movl    $0x208, %ecx\n\t"
540         "wrmsr\n\t"
541                                 "movl    $0x209, %ecx\n\t"
542         "wrmsr\n\t"
543                 );*/
544         }
545 #endif
546 }