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