Skip to content

Commit

Permalink
ARMv7 support.
Browse files Browse the repository at this point in the history
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3572 c046a42c-6fe2-441c-8c8c-71466251a162
  • Loading branch information
pbrook committed Nov 11, 2007
1 parent ee4e83e commit 9ee6e8b
Show file tree
Hide file tree
Showing 35 changed files with 12,392 additions and 1,246 deletions.
1 change: 1 addition & 0 deletions Changelog
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- MIPS mipssim pequdo machine (Thiemo Seufer)
- Strace for Linux userland emulation (Stuart Anderson, Thayne Harbaugh)
- OMAP310 MPU emulation plus Palm T|E machine (Andrzej Zaborowski)
- ARM v6, v7, NEON SIMD and SMP emulation (Paul Brook/CodeSourcery)

version 0.9.0:

Expand Down
4 changes: 3 additions & 1 deletion Makefile.target
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,9 @@ ifeq ($(TARGET_BASE_ARCH), arm)
VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
VL_OBJS+= arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
VL_OBJS+= versatile_pci.o sd.o ptimer.o
VL_OBJS+= arm_gic.o realview.o arm_sysctl.o
VL_OBJS+= realview_gic.o realview.o arm_sysctl.o mpcore.o
VL_OBJS+= armv7m.o armv7m_nvic.o stellaris.o i2c.o ssd0303.o pl022.o
VL_OBJS+= ssd0323.o pl061.o
VL_OBJS+= arm-semi.o
VL_OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
VL_OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o max111x.o max7310.o
Expand Down
13 changes: 12 additions & 1 deletion cpu-exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ static inline TranslationBlock *tb_find_fast(void)
flags |= (1 << 6);
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
flags |= (1 << 7);
flags |= (env->condexec_bits << 8);
cs_base = 0;
pc = env->regs[15];
#elif defined(TARGET_SPARC)
Expand Down Expand Up @@ -511,8 +512,18 @@ int cpu_exec(CPUState *env1)
env->exception_index = EXCP_FIQ;
do_interrupt(env);
}
/* ARMv7-M interrupt return works by loading a magic value
into the PC. On real hardware the load causes the
return to occur. The qemu implementation performs the
jump normally, then does the exception return when the
CPU tries to execute code at the magic address.
This will cause the magic PC value to be pushed to
the stack if an interrupt occured at the wrong time.
We avoid this by disabling interrupts when
pc contains a magic address. */
if (interrupt_request & CPU_INTERRUPT_HARD
&& !(env->uncached_cpsr & CPSR_I)) {
&& ((IS_M(env) && env->regs[15] < 0xfffffff0)
|| !(env->uncached_cpsr & CPSR_I))) {
env->exception_index = EXCP_IRQ;
do_interrupt(env);
}
Expand Down
16 changes: 16 additions & 0 deletions fpu/softfloat-native.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,11 @@ INLINE float32 float32_chs(float32 a)
return -a;
}

INLINE float32 float32_scalbn(float32 a, int n)
{
return scalbnf(a, n);
}

/*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision conversion routines.
*----------------------------------------------------------------------------*/
Expand Down Expand Up @@ -311,6 +316,11 @@ INLINE float64 float64_chs(float64 a)
return -a;
}

INLINE float64 float64_scalbn(float64 a, int n)
{
return scalbn(a, n);
}

#ifdef FLOATX80

/*----------------------------------------------------------------------------
Expand Down Expand Up @@ -391,4 +401,10 @@ INLINE floatx80 floatx80_chs(floatx80 a)
{
return -a;
}

INLINE floatx80 floatx80_scalbn(floatx80 a, int n)
{
return scalbnl(a, n);
}

#endif
75 changes: 75 additions & 0 deletions fpu/softfloat.c
Original file line number Diff line number Diff line change
Expand Up @@ -5377,3 +5377,78 @@ int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM ) \

COMPARE(32, 0xff)
COMPARE(64, 0x7ff)

/* Multiply A by 2 raised to the power N. */
float32 float32_scalbn( float32 a, int n STATUS_PARAM )
{
flag aSign;
int16 aExp;
bits32 aSig;

aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );

if ( aExp == 0xFF ) {
return a;
}
aExp += n;
return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
}

float64 float64_scalbn( float64 a, int n STATUS_PARAM )
{
flag aSign;
int16 aExp;
bits64 aSig;

aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );

if ( aExp == 0x7FF ) {
return a;
}
aExp += n;
return roundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
}

