qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] tests/tcg/alpha: add system boot.S


From: Alex Bennée
Subject: Re: [Qemu-devel] [PATCH] tests/tcg/alpha: add system boot.S
Date: Fri, 03 May 2019 18:07:24 +0100
User-agent: mu4e 1.3.1; emacs 26.1

Richard Henderson <address@hidden> writes:

> This provides the bootstrap and low level helper functions for an
> alpha kernel.  We use direct access to the DP264 serial port for
> test output, and hard machine halt to exit the emulation.

Queued to testing/next, thanks.

I've also added tests/tcg/alpha/system/ to MAINTAINERS

>
> Signed-off-by: Richard Henderson <address@hidden>
> ---
>  tests/tcg/alpha/Makefile.softmmu-target |  32 ++
>  tests/tcg/alpha/system/boot.S           | 511 ++++++++++++++++++++++++
>  tests/tcg/alpha/system/kernel.ld        |  30 ++
>  3 files changed, 573 insertions(+)
>  create mode 100644 tests/tcg/alpha/Makefile.softmmu-target
>  create mode 100644 tests/tcg/alpha/system/boot.S
>  create mode 100644 tests/tcg/alpha/system/kernel.ld
>
> diff --git a/tests/tcg/alpha/Makefile.softmmu-target 
> b/tests/tcg/alpha/Makefile.softmmu-target
> new file mode 100644
> index 0000000000..9f4b199258
> --- /dev/null
> +++ b/tests/tcg/alpha/Makefile.softmmu-target
> @@ -0,0 +1,32 @@
> +#
> +# Alpha system tests
> +#
> +
> +ALPHA_SYSTEM_SRC=$(SRC_PATH)/tests/tcg/alpha/system
> +VPATH+=$(ALPHA_SYSTEM_SRC)
> +
> +# These objects provide the basic boot code and helper functions for all 
> tests
> +CRT_OBJS=boot.o
> +
> +ALPHA_TEST_SRCS=$(wildcard $(ALPHA_SYSTEM_SRC)/*.c)
> +ALPHA_TESTS = $(patsubst $(ALPHA_SYSTEM_SRC)/%.c, %, $(ALPHA_TEST_SRCS))
> +
> +CRT_PATH=$(ALPHA_SYSTEM_SRC)
> +LINK_SCRIPT=$(ALPHA_SYSTEM_SRC)/kernel.ld
> +LDFLAGS=-Wl,-T$(LINK_SCRIPT)
> +TESTS+=$(ALPHA_TESTS) $(MULTIARCH_TESTS)
> +CFLAGS+=-nostdlib -g -O1 -mcpu=ev6 $(MINILIB_INC)
> +LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
> +
> +# building head blobs
> +.PRECIOUS: $(CRT_OBJS)
> +
> +%.o: $(CRT_PATH)/%.S
> +     $(CC) $(CFLAGS) -x assembler-with-cpp -c $< -o $@
> +
> +# Build and link the tests
> +%: %.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS)
> +     $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
> +
> +# Running
> +QEMU_OPTS+=-serial chardev:output -kernel
> diff --git a/tests/tcg/alpha/system/boot.S b/tests/tcg/alpha/system/boot.S
> new file mode 100644
> index 0000000000..6d7fb36e17
> --- /dev/null
> +++ b/tests/tcg/alpha/system/boot.S
> @@ -0,0 +1,511 @@
> +/*
> + * Minimal Alpha system boot code.
> + *
> + * Copyright Linaro Ltd 2019
> + */
> +
> +     .set    noat
> +     .set    nomacro
> +     .arch   ev6
> +     .text
> +
> +.macro load_pci_io reg
> +     /* For typhoon, this is
> +      *   0xfffffc0000000000  -- kseg identity map
> +      * +      0x10000000000  -- typhoon pio base
> +      * +        0x1fc000000  -- typhoon pchip0 pci base
> +      * = 0xfffffd01fc000000
> +      */
> +     ldah    \reg, -3                /* ff..fd0000 */
> +     lda     \reg, 0x1fc(\reg)       /* ff..fd01fc */
> +     sll     \reg, 24, \reg
> +.endm
> +
> +#define com1Rbr 0x3f8
> +#define com1Thr 0x3f8
> +#define com1Ier 0x3f9
> +#define com1Iir 0x3fa
> +#define com1Lcr 0x3fb
> +#define com1Mcr 0x3fc
> +#define com1Lsr 0x3fd
> +#define com1Msr 0x3fe
> +#define com1Scr 0x3ff
> +#define com1Dll 0x3f8
> +#define com1Dlm 0x3f9
> +
> +#define PAL_halt    0
> +#define PAL_wrent  52
> +#define PAL_wrkgp  55
> +
> +     .text
> +     .p2align 4
> +     .globl  _start
> +     .ent    _start
> +_start:
> +     br      $gp, .+4
> +     ldah    $gp, 0($gp)             !gpdisp!1
> +     lda     $gp, 0($gp)             !gpdisp!1
> +
> +     ldah    $sp, $stack_end($gp)    !gprelhigh
> +     lda     $sp, $stack_end($gp)    !gprellow
> +
> +     /* Install kernel gp for exception handlers.  */
> +     mov     $gp, $16
> +     call_pal PAL_wrkgp
> +
> +     /* Install exception handlers.  */
> +     ldah    $16, entInt($gp)        !gprelhigh
> +     lda     $16, entInt($16)        !gprellow
> +     lda     $17, 0
> +     call_pal PAL_wrent
> +
> +     ldah    $16, entArith($gp)      !gprelhigh
> +     lda     $16, entArith($16)      !gprellow
> +     lda     $17, 1
> +     call_pal PAL_wrent
> +
> +     ldah    $16, entMM($gp)         !gprelhigh
> +     lda     $16, entMM($16)         !gprellow
> +     lda     $17, 2
> +     call_pal PAL_wrent
> +
> +     ldah    $16, entIF($gp)         !gprelhigh
> +     lda     $16, entIF($16)         !gprellow
> +     lda     $17, 3
> +     call_pal PAL_wrent
> +
> +     ldah    $16, entUna($gp)        !gprelhigh
> +     lda     $16, entUna($16)        !gprellow
> +     lda     $17, 4
> +     call_pal PAL_wrent
> +
> +     ldah    $16, entSys($gp)        !gprelhigh
> +     lda     $16, entSys($16)        !gprellow
> +     lda     $17, 5
> +     call_pal PAL_wrent
> +
> +     /*
> +      * Initialize COM1.
> +      */
> +     load_pci_io $1
> +     lda     $2, 0x87                /* outb(0x87, com1Lcr); */
> +     stb     $2, com1Lcr($1)
> +     stb     $31, com1Dlm($1)        /* outb(0, com1Dlm); */
> +     lda     $2, 3                   /* baudconst 3 => 56000 */
> +     stb     $2, com1Dll($1)         /* outb(baudconst, com1Dll); */
> +     lda     $2, 0x07
> +     stb     $2, com1Lcr($1)         /* outb(0x07, com1Lcr) */
> +     lda     $2, 0x0f
> +     stb     $2, com1Mcr($1)         /* outb(0x0f, com1Mcr) */
> +
> +     bsr     $26, main               !samegp
> +
> +     /* fall through to _exit */
> +     .end    _start
> +
> +     .globl  _exit
> +     .ent    _exit
> +_exit:
> +     .frame  $sp, 0, $26, 0
> +     .prologue 0
> +
> +     /* We cannot return an error code.  */
> +     call_pal PAL_halt
> +     .end    _exit
> +
> +/*
> + * We have received an exception that we don't handle.  Log and exit.
> + */
> +     .ent    log_exit
> +log_exit:
> +entInt:
> +entArith:
> +entMM:
> +entIF:
> +entUna:
> +entSys:
> +     ldah    $16, $errormsg($gp)     !gprelhigh
> +     lda     $16, $errormsg($16)     !gprellow
> +     bsr     $26, __sys_outs         !samegp
> +     bsr     $26, _exit              !samegp
> +     .end    log_exit
> +
> +     .section .rodata
> +$errormsg:
> +     .string "Terminated by exception.\n"
> +     .previous
> +
> +     /*
> +      * Helper Functions
> +      */
> +
> +     /* Output a single character to serial port */
> +     .global __sys_outc
> +     .ent    __sys_outc
> +__sys_outc:
> +     .frame  $sp, 0, $26, 0
> +     .prologue 0
> +
> +     load_pci_io $1
> +
> +     /*
> +      * while ((inb(com1Lsr) & 0x20) == 0)
> +      *       continue;
> +      */
> +1:   ldbu    $0, com1Lsr($1)
> +     and     $0, 0x20, $0
> +     beq     $0, 1b
> +
> +     /* outb(c, com1Thr); */
> +     stb     $16, com1Thr($1)
> +     ret
> +     .end    __sys_outc
> +
> +     /* Output a nul-terminated string to serial port */
> +     .global __sys_outs
> +     .ent    __sys_outs
> +__sys_outs:
> +     .frame  $sp, 0, $26, 0
> +     .prologue 0
> +
> +     load_pci_io $1
> +
> +     ldbu    $2, 0($16)
> +     beq     $2, 9f
> +
> +     /*
> +      * while ((inb(com1Lsr) & 0x20) == 0)
> +      *       continue;
> +      */
> +1:   ldbu    $0, com1Lsr($1)
> +     and     $0, 0x20, $0
> +     beq     $0, 1b
> +
> +     /* outb(c, com1Thr); */
> +     stb     $2, com1Thr($1)
> +
> +     addq    $16, 1, $16
> +     ldbu    $2, 0($16)
> +     bne     $2, 1b
> +
> +9:   ret
> +     .end    __sys_outs
> +
> +/*
> + * Division routines that are normally in libc.
> + *
> + * These do not follow the C calling convention.  Arguments are in $24+$25,
> + * the result is in $27.  Register $28 may be clobbered; everything else
> + * must be saved.
> + *
> + * We store the remainder in $28, so that we can share code.
> + *
> + * We do not signal divide by zero.
> + */
> +
> +/*
> + * Unsigned 64-bit division.
> + */
> +
> +     .globl  __divqu
> +     .ent    __divqu
> +__divqu:
> +     .frame  $sp, 48, $23
> +     subq    $sp, 48, $sp
> +     stq     $0, 0($sp)
> +     stq     $1, 8($sp)
> +     stq     $2, 16($sp)
> +     stq     $3, 24($sp)
> +     stq     $4, 32($sp)
> +     .prologue 0
> +
> +#define mask     $0
> +#define divisor  $1
> +#define compare  $2
> +#define tmp1     $3
> +#define tmp2     $4
> +#define quotient $27
> +#define modulus  $28
> +
> +     mov     $24, modulus
> +     mov     $25, divisor
> +     mov     $31, quotient
> +     mov     1, mask
> +     beq     $25, 9f
> +
> +     /* Shift left until divisor >= modulus.  */
> +1:   cmpult  divisor, modulus, compare
> +     blt     divisor, 2f
> +     addq    divisor, divisor, divisor
> +     addq    mask, mask, mask
> +     bne     compare, 1b
> +
> +2:   addq    quotient, mask, tmp2
> +     srl     mask, 1, mask
> +     cmpule  divisor, modulus, compare
> +     subq    modulus, divisor, tmp1
> +     cmovne  compare, tmp2, quotient
> +     srl     divisor, 1, divisor
> +     cmovne  compare, tmp1, modulus
> +     bne     mask, 2b
> +
> +9:   ldq     $0, 0($sp)
> +     ldq     $1, 8($sp)
> +     ldq     $2, 16($sp)
> +     ldq     $3, 24($sp)
> +     ldq     $4, 32($sp)
> +     addq    $sp, 48, $sp
> +     ret     $31, ($23), 1
> +
> +#undef mask
> +#undef divisor
> +#undef compare
> +#undef tmp1
> +#undef tmp2
> +#undef quotient
> +#undef modulus
> +
> +     .end    __divqu
> +
> +/*
> + * Unsigned 64-bit remainder.
> + * Note that __divqu above leaves the result in $28.
> + */
> +
> +     .globl  __remqu
> +     .ent    __remqu
> +__remqu:
> +     .frame  $sp, 16, $23
> +     subq    $sp, 16, $sp
> +     stq     $23, 0($sp)
> +     .prologue 0
> +
> +     bsr     $23, __divqu
> +
> +     ldq     $23, 0($sp)
> +     mov     $28, $27
> +     addq    $sp, 16, $sp
> +     ret     $31, ($23), 1
> +     .end    __remqu
> +
> +/*
> + * Signed 64-bit division.
> + */
> +
> +     .globl  __divqs
> +     .ent    __divqs
> +__divqs:
> +     .prologue 0
> +
> +     /* Common case: both arguments are positive.  */
> +     bis     $24, $25, $28
> +     bge     $28, __divqu
> +
> +     /* At least one argument is negative.  */
> +     subq    $sp, 32, $sp
> +     stq     $23, 0($sp)
> +     stq     $24, 8($sp)
> +     stq     $25, 16($sp)
> +
> +     /* Compute absolute values.  */
> +     subq    $31, $24, $28
> +     cmovlt  $24, $28, $24
> +     subq    $31, $25, $28
> +     cmovlt  $25, $28, $25
> +
> +     bsr     $23, __divqu
> +
> +     ldq     $24, 8($sp)
> +     ldq     $25, 16($sp)
> +
> +     /* -a / b = a / -b = -(a / b) */
> +     subq    $31, $27, $23
> +     xor     $24, $25, $28
> +     cmovlt  $28, $23, $27
> +
> +     ldq     $23, 0($sp)
> +     addq    $sp, 32, $sp
> +     ret     $31, ($23), 1
> +     .end    __divqs
> +
> +/*
> + * Signed 64-bit remainder.
> + */
> +
> +     .globl  __remqs
> +     .ent    __remqs
> +__remqs:
> +     .prologue 0
> +
> +     /* Common case: both arguments are positive.  */
> +     bis     $24, $25, $28
> +     bge     $28, __remqu
> +
> +     /* At least one argument is negative.  */
> +     subq    $sp, 32, $sp
> +     stq     $23, 0($sp)
> +     stq     $24, 8($sp)
> +     stq     $25, 16($sp)
> +
> +     /* Compute absolute values.  */
> +     subq    $31, $24, $28
> +     cmovlt  $24, $28, $24
> +     subq    $31, $25, $28
> +     cmovlt  $25, $28, $25
> +
> +     bsr     $23, __divqu
> +
> +     ldq     $23, 0($sp)
> +     ldq     $24, 8($sp)
> +     ldq     $25, 16($sp)
> +
> +     /* -a % b = -(a % b); a % -b = a % b.  */
> +     subq    $31, $28, $27
> +     cmovge  $24, $28, $27
> +
> +     addq    $sp, 32, $sp
> +     ret     $31, ($23), 1
> +     .end    __remqs
> +
> +/*
> + * Unsigned 32-bit division.
> + */
> +
> +     .globl  __divlu
> +     .ent    __divlu
> +__divlu:
> +     .frame  $sp, 32, $23
> +     subq    $sp, 32, $sp
> +     stq     $23, 0($sp)
> +     stq     $24, 8($sp)
> +     stq     $25, 16($sp)
> +     .prologue 0
> +
> +     /* Zero extend and use the 64-bit routine.  */
> +     zap     $24, 0xf0, $24
> +     zap     $25, 0xf0, $25
> +     bsr     $23, __divqu
> +
> +     addl    $27, 0, $27
> +     ldq     $23, 0($sp)
> +     ldq     $24, 8($sp)
> +     ldq     $25, 16($sp)
> +     addq    $sp, 32, $sp
> +     ret     $31, ($23), 1
> +     .end    __divlu
> +
> +/*
> + * Unsigned 32-bit remainder.
> + */
> +
> +     .globl  __remlu
> +     .ent    __remlu
> +__remlu:
> +     .frame  $sp, 32, $23
> +     subq    $sp, 32, $sp
> +     stq     $23, 0($sp)
> +     stq     $24, 8($sp)
> +     stq     $25, 16($sp)
> +     .prologue 0
> +
> +     /* Zero extend and use the 64-bit routine.  */
> +     zap     $24, 0xf0, $24
> +     zap     $25, 0xf0, $25
> +     bsr     $23, __divqu
> +
> +     /* Recall that the remainder is returned in $28.  */
> +     addl    $28, 0, $27
> +     ldq     $23, 0($sp)
> +     ldq     $24, 8($sp)
> +     ldq     $25, 16($sp)
> +     addq    $sp, 32, $sp
> +     ret     $31, ($23), 1
> +     .end    __remlu
> +
> +/*
> + * Signed 32-bit division.
> + */
> +
> +     .globl  __divls
> +     .ent    __divls
> +__divls:
> +     .frame  $sp, 32, $23
> +     subq    $sp, 32, $sp
> +     stq     $23, 0($sp)
> +     stq     $24, 8($sp)
> +     stq     $25, 16($sp)
> +     .prologue 0
> +
> +     /* Sign extend.  */
> +     addl    $24, 0, $24
> +     addl    $25, 0, $25
> +
> +     /* Compute absolute values.  */
> +     subq    $31, $24, $28
> +     cmovlt  $24, $28, $24
> +     subq    $31, $25, $28
> +     cmovlt  $25, $28, $25
> +
> +     bsr     $23, __divqu
> +
> +     ldq     $24, 8($sp)
> +     ldq     $25, 16($sp)
> +
> +     /* Negate the unsigned result, if necessary.  */
> +     xor     $24, $25, $28
> +     subl    $31, $27, $23
> +     addl    $27, 0, $27
> +     addl    $28, 0, $28
> +     cmovlt  $28, $23, $27
> +
> +     ldq     $23, 0($sp)
> +     addq    $sp, 32, $sp
> +     ret     $31, ($23), 1
> +     .end    __divls
> +
> +/*
> + * Signed 32-bit remainder.
> + */
> +
> +     .globl  __remls
> +     .ent    __remls
> +__remls:
> +     .frame  $sp, 32, $23
> +     subq    $sp, 32, $sp
> +     stq     $23, 0($sp)
> +     stq     $24, 8($sp)
> +     stq     $25, 16($sp)
> +     .prologue 0
> +
> +     /* Sign extend.  */
> +     addl    $24, 0, $24
> +     addl    $25, 0, $25
> +
> +     /* Compute absolute values.  */
> +     subq    $31, $24, $28
> +     cmovlt  $24, $28, $24
> +     subq    $31, $25, $28
> +     cmovlt  $25, $28, $25
> +
> +     bsr     $23, __divqu
> +
> +     ldq     $23, 0($sp)
> +     ldq     $24, 8($sp)
> +     ldq     $25, 16($sp)
> +
> +     /* Negate the unsigned result, if necessary.  */
> +     subl    $31, $28, $27
> +     addl    $28, 0, $28
> +     cmovge  $24, $28, $27
> +
> +     addq    $sp, 32, $sp
> +     ret     $31, ($23), 1
> +     .end    __remls
> +
> +     .data
> +     .p2align 4
> +stack:
> +     .skip   65536
> +$stack_end:
> +     .type   stack,@object
> +     .size   stack, . - stack
> diff --git a/tests/tcg/alpha/system/kernel.ld 
> b/tests/tcg/alpha/system/kernel.ld
> new file mode 100644
> index 0000000000..d2ac6ecfeb
> --- /dev/null
> +++ b/tests/tcg/alpha/system/kernel.ld
> @@ -0,0 +1,30 @@
> +ENTRY(_start)
> +
> +SECTIONS
> +{
> +    /* Linux kernel legacy start address.  */
> +    . = 0xfffffc0000310000;
> +    _text = .;
> +    .text : {
> +        *(.text)
> +    }
> +    .rodata : {
> +        *(.rodata)
> +    }
> +    _etext = .;
> +
> +    . = ALIGN(8192);
> +    _data = .;
> +    .got : {
> +        *(.got)
> +    }
> +    .data : {
> +     *(.sdata)
> +        *(.data)
> +    }
> +    _edata = .;
> +    .bss : {
> +        *(.bss)
> +    }
> +    _end = .;
> +}


--
Alex Bennée



reply via email to

[Prev in Thread] Current Thread [Next in Thread]