master
s 145 lines 3.62 KB
Raw
1 # x86 bootblock used in migration test
2 # repeatedly increments the first byte of each page in a 100MB
3 # range.
4 # Outputs an initial 'A' on serial followed by repeated 'B's
5 #
6 # Copyright (c) 2016 Red Hat, Inc. and/or its affiliates
7 # This work is licensed under the terms of the GNU GPL, version 2 or later.
8 # See the COPYING file in the top-level directory.
9 #
10 # Author: dgilbert@redhat.com
11
12 #include "../bootfile.h"
13
14 #define ACPI_ENABLE 0xf1
15 #define ACPI_PORT_SMI_CMD 0xb2
16 #define ACPI_PM_BASE 0x600
17 #define PM1A_CNT_OFFSET 4
18
19 #define ACPI_SCI_ENABLE 0x0001
20 #define ACPI_SLEEP_TYPE 0x0400
21 #define ACPI_SLEEP_ENABLE 0x2000
22 #define SLEEP (ACPI_SCI_ENABLE + ACPI_SLEEP_TYPE + ACPI_SLEEP_ENABLE)
23
24 #define LOW_ADDR X86_TEST_MEM_START
25 #define HIGH_ADDR X86_TEST_MEM_END
26
27 /* Save the suspended status at an address that is not written in the loop. */
28 #define suspended (X86_TEST_MEM_START + 4)
29
30 .code16
31 .org 0x7c00
32 .file "fill.s"
33 .text
34 .globl start
35 .type start, @function
36 start: # at 0x7c00 ?
37 cli
38 lgdt gdtdesc
39 mov $1,%eax
40 mov %eax,%cr0 # Protected mode enable
41 data32 ljmp $8,$0x7c20
42
43 .org 0x7c20
44 .code32
45 # A20 enable - not sure I actually need this
46 inb $0x92,%al
47 or $2,%al
48 outb %al, $0x92
49
50 # set up DS for the whole of RAM (needed on KVM)
51 mov $16,%eax
52 mov %eax,%ds
53
54 # Start from 1MB
55 .set TEST_MEM_START, X86_TEST_MEM_START
56 .set TEST_MEM_END, X86_TEST_MEM_END
57
58 mov $65,%ax
59 mov $0x3f8,%dx
60 outb %al,%dx
61
62 # bl keeps a counter so we limit the output speed
63 mov $0, %bl
64
65 pre_zero:
66 mov $TEST_MEM_START,%eax
67 do_zero:
68 movb $0, (%eax)
69 add $4096,%eax
70 cmp $TEST_MEM_END,%eax
71 jl do_zero
72
73 mainloop:
74 mov $TEST_MEM_START,%eax
75 innerloop:
76 incb (%eax)
77 add $4096,%eax
78 cmp $TEST_MEM_END,%eax
79 jl innerloop
80
81 inc %bl
82 andb $0x3f,%bl
83 jnz mainloop
84
85 mov $66,%ax
86 mov $0x3f8,%dx
87 outb %al,%dx
88
89 # should this test suspend?
90 mov (suspend_me),%eax
91 cmp $0,%eax
92 je mainloop
93
94 # are we waking after suspend? do not suspend again.
95 mov $suspended,%eax
96 mov (%eax),%eax
97 cmp $1,%eax
98 je mainloop
99
100 # enable acpi
101 mov $ACPI_ENABLE,%al
102 outb %al,$ACPI_PORT_SMI_CMD
103
104 # suspend to ram
105 mov $suspended,%eax
106 movl $1,(%eax)
107 mov $SLEEP,%ax
108 mov $(ACPI_PM_BASE + PM1A_CNT_OFFSET),%dx
109 outw %ax,%dx
110 # not reached. The wakeup causes reset and restart at 0x7c00, and we
111 # do not save and restore registers as a real kernel would do.
112
113
114 # GDT magic from old (GPLv2) Grub startup.S
115 .p2align 2 /* force 4-byte alignment */
116 gdt:
117 .word 0, 0
118 .byte 0, 0, 0, 0
119
120 /* -- code segment --
121 * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present
122 * type = 32bit code execute/read, DPL = 0
123 */
124 .word 0xFFFF, 0
125 .byte 0, 0x9A, 0xCF, 0
126
127 /* -- data segment --
128 * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
129 * type = 32 bit data read/write, DPL = 0
130 */
131 .word 0xFFFF, 0
132 .byte 0, 0x92, 0xCF, 0
133
134 gdtdesc:
135 .word 0x27 /* limit */
136 .long gdt /* addr */
137
138 /* test launcher can poke a 1 here to exercise suspend */
139 suspend_me:
140 .int 0
141
142 /* I'm a bootable disk */
143 .org 0x7dfe
144 .byte 0x55
145 .byte 0xAA