117ca7746SDr. David Alan Gilbert# x86 bootblock used in migration test 217ca7746SDr. David Alan Gilbert# repeatedly increments the first byte of each page in a 100MB 317ca7746SDr. David Alan Gilbert# range. 417ca7746SDr. David Alan Gilbert# Outputs an initial 'A' on serial followed by repeated 'B's 517ca7746SDr. David Alan Gilbert# 617ca7746SDr. David Alan Gilbert# Copyright (c) 2016 Red Hat, Inc. and/or its affiliates 717ca7746SDr. David Alan Gilbert# This work is licensed under the terms of the GNU GPL, version 2 or later. 817ca7746SDr. David Alan Gilbert# See the COPYING file in the top-level directory. 917ca7746SDr. David Alan Gilbert# 1017ca7746SDr. David Alan Gilbert# Author: dgilbert@redhat.com 1117ca7746SDr. David Alan Gilbert 12*5014478eSSteve Sistare#include "migration-test.h" 13*5014478eSSteve Sistare 14*5014478eSSteve Sistare#define ACPI_ENABLE 0xf1 15*5014478eSSteve Sistare#define ACPI_PORT_SMI_CMD 0xb2 16*5014478eSSteve Sistare#define ACPI_PM_BASE 0x600 17*5014478eSSteve Sistare#define PM1A_CNT_OFFSET 4 18*5014478eSSteve Sistare 19*5014478eSSteve Sistare#define ACPI_SCI_ENABLE 0x0001 20*5014478eSSteve Sistare#define ACPI_SLEEP_TYPE 0x0400 21*5014478eSSteve Sistare#define ACPI_SLEEP_ENABLE 0x2000 22*5014478eSSteve Sistare#define SLEEP (ACPI_SCI_ENABLE + ACPI_SLEEP_TYPE + ACPI_SLEEP_ENABLE) 23*5014478eSSteve Sistare 24*5014478eSSteve Sistare#define LOW_ADDR X86_TEST_MEM_START 25*5014478eSSteve Sistare#define HIGH_ADDR X86_TEST_MEM_END 26*5014478eSSteve Sistare 27*5014478eSSteve Sistare/* Save the suspended status at an address that is not written in the loop. */ 28*5014478eSSteve Sistare#define suspended (X86_TEST_MEM_START + 4) 2917ca7746SDr. David Alan Gilbert 3017ca7746SDr. David Alan Gilbert.code16 3117ca7746SDr. David Alan Gilbert.org 0x7c00 3217ca7746SDr. David Alan Gilbert .file "fill.s" 3317ca7746SDr. David Alan Gilbert .text 3417ca7746SDr. David Alan Gilbert .globl start 3517ca7746SDr. David Alan Gilbert .type start, @function 3617ca7746SDr. David Alan Gilbertstart: # at 0x7c00 ? 3717ca7746SDr. David Alan Gilbert cli 3817ca7746SDr. David Alan Gilbert lgdt gdtdesc 3917ca7746SDr. David Alan Gilbert mov $1,%eax 4017ca7746SDr. David Alan Gilbert mov %eax,%cr0 # Protected mode enable 4117ca7746SDr. David Alan Gilbert data32 ljmp $8,$0x7c20 4217ca7746SDr. David Alan Gilbert 4317ca7746SDr. David Alan Gilbert.org 0x7c20 4417ca7746SDr. David Alan Gilbert.code32 4517ca7746SDr. David Alan Gilbert # A20 enable - not sure I actually need this 4617ca7746SDr. David Alan Gilbert inb $0x92,%al 4717ca7746SDr. David Alan Gilbert or $2,%al 4817ca7746SDr. David Alan Gilbert outb %al, $0x92 4917ca7746SDr. David Alan Gilbert 5017ca7746SDr. David Alan Gilbert # set up DS for the whole of RAM (needed on KVM) 5117ca7746SDr. David Alan Gilbert mov $16,%eax 5217ca7746SDr. David Alan Gilbert mov %eax,%ds 5317ca7746SDr. David Alan Gilbert 5467aeae79SDaniil Tatianin# Start from 1MB 55*5014478eSSteve Sistare.set TEST_MEM_START, X86_TEST_MEM_START 56*5014478eSSteve Sistare.set TEST_MEM_END, X86_TEST_MEM_END 5767aeae79SDaniil Tatianin 5817ca7746SDr. David Alan Gilbert mov $65,%ax 5917ca7746SDr. David Alan Gilbert mov $0x3f8,%dx 6017ca7746SDr. David Alan Gilbert outb %al,%dx 6117ca7746SDr. David Alan Gilbert 6217ca7746SDr. David Alan Gilbert # bl keeps a counter so we limit the output speed 6317ca7746SDr. David Alan Gilbert mov $0, %bl 64adc1914aSDaniil Tatianin 65adc1914aSDaniil Tatianinpre_zero: 66adc1914aSDaniil Tatianin mov $TEST_MEM_START,%eax 67adc1914aSDaniil Tatianindo_zero: 68adc1914aSDaniil Tatianin movb $0, (%eax) 69adc1914aSDaniil Tatianin add $4096,%eax 70adc1914aSDaniil Tatianin cmp $TEST_MEM_END,%eax 71adc1914aSDaniil Tatianin jl do_zero 72adc1914aSDaniil Tatianin 7317ca7746SDr. David Alan Gilbertmainloop: 7467aeae79SDaniil Tatianin mov $TEST_MEM_START,%eax 7517ca7746SDr. David Alan Gilbertinnerloop: 7617ca7746SDr. David Alan Gilbert incb (%eax) 7717ca7746SDr. David Alan Gilbert add $4096,%eax 7867aeae79SDaniil Tatianin cmp $TEST_MEM_END,%eax 7917ca7746SDr. David Alan Gilbert jl innerloop 8017ca7746SDr. David Alan Gilbert 8117ca7746SDr. David Alan Gilbert inc %bl 8241adc596SThomas Huth andb $0x3f,%bl 8317ca7746SDr. David Alan Gilbert jnz mainloop 8417ca7746SDr. David Alan Gilbert 8517ca7746SDr. David Alan Gilbert mov $66,%ax 8617ca7746SDr. David Alan Gilbert mov $0x3f8,%dx 8717ca7746SDr. David Alan Gilbert outb %al,%dx 8817ca7746SDr. David Alan Gilbert 89*5014478eSSteve Sistare # should this test suspend? 90*5014478eSSteve Sistare mov (suspend_me),%eax 91*5014478eSSteve Sistare cmp $0,%eax 92*5014478eSSteve Sistare je mainloop 93*5014478eSSteve Sistare 94*5014478eSSteve Sistare # are we waking after suspend? do not suspend again. 95*5014478eSSteve Sistare mov $suspended,%eax 96*5014478eSSteve Sistare mov (%eax),%eax 97*5014478eSSteve Sistare cmp $1,%eax 98*5014478eSSteve Sistare je mainloop 99*5014478eSSteve Sistare 100*5014478eSSteve Sistare # enable acpi 101*5014478eSSteve Sistare mov $ACPI_ENABLE,%al 102*5014478eSSteve Sistare outb %al,$ACPI_PORT_SMI_CMD 103*5014478eSSteve Sistare 104*5014478eSSteve Sistare # suspend to ram 105*5014478eSSteve Sistare mov $suspended,%eax 106*5014478eSSteve Sistare movl $1,(%eax) 107*5014478eSSteve Sistare mov $SLEEP,%ax 108*5014478eSSteve Sistare mov $(ACPI_PM_BASE + PM1A_CNT_OFFSET),%dx 109*5014478eSSteve Sistare outw %ax,%dx 110*5014478eSSteve Sistare # not reached. The wakeup causes reset and restart at 0x7c00, and we 111*5014478eSSteve Sistare # do not save and restore registers as a real kernel would do. 112*5014478eSSteve Sistare 11317ca7746SDr. David Alan Gilbert 11417ca7746SDr. David Alan Gilbert # GDT magic from old (GPLv2) Grub startup.S 11517ca7746SDr. David Alan Gilbert .p2align 2 /* force 4-byte alignment */ 11617ca7746SDr. David Alan Gilbertgdt: 11717ca7746SDr. David Alan Gilbert .word 0, 0 11817ca7746SDr. David Alan Gilbert .byte 0, 0, 0, 0 11917ca7746SDr. David Alan Gilbert 12017ca7746SDr. David Alan Gilbert /* -- code segment -- 12117ca7746SDr. David Alan Gilbert * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present 12217ca7746SDr. David Alan Gilbert * type = 32bit code execute/read, DPL = 0 12317ca7746SDr. David Alan Gilbert */ 12417ca7746SDr. David Alan Gilbert .word 0xFFFF, 0 12517ca7746SDr. David Alan Gilbert .byte 0, 0x9A, 0xCF, 0 12617ca7746SDr. David Alan Gilbert 12717ca7746SDr. David Alan Gilbert /* -- data segment -- 12817ca7746SDr. David Alan Gilbert * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present 12917ca7746SDr. David Alan Gilbert * type = 32 bit data read/write, DPL = 0 13017ca7746SDr. David Alan Gilbert */ 13117ca7746SDr. David Alan Gilbert .word 0xFFFF, 0 13217ca7746SDr. David Alan Gilbert .byte 0, 0x92, 0xCF, 0 13317ca7746SDr. David Alan Gilbert 13417ca7746SDr. David Alan Gilbertgdtdesc: 13517ca7746SDr. David Alan Gilbert .word 0x27 /* limit */ 13617ca7746SDr. David Alan Gilbert .long gdt /* addr */ 13717ca7746SDr. David Alan Gilbert 138*5014478eSSteve Sistare /* test launcher can poke a 1 here to exercise suspend */ 139*5014478eSSteve Sistaresuspend_me: 140*5014478eSSteve Sistare .int 0 141*5014478eSSteve Sistare 14217ca7746SDr. David Alan Gilbert/* I'm a bootable disk */ 14317ca7746SDr. David Alan Gilbert.org 0x7dfe 14417ca7746SDr. David Alan Gilbert .byte 0x55 14517ca7746SDr. David Alan Gilbert .byte 0xAA 146