Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
| 4 | * Copyright (C) 2009 Rudolf Marek <r.marek@assembler.cz> |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 5 | * Copyright (C) 2009 coresystems GmbH |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; version 2 of the License. |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 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 |
Paul Menzel | a46a712 | 2013-02-23 18:37:27 +0100 | [diff] [blame] | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 19 | */ |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 20 | |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 21 | #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 Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 32 | /* last 4 bits of linear addr are taken as offset */ |
| 33 | andw $0x0f, %ax |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 34 | movw %ax, (__wakeup_offset) |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 35 | mov 0x4(%esp), %eax |
| 36 | /* the rest is taken as segment */ |
| 37 | shr $4, %eax |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 38 | movw %ax, (__wakeup_segment) |
| 39 | |
| 40 | /* Then overwrite coreboot with our backed up memory */ |
Stefan Reinauer | 8acbc2a | 2011-11-17 13:03:38 -0800 | [diff] [blame] | 41 | cld |
| 42 | movl 8(%esp), %esi |
| 43 | movl 12(%esp), %edi |
| 44 | movl 16(%esp), %ecx |
| 45 | shrl $2, %ecx |
| 46 | rep movsl |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 47 | |
| 48 | /* Activate the right segment descriptor real mode. */ |
| 49 | ljmp $0x28, $RELOCATED(1f) |
| 50 | 1: |
| 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 Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 60 | mov %ax, %ds |
| 61 | mov %ax, %es |
| 62 | mov %ax, %fs |
| 63 | mov %ax, %gs |
| 64 | mov %ax, %ss |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 65 | |
| 66 | /* Turn off protection */ |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 67 | movl %cr0, %eax |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 68 | andl $~PE, %eax |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 69 | movl %eax, %cr0 |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 70 | |
| 71 | /* Now really going into real mode */ |
| 72 | ljmp $0, $RELOCATED(1f) |
| 73 | 1: |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 74 | movw $0x0, %ax |
| 75 | movw %ax, %ds |
| 76 | movw %ax, %es |
| 77 | movw %ax, %ss |
| 78 | movw %ax, %fs |
| 79 | movw %ax, %gs |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 80 | |
| 81 | /* This is a FAR JMP to the OS waking vector. The C code changed |
| 82 | * the address to be correct. |
| 83 | */ |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 84 | .byte 0xea |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 85 | |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 86 | __wakeup_offset = RELOCATED(.) |
| 87 | .word 0x0000 |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 88 | |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 89 | __wakeup_segment = RELOCATED(.) |
| 90 | .word 0x0000 |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 91 | |
Stefan Reinauer | c0ac7e9 | 2009-11-10 22:17:15 +0000 | [diff] [blame] | 92 | .globl __wakeup_size |
| 93 | __wakeup_size = ( . - __wakeup) |
Rudolf Marek | 33cafe5 | 2009-04-13 18:07:02 +0000 | [diff] [blame] | 94 | |