#ifdef FLOATX80
floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
{
flag aSign;
int16 aExp;
bits64 aSig;

aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );

if ( aExp == 0x7FF ) {
return a;
}
aExp += n;
return roundAndPackFloatx80( STATUS(floatx80_rounding_precision),
aSign, aExp, aSig, 0 STATUS_VAR );
}
#endif

#ifdef FLOAT128
float128 float128_scalbn( float128 a, int n STATUS_PARAM )
{
flag aSign;
int32 aExp;
bits64 aSig0, aSig1;

aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
if ( aExp == 0x7FFF ) {
return a;
}
aExp += n;
return roundAndPackFloat128( aSign, aExp, aSig0, aSig1, 0 STATUS_VAR );

}
#endif
4 changes: 4 additions & 0 deletions fpu/softfloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ int float32_compare( float32, float32 STATUS_PARAM );
int float32_compare_quiet( float32, float32 STATUS_PARAM );
int float32_is_nan( float32 );
int float32_is_signaling_nan( float32 );
float32 float32_scalbn( float32, int STATUS_PARAM );

INLINE float32 float32_abs(float32 a)
{
Expand Down Expand Up @@ -295,6 +296,7 @@ int float64_compare( float64, float64 STATUS_PARAM );
int float64_compare_quiet( float64, float64 STATUS_PARAM );
int float64_is_nan( float64 a );
int float64_is_signaling_nan( float64 );
float64 float64_scalbn( float64, int STATUS_PARAM );

INLINE float64 float64_abs(float64 a)
{
Expand Down Expand Up @@ -339,6 +341,7 @@ int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
int floatx80_is_nan( floatx80 );
int floatx80_is_signaling_nan( floatx80 );
floatx80 floatx80_scalbn( floatx80, int STATUS_PARAM );

INLINE floatx80 floatx80_abs(floatx80 a)
{
Expand Down Expand Up @@ -387,6 +390,7 @@ int float128_le_quiet( float128, float128 STATUS_PARAM );
int float128_lt_quiet( float128, float128 STATUS_PARAM );
int float128_is_nan( float128 );
int float128_is_signaling_nan( float128 );
float128 float128_scalbn( float128, int STATUS_PARAM );

INLINE float128 float128_abs(float128 a)
{
Expand Down
22 changes: 21 additions & 1 deletion hw/arm_boot.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* ARM kernel loader.
*
* Copyright (c) 2006 CodeSourcery.
* Copyright (c) 2006-2007 CodeSourcery.
* Written by Paul Brook
*
* This code is licenced under the GPL.
Expand All @@ -24,6 +24,22 @@ static uint32_t bootloader[] = {
0 /* Kernel entry point. Set by integratorcp_init. */
};

/* Entry point for secondary CPUs. Enable interrupt controller and
Issue WFI until start address is written to system controller. */
static uint32_t smpboot[] = {
0xe3a00201, /* mov r0, #0x10000000 */
0xe3800601, /* orr r0, r0, #0x001000000 */
0xe3a01001, /* mov r1, #1 */
0xe5801100, /* str r1, [r0, #0x100] */
0xe3a00201, /* mov r0, #0x10000000 */
0xe3800030, /* orr r0, #0x30 */
0xe320f003, /* wfi */
0xe5901000, /* ldr r1, [r0] */
0xe3110003, /* tst r1, #3 */
0x1afffffb, /* bne <wfi> */
0xe12fff11 /* bx r1 */
};

static void main_cpu_reset(void *opaque)
{
CPUState *env = opaque;
Expand All @@ -33,6 +49,8 @@ static void main_cpu_reset(void *opaque)
arm_load_kernel(env, env->ram_size, env->kernel_filename,
env->kernel_cmdline, env->initrd_filename,
env->board_id, env->loader_start);

/* TODO: Reset secondary CPUs. */
}

static void set_kernel_args(uint32_t ram_size, int initrd_size,
Expand Down Expand Up @@ -211,6 +229,8 @@ void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename,
bootloader[6] = entry;
for (n = 0; n < sizeof(bootloader) / 4; n++)
stl_raw(phys_ram_base + (n * 4), bootloader[n]);
for (n = 0; n < sizeof(smpboot) / 4; n++)
stl_raw(phys_ram_base + ram_size + (n * 4), smpboot[n]);
if (old_param)
set_kernel_args_old(ram_size, initrd_size,
kernel_cmdline, loader_start);
Expand Down
Loading

0 comments on commit 9ee6e8b

Please sign in to comment.