aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/acpi
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /arch/x86/kernel/acpi
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'arch/x86/kernel/acpi')
-rw-r--r--arch/x86/kernel/acpi/realmode/Makefile59
-rw-r--r--arch/x86/kernel/acpi/realmode/bioscall.S1
-rw-r--r--arch/x86/kernel/acpi/realmode/copy.S1
-rw-r--r--arch/x86/kernel/acpi/realmode/regs.c1
-rw-r--r--arch/x86/kernel/acpi/realmode/video-bios.c1
-rw-r--r--arch/x86/kernel/acpi/realmode/video-mode.c1
-rw-r--r--arch/x86/kernel/acpi/realmode/video-vesa.c1
-rw-r--r--arch/x86/kernel/acpi/realmode/video-vga.c1
-rw-r--r--arch/x86/kernel/acpi/realmode/wakemain.c81
-rw-r--r--arch/x86/kernel/acpi/realmode/wakeup.S170
-rw-r--r--arch/x86/kernel/acpi/realmode/wakeup.h48
-rw-r--r--arch/x86/kernel/acpi/realmode/wakeup.lds.S62
-rw-r--r--arch/x86/kernel/acpi/wakeup_rm.S12
13 files changed, 439 insertions, 0 deletions
diff --git a/arch/x86/kernel/acpi/realmode/Makefile b/arch/x86/kernel/acpi/realmode/Makefile
new file mode 100644
index 00000000000..6a564ac67ef
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/Makefile
@@ -0,0 +1,59 @@
1#
2# arch/x86/kernel/acpi/realmode/Makefile
3#
4# This file is subject to the terms and conditions of the GNU General Public
5# License. See the file "COPYING" in the main directory of this archive
6# for more details.
7#
8
9always := wakeup.bin
10targets := wakeup.elf wakeup.lds
11
12wakeup-y += wakeup.o wakemain.o video-mode.o copy.o bioscall.o regs.o
13
14# The link order of the video-*.o modules can matter. In particular,
15# video-vga.o *must* be listed first, followed by video-vesa.o.
16# Hardware-specific drivers should follow in the order they should be
17# probed, and video-bios.o should typically be last.
18wakeup-y += video-vga.o
19wakeup-y += video-vesa.o
20wakeup-y += video-bios.o
21
22targets += $(wakeup-y)
23
24bootsrc := $(src)/../../../boot
25
26# ---------------------------------------------------------------------------
27
28# How to compile the 16-bit code. Note we always compile for -march=i386,
29# that way we can complain to the user if the CPU is insufficient.
30# Compile with _SETUP since this is similar to the boot-time setup code.
31KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D_WAKEUP -D__KERNEL__ \
32 -I$(srctree)/$(bootsrc) \
33 $(cflags-y) \
34 -Wall -Wstrict-prototypes \
35 -march=i386 -mregparm=3 \
36 -include $(srctree)/$(bootsrc)/code16gcc.h \
37 -fno-strict-aliasing -fomit-frame-pointer \
38 $(call cc-option, -ffreestanding) \
39 $(call cc-option, -fno-toplevel-reorder,\
40 $(call cc-option, -fno-unit-at-a-time)) \
41 $(call cc-option, -fno-stack-protector) \
42 $(call cc-option, -mpreferred-stack-boundary=2)
43KBUILD_CFLAGS += $(call cc-option, -m32)
44KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
45GCOV_PROFILE := n
46
47WAKEUP_OBJS = $(addprefix $(obj)/,$(wakeup-y))
48
49LDFLAGS_wakeup.elf := -T
50
51CPPFLAGS_wakeup.lds += -P -C
52
53$(obj)/wakeup.elf: $(obj)/wakeup.lds $(WAKEUP_OBJS) FORCE
54 $(call if_changed,ld)
55
56OBJCOPYFLAGS_wakeup.bin := -O binary
57
58$(obj)/wakeup.bin: $(obj)/wakeup.elf FORCE
59 $(call if_changed,objcopy)
diff --git a/arch/x86/kernel/acpi/realmode/bioscall.S b/arch/x86/kernel/acpi/realmode/bioscall.S
new file mode 100644
index 00000000000..f51eb0bb56c
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/bioscall.S
@@ -0,0 +1 @@
#include "../../../boot/bioscall.S"
diff --git a/arch/x86/kernel/acpi/realmode/copy.S b/arch/x86/kernel/acpi/realmode/copy.S
new file mode 100644
index 00000000000..dc59ebee69d
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/copy.S
@@ -0,0 +1 @@
#include "../../../boot/copy.S"
diff --git a/arch/x86/kernel/acpi/realmode/regs.c b/arch/x86/kernel/acpi/realmode/regs.c
new file mode 100644
index 00000000000..6206033ba20
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/regs.c
@@ -0,0 +1 @@
#include "../../../boot/regs.c"
diff --git a/arch/x86/kernel/acpi/realmode/video-bios.c b/arch/x86/kernel/acpi/realmode/video-bios.c
new file mode 100644
index 00000000000..7deabc144a2
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/video-bios.c
@@ -0,0 +1 @@
#include "../../../boot/video-bios.c"
diff --git a/arch/x86/kernel/acpi/realmode/video-mode.c b/arch/x86/kernel/acpi/realmode/video-mode.c
new file mode 100644
index 00000000000..328ad209f11
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/video-mode.c
@@ -0,0 +1 @@
#include "../../../boot/video-mode.c"
diff --git a/arch/x86/kernel/acpi/realmode/video-vesa.c b/arch/x86/kernel/acpi/realmode/video-vesa.c
new file mode 100644
index 00000000000..9dbb9672226
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/video-vesa.c
@@ -0,0 +1 @@
#include "../../../boot/video-vesa.c"
diff --git a/arch/x86/kernel/acpi/realmode/video-vga.c b/arch/x86/kernel/acpi/realmode/video-vga.c
new file mode 100644
index 00000000000..bcc81255f37
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/video-vga.c
@@ -0,0 +1 @@
#include "../../../boot/video-vga.c"
diff --git a/arch/x86/kernel/acpi/realmode/wakemain.c b/arch/x86/kernel/acpi/realmode/wakemain.c
new file mode 100644
index 00000000000..883962d9eef
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/wakemain.c
@@ -0,0 +1,81 @@
1#include "wakeup.h"
2#include "boot.h"
3
4static void udelay(int loops)
5{
6 while (loops--)
7 io_delay(); /* Approximately 1 us */
8}
9
10static void beep(unsigned int hz)
11{
12 u8 enable;
13
14 if (!hz) {
15 enable = 0x00; /* Turn off speaker */
16 } else {
17 u16 div = 1193181/hz;
18
19 outb(0xb6, 0x43); /* Ctr 2, squarewave, load, binary */
20 io_delay();
21 outb(div, 0x42); /* LSB of counter */
22 io_delay();
23 outb(div >> 8, 0x42); /* MSB of counter */
24 io_delay();
25
26 enable = 0x03; /* Turn on speaker */
27 }
28 inb(0x61); /* Dummy read of System Control Port B */
29 io_delay();
30 outb(enable, 0x61); /* Enable timer 2 output to speaker */
31 io_delay();
32}
33
34#define DOT_HZ 880
35#define DASH_HZ 587
36#define US_PER_DOT 125000
37
38/* Okay, this is totally silly, but it's kind of fun. */
39static void send_morse(const char *pattern)
40{
41 char s;
42
43 while ((s = *pattern++)) {
44 switch (s) {
45 case '.':
46 beep(DOT_HZ);
47 udelay(US_PER_DOT);
48 beep(0);
49 udelay(US_PER_DOT);
50 break;
51 case '-':
52 beep(DASH_HZ);
53 udelay(US_PER_DOT * 3);
54 beep(0);
55 udelay(US_PER_DOT);
56 break;
57 default: /* Assume it's a space */
58 udelay(US_PER_DOT * 3);
59 break;
60 }
61 }
62}
63
64void main(void)
65{
66 /* Kill machine if structures are wrong */
67 if (wakeup_header.real_magic != 0x12345678)
68 while (1);
69
70 if (wakeup_header.realmode_flags & 4)
71 send_morse("...-");
72
73 if (wakeup_header.realmode_flags & 1)
74 asm volatile("lcallw $0xc000,$3");
75
76 if (wakeup_header.realmode_flags & 2) {
77 /* Need to call BIOS */
78 probe_cards(0);
79 set_mode(wakeup_header.video_mode);
80 }
81}
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.S b/arch/x86/kernel/acpi/realmode/wakeup.S
new file mode 100644
index 00000000000..b4fd836e405
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/wakeup.S
@@ -0,0 +1,170 @@
1/*
2 * ACPI wakeup real mode startup stub
3 */
4#include <asm/segment.h>
5#include <asm/msr-index.h>
6#include <asm/page_types.h>
7#include <asm/pgtable_types.h>
8#include <asm/processor-flags.h>
9#include "wakeup.h"
10
11 .code16
12 .section ".jump", "ax"
13 .globl _start
14_start:
15 cli
16 jmp wakeup_code
17
18/* This should match the structure in wakeup.h */
19 .section ".header", "a"
20 .globl wakeup_header
21wakeup_header:
22video_mode: .short 0 /* Video mode number */
23pmode_return: .byte 0x66, 0xea /* ljmpl */
24 .long 0 /* offset goes here */
25 .short __KERNEL_CS
26pmode_cr0: .long 0 /* Saved %cr0 */
27pmode_cr3: .long 0 /* Saved %cr3 */
28pmode_cr4: .long 0 /* Saved %cr4 */
29pmode_efer: .quad 0 /* Saved EFER */
30pmode_gdt: .quad 0
31pmode_misc_en: .quad 0 /* Saved MISC_ENABLE MSR */
32pmode_behavior: .long 0 /* Wakeup behavior flags */
33realmode_flags: .long 0
34real_magic: .long 0
35trampoline_segment: .word 0
36_pad1: .byte 0
37wakeup_jmp: .byte 0xea /* ljmpw */
38wakeup_jmp_off: .word 3f
39wakeup_jmp_seg: .word 0
40wakeup_gdt: .quad 0, 0, 0
41signature: .long WAKEUP_HEADER_SIGNATURE
42
43 .text
44 .code16
45wakeup_code:
46 cld
47
48 /* Apparently some dimwit BIOS programmers don't know how to
49 program a PM to RM transition, and we might end up here with
50 junk in the data segment descriptor registers. The only way
51 to repair that is to go into PM and fix it ourselves... */
52 movw $16, %cx
53 lgdtl %cs:wakeup_gdt
54 movl %cr0, %eax
55 orb $X86_CR0_PE, %al
56 movl %eax, %cr0
57 jmp 1f
581: ljmpw $8, $2f
592:
60 movw %cx, %ds
61 movw %cx, %es
62 movw %cx, %ss
63 movw %cx, %fs
64 movw %cx, %gs
65
66 andb $~X86_CR0_PE, %al
67 movl %eax, %cr0
68 jmp wakeup_jmp
693:
70 /* Set up segments */
71 movw %cs, %ax
72 movw %ax, %ds
73 movw %ax, %es
74 movw %ax, %ss
75 lidtl wakeup_idt
76
77 movl $wakeup_stack_end, %esp
78
79 /* Clear the EFLAGS */
80 pushl $0
81 popfl
82
83 /* Check header signature... */
84 movl signature, %eax
85 cmpl $WAKEUP_HEADER_SIGNATURE, %eax
86 jne bogus_real_magic
87
88 /* Check we really have everything... */
89 movl end_signature, %eax
90 cmpl $WAKEUP_END_SIGNATURE, %eax
91 jne bogus_real_magic
92
93 /* Call the C code */
94 calll main
95
96 /* Restore MISC_ENABLE before entering protected mode, in case
97 BIOS decided to clear XD_DISABLE during S3. */
98 movl pmode_behavior, %eax
99 btl $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %eax
100 jnc 1f
101
102 movl pmode_misc_en, %eax
103 movl pmode_misc_en + 4, %edx
104 movl $MSR_IA32_MISC_ENABLE, %ecx
105 wrmsr
1061:
107
108 /* Do any other stuff... */
109
110#ifndef CONFIG_64BIT
111 /* This could also be done in C code... */
112 movl pmode_cr3, %eax
113 movl %eax, %cr3
114
115 movl pmode_cr4, %ecx
116 jecxz 1f
117 movl %ecx, %cr4
1181:
119 movl pmode_efer, %eax
120 movl pmode_efer + 4, %edx
121 movl %eax, %ecx
122 orl %edx, %ecx
123 jz 1f
124 movl $MSR_EFER, %ecx
125 wrmsr
1261:
127
128 lgdtl pmode_gdt
129
130 /* This really couldn't... */
131 movl pmode_cr0, %eax
132 movl %eax, %cr0
133 jmp pmode_return
134#else
135 pushw $0
136 pushw trampoline_segment
137 pushw $0
138 lret
139#endif
140
141bogus_real_magic:
1421:
143 hlt
144 jmp 1b
145
146 .data
147 .balign 8
148
149 /* This is the standard real-mode IDT */
150wakeup_idt:
151 .word 0xffff /* limit */
152 .long 0 /* address */
153 .word 0
154
155 .globl HEAP, heap_end
156HEAP:
157 .long wakeup_heap
158heap_end:
159 .long wakeup_stack
160
161 .bss
162wakeup_heap:
163 .space 2048
164wakeup_stack:
165 .space 2048
166wakeup_stack_end:
167
168 .section ".signature","a"
169end_signature:
170 .long WAKEUP_END_SIGNATURE
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.h b/arch/x86/kernel/acpi/realmode/wakeup.h
new file mode 100644
index 00000000000..97a29e1430e
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/wakeup.h
@@ -0,0 +1,48 @@
1/*
2 * Definitions for the wakeup data structure at the head of the
3 * wakeup code.
4 */
5
6#ifndef ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H
7#define ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H
8
9#ifndef __ASSEMBLY__
10#include <linux/types.h>
11
12/* This must match data at wakeup.S */
13struct wakeup_header {
14 u16 video_mode; /* Video mode number */
15 u16 _jmp1; /* ljmpl opcode, 32-bit only */
16 u32 pmode_entry; /* Protected mode resume point, 32-bit only */
17 u16 _jmp2; /* CS value, 32-bit only */
18 u32 pmode_cr0; /* Protected mode cr0 */
19 u32 pmode_cr3; /* Protected mode cr3 */
20 u32 pmode_cr4; /* Protected mode cr4 */
21 u32 pmode_efer_low; /* Protected mode EFER */
22 u32 pmode_efer_high;
23 u64 pmode_gdt;
24 u32 pmode_misc_en_low; /* Protected mode MISC_ENABLE */
25 u32 pmode_misc_en_high;
26 u32 pmode_behavior; /* Wakeup routine behavior flags */
27 u32 realmode_flags;
28 u32 real_magic;
29 u16 trampoline_segment; /* segment with trampoline code, 64-bit only */
30 u8 _pad1;
31 u8 wakeup_jmp;
32 u16 wakeup_jmp_off;
33 u16 wakeup_jmp_seg;
34 u64 wakeup_gdt[3];
35 u32 signature; /* To check we have correct structure */
36} __attribute__((__packed__));
37
38extern struct wakeup_header wakeup_header;
39#endif
40
41#define WAKEUP_HEADER_OFFSET 8
42#define WAKEUP_HEADER_SIGNATURE 0x51ee1111
43#define WAKEUP_END_SIGNATURE 0x65a22c82
44
45/* Wakeup behavior bits */
46#define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0
47
48#endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.lds.S b/arch/x86/kernel/acpi/realmode/wakeup.lds.S
new file mode 100644
index 00000000000..d4f8010a5b1
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/wakeup.lds.S
@@ -0,0 +1,62 @@
1/*
2 * wakeup.ld
3 *
4 * Linker script for the real-mode wakeup code
5 */
6#undef i386
7#include "wakeup.h"
8
9OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
10OUTPUT_ARCH(i386)
11ENTRY(_start)
12
13SECTIONS
14{
15 . = 0;
16 .jump : {
17 *(.jump)
18 } = 0x90909090
19
20 . = WAKEUP_HEADER_OFFSET;
21 .header : {
22 *(.header)
23 }
24
25 . = ALIGN(16);
26 .text : {
27 *(.text*)
28 } = 0x90909090
29
30 . = ALIGN(16);
31 .rodata : {
32 *(.rodata*)
33 }
34
35 .videocards : {
36 video_cards = .;
37 *(.videocards)
38 video_cards_end = .;
39 }
40
41 . = ALIGN(16);
42 .data : {
43 *(.data*)
44 }
45
46 . = ALIGN(16);
47 .bss : {
48 __bss_start = .;
49 *(.bss)
50 __bss_end = .;
51 }
52
53 .signature : {
54 *(.signature)
55 }
56
57 _end = .;
58
59 /DISCARD/ : {
60 *(.note*)
61 }
62}
diff --git a/arch/x86/kernel/acpi/wakeup_rm.S b/arch/x86/kernel/acpi/wakeup_rm.S
new file mode 100644
index 00000000000..63b8ab524f2
--- /dev/null
+++ b/arch/x86/kernel/acpi/wakeup_rm.S
@@ -0,0 +1,12 @@
1/*
2 * Wrapper script for the realmode binary as a transport object
3 * before copying to low memory.
4 */
5#include <asm/page_types.h>
6
7 .section ".x86_trampoline","a"
8 .balign PAGE_SIZE
9 .globl acpi_wakeup_code
10acpi_wakeup_code:
11 .incbin "arch/x86/kernel/acpi/realmode/wakeup.bin"
12 .size acpi_wakeup_code, .-acpi_wakeup_code