blob: d34c583a589da94a3701134aa9767e7c206f7852 [file] [log] [blame]
Rudolf Marek33cafe52009-04-13 18:07:02 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2009 Rudolf Marek <r.marek@assembler.cz>
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +00005 * Copyright (C) 2009 coresystems GmbH
Rudolf Marek33cafe52009-04-13 18:07:02 +00006 *
7 * This program is free software; you can redistribute it and/or modify
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +00008 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
Rudolf Marek33cafe52009-04-13 18:07:02 +000010 *
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
Paul Menzela46a7122013-02-23 18:37:27 +010018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Rudolf Marek33cafe52009-04-13 18:07:02 +000019 */
Rudolf Marek33cafe52009-04-13 18:07:02 +000020
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +000021#define WAKEUP_BASE 0x600
22#define RELOCATED(x) (x - __wakeup + WAKEUP_BASE)
23
24/* CR0 bits */
25#define PE (1 << 0)
26
27 .code32
28 .globl __wakeup
29__wakeup:
30 /* First prepare the jmp to the resume vector */
31 mov 0x4(%esp), %eax /* vector */
Rudolf Marek33cafe52009-04-13 18:07:02 +000032 /* last 4 bits of linear addr are taken as offset */
33 andw $0x0f, %ax
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +000034 movw %ax, (__wakeup_offset)
Rudolf Marek33cafe52009-04-13 18:07:02 +000035 mov 0x4(%esp), %eax
36 /* the rest is taken as segment */
37 shr $4, %eax
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +000038 movw %ax, (__wakeup_segment)
39
40 /* Then overwrite coreboot with our backed up memory */
Stefan Reinauer8acbc2a2011-11-17 13:03:38 -080041 cld
42 movl 8(%esp), %esi
43 movl 12(%esp), %edi
44 movl 16(%esp), %ecx
45 shrl $2, %ecx
46 rep movsl
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +000047
48 /* Activate the right segment descriptor real mode. */
49 ljmp $0x28, $RELOCATED(1f)
501:
51.code16
52 /* 16 bit code from here on... */
53
54 /* Load the segment registers w/ properly configured
55 * segment descriptors. They will retain these
56 * configurations (limits, writability, etc.) once
57 * protected mode is turned off.
58 */
59 mov $0x30, %ax
Stefan Reinauer14e22772010-04-27 06:56:47 +000060 mov %ax, %ds
61 mov %ax, %es
62 mov %ax, %fs
63 mov %ax, %gs
64 mov %ax, %ss
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +000065
66 /* Turn off protection */
Rudolf Marek33cafe52009-04-13 18:07:02 +000067 movl %cr0, %eax
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +000068 andl $~PE, %eax
Rudolf Marek33cafe52009-04-13 18:07:02 +000069 movl %eax, %cr0
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +000070
71 /* Now really going into real mode */
72 ljmp $0, $RELOCATED(1f)
731:
Rudolf Marek33cafe52009-04-13 18:07:02 +000074 movw $0x0, %ax
75 movw %ax, %ds
76 movw %ax, %es
77 movw %ax, %ss
78 movw %ax, %fs
79 movw %ax, %gs
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +000080
81 /* This is a FAR JMP to the OS waking vector. The C code changed
82 * the address to be correct.
83 */
Rudolf Marek33cafe52009-04-13 18:07:02 +000084 .byte 0xea
Rudolf Marek33cafe52009-04-13 18:07:02 +000085
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +000086__wakeup_offset = RELOCATED(.)
87 .word 0x0000
Rudolf Marek33cafe52009-04-13 18:07:02 +000088
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +000089__wakeup_segment = RELOCATED(.)
90 .word 0x0000
Rudolf Marek33cafe52009-04-13 18:07:02 +000091
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +000092 .globl __wakeup_size
93__wakeup_size = ( . - __wakeup)
Rudolf Marek33cafe52009-04-13 18:07:02 +000094