Test framwork ported to qemu -kernel
cover Test framwork ported to qemu -kernel
This patchset ports the test framework to qemu's multiboot support with -kernel. You can now run tests using the following command:
qemu -chardev stdio,id=test -device testdev,chardev=test
-kernel kvm/user/test/x86/apic.flat
the test device is transitional an I plan to remove it in the future, replacing it with native qemu devices.
Avi Kivity (33):
test: load image immediately after program headers
test: Set up a default stack
test: add multiboot headers to startup files
test: Map 4GB of memory
test: use real APIC instead of fake APIC
test: switch output format to elf
test: Remove smp support from access.c
test: fix realmode test print_serial() direction flag
test: port readmode tests to multiboot
test: Allow adding mode vmexit latency tests
test: Add vmcall latency test
test: add cr8 latency tests
test: Mask PIC interrupts before APIC test
test-device: add support for irq injection
test: Use function table for APIC access
test: use new apic_icr_write() to issue IPI
test: add x2apic test
test: add support for the firmware configuration interface
test: Add fwcfg interface for getting the cpu count
test: vm: map mmio 1:1
test: apic: use 1:1 mapping for apic
test: Move apic functions to libcflat
test: switch 64-bit smp startup to real APIC
test: add apic_id() accessor
test: Use xapic_write() to enable xapic()
test: initialize idt on all processors
test: initialize apic/x2apic on all processors
test: wait for all processors to complete initialization
test: port smp runtime to real apic
test: drop irq.flat
test: fix autodependencies
test: Fix compilation rule for assembly files wrt autodependencies
test: avoid deleting intermediate .o files
Gerd Hoffmann (1):
Add test device
Makefile.target | 1 +
hw/pc.c | 3 +
hw/testdev.c | 63 +++++++++
kvm/user/Makefile | 2 +-
kvm/user/config-x86-common.mak | 16 ++-
kvm/user/config-x86_64.mak | 2 +-
kvm/user/flat.lds | 4 +-
kvm/user/test/{x86/apic.h => lib/x86/apic-defs.h} | 0
kvm/user/test/lib/x86/apic.c | 149 +++++++++++++++++++++
kvm/user/test/lib/x86/apic.h | 34 +++++
kvm/user/test/lib/x86/fwcfg.c | 40 ++++++
kvm/user/test/lib/x86/fwcfg.h | 44 ++++++
kvm/user/test/lib/x86/smp.c | 68 ++--------
kvm/user/test/lib/x86/smp.h | 2 +-
kvm/user/test/x86/access.c | 4 +-
kvm/user/test/x86/apic.c | 70 +++-------
kvm/user/test/x86/cstart.S | 9 ++
kvm/user/test/x86/cstart64.S | 114 +++++++++++-----
kvm/user/test/x86/irq.S | 118 ----------------
kvm/user/test/x86/realmode.c | 54 ++++++--
kvm/user/test/x86/realmode.lds | 6 +-
kvm/user/test/x86/smptest.c | 10 +-
kvm/user/test/x86/vm.c | 3 +
kvm/user/test/x86/vmexit.c | 56 +++++++-
24 files changed, 573 insertions(+), 299 deletions(-)
create mode 100644 hw/testdev.c
rename kvm/user/test/{x86/apic.h => lib/x86/apic-defs.h} (100%)
create mode 100644 kvm/user/test/lib/x86/apic.c
create mode 100644 kvm/user/test/lib/x86/apic.h
create mode 100644 kvm/user/test/lib/x86/fwcfg.c
create mode 100644 kvm/user/test/lib/x86/fwcfg.h
delete mode 100644 kvm/user/test/x86/irq.SPATCH 1/34 Add test device
From: Gerd Hoffmann <[email protected]>
Add a test device which supports the kvmctl ioports, for running the test suite.
Usage:
qemu
-chardev file,path=/log/file/some/where,id=testlog -device testdev,chardev=testlog
--- Makefile.target | 1 + hw/testdev.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 0 deletions(-) create mode 100644 hw/testdev.c
Makefile.target +1 -0
@@ -216,6 +216,7 @@ obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o obj-i386-y += extboot.o obj-i386-y += piix4.o obj-i386-y += ne2000-isa.o +obj-i386-y += testdev.o ifeq ($(USE_KVM_PIT), 1) obj-i386-y += i8254-kvm.o endif
hw/testdev.c new file +55 -0
55 lines not on this page · raw message
Signature · 1 line
1.6.4.1
PATCH 2/34 test: load image immediately after program headers
In reply to Avi KivityOtherwise, ld places the image somewhere where multiboot can't find the multiboot headers.
--- kvm/user/flat.lds | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
kvm/user/flat.lds +1 -1
@@ -2,7 +2,7 @@ OUTPUT_FORMAT(binary) SECTIONS { - . = 1M; + . = 4M + SIZEOF_HEADERS; stext = .; .text : { *(.init) *(.text) *(.text.*) } . = ALIGN(4K);
Signature · 1 line
1.6.4.1
PATCH 3/34 test: Set up a default stack
In reply to Avi Kivitymultiboot doesn't give us any stack, so we need to set one up.
--- kvm/user/test/x86/cstart64.S | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
kvm/user/test/x86/cstart64.S +1 -0
@@ -69,6 +69,7 @@ tss_end: .section .init .code32 + mov $stacktop, %esp call prepare_64 jmpl $8, $start64
Signature · 1 line
1.6.4.1
PATCH 4/34 test: add multiboot headers to startup files
In reply to Avi KivityWith these headers, multiboot can launch us directly in protected mode.
--- kvm/user/test/x86/cstart.S | 9 +++++++++ kvm/user/test/x86/cstart64.S | 9 +++++++++ 2 files changed, 18 insertions(+), 0 deletions(-)
kvm/user/test/x86/cstart.S +9 -0
@@ -3,6 +3,15 @@ .bss .section .init + +mb_magic = 0x1BADB002 +mb_flags = 0x0 + + # multiboot header + .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) + +.globl start +start: call main push %eax call exit
kvm/user/test/x86/cstart64.S +9 -0
@@ -69,6 +69,15 @@ tss_end: .section .init .code32 + +mb_magic = 0x1BADB002 +mb_flags = 0x0 + + # multiboot header + .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) + +.globl start +start: mov $stacktop, %esp call prepare_64 jmpl $8, $start64
Signature · 1 line
1.6.4.1
PATCH 5/34 test: Map 4GB of memory
In reply to Avi KivityNeeded so the APIC can be accessed at address 0xfee00000.
--- kvm/user/test/x86/cstart64.S | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-)
kvm/user/test/x86/cstart64.S +5 -2
@@ -22,14 +22,17 @@ ring0stacktop: .align 4096 ptl2: i = 0 - .rept 512 + .rept 512 * 4 .quad 0x1e7 | (i << 21) i = i + 1 .endr .align 4096 ptl3: - .quad ptl2 + 7 + .quad ptl2 + 7 + 0 * 4096 + .quad ptl2 + 7 + 1 * 4096 + .quad ptl2 + 7 + 2 * 4096 + .quad ptl2 + 7 + 3 * 4096 .align 4096 ptl4:
Signature · 1 line
1.6.4.1
PATCH 6/34 test: use real APIC instead of fake APIC
In reply to Avi Kivitysmp temporarily disabled
--- kvm/user/test/x86/cstart64.S | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)
kvm/user/test/x86/cstart64.S +6 -3
@@ -1,5 +1,5 @@ -#include "fake-apic.h" +#include "apic.h" boot_idt = 0
@@ -131,8 +131,9 @@ start64: load_tss: mov $0, %eax mov %ax, %ss - mov $(APIC_BASE + APIC_REG_ID), %dx - in %dx, %eax + mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax + mov (%rax), %eax + shr $24, %eax mov %eax, %ebx shl $4, %ebx mov $((tss_end - tss) / max_cpus), %edx
@@ -150,6 +151,7 @@ load_tss: ret smp_init: +#if 0 lea boot_idt + ipi_vector * 8, %rdi mov $smp_init_ipi, %eax mov %ax, (%rdi)
@@ -178,4 +180,5 @@ smp_loop: inc %esi jmp smp_loop smp_init_done: +#endif ret
Signature · 1 line
1.6.4.1
PATCH 7/34 test: switch output format to elf
In reply to Avi KivityThis can be loaded by multiboot (qemu -kernel ...)
--- kvm/user/flat.lds | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)
kvm/user/flat.lds +0 -2
@@ -1,5 +1,3 @@ -OUTPUT_FORMAT(binary) - SECTIONS { . = 4M + SIZEOF_HEADERS;
Signature · 1 line
1.6.4.1
PATCH 8/34 test: Remove smp support from access.c
In reply to Avi KivityDoesn't do anthing anyway.
--- kvm/user/test/x86/access.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
kvm/user/test/x86/access.c +2 -2
@@ -1,6 +1,7 @@#include "libcflat.h" -#include "smp.h" + +#define smp_id () 0#define true 1#define false 0
@@ -598,7 +599,6 @@ int main()int r;printf ("starting test\n\n" ); -smp_init ((void (*)(void ))ac_test_run); r =ac_test_run ();return r ?0 :1 ; }
Signature · 1 line
1.6.4.1
PATCH 9/34 test: fix realmode test print_serial() direction flag
In reply to Avi KivityClear the direction flag to get the correct output.
--- kvm/user/test/x86/realmode.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
kvm/user/test/x86/realmode.c +1 -1
@@ -26,7 +26,7 @@ static void print_serial(const char *buf) {unsigned long len =strlen (buf); - asmvolatile ("addr32/rep/outsb" :"+S" (buf),"+c" (len) :"d" (0xf1 )); + asmvolatile ("cld; addr32/rep/outsb" :"+S" (buf),"+c" (len) :"d" (0xf1 )); }static void exit (int code)
Signature · 1 line
1.6.4.1
PATCH 10/34 test: port readmode tests to multiboot
In reply to Avi Kivity--- kvm/user/test/x86/realmode.c | 52 ++++++++++++++++++++++++++++++++------- kvm/user/test/x86/realmode.lds | 6 +---- 2 files changed, 43 insertions(+), 15 deletions(-)
kvm/user/test/x86/realmode.c +42 -10
@@ -549,7 +549,7 @@ void test_null(void)print_serial ("null test: FAIL\n" ); } -void start (void ) +void realmode_start (void ) {test_null ();
@@ -570,23 +570,55 @@ void start(void)exit (0 ); } +unsigned long long r_gdt[] = {0 ,0x9b000000ffff ,0x93000000ffff }; + +struct __attribute__((packed)) { +unsigned short limit; +void *base; +} r_gdt_descr = {sizeof (r_gdt) -1 , &r_gdt }; + asm( +".section .init \n\t" + +".code32 \n\t" + +"mb_magic = 0x1BADB002 \n\t" +"mb_flags = 0x0 \n\t" + +"# multiboot header \n\t" +".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t" + +".globl start \n\t" ".data \n\t" ". = . + 4096 \n\t" "stacktop: \n\t" +".text \n\t" -"init: \n\t" +"start: \n\t" +"lgdt r_gdt_descr \n\t" +"ljmp $8, $1f; 1: \n\t" +".code16gcc \n\t" +"mov $16, %eax \n\t" +"mov %ax, %ds \n\t" +"mov %ax, %es \n\t" +"mov %ax, %fs \n\t" +"mov %ax, %gs \n\t" +"mov %ax, %ss \n\t" +"mov %cr0, %eax \n\t" +"btc $0, %eax \n\t" +"mov %eax, %cr0 \n\t" +"ljmp $0, $realmode_entry \n\t" + +"realmode_entry: \n\t" +"xor %ax, %ax \n\t" "mov %ax, %ds \n\t" "mov %ax, %es \n\t" "mov %ax, %ss \n\t" -"mov $0x4000, %cx \n\t" -"xor %esi, %esi \n\t" -"mov %esi, %edi \n\t" -"rep/addr32/cs/movsl \n\t" +"mov %ax, %fs \n\t" +"mov %ax, %gs \n\t" "mov $stacktop, %sp\n\t" -"ljmp $0, $start \n\t" -".pushsection .boot, \"ax\" \n\t" -"ljmp $0xf000, $init \n\t" -".popsection" +"ljmp $0, $realmode_start \n\t" + +".code16gcc \n\t" );
kvm/user/test/x86/realmode.lds +1 -5
@@ -1,16 +1,12 @@ -OUTPUT_FORMAT(binary) - SECTIONS { - . = 0; + . = 16K; stext = .; .text : { *(.init) *(.text) } . = ALIGN(4K); .data : { *(.data) *(.rodata*) } . = ALIGN(16); .bss : { *(.bss) } - . = 0xfff0; - .boot : { *(.boot) } edata = .; }
Signature · 1 line
1.6.4.1
PATCH 11/34 test: Allow adding mode vmexit latency tests
In reply to Avi KivityMake the latency test run on an array of function pointers, which can be expanded with more tests.
--- kvm/user/test/x86/vmexit.c | 32 ++++++++++++++++++++++++++++---- 1 files changed, 28 insertions(+), 4 deletions(-)
kvm/user/test/x86/vmexit.c +28 -4
@@ -24,16 +24,40 @@ static inline unsigned long long rdtsc()# define R "e"#endif -int main () +static void cpuid (void ) +{ + asmvolatile ("push %%" R "bx; cpuid; pop %%" R "bx" + : : :"eax" ,"ecx" ,"edx" ); +} + +static struct test { +void (*func)(void ); +const char *name; +} tests[] = { + { cpuid,"cpuid" , }, +}; + +static void do_test (struct test *test) {int i;unsigned long long t1, t2; +void (*func)(void ) = test->func; t1 =rdtsc ();for (i =0 ; i <N ; ++i) - asmvolatile ("push %%" R "bx; cpuid; pop %%" R "bx" - : : :"eax" ,"ecx" ,"edx" ); +func (); t2 =rdtsc (); -printf ("vmexit latency: %d\n" , (int )((t2 - t1) /N )); +printf ("%s %d\n" , test->name, (int )((t2 - t1) /N )); +} + +#define ARRAY_SIZE (_x) (sizeof(_x) / sizeof((_x)[0])) + +int main (void ) +{ +int i; + +for (i =0 ; i <ARRAY_SIZE (tests); ++i) +do_test (&tests[i]); +return 0 ; }
Signature · 1 line
1.6.4.1
PATCH 12/34 test: Add vmcall latency test
In reply to Avi Kivity--- kvm/user/test/x86/vmexit.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
kvm/user/test/x86/vmexit.c +8 -0
@@ -30,11 +30,19 @@ static void cpuid(void) : : : "eax", "ecx", "edx"); } +static void vmcall (void ) +{ +unsigned long a =0 , b, c, d; + + asmvolatile ("vmcall" :"+a" (a),"=b" (b),"=c" (c),"=d" (d)); +} +static struct test {void (*func)(void );const char *name; } tests[] = { { cpuid,"cpuid" , }, + { vmcall,"vmcall" , }, };static void do_test (struct test *test)
Signature · 1 line
1.6.4.1
PATCH 13/34 test: add cr8 latency tests
In reply to Avi KivityIn light of the recent cr8/ept problem.
--- kvm/user/test/x86/vmexit.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-)
kvm/user/test/x86/vmexit.c +16 -0
@@ -37,12 +37,28 @@ static void vmcall(void) asmvolatile ("vmcall" :"+a" (a),"=b" (b),"=c" (c),"=d" (d)); } +static void mov_from_cr8 (void ) +{ +unsigned long cr8; + + asmvolatile ("mov %%cr8, %0" :"=r" (cr8)); +} + +static void mov_to_cr8 (void ) +{ +unsigned long cr8 =0 ; + + asmvolatile ("mov %0, %%cr8" : :"r" (cr8)); +} +static struct test {void (*func)(void );const char *name; } tests[] = { { cpuid,"cpuid" , }, { vmcall,"vmcall" , }, + { mov_from_cr8,"mov_from_cr8" }, + { mov_to_cr8,"mov_to_cr8" }, };static void do_test (struct test *test)
Signature · 1 line
1.6.4.1
PATCH 14/34 test: Mask PIC interrupts before APIC test
In reply to Avi KivityWe aren't ready to handle PIC interrupts, so mask them.
--- kvm/user/test/x86/apic.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)
kvm/user/test/x86/apic.c +13 -0
@@ -102,6 +102,11 @@ static idt_entry_t idt[256];static int g_fail;static int g_tests; +static void outb (unsigned char data,unsigned short port) +{ + asmvolatile ("out %0, %1" : :"a" (data),"d" (port)); +} +static void report (const char *msg,int pass) { ++g_tests;
@@ -325,9 +330,16 @@ static void test_ioapic_simultaneous(void)static void enable_apic (void ) { +printf ("enabling apic\n" );apic_write (0xf0 ,0x1ff );/* spurious vector register */ } +static void mask_pic_interrupts (void ) +{ +outb (0xff ,0x21 ); +outb (0xff ,0xa1 ); +} +int main () {setup_vm ();
@@ -337,6 +349,7 @@ int main()test_lapic_existence (); +mask_pic_interrupts ();enable_apic ();init_idt ();
Signature · 1 line
1.6.4.1
PATCH 15/34 test-device: add support for irq injection
In reply to Avi KivityThis allows apic.flat to pass.
Direct access to the ioapic is required, which is not supported by qdev at this time, so we pass the isa_irq array using a hack.
--- hw/pc.c | 3 +++ hw/testdev.c | 8 ++++++++ 2 files changed, 11 insertions(+), 0 deletions(-)
hw/pc.c +3 -0
@@ -68,6 +68,8 @@ static RTCState *rtc_state;static PITState *pit;static PCII440FXState *i440fx_state; +qemu_irq *ioapic_irq_hack; + typedef struct rom_reset_data { uint8_t *data; target_phys_addr_t addr;
@@ -1340,6 +1342,7 @@ static void pc_init1(ram_addr_t ram_size,if (pci_enabled) { isa_irq_state->ioapic =ioapic_init (); + ioapic_irq_hack = isa_irq; }#ifdef USE_KVM_PIT if (kvm_enabled () &&qemu_kvm_pit_in_kernel ())
hw/testdev.c +8 -0
@@ -27,6 +27,13 @@ static uint32_t test_device_memsize_read(void *opaque, uint32_t addr)return ram_size; } +static void test_device_irq_line (void *opaque,uint32_t addr,uint32_t data) +{ +extern qemu_irq *ioapic_irq_hack; + +qemu_set_irq (ioapic_irq_hack[addr -0x2000 ], !!data); +} +static int init_test_device (ISADevice *isa) { struct testdev *dev = DO_UPCAST(struct testdev, dev, isa);
@@ -34,6 +41,7 @@ static int init_test_device(ISADevice *isa)register_ioport_write (0xf1 ,1 ,1 , test_device_serial_write, dev);register_ioport_write (0xf4 ,1 ,4 , test_device_exit, dev);register_ioport_read (0xd1 ,1 ,4 , test_device_memsize_read, dev); +register_ioport_write (0x2000 ,24 ,1 , test_device_irq_line,NULL );return 0 ; }
Signature · 1 line
1.6.4.1
PATCH 16/34 test: Use function table for APIC access
In reply to Avi KivityPrepare for x2apic.
--- kvm/user/test/x86/apic.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 files changed, 39 insertions(+), 2 deletions(-)
kvm/user/test/x86/apic.c +39 -2
@@ -102,6 +102,12 @@ static idt_entry_t idt[256];static int g_fail;static int g_tests; +struct apic_ops { +u32 (*reg_read)(unsigned reg); +void (*reg_write)(unsigned reg,u32 val); +void (*icr_write)(u32 val,u32 dest); +}; +static void outb (unsigned char data,unsigned short port) { asmvolatile ("out %0, %1" : :"a" (data),"d" (port));
@@ -115,16 +121,47 @@ static void report(const char *msg, int pass) ++g_fail; } -static u32 apic_read (unsigned reg) +static u32 xapic_read (unsigned reg) {return *(volatile u32 *)(g_apic + reg); } -static void apic_write (unsigned reg,u32 val) +static void xapic_write (unsigned reg,u32 val) { *(volatile u32 *)(g_apic + reg) = val; } +static void xapic_icr_write (u32 val,u32 dest) +{ +while (xapic_read (APIC_ICR ) &APIC_ICR_BUSY ) + ; +xapic_write (APIC_ICR2 , dest <<24 ); +xapic_write (APIC_ICR , val); +} + +static const struct apic_ops xapic_ops = { + .reg_read = xapic_read, + .reg_write = xapic_write, + .icr_write = xapic_icr_write, +}; + +static const struct apic_ops *apic_ops = &xapic_ops; + +static u32 apic_read (unsigned reg) +{ +return apic_ops->reg_read (reg); +} + +static void apic_write (unsigned reg,u32 val) +{ + apic_ops->reg_write (reg, val); +} + +static void apic_icr_write (u32 val,u32 dest) +{ + apic_ops->icr_write (val, dest); +} +static void test_lapic_existence (void ) {u32 lvr;
Signature · 1 line
1.6.4.1
PATCH 17/34 test: use new apic_icr_write() to issue IPI
In reply to Avi Kivity--- kvm/user/test/x86/apic.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
kvm/user/test/x86/apic.c +2 -2
@@ -260,8 +260,8 @@ static void test_self_ipi(void)set_idt_entry (vec, self_ipi_isr);irq_enable (); -apic_write (APIC_ICR , -APIC_DEST_SELF |APIC_DEST_PHYSICAL |APIC_DM_FIXED | vec); +apic_icr_write (APIC_DEST_SELF |APIC_DEST_PHYSICAL |APIC_DM_FIXED | vec, +0 ); asmvolatile ("nop" );report ("self ipi" , ipi_count ==1 ); }
Signature · 1 line
1.6.4.1
PATCH 18/34 test: add x2apic test
In reply to Avi Kivity--- kvm/user/test/x86/apic.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 46 insertions(+), 0 deletions(-)
kvm/user/test/x86/apic.c +46 -0
@@ -9,6 +9,7 @@ typedef unsigned char u8;typedef unsigned short u16 ;typedef unsigned u32 ;typedef unsigned long ulong ; +typedef unsigned long long u64 ; typedef struct { unsigned short offset0;
@@ -147,6 +148,31 @@ static const struct apic_ops xapic_ops = {static const struct apic_ops *apic_ops = &xapic_ops; +static u32 x2apic_read (unsigned reg) +{ +unsigned a, d; + + asmvolatile ("rdmsr" :"=a" (a),"=d" (d) :"c" (APIC_BASE_MSR + reg/16 )); +return a | (u64 )d <<32 ; +} + +static void x2apic_write (unsigned reg,u32 val) +{ + asmvolatile ("wrmsr" : :"a" (val),"d" (0 ),"c" (APIC_BASE_MSR + reg/16 )); +} + +static void x2apic_icr_write (u32 val,u32 dest) +{ + asmvolatile ("wrmsr" : :"a" (val),"d" (dest), +"c" (APIC_BASE_MSR +APIC_ICR /16 )); +} + +static const struct apic_ops x2apic_ops = { + .reg_read = x2apic_read, + .reg_write = x2apic_write, + .icr_write = x2apic_icr_write, +}; +static u32 apic_read (unsigned reg) {return apic_ops->reg_read (reg);
@@ -171,6 +197,25 @@ static void test_lapic_existence(void)report ("apic existence" , (u16 )lvr ==0x14 ); } +#define MSR_APIC_BASE 0x0000001b + +static void enable_x2apic (void ) +{ +unsigned a, b, c, d; + + asm ("cpuid" :"=a" (a),"=b" (b),"=c" (c),"=d" (d) :"0" (1 )); + +if (c & (1 <<21 )) { + asm ("rdmsr" :"=a" (a),"=d" (d) :"c" (MSR_APIC_BASE )); + a |=1 <<10 ; + asm ("wrmsr" : :"a" (a),"d" (d),"c" (MSR_APIC_BASE )); + apic_ops = &x2apic_ops; +printf ("x2apic enabled\n" ); + }else { +printf ("x2apic not detected\n" ); + } +} +static u16 read_cs (void ) {u16 v;
@@ -388,6 +433,7 @@ int main()mask_pic_interrupts ();enable_apic (); +enable_x2apic ();init_idt ();test_self_ipi ();
Signature · 1 line
1.6.4.1
PATCH 19/34 test: add support for the firmware configuration interface
In reply to Avi Kivity--- kvm/user/config-x86-common.mak | 2 + kvm/user/test/lib/x86/fwcfg.c | 35 +++++++++++++++++++++++++++++++++ kvm/user/test/lib/x86/fwcfg.h | 42 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 0 deletions(-) create mode 100644 kvm/user/test/lib/x86/fwcfg.c create mode 100644 kvm/user/test/lib/x86/fwcfg.h
kvm/user/config-x86-common.mak +2 -0
@@ -11,6 +11,8 @@ cflatobjs += \ test/lib/x86/io.o \ test/lib/x86/smp.o +cflatobjs += test/lib/x86/fwcfg.o + $(libcflat): LDFLAGS += -nostdlib $(libcflat): CFLAGS += -ffreestanding -I test/lib
kvm/user/test/lib/x86/fwcfg.c new file +35 -0
@@ -0,0 +1,35 @@ +#include "fwcfg.h" + +uint64_t fwcfg_get_u (uint16_t index,int bytes) +{ +uint64_t r =0 ; +uint8_t b; +int i; + + asmvolatile ("out %0, %1" : :"a" (index),"d" ((uint16_t )BIOS_CFG_IOPORT )); +for (i =0 ; i < bytes; ++i) { + asmvolatile ("in %1, %0" :"=a" (b) :"d" ((uint16_t )(BIOS_CFG_IOPORT +1 ))); + r |= (uint64_t )b << (i *8 ); + } +return r; +} + +uint8_t fwcfg_get_u8 (unsigned index) +{ +return fwcfg_get_u (index,1 ); +} + +uint16_t fwcfg_get_u16 (unsigned index) +{ +return fwcfg_get_u (index,2 ); +} + +uint32_t fwcfg_get_u32 (unsigned index) +{ +return fwcfg_get_u (index,4 ); +} + +uint64_t fwcfg_get_u64 (unsigned index) +{ +return fwcfg_get_u (index,8 ); +}
kvm/user/test/lib/x86/fwcfg.h new file +42 -0
42 lines not on this page · raw message
Signature · 1 line
1.6.4.1
PATCH 20/34 test: Add fwcfg interface for getting the cpu count
In reply to Avi Kivity--- kvm/user/test/lib/x86/fwcfg.c | 5 +++++ kvm/user/test/lib/x86/fwcfg.h | 2 ++ 2 files changed, 7 insertions(+), 0 deletions(-)
kvm/user/test/lib/x86/fwcfg.c +5 -0
@@ -33,3 +33,8 @@ uint64_t fwcfg_get_u64(unsigned index) {return fwcfg_get_u (index,8 ); } + +unsigned fwcfg_get_nb_cpus (void ) +{ +return fwcfg_get_u16 (FW_CFG_NB_CPUS ); +}
kvm/user/test/lib/x86/fwcfg.h +2 -0
@@ -38,5 +38,7 @@ uint16_t fwcfg_get_u16(unsigned index);uint32_t fwcfg_get_u32 (unsigned index);uint64_t fwcfg_get_u64 (unsigned index); +unsigned fwcfg_get_nb_cpus (void ); +#endif
Signature · 1 line
1.6.4.1
PATCH 21/34 test: vm: map mmio 1:1
In reply to Avi KivityWith this assumption, the apic code will be able to run either before or after the vm is set up.
--- kvm/user/test/x86/vm.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
kvm/user/test/x86/vm.c +3 -0
@@ -189,6 +189,9 @@ static void setup_mmu(unsigned long len)unsigned long *cr3 =alloc_page ();unsigned long phys =0 ; +if (len < (1ul <<32 )) + len =1ul <<32 ;/* map mmio 1:1 */ +memset (cr3,0 ,PAGE_SIZE );while (phys +LARGE_PAGE_SIZE <= len) {install_large_page (cr3, phys, (void *)phys);
Signature · 1 line
1.6.4.1
PATCH 22/34 test: apic: use 1:1 mapping for apic
In reply to Avi KivityThis allows the apic code to be run early, before virtual memory is set up.
--- kvm/user/test/x86/apic.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
kvm/user/test/x86/apic.c +2 -2
@@ -426,8 +426,8 @@ int main() {setup_vm (); - g_apic =vmap (0xfee00000 ,0x1000 ); - g_ioapic =vmap (0xfec00000 ,0x1000 ); + g_apic = (void *)0xfee00000 ; + g_ioapic = (void *)0xfec00000 ;test_lapic_existence ();
Signature · 1 line
1.6.4.1
PATCH 23/34 test: Move apic functions to libcflat
In reply to Avi Kivity---
kvm/user/config-x86-common.mak | 1 +
kvm/user/test/{x86/apic.h => lib/x86/apic-defs.h} | 0
kvm/user/test/lib/x86/apic.c | 131 +++++++++++++++++++++
kvm/user/test/lib/x86/apic.h | 33 +++++
kvm/user/test/x86/apic.c | 130 +--------------------
kvm/user/test/x86/cstart64.S | 2 +-
6 files changed, 169 insertions(+), 128 deletions(-)
rename kvm/user/test/{x86/apic.h => lib/x86/apic-defs.h} (100%)
create mode 100644 kvm/user/test/lib/x86/apic.c
create mode 100644 kvm/user/test/lib/x86/apic.hkvm/user/config-x86-common.mak +1 -0
@@ -12,6 +12,7 @@ cflatobjs += \ test/lib/x86/smp.o cflatobjs += test/lib/x86/fwcfg.o +cflatobjs += test/lib/x86/apic.o $(libcflat): LDFLAGS += -nostdlib $(libcflat): CFLAGS += -ffreestanding -I test/lib
kvm/user/test/lib/x86/apic-defs.h renamed from kvm/user/test/x86/apic.h +0 -0
kvm/user/test/lib/x86/apic.c new file +131 -0
131 lines not on this page · raw message
kvm/user/test/lib/x86/apic.h new file +33 -0
@@ -0,0 +1,33 @@ +#ifndef CFLAT_APIC_H +#define CFLAT_APIC_H + +#include <stdint.h> +#include "apic-defs.h" + +typedef struct { +uint8_t vector; +uint8_t delivery_mode:3 ; +uint8_t dest_mode:1 ; +uint8_t delivery_status:1 ; +uint8_t polarity:1 ; +uint8_t remote_irr:1 ; +uint8_t trig_mode:1 ; +uint8_t mask:1 ; +uint8_t reserve:7 ; +uint8_t reserved[4 ]; +uint8_t dest_id; +}ioapic_redir_entry_t ; + +void mask_pic_interrupts (void ); + +void ioapic_write_redir (unsigned line,ioapic_redir_entry_t e); +void ioapic_write_reg (unsigned reg,uint32_t value); + +void enable_apic (void ); +uint32_t apic_read (unsigned reg); +void apic_write (unsigned reg,uint32_t val); +void apic_icr_write (uint32_t val,uint32_t dest); + +int enable_x2apic (void ); + +#endif
kvm/user/test/x86/apic.c +3 -127
175 lines not on this page · raw message
kvm/user/test/x86/cstart64.S +1 -1
@@ -1,5 +1,5 @@ -#include "apic.h" +#include "apic-defs.h" boot_idt = 0
Signature · 1 line
1.6.4.1
PATCH 24/34 test: switch 64-bit smp startup to real APIC
In reply to Avi Kivity--- kvm/user/test/x86/cstart64.S | 74 ++++++++++++++++++++++++----------------- 1 files changed, 43 insertions(+), 31 deletions(-)
kvm/user/test/x86/cstart64.S +43 -31
@@ -107,10 +107,42 @@ efer = 0xc0000080 mov %eax, %cr0 ret +smp_stacktop: .long 0xa0000 -smp_init_ipi: +.align 16 + +gdt32: + .quad 0 + .quad 0x00cf9b000000ffff // flat 32-bit code segment + .quad 0x00cf93000000ffff // flat 32-bit data segment +gdt32_end: + +.code16 +sipi_entry: + mov %cr0, %eax + or $1, %eax + mov %eax, %cr0 + lgdtl gdt32_descr - sipi_entry + ljmpl $8, $ap_start32 + +gdt32_descr: + .word gdt32_end - gdt32 - 1 + .long gdt32 + +sipi_end: + +.code32 +ap_start32: + mov $0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + mov $-4096, %esp + lock/xaddl %esp, smp_stacktop call prepare_64 - jmpl $8, $ap_start64 + ljmpl $8, $ap_start64 .code64 ap_start64:
@@ -151,34 +183,14 @@ load_tss: ret smp_init: -#if 0 - lea boot_idt + ipi_vector * 8, %rdi - mov $smp_init_ipi, %eax - mov %ax, (%rdi) - mov %cs, %ax - mov %ax, 2(%rdi) - movw $0x8e00, 4(%rdi) - shr $16, %eax - mov %ax, 6(%rdi) - - mov $(APIC_BASE + APIC_REG_IPI_VECTOR), %dx - mov $ipi_vector, %eax - out %eax, %dx - - mov $(APIC_BASE + APIC_REG_NCPU), %dx - in %dx, %eax - mov %eax, %ecx - mov $1, %esi -smp_loop: - cmp %esi, %ecx - je smp_init_done - - mov $(APIC_BASE + APIC_REG_SEND_IPI), %dx - mov %esi, %eax - out %eax, %dx - - inc %esi - jmp smp_loop + cld + lea sipi_entry, %rsi + xor %rdi, %rdi + mov $(sipi_end - sipi_entry), %rcx + rep/movsb + mov $APIC_DEFAULT_PHYS_BASE, %eax + movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax) + movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%rax) + movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax) smp_init_done: -#endif ret
Signature · 1 line
1.6.4.1
PATCH 25/34 test: add apic_id() accessor
In reply to Avi Kivityapic and x2apic have different formats for the ID register, so we need an accessor for it.
--- kvm/user/test/lib/x86/apic.c | 18 ++++++++++++++++++ kvm/user/test/lib/x86/apic.h | 1 + 2 files changed, 19 insertions(+), 0 deletions(-)
kvm/user/test/lib/x86/apic.c +18 -0
@@ -14,6 +14,7 @@ struct apic_ops {u32 (*reg_read)(unsigned reg);void (*reg_write)(unsigned reg,u32 val);void (*icr_write)(u32 val,u32 dest); +u32 (*id)(void); };static void outb (unsigned char data,unsigned short port)
@@ -39,10 +40,16 @@ static void xapic_icr_write(u32 val, u32 dest)xapic_write (APIC_ICR , val); } +static uint32_t xapic_id (void ) +{ +return xapic_read (APIC_ID ) >>24 ; +} +static const struct apic_ops xapic_ops = { .reg_read = xapic_read, .reg_write = xapic_write, .icr_write = xapic_icr_write, + .id = xapic_id, };static const struct apic_ops *apic_ops = &xapic_ops;
@@ -66,10 +73,16 @@ static void x2apic_icr_write(u32 val, u32 dest) "c"(APIC_BASE_MSR + APIC_ICR/16)); } +static uint32_t x2apic_id (void ) +{ +return xapic_read (APIC_ID ); +} +static const struct apic_ops x2apic_ops = { .reg_read = x2apic_read, .reg_write = x2apic_write, .icr_write = x2apic_icr_write, + .id = x2apic_id, };u32 apic_read (unsigned reg)
@@ -87,6 +100,11 @@ void apic_icr_write(u32 val, u32 dest) apic_ops->icr_write (val, dest); } +uint32_t apic_id (void ) +{ +return apic_ops->id (); +} +#define MSR_APIC_BASE 0x0000001bint enable_x2apic (void )
kvm/user/test/lib/x86/apic.h +1 -0
@@ -27,6 +27,7 @@ void enable_apic(void);uint32_t apic_read (unsigned reg);void apic_write (unsigned reg,uint32_t val);void apic_icr_write (uint32_t val,uint32_t dest); +uint32_t apic_id (void );int enable_x2apic (void );
Signature · 1 line
1.6.4.1
PATCH 26/34 test: Use xapic_write() to enable xapic()
In reply to Avi Kivityapic_write() depends on apic_ops, which is shared among cpus and can be modified if another cpu enabled x2apic. Use xapic_write() which is race-proof.
--- kvm/user/test/lib/x86/apic.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
kvm/user/test/lib/x86/apic.c +1 -1
@@ -139,7 +139,7 @@ void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e)void enable_apic (void ) {printf ("enabling apic\n" ); -apic_write (0xf0 ,0x1ff );/* spurious vector register */ +xapic_write (0xf0 ,0x1ff );/* spurious vector register */ }void mask_pic_interrupts (void )
Signature · 1 line
1.6.4.1
PATCH 27/34 test: initialize idt on all processors
In reply to Avi Kivity--- kvm/user/test/x86/cstart64.S | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
kvm/user/test/x86/cstart64.S +6 -0
@@ -1,6 +1,7 @@ #include "apic-defs.h" +.globl boot_idt boot_idt = 0 ipi_vector = 0x20
@@ -160,7 +161,12 @@ start64: mov %eax, %edi call exit +idt_descr: + .word 16 * 256 - 1 + .quad boot_idt + load_tss: + lidtq idt_descr mov $0, %eax mov %ax, %ss mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
Signature · 1 line
1.6.4.1
PATCH 28/34 test: initialize apic/x2apic on all processors
In reply to Avi Kivity--- kvm/user/test/x86/cstart64.S | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
kvm/user/test/x86/cstart64.S +5 -0
@@ -148,6 +148,8 @@ ap_start32: .code64 ap_start64: call load_tss + call enable_apic + call enable_x2apic sti nop
@@ -156,7 +158,10 @@ ap_start64: start64: call load_tss + call mask_pic_interrupts + call enable_apic call smp_init + call enable_x2apic call main mov %eax, %edi call exit
Signature · 1 line
1.6.4.1
PATCH 29/34 test: wait for all processors to complete initialization
In reply to Avi Kivityso we can start blasting them with IPIs.
--- kvm/user/test/x86/cstart64.S | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
kvm/user/test/x86/cstart64.S +7 -0
@@ -152,6 +152,7 @@ ap_start64: call enable_x2apic sti nop + lock incw cpu_online_count 1: hlt jmp 1b
@@ -203,5 +204,11 @@ smp_init: movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax) movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%rax) movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax) + call fwcfg_get_nb_cpus +1: pause + cmpw %ax, cpu_online_count + jne 1b smp_init_done: ret + +cpu_online_count: .word 1
Signature · 1 line
1.6.4.1
PATCH 30/34 test: port smp runtime to real apic
In reply to Avi Kivityinstead of the old fake apic.
--- kvm/user/test/lib/x86/smp.c | 68 ++++++------------------------------------- kvm/user/test/lib/x86/smp.h | 2 +- kvm/user/test/x86/smptest.c | 10 +----- 3 files changed, 12 insertions(+), 68 deletions(-)
kvm/user/test/lib/x86/smp.c +9 -59
@@ -1,46 +1,11 @@#include <libcflat.h> #include "smp.h" -#include "fake-apic.h" +#include "apic.h" +#include "fwcfg.h" #define IPI_VECTOR 0x20 -static int apic_read (int reg) -{ -unsigned short port =APIC_BASE + reg; -unsigned v; - - asmvolatile ("in %1, %0" :"=a" (v) :"d" (port)); -return v; -} - -static void apic_write (int reg,unsigned v) -{ -unsigned short port =APIC_BASE + reg; - - asmvolatile ("out %0, %1" : :"a" (v),"d" (port)); -} - -static int apic_get_cpu_count () -{ -return apic_read (APIC_REG_NCPU ); -} - -static int apic_get_id () -{ -return apic_read (APIC_REG_ID ); -} - -static void apic_set_ipi_vector (int vector) -{ -apic_write (APIC_REG_IPI_VECTOR , vector); -} - -static void apic_send_ipi (int cpu) -{ -apic_write (APIC_REG_SEND_IPI , cpu); -} -static struct spinlock ipi_lock;static void (*ipi_function)(void *data);static void *ipi_data;
@@ -100,23 +65,25 @@ void spin_unlock(struct spinlock *lock)int cpu_count (void ) { -return apic_get_cpu_count (); +return fwcfg_get_nb_cpus (); }int smp_id (void ) { -return apic_get_id (); +return apic_read (APIC_ID ); }void on_cpu (int cpu,void (*function)(void *data),void *data) {spin_lock (&ipi_lock); -if (cpu ==apic_get_id ()) +if (cpu ==apic_id ())function (data);else { ipi_function = function; ipi_data = data; -apic_send_ipi (cpu); +apic_icr_write (APIC_INT_ASSERT |APIC_DEST_PHYSICAL |APIC_DM_FIXED + |IPI_VECTOR , + cpu);while (!ipi_done) ; ipi_done =0 ;
@@ -124,27 +91,10 @@ void on_cpu(int cpu, void (*function)(void *data), void *data)spin_unlock (&ipi_lock); } -static void (*smp_main_func)(void ); -static volatile int smp_main_running; - -asm ("smp_init_entry: \n" -"incl smp_main_running \n" -"sti \n" -"call *smp_main_func" ); - -void smp_init (void (*smp_main)(void )) +void smp_init (void ) {int i; -void smp_init_entry (void );void ipi_entry (void ); -apic_set_ipi_vector (IPI_VECTOR ); -set_ipi_descriptor (smp_init_entry); - smp_main_func = smp_main; -for (i =1 ; i <cpu_count (); ++i) { -apic_send_ipi (i); -while (smp_main_running < i) - ; - }set_ipi_descriptor (ipi_entry); }
kvm/user/test/lib/x86/smp.h +1 -1
@@ -5,7 +5,7 @@ struct spinlock {int v; }; -void smp_init (void (*smp_main)(void )); +void smp_init (void );int cpu_count (void );int smp_id (void );
kvm/user/test/x86/smptest.c +2 -8
@@ -10,19 +10,13 @@ static void ipi_test(void *data)printf ("but wrong cpu %d\n" ,smp_id ()); } -static void smp_main (void ) -{ -printf ("smp main %d\n" ,smp_id ()); -while (1 ) - asmvolatile ("hlt" : : :"memory" ); -} -int main () {int ncpus;int i; -smp_init (smp_main); +smp_init (); + ncpus =cpu_count ();printf ("found %d cpus\n" , ncpus);for (i =0 ; i < ncpus; ++i)
Signature · 1 line
1.6.4.1
PATCH 31/34 test: drop irq.flat
In reply to Avi KivityObsolete.
--- kvm/user/config-x86-common.mak | 2 - kvm/user/config-x86_64.mak | 2 +- kvm/user/test/x86/irq.S | 118 ---------------------------------------- 3 files changed, 1 insertions(+), 121 deletions(-) delete mode 100644 kvm/user/test/x86/irq.S
kvm/user/config-x86-common.mak +0 -2
@@ -35,8 +35,6 @@ $(TEST_DIR)/%.o: CFLAGS += -std=gnu99 -ffreestanding -I test/lib -I test/lib/x86 $(TEST_DIR)/bootstrap: $(TEST_DIR)/bootstrap.o $(CC) -nostdlib -o $@ -Wl,-T,bootstrap.lds $^ -$(TEST_DIR)/irq.flat: $(TEST_DIR)/print.o - $(TEST_DIR)/access.flat: $(cstart.o) $(TEST_DIR)/access.o $(TEST_DIR)/print.o $(TEST_DIR)/hypercall.flat: $(cstart.o) $(TEST_DIR)/hypercall.o $(TEST_DIR)/print.o
kvm/user/config-x86_64.mak +1 -1
@@ -4,7 +4,7 @@ bits = 64 ldarch = elf64-x86-64 CFLAGS += -D__x86_64__ -tests = $(TEST_DIR)/access.flat $(TEST_DIR)/irq.flat $(TEST_DIR)/sieve.flat \ +tests = $(TEST_DIR)/access.flat $(TEST_DIR)/sieve.flat \ $(TEST_DIR)/simple.flat $(TEST_DIR)/stringio.flat \ $(TEST_DIR)/memtest1.flat $(TEST_DIR)/emulator.flat \ $(TEST_DIR)/hypercall.flat $(TEST_DIR)/apic.flat
kvm/user/test/x86/irq.S deleted +0 -118
118 lines not on this page · raw message
Signature · 1 line
1.6.4.1
PATCH 32/34 test: fix autodependencies
In reply to Avi KivityThe autodependencies files were generated, but not included.
--- kvm/user/config-x86-common.mak | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
kvm/user/config-x86-common.mak +2 -0
@@ -67,3 +67,5 @@ $(TEST_DIR)/msr.flat: $(cstart.o) $(TEST_DIR)/msr.o arch_clean: $(RM) $(TEST_DIR)/bootstrap $(TEST_DIR)/*.o $(TEST_DIR)/*.flat \ $(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o + +-include $(TEST_DIR)/.*.d test/lib/.*.d test/lib/x86/.*.d
Signature · 1 line
1.6.4.1
PATCH 33/34 test: Fix compilation rule for assembly files wrt autodependencies
In reply to Avi KivityOnly compile the first dependency (the source file), not the rest (headers).
--- kvm/user/Makefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
kvm/user/Makefile +1 -1
@@ -52,7 +52,7 @@ $(libcflat): $(cflatobjs) $(AR) rcs $@ $^ %.o: %.S - $(CC) $(CFLAGS) -c -nostdlib -o $@ $^ + $(CC) $(CFLAGS) -c -nostdlib -o $@ $< -include .*.d
Signature · 1 line
1.6.4.1
PATCH 34/34 test: avoid deleting intermediate .o files
In reply to Avi KivityIf make doesn't see an intermediate file mentioned explicitly, it deletes it after making the target. This silly behaviour causes needless rebuilds.
Add all intermediates as explicit dependncies to prevent this behaviour.
--- kvm/user/config-x86-common.mak | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)
kvm/user/config-x86-common.mak +8 -1
@@ -48,7 +48,8 @@ $(TEST_DIR)/test32.flat: $(TEST_DIR)/test32.o $(TEST_DIR)/smptest.flat: $(cstart.o) $(TEST_DIR)/smptest.o -$(TEST_DIR)/emulator.flat: $(cstart.o) $(TEST_DIR)/vm.o $(TEST_DIR)/print.o +$(TEST_DIR)/emulator.flat: $(cstart.o) $(TEST_DIR)/emulator.o \ + $(TEST_DIR)/vm.o $(TEST_DIR)/print.o $(TEST_DIR)/port80.flat: $(cstart.o) $(TEST_DIR)/port80.o
@@ -62,6 +63,12 @@ $(TEST_DIR)/realmode.flat: $(TEST_DIR)/realmode.o $(TEST_DIR)/realmode.o: bits = 32 +$(TEST_DIR)/memtest1.flat: $(TEST_DIR)/memtest1.o + +$(TEST_DIR)/stringio.flat: $(TEST_DIR)/stringio.o + +$(TEST_DIR)/simple.flat: $(TEST_DIR)/simple.o + $(TEST_DIR)/msr.flat: $(cstart.o) $(TEST_DIR)/msr.o arch_clean:
Signature · 1 line
1.6.4.1