[PATCH] multiboot: Use DMA instead port-based transfer

2021-10-10 Thread Adam Lackorzynski
Use DMA transfers in the multiboot loader to copy
data.

This significantly lowers QEMU's startup latency by
a factor of about 40, for example, going from 30sec
to 0.8sec when loading modules of 120MB in size.
This change has been used successfully for some time.

Signed-off-by: Marcus Hähnel 
Signed-off-by: Adam Lackorzynski 
---
 pc-bios/multiboot.bin | Bin 1024 -> 1536 bytes
 pc-bios/optionrom/multiboot.S |  10 ++---
 pc-bios/optionrom/optionrom.h |  77 ++
 3 files changed, 82 insertions(+), 5 deletions(-)

diff --git a/pc-bios/multiboot.bin b/pc-bios/multiboot.bin
index 
e772713c95749bee82c20002b50ec6d05b2d4987..94dc3fc9644ad2e1c87a3ac62a60cce659ada04f
 100644
GIT binary patch
literal 1536
zcmds1&ubG=5S~qT?GnMHKP*K`h!WyKk>(FGWJ<31w0V@s$A79HaepfSLo_l~H>SdrOA+1nDF6ZVLMD9PF-abWu&V
zWk}5eM3U%@N(GUWshU(32FHlqF=gad30cdqAhx0RreGfDM9iLm?nL-e5qFj#=F^{H
z%D!tf-G^v}cmUI{E(q&GxX?QZ_SI(;?7@`$T?fP9>MiCu-Kcz7LUlg93t@lH8}q~d
zTHZC76F*HToUk+QvLE8#=oAaE0QW^Ju!BH;?CT4cr5AU=(%TEz4>-aX
z9c!-dD^A!$-m#k5bG
uF?zB=fqgWxPiZtKI!iA9P;TTF7U^DPxqSCdu~<$m7jJ8YQb_SX+SzZT$^;((

delta 357
zcmZqRY2aW9UBz^IvLUP3L@5E5X-u=3ChA$%CorWk9!^c`lw)An&B2h`DaXRlEjNJ)
z$Y5hg>z11YljdMZGd$3DU!5u;jX+Q%Q
z7(hn+`J5w**TBgMOvmffcCdr>q`glASqriihWSr)9#7i=bQ;h|?9vC*b_jx8#J~WN
w2U?l7Ljb=9E);1=RQnF^VA`-&`~O3R-HelOu^2FAFiqxR{XE%$wSw^v0Movl^Z)<=

diff --git a/pc-bios/optionrom/multiboot.S b/pc-bios/optionrom/multiboot.S
index b7efe4de34..5fe4da6486 100644
--- a/pc-bios/optionrom/multiboot.S
+++ b/pc-bios/optionrom/multiboot.S
@@ -68,10 +68,10 @@ run_multiboot:
mov %eax, %es
 
/* Read the bootinfo struct into RAM */
-   read_fw_blob(FW_CFG_INITRD)
+   read_fw_blob_dma(FW_CFG_INITRD)
 
/* FS = bootinfo_struct */
-   read_fw FW_CFG_INITRD_ADDR
+   read_fw_dma_var32   FW_CFG_INITRD_ADDR
shr $4, %eax
mov %ax, %fs
 
@@ -188,14 +188,14 @@ prot_mode:
movl%eax, %gs
 
/* Read the kernel and modules into RAM */
-   read_fw_blob(FW_CFG_KERNEL)
+   read_fw_blob_dma(FW_CFG_KERNEL)
 
/* Jump off to the kernel */
-   read_fw FW_CFG_KERNEL_ENTRY
+   read_fw_dma_var32 FW_CFG_KERNEL_ENTRY
mov %eax, %ecx
 
/* EBX contains a pointer to the bootinfo struct */
-   read_fw FW_CFG_INITRD_ADDR
+   read_fw_dma_var32   FW_CFG_INITRD_ADDR
movl%eax, %ebx
 
/* EAX has to contain the magic */
diff --git a/pc-bios/optionrom/optionrom.h b/pc-bios/optionrom/optionrom.h
index a2b612f1a7..5a88c7c5a3 100644
--- a/pc-bios/optionrom/optionrom.h
+++ b/pc-bios/optionrom/optionrom.h
@@ -37,6 +37,17 @@
 #define BIOS_CFG_IOPORT_CFG0x510
 #define BIOS_CFG_IOPORT_DATA   0x511
 
+#define FW_CFG_DMA_CTL_ERROR   0x01
+#define FW_CFG_DMA_CTL_READ0x02
+#define FW_CFG_DMA_CTL_SKIP0x04
+#define FW_CFG_DMA_CTL_SELECT  0x08
+#define FW_CFG_DMA_CTL_WRITE   0x10
+
+#define FW_CFG_DMA_SIGNATURE 0x51454d5520434647ULL /* "QEMU CFG" */
+
+#define BIOS_CFG_DMA_ADDR_HIGH  0x514
+#define BIOS_CFG_DMA_ADDR_LOW   0x518
+
 /* Break the translation block flow so -d cpu shows us values */
 #define DEBUG_HERE \
jmp 1f; \
@@ -62,6 +73,72 @@
bswap   %eax
 .endm
 
+
+/*
+ * Read data from the fw_cfg device using DMA.
+ * Clobbers:   %eax, %edx, memory[%esp-16] to memory[%esp]
+ */
+.macro read_fw_dma VAR, SIZE, ADDR
+   movl$\VAR, %eax /* Control */
+   shl $16, %eax
+   or  $FW_CFG_DMA_CTL_READ, %eax
+   or  $FW_CFG_DMA_CTL_SELECT, %eax
+   bswapl  %eax
+   movl%eax, -16(%esp)
+
+   movl\SIZE, %eax /* Length */
+   bswapl  %eax
+   mov %eax, -12(%esp)
+
+   mov \ADDR, %eax /* Address to write to */
+   bswapl  %eax
+   mov %eax, -4(%esp)
+
+   movl$0, %eax  /* We only support 32 bit target addresses */
+   mov %eax, -8(%esp)
+
+   mov %esp, %eax /* Address of the struct we generated */
+   subl$16, %eax
+   bswapl  %eax
+
+   mov $BIOS_CFG_DMA_ADDR_LOW, %dx
+   outl%eax, (%dx) /* Initiate DMA */
+
+   movl$FW_CFG_DMA_CTL_ERROR, %eax
+   not %eax
+   bswapl  %eax
+
+1:  mov-16(%esp), %edx /* Wait for completion */
+   and %eax, %edx
+   jnz 1b
+.endm
+
+/*
+ * Read a single 32 bit value from the fw_cfg device using DMA
+ * Clobbers: %edx, memory[%esp-20] to memory[%esp]
+ * Out:%eax
+ */
+.macro read_fw_dma_var32 VAR
+   mov %esp, %edx
+   subl$20, %edx
+   read_fw_dma \VAR, $4, %edx
+   mo

Re: arm: Launching EFI-enabled arm32 Linux

2021-09-08 Thread Adam Lackorzynski
Hi Andre,

On Wed Sep 08, 2021 at 00:47:10 +0100, Andre Przywara wrote:
> On Wed, 8 Sep 2021 01:25:04 +0200
> Adam Lackorzynski  wrote:
> 
> Hi Adam,
> 
> > On Mon Sep 06, 2021 at 16:34:03 +0100, Andre Przywara wrote:
> > > On Sat, 4 Sep 2021 21:26:45 +0200
> > > Adam Lackorzynski  wrote:
> > > 
> > > Hi Adam,
> > >   
> > > > while trying to launch an EFI-enabled arm32 Linux binary (zImage) I
> > > > noticed I get an undefined instruction exception on the first
> > > > instruction. Now this is a bit special because Linux uses a nop
> > > > instruction there that also is a PE file signature ('MZ') such that the
> > > > CPU runs over it and the file is still recognized as a PE binary. Linux
> > > > uses 0x13105a4d (tstne r0, #0x4d000) as the instruction (see also
> > > > arch/arm/boot/compressed/head.S and efi-header.S in Linux).
> > > > However, QEMU's instruction decoder will only recognize TST with bits
> > > > 12-15 being 0, which this instruction is not fullfilling, and thus the
> > > > undef exception. I guess other CPU implementations will allow this
> > > > encoding. So while investigating I was doing the following to make Linux
> > > > proceed. I also believe this was working in a previous version of QEMU.
> > > > 
> > > > diff --git a/target/arm/a32.decode b/target/arm/a32.decode
> > > > index fcd8cd4f7d..222553750e 100644
> > > > --- a/target/arm/a32.decode
> > > > +++ b/target/arm/a32.decode
> > > > @@ -127,7 +127,7 @@ ADD_rri   001 0100 .   
> > > >    @s_rri_rot
> > > >  ADC_rri   001 0101 .      
> > > > @s_rri_rot
> > > >  SBC_rri   001 0110 .      
> > > > @s_rri_rot
> > > >  RSC_rri   001 0111 .      
> > > > @s_rri_rot
> > > > -TST_xri   001 1000 1      
> > > > @S_xri_rot
> > > > +TST_xri   001 1000 1      
> > > > @S_xri_rot
> > > >  TEQ_xri   001 1001 1      
> > > > @S_xri_rot
> > > >  CMP_xri   001 1010 1      
> > > > @S_xri_rot
> > > >  CMN_xri   001 1011 1      
> > > > @S_xri_rot
> > > > 
> > > > 
> > > > Any thoughts on this?  
> > > 
> > > thanks for the report, I was looking at this and have a kernel patch
> > > to fix this properly as Peter suggested. And while I agree on the
> > > problem, I was struggling to reproduce this in reality: both with
> > > -kernel and when booting through U-Boot the "Z" bit is set, which lets
> > > QEMU not even bother about the rest of the encoding - the condition
> > > flags don't match, so it proceeds. If I change the __nop to use "tsteq",
> > > I see it hanging due to the missing exception handler, but not with
> > > "tstne".
> > > So can you say how you spotted this issue? This would be needed as a
> > > justification for patching the guts of the ARM Linux kernel port.  
> > 
> > Good point with the condition flags. I'm doing this with our own vmm
> > where I'm loading the binary directly as the payload (as mandated by the
> > header), and where psr is set to a defined value with all flags cleared.
> 
> Right, I was thinking something like this.
> 
> > If I set the Z bit than it also works (of course).
> > Looking a bit around in QEMU as well as u-boot I it looks like this is
> > rather by luck how flags are set.
> 
> Yes, the kernel boot protocol doesn't say anything about the condition
> flags, so any combination would be valid and we were just lucky before.
> I did also test on an Cortex-A7 and A53, both ignore bits [15:12] (so
> execute the instruction as if they were 0), which explains why it works
> on real hardware.
> 
> > Thanks for doing the Linux patch, I'll scrap mine, and also thanks to
> > Peter for the idea!
> 
> Oh, didn't want to cut you off, if you want to have the commit: be my
> guest!
> Otherwise I will send something tomorrow, with a Reported-by: to you.

No, that's fine, I'm happy this is taken care of :)

> Grüße an die Elbe!

Danke, Grüße zurück :-)


Adam



Re: arm: Launching EFI-enabled arm32 Linux

2021-09-07 Thread Adam Lackorzynski
Hi Andre,

On Mon Sep 06, 2021 at 16:34:03 +0100, Andre Przywara wrote:
> On Sat, 4 Sep 2021 21:26:45 +0200
> Adam Lackorzynski  wrote:
> 
> Hi Adam,
> 
> > while trying to launch an EFI-enabled arm32 Linux binary (zImage) I
> > noticed I get an undefined instruction exception on the first
> > instruction. Now this is a bit special because Linux uses a nop
> > instruction there that also is a PE file signature ('MZ') such that the
> > CPU runs over it and the file is still recognized as a PE binary. Linux
> > uses 0x13105a4d (tstne r0, #0x4d000) as the instruction (see also
> > arch/arm/boot/compressed/head.S and efi-header.S in Linux).
> > However, QEMU's instruction decoder will only recognize TST with bits
> > 12-15 being 0, which this instruction is not fullfilling, and thus the
> > undef exception. I guess other CPU implementations will allow this
> > encoding. So while investigating I was doing the following to make Linux
> > proceed. I also believe this was working in a previous version of QEMU.
> > 
> > diff --git a/target/arm/a32.decode b/target/arm/a32.decode
> > index fcd8cd4f7d..222553750e 100644
> > --- a/target/arm/a32.decode
> > +++ b/target/arm/a32.decode
> > @@ -127,7 +127,7 @@ ADD_rri   001 0100 .    
> >   @s_rri_rot
> >  ADC_rri   001 0101 .      @s_rri_rot
> >  SBC_rri   001 0110 .      @s_rri_rot
> >  RSC_rri   001 0111 .      @s_rri_rot
> > -TST_xri   001 1000 1      @S_xri_rot
> > +TST_xri   001 1000 1      @S_xri_rot
> >  TEQ_xri   001 1001 1      @S_xri_rot
> >  CMP_xri   001 1010 1      @S_xri_rot
> >  CMN_xri   001 1011 1      @S_xri_rot
> > 
> > 
> > Any thoughts on this?
> 
> thanks for the report, I was looking at this and have a kernel patch
> to fix this properly as Peter suggested. And while I agree on the
> problem, I was struggling to reproduce this in reality: both with
> -kernel and when booting through U-Boot the "Z" bit is set, which lets
> QEMU not even bother about the rest of the encoding - the condition
> flags don't match, so it proceeds. If I change the __nop to use "tsteq",
> I see it hanging due to the missing exception handler, but not with
> "tstne".
> So can you say how you spotted this issue? This would be needed as a
> justification for patching the guts of the ARM Linux kernel port.

Good point with the condition flags. I'm doing this with our own vmm
where I'm loading the binary directly as the payload (as mandated by the
header), and where psr is set to a defined value with all flags cleared.
If I set the Z bit than it also works (of course).
Looking a bit around in QEMU as well as u-boot I it looks like this is
rather by luck how flags are set.

Thanks for doing the Linux patch, I'll scrap mine, and also thanks to
Peter for the idea!


Adam



arm: Launching EFI-enabled arm32 Linux

2021-09-04 Thread Adam Lackorzynski
Hi,

while trying to launch an EFI-enabled arm32 Linux binary (zImage) I
noticed I get an undefined instruction exception on the first
instruction. Now this is a bit special because Linux uses a nop
instruction there that also is a PE file signature ('MZ') such that the
CPU runs over it and the file is still recognized as a PE binary. Linux
uses 0x13105a4d (tstne r0, #0x4d000) as the instruction (see also
arch/arm/boot/compressed/head.S and efi-header.S in Linux).
However, QEMU's instruction decoder will only recognize TST with bits
12-15 being 0, which this instruction is not fullfilling, and thus the
undef exception. I guess other CPU implementations will allow this
encoding. So while investigating I was doing the following to make Linux
proceed. I also believe this was working in a previous version of QEMU.

diff --git a/target/arm/a32.decode b/target/arm/a32.decode
index fcd8cd4f7d..222553750e 100644
--- a/target/arm/a32.decode
+++ b/target/arm/a32.decode
@@ -127,7 +127,7 @@ ADD_rri   001 0100 .    
  @s_rri_rot
 ADC_rri   001 0101 .      @s_rri_rot
 SBC_rri   001 0110 .      @s_rri_rot
 RSC_rri   001 0111 .      @s_rri_rot
-TST_xri   001 1000 1      @S_xri_rot
+TST_xri   001 1000 1      @S_xri_rot
 TEQ_xri   001 1001 1      @S_xri_rot
 CMP_xri   001 1010 1      @S_xri_rot
 CMN_xri   001 1011 1      @S_xri_rot


Any thoughts on this?



Adam



Re: Arm: VFP regression

2021-03-22 Thread Adam Lackorzynski
Hi,

On Sun Mar 21, 2021 at 12:56:12 +, Peter Maydell wrote:
> On Sat, 20 Mar 2021 at 22:38, Adam Lackorzynski  wrote:
> >
> > Hi,
> >
> > I'm seeing a regression in Arm's vfp handling, giving an undefined
> > instruction when reading mvfr1 in PL2/armv7 although the FPU is enabled.
> > The following makes it work again for me, however this just looks like a
> > band-aid. Thanks for taking a look.
> 
> Could you provide a test case, please (QEMU command line and
> image/etc files needed to reproduce) ?

Turns out I was missing one path in my code wrt FPU state and due to
unfortunate and unforeseen timing I was hitting this case. Apologies and
sorry for the noise.


Thanks,
Adam



Arm: VFP regression

2021-03-20 Thread Adam Lackorzynski
Hi,

I'm seeing a regression in Arm's vfp handling, giving an undefined
instruction when reading mvfr1 in PL2/armv7 although the FPU is enabled.
The following makes it work again for me, however this just looks like a
band-aid. Thanks for taking a look.

Adam

diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 10766f210c..37c079fab1 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -120,7 +120,7 @@ static void gen_preserve_fp_state(DisasContext *s)
  */
 static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
 {
-if (s->fp_excp_el) {
+if (s->fp_excp_el && !ignore_vfp_enabled) {
 /* M-profile handled this earlier, in disas_m_nocp() */
 assert (!arm_dc_feature(s, ARM_FEATURE_M));
 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,





Re: [PATCH] target/arm: Init GIC CPU IF regs for A15/A7

2020-06-01 Thread Adam Lackorzynski


On Mon Jun 01, 2020 at 13:36:13 +0100, Peter Maydell wrote:
> On Sat, 30 May 2020 at 00:07, Adam Lackorzynski  wrote:
> >
> > Initialize the CPU interface registers also
> > for Cortex-A15 and Cortex-A7 CPU models, in
> > the same way as done for 64bit CPU models.
> > This fixes usage of GICv3 in virtualization
> > contexts in 32bit configurations.
> >
> > Signed-off-by: Adam Lackorzynski 
> 
> Hi; I'm confused by this patch. The Cortex-A15 and Cortex-A7
> do not have or support the GICv3, so why would we need
> to set GICv3-specific settings for them?
> 
> We're probably missing a sanity-check somewhere
> to forbid user attempts to use non-GICv3 CPUs with
> the GICv3.

Indeed that's another option. Besides that A15+GICv3 currently just
works with this.
So I guess the alternative is to switch to 32bit from EL3 when using an A57?


Thanks,
Adam



[PATCH] target/arm: Init GIC CPU IF regs for A15/A7

2020-05-29 Thread Adam Lackorzynski
Initialize the CPU interface registers also
for Cortex-A15 and Cortex-A7 CPU models, in
the same way as done for 64bit CPU models.
This fixes usage of GICv3 in virtualization
contexts in 32bit configurations.

Signed-off-by: Adam Lackorzynski 
---
 target/arm/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 32bec156f2..f525d45f6a 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1972,6 +1972,9 @@ static void cortex_a7_initfn(Object *obj)
 cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
 cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
 cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
+cpu->gic_num_lrs = 4;
+cpu->gic_vpribits = 5;
+cpu->gic_vprebits = 5;
 define_arm_cp_regs(cpu, cortexa15_cp_reginfo); /* Same as A15 */
 }
 
@@ -2014,6 +2017,9 @@ static void cortex_a15_initfn(Object *obj)
 cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
 cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
 cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
+cpu->gic_num_lrs = 4;
+cpu->gic_vpribits = 5;
+cpu->gic_vprebits = 5;
 define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
 }
 
-- 
2.27.0.rc2



[Qemu-devel] [PATCH] arm: Fix return code of arm_load_elf

2018-07-30 Thread Adam Lackorzynski
Use an int64_t as a return type to restore
the negative check for arm_load_as.

Signed-off-by: Adam Lackorzynski 
---
 hw/arm/boot.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index e09201cc97..ca9467e583 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -818,9 +818,9 @@ static int do_arm_linux_init(Object *obj, void *opaque)
 return 0;
 }
 
-static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
- uint64_t *lowaddr, uint64_t *highaddr,
- int elf_machine, AddressSpace *as)
+static int64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
+uint64_t *lowaddr, uint64_t *highaddr,
+int elf_machine, AddressSpace *as)
 {
 bool elf_is64;
 union {
@@ -829,7 +829,7 @@ static uint64_t arm_load_elf(struct arm_boot_info *info, 
uint64_t *pentry,
 } elf_header;
 int data_swab = 0;
 bool big_endian;
-uint64_t ret = -1;
+int64_t ret = -1;
 Error *err = NULL;
 
 
-- 
2.18.0



Re: [Qemu-devel] [PATCH] Remove restriction that prevents bootimg elf64 images

2017-06-19 Thread Adam Lackorzynski
Hi,

On Tue Jun 13, 2017 at 17:05:41 -0700, Anatol Pomozov wrote:
> Do these arguments sound reasonable to apply the patch?

I'm not really convinced.

> On Thu, Jun 8, 2017 at 2:07 PM, Anatol Pomozov  
> wrote:
> > +reply-all
> >
> > On Thu, Jun 8, 2017 at 1:41 PM, Adam Lackorzynski
> >  wrote:
> >>
> >> On Tue Jun 06, 2017 at 21:41:48 -0700, Anatol Pomozov wrote:
> >>> It is possible to create a 64 bit elf image that has valid multiboot 
> >>> header.
> >>> qemu should be able to boot such images.
> >>
> >> But this 64bit image actually starts with 32bit code, right?
> >
> > Correct. The very first part of the startup code has to be 32bit.
> > After it sets "long mode" it can use 64bit instructions. To make sure
> > that the preamble has only 32bit instructions one have to use asm
> > directive such as ".code32".
> >
> > Here is an example from LitleKernel sturtup code:
> >
> > https://github.com/littlekernel/lk/blob/master/arch/x86/64/start.S#L50
> >
> > .code32 tells assembler to treat following text as 32 bit code. And
> > later when it jumps into "long mode"
> >
> > https://github.com/littlekernel/lk/blob/master/arch/x86/64/start.S#L214
> > one can use 64bit code.
> >
> >> So it's a 32bit program and the check verifies that this is the case.
> >
> > While preamble have to contain 32 only instructions the rest of the
> > image can perfectly contain 64bit code. Right now 64bit binary cannot
> > be run with "qemu-system-x86_64 -kernel". But the same binary runs
> > fine if packed with GRUB as iso.
> >
> > I tried to hack around this restriction by adding
> > "OUTPUT_FORMAT(elf32-i386)" to the linker file and compiling project
> > with 64bit support. But GNU ld program crashed at Ubuntu 14.04. It
> > means not that many people use this code path. GNU ld compiled from
> > HEAD does not have this problem but now GDB is confused by the fact
> > that ELF contains 64bit code while header reports i386.

That's unfortunate.

> > Practically there is no reason for this check as it prevents running
> > 64bit binaries with "qemu-system-x86_64 -kernel".

One reason for the check is that it prevents that one loads a 64bit ELF
binary that then fails strangely because it does not have the magic
32bit code to set up things. At least there needs to be an override
(could also be in the ELF info).

Doing a proper 32bit wrapper is also possible, although that would need
a little ELF loader, or a custom loader, probably. We've done it this
way but that also requires some more lines.

If allowing 64bit binaries it should also be checked that all relevant
values fit into 32bit.



Adam



Re: [Qemu-devel] [PATCH] Remove restriction that prevents bootimg elf64 images

2017-06-08 Thread Adam Lackorzynski

On Tue Jun 06, 2017 at 21:41:48 -0700, Anatol Pomozov wrote:
> It is possible to create a 64 bit elf image that has valid multiboot header.
> qemu should be able to boot such images.

But this 64bit image actually starts with 32bit code, right?
So it's a 32bit program and the check verifies that this is the case.



Adam



Re: [Qemu-devel] [PATCH] Add bootloader name to multiboot implementation

2014-11-13 Thread Adam Lackorzynski
On Wed Oct 29, 2014 at 23:52:03 -0600, Drew DeVault wrote:
> The name is set to "qemu".
> 
> Signed-off-by: Drew DeVault 
> ---
> For the future, it may be useful to add a command line flag for setting this 
> to
> some user-specified value. I also considered naming it "qemu-system-i386" or
> "qemu-system-x86_64" (as appropriate), but couldn't find an easy way to get
> those strings and decided it didn't matter.
> 
>  hw/i386/multiboot.c | 32 +++-
>  1 file changed, 27 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
> index 985ca1e..f86d351 100644
> --- a/hw/i386/multiboot.c
> +++ b/hw/i386/multiboot.c
> @@ -54,6 +54,7 @@ enum {
>  MBI_MODS_COUNT  = 20,
>  MBI_MODS_ADDR   = 24,
>  MBI_MMAP_ADDR   = 48,
> +MBI_BOOTLOADER  = 64,
>  
>  MBI_SIZE= 88,
>  
> @@ -74,6 +75,7 @@ enum {
>  MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
>  MULTIBOOT_FLAGS_MODULES = 1 << 3,
>  MULTIBOOT_FLAGS_MMAP= 1 << 6,
> +MULTIBOOT_FLAGS_BOOTLOADER  = 1 << 9,
>  };
>  
>  typedef struct {
> @@ -87,6 +89,8 @@ typedef struct {
>  hwaddr offset_mbinfo;
>  /* offset in buffer for cmdlines in bytes */
>  hwaddr offset_cmdlines;
> +/* offset in buffer for bootloader name in bytes */
> +hwaddr offset_bootloader;
>  /* offset of modules in bytes */
>  hwaddr offset_mods;
>  /* available slots for mb modules infos */
> @@ -95,6 +99,8 @@ typedef struct {
>  int mb_mods_count;
>  } MultibootState;
>  
> +const char *bootloader_name = "qemu";
> +
>  static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
>  {
>  hwaddr p = s->offset_cmdlines;
> @@ -105,6 +111,16 @@ static uint32_t mb_add_cmdline(MultibootState *s, const 
> char *cmdline)
>  return s->mb_buf_phys + p;
>  }
>  
> +static uint32_t mb_add_bootloader(MultibootState *s, const char *bootloader)
> +{
> +hwaddr p = s->offset_bootloader;
> +char *b = (char *)s->mb_buf + p;
> +
> +memcpy(b, bootloader, strlen(bootloader) + 1);
> +s->offset_bootloader += strlen(b) + 1;
> +return s->mb_buf_phys + p;
> +}
> +
>  static void mb_add_mod(MultibootState *s,
> hwaddr start, hwaddr end,
> hwaddr cmdline_phys)
> @@ -241,9 +257,10 @@ int load_multiboot(FWCfgState *fw_cfg,
>  mbs.mb_buf_size = TARGET_PAGE_ALIGN(mb_kernel_size);
>  mbs.offset_mbinfo = mbs.mb_buf_size;
>  
> -/* Calculate space for cmdlines and mb_mods */
> +/* Calculate space for cmdlines, bootloader name, and mb_mods */
>  mbs.mb_buf_size += strlen(kernel_filename) + 1;
>  mbs.mb_buf_size += strlen(kernel_cmdline) + 1;
> +mbs.mb_buf_size += strlen(bootloader_name) + 1;
>  if (initrd_filename) {
>  const char *r = initrd_filename;
>  mbs.mb_buf_size += strlen(r) + 1;
> @@ -257,9 +274,11 @@ int load_multiboot(FWCfgState *fw_cfg,
>  
>  mbs.mb_buf_size = TARGET_PAGE_ALIGN(mbs.mb_buf_size);
>  
> -/* enlarge mb_buf to hold cmdlines and mb-info structs */
> -mbs.mb_buf  = g_realloc(mbs.mb_buf, mbs.mb_buf_size);
> -mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * 
> MB_MOD_SIZE;
> +/* enlarge mb_buf to hold cmdlines, bootloader, mb-info structs */
> +mbs.mb_buf= g_realloc(mbs.mb_buf, mbs.mb_buf_size);
> +mbs.offset_cmdlines   = mbs.offset_mbinfo + mbs.mb_mods_avail * 
> MB_MOD_SIZE;
> +mbs.offset_bootloader = mbs.offset_cmdlines + strlen(kernel_filename) + 
> 1 
> ++ strlen(kernel_cmdline) + 1;
>  
>  if (initrd_filename) {
>  char *next_initrd, not_last;
> @@ -306,6 +325,8 @@ int load_multiboot(FWCfgState *fw_cfg,
>   kernel_filename, kernel_cmdline);
>  stl_p(bootinfo + MBI_CMDLINE, mb_add_cmdline(&mbs, kcmdline));
>  
> +stl_p(bootinfo + MBI_BOOTLOADER, mb_add_bootloader(&mbs, 
> bootloader_name));
> +
>  stl_p(bootinfo + MBI_MODS_ADDR,  mbs.mb_buf_phys + mbs.offset_mbinfo);
>  stl_p(bootinfo + MBI_MODS_COUNT, mbs.mb_mods_count); /* mods_count */
>  
> @@ -314,7 +335,8 @@ int load_multiboot(FWCfgState *fw_cfg,
>  | MULTIBOOT_FLAGS_BOOT_DEVICE
>  | MULTIBOOT_FLAGS_CMDLINE
>  | MULTIBOOT_FLAGS_MODULES
> -| MULTIBOOT_FLAGS_MMAP);
> +| MULTIBOOT_FLAGS_MMAP
> +| MULTIBOOT_FLAGS_BOOTLOADER);
>  stl_p(bootinfo + MBI_BOOT_DEVICE, 0x8000); /* XXX: use the -boot 
> switch? */
>  stl_p(bootinfo + MBI_MMAP_ADDR,   ADDR_E820_MAP);
>  

Looks good to me and no negative impact on a simple test.

Reviewed-by: Adam Lackorzynski 



Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



Re: [Qemu-devel] [PATCH v4 0/4] Improve handling of GICD_ICFGR

2014-08-21 Thread Adam Lackorzynski
On Mon Aug 18, 2014 at 16:30:51 +0200, Adam Lackorzynski wrote:
> The following patches address the behavior of the GICD_ICFGR register
> in the ARM GIC.

Any takers or comments?


> Changes to v3:
>  - Tag patchset with proper version
> 
> Changes to v2:
>  - Replace 16 with GIC_NR_SGIS in setup
> 
> Changes to v1:
>   
>  - Setting of model mode only for old GIC revisions   
> 
>  - Less invasive change for PPI settings  
>     
> 
> Adam Lackorzynski (4):
>   arm_gic: Fix read of GICD_ICFGR
>   arm_gic: GICD_ICFGR: Write model only for pre v1 GICs
>   arm_gic: Do not force PPIs to edge-triggered mode
>   arm_gic: Use GIC_NR_SGIS constant
> 
>  hw/intc/arm_gic.c| 14 --
>  hw/intc/arm_gic_common.c |  2 +-
>  2 files changed, 9 insertions(+), 7 deletions(-)


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH v4 0/4] Improve handling of GICD_ICFGR

2014-08-18 Thread Adam Lackorzynski
The following patches address the behavior of the GICD_ICFGR register
in the ARM GIC.

Changes to v3:
 - Tag patchset with proper version

Changes to v2:
 - Replace 16 with GIC_NR_SGIS in setup

Changes to v1:  

 - Setting of model mode only for old GIC revisions 
  
 - Less invasive change for PPI settings
  

Adam Lackorzynski (4):
  arm_gic: Fix read of GICD_ICFGR
  arm_gic: GICD_ICFGR: Write model only for pre v1 GICs
  arm_gic: Do not force PPIs to edge-triggered mode
  arm_gic: Use GIC_NR_SGIS constant

 hw/intc/arm_gic.c| 14 --
 hw/intc/arm_gic_common.c |  2 +-
 2 files changed, 9 insertions(+), 7 deletions(-)

-- 
2.1.0.rc1




[Qemu-devel] [PATCH v4 3/4] arm_gic: Do not force PPIs to edge-triggered mode

2014-08-18 Thread Adam Lackorzynski
Only SGIs must be WI, done by forcing them to their default
(edge-triggered).

Acked-by: Christoffer Dall 
Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index e546647..55019c9 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -558,7 +558,7 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
 irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
 if (irq >= s->num_irq)
 goto bad_reg;
-if (irq < GIC_INTERNAL)
+if (irq < GIC_NR_SGIS)
 value |= 0xaa;
 for (i = 0; i < 4; i++) {
 if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
-- 
2.1.0.rc1




[Qemu-devel] [PATCH v4 4/4] arm_gic: Use GIC_NR_SGIS constant

2014-08-18 Thread Adam Lackorzynski
Use constant rather than a plain number.

Acked-by: Christoffer Dall 
Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic_common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c
index 6d884ec..18b01ba 100644
--- a/hw/intc/arm_gic_common.c
+++ b/hw/intc/arm_gic_common.c
@@ -128,7 +128,7 @@ static void arm_gic_common_reset(DeviceState *dev)
 s->running_priority[i] = 0x100;
 s->cpu_enabled[i] = false;
 }
-for (i = 0; i < 16; i++) {
+for (i = 0; i < GIC_NR_SGIS; i++) {
 GIC_SET_ENABLED(i, ALL_CPU_MASK);
 GIC_SET_EDGE_TRIGGER(i);
 }
-- 
2.1.0.rc1




[Qemu-devel] [PATCH v4 1/4] arm_gic: Fix read of GICD_ICFGR

2014-08-18 Thread Adam Lackorzynski
The GICD_ICFGR register covers 4 interrupts per byte.

Acked-by: Christoffer Dall 
Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 1532ef9..d2b1aaf 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -372,7 +372,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset)
 }
 } else if (offset < 0xf00) {
 /* Interrupt Configuration.  */
-irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
+irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
 if (irq >= s->num_irq)
 goto bad_reg;
 res = 0;
-- 
2.1.0.rc1




[Qemu-devel] [PATCH v4 2/4] arm_gic: GICD_ICFGR: Write model only for pre v1 GICs

2014-08-18 Thread Adam Lackorzynski
Setting the model is only available in pre-v1 GIC models.

Acked-by: Christoffer Dall 
Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index d2b1aaf..e546647 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -561,10 +561,12 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
 if (irq < GIC_INTERNAL)
 value |= 0xaa;
 for (i = 0; i < 4; i++) {
-if (value & (1 << (i * 2))) {
-GIC_SET_MODEL(irq + i);
-} else {
-GIC_CLEAR_MODEL(irq + i);
+if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
+if (value & (1 << (i * 2))) {
+GIC_SET_MODEL(irq + i);
+} else {
+GIC_CLEAR_MODEL(irq + i);
+}
 }
 if (value & (2 << (i * 2))) {
 GIC_SET_EDGE_TRIGGER(irq + i);
-- 
2.1.0.rc1




[Qemu-devel] [PATCH 0/4] arm_gic: Improve handling of GICD_ICFGR

2014-08-18 Thread Adam Lackorzynski
The following patches address the behavior of the GICD_ICFGR register
in the ARM GIC.

Changes to second version:
 - Replace 16 with GIC_NR_SGIS in setup

Changes to first version:   
   
 - Setting of model mode only for old GIC revisions 
  
 - Less invasive change for PPI settings
  

Adam Lackorzynski (4):
  arm_gic: Fix read of GICD_ICFGR
  arm_gic: GICD_ICFGR: Write model only for pre v1 GICs
  arm_gic: Do not force PPIs to edge-triggered mode
  arm_gic: Use GIC_NR_SGIS constant

 hw/intc/arm_gic.c| 14 --
 hw/intc/arm_gic_common.c |  2 +-
 2 files changed, 9 insertions(+), 7 deletions(-)

-- 
2.1.0.rc1




[Qemu-devel] [PATCH 4/4] arm_gic: Use GIC_NR_SGIS constant

2014-08-18 Thread Adam Lackorzynski
Use constant rather than a plain number.

Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic_common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c
index 6d884ec..18b01ba 100644
--- a/hw/intc/arm_gic_common.c
+++ b/hw/intc/arm_gic_common.c
@@ -128,7 +128,7 @@ static void arm_gic_common_reset(DeviceState *dev)
 s->running_priority[i] = 0x100;
 s->cpu_enabled[i] = false;
 }
-for (i = 0; i < 16; i++) {
+for (i = 0; i < GIC_NR_SGIS; i++) {
 GIC_SET_ENABLED(i, ALL_CPU_MASK);
 GIC_SET_EDGE_TRIGGER(i);
 }
-- 
2.1.0.rc1




[Qemu-devel] [PATCH 2/4] arm_gic: GICD_ICFGR: Write model only for pre v1 GICs

2014-08-18 Thread Adam Lackorzynski
Setting the model is only available in pre-v1 GIC models.

Acked-by: Christoffer Dall 
Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index d2b1aaf..e546647 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -561,10 +561,12 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
 if (irq < GIC_INTERNAL)
 value |= 0xaa;
 for (i = 0; i < 4; i++) {
-if (value & (1 << (i * 2))) {
-GIC_SET_MODEL(irq + i);
-} else {
-GIC_CLEAR_MODEL(irq + i);
+if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
+if (value & (1 << (i * 2))) {
+GIC_SET_MODEL(irq + i);
+} else {
+GIC_CLEAR_MODEL(irq + i);
+}
 }
 if (value & (2 << (i * 2))) {
 GIC_SET_EDGE_TRIGGER(irq + i);
-- 
2.1.0.rc1




[Qemu-devel] [PATCH 3/4] arm_gic: Do not force PPIs to edge-triggered mode

2014-08-18 Thread Adam Lackorzynski
Only SGIs must be WI, done by forcing them to their default
(edge-triggered).

Acked-by: Christoffer Dall 
Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index e546647..55019c9 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -558,7 +558,7 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
 irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
 if (irq >= s->num_irq)
 goto bad_reg;
-if (irq < GIC_INTERNAL)
+if (irq < GIC_NR_SGIS)
 value |= 0xaa;
 for (i = 0; i < 4; i++) {
 if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
-- 
2.1.0.rc1




[Qemu-devel] [PATCH 1/4] arm_gic: Fix read of GICD_ICFGR

2014-08-18 Thread Adam Lackorzynski
The GICD_ICFGR register covers 4 interrupts per byte.

Acked-by: Christoffer Dall 
Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 1532ef9..d2b1aaf 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -372,7 +372,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset)
 }
 } else if (offset < 0xf00) {
 /* Interrupt Configuration.  */
-irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
+irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
 if (irq >= s->num_irq)
 goto bad_reg;
 res = 0;
-- 
2.1.0.rc1




Re: [Qemu-devel] [PATCH 3/3] arm_gic: Do not force PPIs to edge-triggered mode

2014-08-18 Thread Adam Lackorzynski
On Mon Aug 18, 2014 at 14:48:15 +0200, Christoffer Dall wrote:
> On Sat, Aug 16, 2014 at 09:48:21PM +0200, Adam Lackorzynski wrote:
> > Only SGIs must be WI, done by forcing them to their default
> > (edge-triggered).
> > 
> > Signed-off-by: Adam Lackorzynski 
> > ---
> >  hw/intc/arm_gic.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
> > index e546647..55019c9 100644
> > --- a/hw/intc/arm_gic.c
> > +++ b/hw/intc/arm_gic.c
> > @@ -558,7 +558,7 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
> >  irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
> >  if (irq >= s->num_irq)
> >  goto bad_reg;
> > -if (irq < GIC_INTERNAL)
> > +if (irq < GIC_NR_SGIS)
> >  value |= 0xaa;
> >  for (i = 0; i < 4; i++) {
> >  if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
> > -- 
> > 2.1.0.rc1
> > 
> 
> where do we ensure that the SGIs are actually configured as
> edge-triggered when creating the gic?

It's setup in arm_gic_common_reset() in arm_gic_common.c.
(Looks like I should add another change to use GIC_NR_SGIS there too.)



Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



Re: [Qemu-devel] [PATCH 2/3] arm_gic: SGIs for GICD_ICFGR are WI

2014-08-16 Thread Adam Lackorzynski
On Fri Aug 15, 2014 at 14:12:17 +0200, Christoffer Dall wrote:
> On Sun, Aug 03, 2014 at 10:53:46AM +0200, Adam Lackorzynski wrote:
> > Writes to SGIs for GICD_ICFGR register must be ignored.
> > 
> > Signed-off-by: Adam Lackorzynski 
> > ---
> >  hw/intc/arm_gic.c | 11 +++
> >  1 file changed, 7 insertions(+), 4 deletions(-)
> > 
> > diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
> > index d2b1aaf..cd6e6ea 100644
> > --- a/hw/intc/arm_gic.c
> > +++ b/hw/intc/arm_gic.c
> > @@ -566,10 +566,13 @@ static void gic_dist_writeb(void *opaque, hwaddr 
> > offset,
> >  } else {
> >  GIC_CLEAR_MODEL(irq + i);
> >  }
> > -if (value & (2 << (i * 2))) {
> > -GIC_SET_EDGE_TRIGGER(irq + i);
> > -} else {
> > -GIC_CLEAR_EDGE_TRIGGER(irq + i);
> > +/* SGIs are WI */
> > +if (irq >= 16) {
> > +if (value & (2 << (i * 2))) {
> > +GIC_SET_EDGE_TRIGGER(irq + i);
> > +} else {
> > +GIC_CLEAR_EDGE_TRIGGER(irq + i);
> > +}
> >  }
> >  }
> >  } else if (offset < 0xf10) {
> 
> Actually, this looks a bit weird given that you do set the model bit,
> which should probably be treated as WI/RAZ for a GICv2 emulation, but
> you don't set the edge trigger bit for them.

I've addressed that in a separate patch now. However, I'm not sure got
the revision check right. Comments appreciated!

> I think a cleaner fix might be to to just change the existing check from
> (irq < GIC_INTERNAL) to (irq < GIT_NR_SGIS), then you also don't need
> the next patch.

Ok, new series sent out.



Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH 0/3] arm_gic: Improve handling of GICD_ICFGR

2014-08-16 Thread Adam Lackorzynski
The following patches address the behavior of the GICD_ICFGR register
in the ARM GIC. 
  

Changes to previous version:
 - Setting of model mode only for old GIC revisions
 - Less invasive change for PPI settings


Adam Lackorzynski (3):
  arm_gic: Fix read of GICD_ICFGR
  arm_gic: GICD_ICFGR: Write model only for pre v1 GICs
  arm_gic: Do not force PPIs to edge-triggered mode

 hw/intc/arm_gic.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

-- 
2.1.0.rc1




[Qemu-devel] [PATCH 3/3] arm_gic: Do not force PPIs to edge-triggered mode

2014-08-16 Thread Adam Lackorzynski
Only SGIs must be WI, done by forcing them to their default
(edge-triggered).

Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index e546647..55019c9 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -558,7 +558,7 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
 irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
 if (irq >= s->num_irq)
 goto bad_reg;
-if (irq < GIC_INTERNAL)
+if (irq < GIC_NR_SGIS)
 value |= 0xaa;
 for (i = 0; i < 4; i++) {
 if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
-- 
2.1.0.rc1




[Qemu-devel] [PATCH 2/3] arm_gic: GICD_ICFGR: Write model only for pre v1 GICs

2014-08-16 Thread Adam Lackorzynski
Setting the model is only available in pre-v1 GIC models.
---
 hw/intc/arm_gic.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index d2b1aaf..e546647 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -561,10 +561,12 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
 if (irq < GIC_INTERNAL)
 value |= 0xaa;
 for (i = 0; i < 4; i++) {
-if (value & (1 << (i * 2))) {
-GIC_SET_MODEL(irq + i);
-} else {
-GIC_CLEAR_MODEL(irq + i);
+if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
+if (value & (1 << (i * 2))) {
+GIC_SET_MODEL(irq + i);
+} else {
+GIC_CLEAR_MODEL(irq + i);
+}
 }
 if (value & (2 << (i * 2))) {
 GIC_SET_EDGE_TRIGGER(irq + i);
-- 
2.1.0.rc1




[Qemu-devel] [PATCH 1/3] arm_gic: Fix read of GICD_ICFGR

2014-08-16 Thread Adam Lackorzynski
The GICD_ICFGR register covers 4 interrupts per byte.

Acked-by: Christoffer Dall 
Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 1532ef9..d2b1aaf 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -372,7 +372,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset)
 }
 } else if (offset < 0xf00) {
 /* Interrupt Configuration.  */
-irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
+irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
 if (irq >= s->num_irq)
 goto bad_reg;
 res = 0;
-- 
2.1.0.rc1




Re: [Qemu-devel] [PATCH 2/3] arm_gic: SGIs for GICD_ICFGR are WI

2014-08-15 Thread Adam Lackorzynski
On Fri Aug 15, 2014 at 14:07:14 +0200, Christoffer Dall wrote:
> On Sun, Aug 03, 2014 at 10:53:46AM +0200, Adam Lackorzynski wrote:
> > Writes to SGIs for GICD_ICFGR register must be ignored.
> > 
> > Signed-off-by: Adam Lackorzynski 
> > ---
> >  hw/intc/arm_gic.c | 11 +++
> >  1 file changed, 7 insertions(+), 4 deletions(-)
> > 
> > diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
> > index d2b1aaf..cd6e6ea 100644
> > --- a/hw/intc/arm_gic.c
> > +++ b/hw/intc/arm_gic.c
> > @@ -566,10 +566,13 @@ static void gic_dist_writeb(void *opaque, hwaddr 
> > offset,
> >  } else {
> >  GIC_CLEAR_MODEL(irq + i);
> >  }
> > -if (value & (2 << (i * 2))) {
> > -GIC_SET_EDGE_TRIGGER(irq + i);
> > -} else {
> > -GIC_CLEAR_EDGE_TRIGGER(irq + i);
> > +/* SGIs are WI */
> 
> They're actually WI/RAO, so we should set them to edge-triggered
> somewhere or always return 1 for reads of these values as well as part
> of this fix.

SGIs are initialized to edge triggered in arm_gic_common_reset(), i.e.
this is already the case.
 
> > +if (irq >= 16) {
> > +if (value & (2 << (i * 2))) {
> > +GIC_SET_EDGE_TRIGGER(irq + i);
> > +} else {
> > +GIC_CLEAR_EDGE_TRIGGER(irq + i);
> > +}
> >  }
> >  }
> >  } else if (offset < 0xf10) {
> > -- 
> > 2.0.1
> > 
> > 

Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



Re: [Qemu-devel] [PATCH 0/3] arm_gic: Improve handling of GICD_ICFGR

2014-08-11 Thread Adam Lackorzynski
Hi,

On Sun Aug 03, 2014 at 21:36:21 +0200, Christoffer Dall wrote:
> On 3 August 2014 15:21, Peter Maydell  wrote:
> > On 3 August 2014 09:53, Adam Lackorzynski  wrote:
> >> Hi,
> >>
> >> the following three patches address the behavior of the GICD_ICFGR register
> >> in the ARM GIC.
> >>
> >> Adam Lackorzynski (3):
> >>   arm_gic: Fix read of GICD_ICFGR
> >>   arm_gic: SGIs for GICD_ICFGR are WI
> >>   arm_gic: GICD_ICFGR: Do not force edge-triggered PPIs
> >>
> >>  hw/intc/arm_gic.c | 15 ---
> >>  1 file changed, 8 insertions(+), 7 deletions(-)
> >
> > Christoffer, did you want to review these? (I'll have a look through
> > them too shortly.)
> >
> Yeah, I'll have a look some time this week if that's timely enough?

Any comment appreciated.



Thanks,
Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH 0/3] arm_gic: Improve handling of GICD_ICFGR

2014-08-03 Thread Adam Lackorzynski
Hi,

the following three patches address the behavior of the GICD_ICFGR register
in the ARM GIC.

Adam Lackorzynski (3):
  arm_gic: Fix read of GICD_ICFGR
  arm_gic: SGIs for GICD_ICFGR are WI
  arm_gic: GICD_ICFGR: Do not force edge-triggered PPIs

 hw/intc/arm_gic.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

-- 
2.0.1




[Qemu-devel] [PATCH 3/3] arm_gic: GICD_ICFGR: Do not force edge-triggered PPIs

2014-08-03 Thread Adam Lackorzynski
Using GICD_ICFGR for PPIs forces PPIs to edge-triggered mode, although they
have been initialised to level-triggered. This affects all interrupts
covered by the write access. Change the handling of PPIs to not force a
specific mode. It is implementation defined whether setting the mode of PPIs
is supported.

Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index cd6e6ea..066a7f2 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -558,8 +558,6 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
 irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
 if (irq >= s->num_irq)
 goto bad_reg;
-if (irq < GIC_INTERNAL)
-value |= 0xaa;
 for (i = 0; i < 4; i++) {
 if (value & (1 << (i * 2))) {
 GIC_SET_MODEL(irq + i);
-- 
2.0.1




[Qemu-devel] [PATCH 2/3] arm_gic: SGIs for GICD_ICFGR are WI

2014-08-03 Thread Adam Lackorzynski
Writes to SGIs for GICD_ICFGR register must be ignored.

Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index d2b1aaf..cd6e6ea 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -566,10 +566,13 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
 } else {
 GIC_CLEAR_MODEL(irq + i);
 }
-if (value & (2 << (i * 2))) {
-GIC_SET_EDGE_TRIGGER(irq + i);
-} else {
-GIC_CLEAR_EDGE_TRIGGER(irq + i);
+/* SGIs are WI */
+if (irq >= 16) {
+if (value & (2 << (i * 2))) {
+GIC_SET_EDGE_TRIGGER(irq + i);
+} else {
+GIC_CLEAR_EDGE_TRIGGER(irq + i);
+}
 }
 }
 } else if (offset < 0xf10) {
-- 
2.0.1




[Qemu-devel] [PATCH 1/3] arm_gic: Fix read of GICD_ICFGR

2014-08-03 Thread Adam Lackorzynski
The GICD_ICFGR register covers 4 interrupts per byte.

Signed-off-by: Adam Lackorzynski 
---
 hw/intc/arm_gic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 1532ef9..d2b1aaf 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -372,7 +372,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset)
 }
 } else if (offset < 0xf00) {
 /* Interrupt Configuration.  */
-irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
+irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
 if (irq >= s->num_irq)
 goto bad_reg;
 res = 0;
-- 
2.0.1




Re: [Qemu-devel] [PATCH] hw/pc.c: Fix converting of ioport_register* to MemoryRegion

2013-01-09 Thread Adam Lackorzynski
On Wed Jan 09, 2013 at 18:10:22 +, Julien Grall wrote:
> The commit 258711 introduced MemoryRegion to replace ioport_region*
> for ioport 80h and F0h.
> A MemoryRegion needs to have both read and write callback otherwise a segfault
> will occur when an access is made.
> 
> The previous behaviour of this both ioport is to return 0x.
> So keep this behaviour.

Thanks, confirmed.

> Reported-by: Adam Lackorzynski 
> Signed-off-by: Julien Grall 

Tested-by: Adam Lackorzynski 

> ---
>  hw/pc.c |   12 
>  1 file changed, 12 insertions(+)
> 
> diff --git a/hw/pc.c b/hw/pc.c
> index df0c48e..90b1bf7 100644
> --- a/hw/pc.c
> +++ b/hw/pc.c
> @@ -103,6 +103,11 @@ static void ioport80_write(void *opaque, hwaddr addr, 
> uint64_t data,
>  {
>  }
>  
> +static uint64_t ioport80_read(void *opaque, hwaddr addr, unsigned size)
> +{
> +return 0x;
> +}
> +
>  /* MSDOS compatibility mode FPU exception support */
>  static qemu_irq ferr_irq;
>  
> @@ -123,6 +128,11 @@ static void ioportF0_write(void *opaque, hwaddr addr, 
> uint64_t data,
>  qemu_irq_lower(ferr_irq);
>  }
>  
> +static uint64_t ioportF0_read(void *opaque, hwaddr addr, unsigned size)
> +{
> +return 0x;
> +}
> +
>  /* TSC handling */
>  uint64_t cpu_get_tsc(CPUX86State *env)
>  {
> @@ -960,6 +970,7 @@ static void cpu_request_exit(void *opaque, int irq, int 
> level)
>  
>  static const MemoryRegionOps ioport80_io_ops = {
>  .write = ioport80_write,
> +.read = ioport80_read,
>  .endianness = DEVICE_NATIVE_ENDIAN,
>  .impl = {
>  .min_access_size = 1,
> @@ -969,6 +980,7 @@ static const MemoryRegionOps ioport80_io_ops = {
>  
>  static const MemoryRegionOps ioportF0_io_ops = {
>  .write = ioportF0_write,
> +.read = ioportF0_read,
>  .endianness = DEVICE_NATIVE_ENDIAN,
>  .impl = {
>  .min_access_size = 1,
> -- 
> Julien Grall
> 

Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] Qemu x86 segfault

2013-01-04 Thread Adam Lackorzynski
Hi,

I'm seeing the following segfault of qemu-system-i386 and
qemu-system-x86_64 with master. git bisect points to
258711c6448c44b60b0fecef1d3b09c71e23e304.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xea930b70 (LWP 14297)]
0x in ?? ()
(gdb) bt
#0  0x in ?? ()
#1  0x567a1b48 in memory_region_read_accessor (opaque=opaque@entry=0x5704ab58, 
addr=0, value=value@entry=0xea92fe10, size=size@entry=1, shift=0, mask=255)
at qemu/memory.c:316
#2  0x567a1536 in access_with_adjusted_size (addr=, 
value=value@entry=0xea92fe10, size=size@entry=1, 
access_size_min=, access_size_max=, 
access=access@entry=0x567a1ac0 , 
opaque=opaque@entry=0x5704ab58) at qemu/memory.c:364
#3  0x567a288b in memory_region_iorange_read (iorange=0x57098fd0, offset=0, 
width=1, data=0xea92fe10) at qemu/memory.c:409
#4  0x5679bc4f in ioport_readb_thunk (opaque=0x57098fd0, addr=128)
at qemu/ioport.c:186
#5  0x5679c8a5 in ioport_read (address=128, index=0)
at qemu/ioport.c:70
#6  cpu_inb (addr=addr@entry=128) at qemu/ioport.c:309
#7  0x567e0637 in helper_inb (port=128)
at qemu/target-i386/misc_helper.c:77
#8  0xeee28e84 in code_gen_buffer ()
#9  0x5673e528 in cpu_x86_exec (env=env@entry=0x570077c8)
at qemu/cpu-exec.c:599
#10 0x5674043b in tcg_cpu_exec (env=0x570077c8)
at qemu/cpus.c:1115
#11 tcg_exec_all () at qemu/cpus.c:1148
#12 qemu_tcg_cpu_thread_fn (arg=0x57007788)
at qemu/cpus.c:841
#13 0xf79d0c39 in start_thread (arg=0xea930b70) at pthread_create.c:304
#14 0xf793d78e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130
(gdb) 

With ioport logging enabled, the last few lines of qemu.log are:
inb : 03fd 60
outb: 03f9 00
inb : 03f9 00
outb: 03f9 00
inb : 03fd 60
outb: 03f8 34
inb : 03fd 60
outb: 03f9 00
inb : 03f9 00
outb: 03f9 00
inb : 03fd 60
outb: 03f8 0d
inb : 03fd 60
outb: 03f9 00
inb : 03f9 00
outb: 03f9 00
inb : 03fd 60
outb: 03f8 0a
inb : 03fd 60
outb: 03f9 00
inb : 03f9 00
outb: 03f9 00

In memory_region_read_accessor(), the function pointer mr->ops->read is
nil. Please let me know if any more info is required.


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] qemu-system-arm segfault

2012-08-28 Thread Adam Lackorzynski
Hi,

I'm getting a segfault for qemu-system-arm (git).
Git bisect points to 33e95c6328a3149a52615176617997c4f8f7088b.
Host is x86-32, I'm not getting it in a 64bit environment.
However, valgrind is showing a similar output for arm_gic_class_init and
arm_gic_init.

$ arm-softmmu/qemu-system-arm -M realview-eb
*** glibc detected *** arm-softmmu/qemu-system-arm: malloc(): memory 
corruption: 0xf7f15b38 ***
=== Backtrace: =
/lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x6e3b1)[0xf6da43b1]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x71194)[0xf6da7194]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(__libc_malloc+0x5c)[0xf6da8d9c]
arm-softmmu/qemu-system-arm(+0x15aae7)[0xf758dae7]
...

$ gdb --args arm-softmmu/qemu-system-arm -M realview-eb
(gdb) r
Starting program: /tmp/qemu/qemu/arm-softmmu/qemu-system-arm -M realview-eb
[Thread debugging using libthread_db enabled]
Using host libthread_db library 
"/lib/i386-linux-gnu/i686/cmov/libthread_db.so.1".
[New Thread 0xf3ccab70 (LWP 11267)]

Program received signal SIGSEGV, Segmentation fault.
_int_malloc (av=, bytes=) at malloc.c:4674
4674malloc.c: No such file or directory.
(gdb) bt
#0  _int_malloc (av=, bytes=) at malloc.c:4674
#1  0xf7973d9c in *__GI___libc_malloc (bytes=32) at malloc.c:3660
#2  0x566afae7 in malloc_and_trace (n_bytes=32) at /tmp/qemu/qemu/vl.c:2322
#3  0xf7edd45c in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0
#4  0xf7edd78b in g_malloc0 () from /lib/i386-linux-gnu/libglib-2.0.so.0
#5  0x566f29c6 in object_property_add (obj=obj@entry=0x57042a18, 
name=name@entry=0x56881b00 "type", 
type=type@entry=0x568a1c87 "string", get=get@entry=0x566f1620 
, set=set@entry=0, 
release=release@entry=0x566f15e0 , opaque=0x570413a0, 
errp=0x0) at qom/object.c:623
#6  0x566f438d in object_property_add_str (obj=obj@entry=0x57042a18, 
name=name@entry=0x56881b00 "type", 
get=get@entry=0x566f14c0 , set=set@entry=0, 
errp=errp@entry=0x0) at qom/object.c:1179
#7  0x566f440b in object_instance_init (obj=0x57042a18) at qom/object.c:1193
#8  0x566f18af in object_init_with_type (obj=obj@entry=0x57042a18, 
ti=0x56fd0e10) at qom/object.c:294
#9  0x566f18a3 in object_init_with_type (obj=obj@entry=0x57042a18, 
ti=0x56fc8b88) at qom/object.c:290
#10 0x566f18a3 in object_init_with_type (obj=obj@entry=0x57042a18, 
ti=0x56fcea50) at qom/object.c:290
#11 0x566f18a3 in object_init_with_type (obj=obj@entry=0x57042a18, 
ti=0x56fd1470) at qom/object.c:290
#12 0x566f18a3 in object_init_with_type (obj=obj@entry=0x57042a18, 
ti=ti@entry=0x56fd1388) at qom/object.c:290
#13 0x566f1fae in object_initialize_with_type (data=data@entry=0x57042a18, 
type=type@entry=0x56fd1388) at qom/object.c:311
#14 0x566f21fe in object_new_with_type (type=0x56fd1388) at qom/object.c:397
#15 0x566f2291 in object_new (typename=0x56fd1388 "H\024\375V4", 
typename@entry=0x5688b60a "arm_gic") at qom/object.c:407
#16 0x565f93a2 in qdev_try_create (bus=bus@entry=0x0, 
type=type@entry=0x5688b60a "arm_gic") at hw/qdev.c:134
#17 0x565f944a in qdev_create (bus=bus@entry=0x0, name=name@entry=0x5688b60a 
"arm_gic") at hw/qdev.c:114
#18 0x567adf7e in realview_gic_init (dev=0x57041748) at 
/tmp/qemu/qemu/hw/arm/../realview_gic.c:34
#19 0x56697148 in sysbus_device_init (dev=0x57041748) at 
/tmp/qemu/qemu/hw/sysbus.c:121
#20 0x565fa6c8 in qdev_init (dev=dev@entry=0x57041748) at hw/qdev.c:160
#21 0x565fa84c in qdev_init_nofail (dev=dev@entry=0x57041748) at hw/qdev.c:261
#22 0x56697884 in sysbus_create_varargs (name=name@entry=0x5688b742 
"realview_gic", addr=268697600)
at /tmp/qemu/qemu/hw/sysbus.c:135
#23 0x567ada5c in sysbus_create_simple (irq=, addr=, name=0x5688b742 "realview_gic")
at /tmp/qemu/qemu/hw/arm/../sysbus.h:79
#24 realview_init (ram_size=, kernel_filename=0x0, 
kernel_cmdline=0x5685a80d "", initrd_filename=0x0, 
cpu_model=0x5689010b "arm926", board_type=BOARD_EB, 
boot_device=) at /tmp/qemu/qemu/hw/arm/../realview.c:168
#25 0x5658e7c8 in main (argc=3, argv=0xd6a4, envp=0xd6b4) at 
/tmp/qemu/qemu/vl.c:3616
(gdb) 

$ valgrind arm-softmmu/qemu-system-arm -M realview-eb   
 [master]
==11274== Memcheck, a memory error detector
==11274== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==11274== Using Valgrind-3.8.0 and LibVEX; rerun with -h for copyright info
==11274== Command: arm-softmmu/qemu-system-arm -M realview-eb
==11274== 
==11274== Invalid write of size 4
==11274==at 0x3035AB: arm_gic_class_init (arm_gic.c:696)
==11274==by 0x2A4E48: type_initialize (object.c:281)
==11274==by 0x2A5633: object_class_by_name (object.c:510)
==11274==by 0x1AC395: qdev_try_create (qdev.c:131)
==11274==by 0x1AC449: qdev_create (qdev.c:114)
==11274==by 0x360F7D: realview_gic_init (realview_gic.c:34)
==11274==by 0x24A147: sysbus_device_init (sysbus.c:121)
==11274==by 0x1AD6C7: qdev_init (qdev.c:160)
==11274==by 0x1AD84B: qdev_init_nofail (qdev.c:261)
==11274==by 0x24A883: sysbus_create_varargs (sysbus.c:135)

[Qemu-devel] smp-parse: smp-opt-cores for simple -smp X

2011-07-08 Thread Adam Lackorzynski
Hi,

When just using a simple '-smp X', both the smp_cores and smp_threads
variables are set to 1, which on x86 leads to CPUid-0x8008-ecx
returning 1 for the CPU count despite more CPUs are there. Docs say
'Missing values will be computed.', so my try on this is the following.
Comments?


Signed-off-by: Adam Lackorzynski 
---
 vl.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/vl.c b/vl.c
index fcd7395..1459bde 100644
--- a/vl.c
+++ b/vl.c
@@ -886,6 +886,8 @@ static void smp_parse(const char *optarg)
 max_cpus = strtoull(option, NULL, 10);
 
 /* compute missing values, prefer sockets over cores over threads */
+if (sockets + cores + threads == 0)
+cores = smp;
 if (smp == 0 || sockets == 0) {
 sockets = sockets > 0 ? sockets : 1;
 cores = cores > 0 ? cores : 1;
-- 
1.7.5.3


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] multiboot: Support commas in module parameters

2011-07-06 Thread Adam Lackorzynski
Support commas in the parameter list of multiboot modules as well as for the
kernel command line, by using double commas (via get_opt_value()).

Signed-off-by: Adam Lackorzynski 
Reviewed-by: Kevin Wolf 
---
 hw/multiboot.c |   18 +-
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index 6e6cfb9..2426e84 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -97,11 +97,11 @@ typedef struct {
 
 static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
 {
-int len = strlen(cmdline) + 1;
 target_phys_addr_t p = s->offset_cmdlines;
+char *b = (char *)s->mb_buf + p;
 
-pstrcpy((char *)s->mb_buf + p, len, cmdline);
-s->offset_cmdlines += len;
+get_opt_value(b, strlen(cmdline) + 1, cmdline);
+s->offset_cmdlines += strlen(b) + 1;
 return s->mb_buf_phys + p;
 }
 
@@ -238,7 +238,7 @@ int load_multiboot(void *fw_cfg,
 const char *r = initrd_filename;
 mbs.mb_buf_size += strlen(r) + 1;
 mbs.mb_mods_avail = 1;
-while ((r = strchr(r, ','))) {
+while (*(r = get_opt_value(NULL, 0, r))) {
mbs.mb_mods_avail++;
r++;
 }
@@ -252,7 +252,7 @@ int load_multiboot(void *fw_cfg,
 mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE;
 
 if (initrd_filename) {
-char *next_initrd;
+char *next_initrd, not_last;
 
 mbs.offset_mods = mbs.mb_buf_size;
 
@@ -261,9 +261,9 @@ int load_multiboot(void *fw_cfg,
 int mb_mod_length;
 uint32_t offs = mbs.mb_buf_size;
 
-next_initrd = strchr(initrd_filename, ',');
-if (next_initrd)
-*next_initrd = '\0';
+next_initrd = (char *)get_opt_value(NULL, 0, initrd_filename);
+not_last = *next_initrd;
+*next_initrd = '\0';
 /* if a space comes after the module filename, treat everything
after that as parameters */
 target_phys_addr_t c = mb_add_cmdline(&mbs, initrd_filename);
@@ -287,7 +287,7 @@ int load_multiboot(void *fw_cfg,
  (char *)mbs.mb_buf + offs,
  (char *)mbs.mb_buf + offs + mb_mod_length, c);
 initrd_filename = next_initrd+1;
-} while (next_initrd);
+} while (not_last);
 }
 
 /* Commandline support */
-- 
1.7.5.3




[Qemu-devel] [PATCH] multiboot: Support commas in module parameters

2011-06-16 Thread Adam Lackorzynski
Support commas in the parameter list of multiboot modules, by using double
commas (via get_opt_value()).

Signed-off-by: Adam Lackorzynski 
---
 hw/multiboot.c |   18 +-
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index 6e6cfb9..2426e84 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -97,11 +97,11 @@ typedef struct {
 
 static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
 {
-int len = strlen(cmdline) + 1;
 target_phys_addr_t p = s->offset_cmdlines;
+char *b = (char *)s->mb_buf + p;
 
-pstrcpy((char *)s->mb_buf + p, len, cmdline);
-s->offset_cmdlines += len;
+get_opt_value(b, strlen(cmdline) + 1, cmdline);
+s->offset_cmdlines += strlen(b) + 1;
 return s->mb_buf_phys + p;
 }
 
@@ -238,7 +238,7 @@ int load_multiboot(void *fw_cfg,
 const char *r = initrd_filename;
 mbs.mb_buf_size += strlen(r) + 1;
 mbs.mb_mods_avail = 1;
-while ((r = strchr(r, ','))) {
+while (*(r = get_opt_value(NULL, 0, r))) {
mbs.mb_mods_avail++;
r++;
 }
@@ -252,7 +252,7 @@ int load_multiboot(void *fw_cfg,
 mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE;
 
 if (initrd_filename) {
-char *next_initrd;
+char *next_initrd, not_last;
 
 mbs.offset_mods = mbs.mb_buf_size;
 
@@ -261,9 +261,9 @@ int load_multiboot(void *fw_cfg,
 int mb_mod_length;
 uint32_t offs = mbs.mb_buf_size;
 
-next_initrd = strchr(initrd_filename, ',');
-if (next_initrd)
-*next_initrd = '\0';
+next_initrd = (char *)get_opt_value(NULL, 0, initrd_filename);
+not_last = *next_initrd;
+*next_initrd = '\0';
 /* if a space comes after the module filename, treat everything
after that as parameters */
 target_phys_addr_t c = mb_add_cmdline(&mbs, initrd_filename);
@@ -287,7 +287,7 @@ int load_multiboot(void *fw_cfg,
  (char *)mbs.mb_buf + offs,
  (char *)mbs.mb_buf + offs + mb_mod_length, c);
 initrd_filename = next_initrd+1;
-} while (next_initrd);
+} while (not_last);
 }
 
 /* Commandline support */
-- 
1.7.5.3




[Qemu-devel] [PATCH] multiboot: Support commas in module parameters

2011-05-21 Thread Adam Lackorzynski
Support commas in the parameter list of multiboot modules, by using double
commas (via get_opt_value()).

Signed-off-by: Adam Lackorzynski 
---
 hw/multiboot.c |   18 +-
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index 394ed01..7d5cb22 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -97,11 +97,11 @@ typedef struct {
 
 static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
 {
-int len = strlen(cmdline) + 1;
 target_phys_addr_t p = s->offset_cmdlines;
+char *b = (char *)s->mb_buf + p;
 
-pstrcpy((char *)s->mb_buf + p, len, cmdline);
-s->offset_cmdlines += len;
+get_opt_value(b, strlen(cmdline) + 1, cmdline);
+s->offset_cmdlines += strlen(b) + 1;
 return s->mb_buf_phys + p;
 }
 
@@ -238,7 +238,7 @@ int load_multiboot(void *fw_cfg,
 const char *r = initrd_filename;
 mbs.mb_buf_size += strlen(r) + 1;
 mbs.mb_mods_avail = 1;
-while ((r = strchr(r, ','))) {
+while (*(r = get_opt_value(NULL, 0, r))) {
mbs.mb_mods_avail++;
r++;
 }
@@ -252,7 +252,7 @@ int load_multiboot(void *fw_cfg,
 mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE;
 
 if (initrd_filename) {
-char *next_initrd;
+char *next_initrd, not_last;
 
 mbs.offset_mods = mbs.mb_buf_size;
 
@@ -261,9 +261,9 @@ int load_multiboot(void *fw_cfg,
 int mb_mod_length;
 uint32_t offs = mbs.mb_buf_size;
 
-next_initrd = strchr(initrd_filename, ',');
-if (next_initrd)
-*next_initrd = '\0';
+next_initrd = (char *)get_opt_value(NULL, 0, initrd_filename);
+not_last = *next_initrd;
+*next_initrd = '\0';
 /* if a space comes after the module filename, treat everything
after that as parameters */
 target_phys_addr_t c = mb_add_cmdline(&mbs, initrd_filename);
@@ -287,7 +287,7 @@ int load_multiboot(void *fw_cfg,
  (char *)mbs.mb_buf + offs,
  (char *)mbs.mb_buf + offs + mb_mod_length, c);
 initrd_filename = next_initrd+1;
-} while (next_initrd);
+} while (not_last);
 }
 
 /* Commandline support */
-- 
1.7.5.1




[Qemu-devel] [PATCH] multiboot: Support commas in module parameters

2011-05-01 Thread Adam Lackorzynski
Support commas in the parameter list of multiboot modules, by using double
commas (via get_opt_value()).

Signed-off-by: Adam Lackorzynski 
---
 hw/multiboot.c |   18 +-
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index 394ed01..7d5cb22 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -97,11 +97,11 @@ typedef struct {
 
 static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
 {
-int len = strlen(cmdline) + 1;
 target_phys_addr_t p = s->offset_cmdlines;
+char *b = (char *)s->mb_buf + p;
 
-pstrcpy((char *)s->mb_buf + p, len, cmdline);
-s->offset_cmdlines += len;
+get_opt_value(b, strlen(cmdline) + 1, cmdline);
+s->offset_cmdlines += strlen(b) + 1;
 return s->mb_buf_phys + p;
 }
 
@@ -238,7 +238,7 @@ int load_multiboot(void *fw_cfg,
 const char *r = initrd_filename;
 mbs.mb_buf_size += strlen(r) + 1;
 mbs.mb_mods_avail = 1;
-while ((r = strchr(r, ','))) {
+while (*(r = get_opt_value(NULL, 0, r))) {
mbs.mb_mods_avail++;
r++;
 }
@@ -252,7 +252,7 @@ int load_multiboot(void *fw_cfg,
 mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE;
 
 if (initrd_filename) {
-char *next_initrd;
+char *next_initrd, not_last;
 
 mbs.offset_mods = mbs.mb_buf_size;
 
@@ -261,9 +261,9 @@ int load_multiboot(void *fw_cfg,
 int mb_mod_length;
 uint32_t offs = mbs.mb_buf_size;
 
-next_initrd = strchr(initrd_filename, ',');
-if (next_initrd)
-*next_initrd = '\0';
+next_initrd = (char *)get_opt_value(NULL, 0, initrd_filename);
+not_last = *next_initrd;
+*next_initrd = '\0';
 /* if a space comes after the module filename, treat everything
after that as parameters */
 target_phys_addr_t c = mb_add_cmdline(&mbs, initrd_filename);
@@ -287,7 +287,7 @@ int load_multiboot(void *fw_cfg,
  (char *)mbs.mb_buf + offs,
  (char *)mbs.mb_buf + offs + mb_mod_length, c);
 initrd_filename = next_initrd+1;
-} while (next_initrd);
+} while (not_last);
 }
 
 /* Commandline support */
-- 
1.7.4.4




[Qemu-devel] [PATCH] multiboot: Support commas in module parameters

2011-04-18 Thread Adam Lackorzynski
Support commas in the parameter list of modules, by using double commas
(via get_opt_value()).

Signed-off-by: Adam Lackorzynski 
---
 hw/multiboot.c |   18 +-
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index 394ed01..7d5cb22 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -97,11 +97,11 @@ typedef struct {
 
 static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
 {
-int len = strlen(cmdline) + 1;
 target_phys_addr_t p = s->offset_cmdlines;
+char *b = (char *)s->mb_buf + p;
 
-pstrcpy((char *)s->mb_buf + p, len, cmdline);
-s->offset_cmdlines += len;
+get_opt_value(b, strlen(cmdline) + 1, cmdline);
+s->offset_cmdlines += strlen(b) + 1;
 return s->mb_buf_phys + p;
 }
 
@@ -238,7 +238,7 @@ int load_multiboot(void *fw_cfg,
 const char *r = initrd_filename;
 mbs.mb_buf_size += strlen(r) + 1;
 mbs.mb_mods_avail = 1;
-while ((r = strchr(r, ','))) {
+while (*(r = get_opt_value(NULL, 0, r))) {
mbs.mb_mods_avail++;
r++;
 }
@@ -252,7 +252,7 @@ int load_multiboot(void *fw_cfg,
 mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE;
 
 if (initrd_filename) {
-char *next_initrd;
+char *next_initrd, not_last;
 
 mbs.offset_mods = mbs.mb_buf_size;
 
@@ -261,9 +261,9 @@ int load_multiboot(void *fw_cfg,
 int mb_mod_length;
 uint32_t offs = mbs.mb_buf_size;
 
-next_initrd = strchr(initrd_filename, ',');
-if (next_initrd)
-*next_initrd = '\0';
+next_initrd = (char *)get_opt_value(NULL, 0, initrd_filename);
+not_last = *next_initrd;
+*next_initrd = '\0';
 /* if a space comes after the module filename, treat everything
after that as parameters */
 target_phys_addr_t c = mb_add_cmdline(&mbs, initrd_filename);
@@ -287,7 +287,7 @@ int load_multiboot(void *fw_cfg,
  (char *)mbs.mb_buf + offs,
  (char *)mbs.mb_buf + offs + mb_mod_length, c);
 initrd_filename = next_initrd+1;
-} while (next_initrd);
+} while (not_last);
 }
 
 /* Commandline support */
-- 
1.7.4.1




Re: [Qemu-devel] [PATCH] multiboot: Support quotable commas in module list

2011-04-16 Thread Adam Lackorzynski

On Fri Apr 15, 2011 at 15:17:28 +0200, Kevin Wolf wrote:
> Am 15.04.2011 09:56, schrieb Adam Lackorzynski:
> > Support quoting of ',' (and '\') to allow commas in the parameter list of
> > modules.
> > 
> > Signed-off-by: Adam Lackorzynski 
> 
> Other options in qemu use double commas for escaping. So maybe reusing
> get_opt_value() would make things more consistent. It also has the
> advantage that double commas don't need additional escape characters for
> the shell.
> 
> On the other hand, using backslashes for escaping is probably more
> familiar for most people, so I don't have a very strong opinion on it.

Same for me. I like the fact with the double-commas and easier shell
quoting. On the other side using backslashes is more common. However, I
construct the overall command via scripts anyway, so I'll only very
seldom actually type this myself.

Here's how it would look like. Diff is smaller.
More opinions very welcome.


diff --git a/hw/multiboot.c b/hw/multiboot.c
index 394ed01..7d5cb22 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -97,11 +97,11 @@ typedef struct {
 
 static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
 {
-int len = strlen(cmdline) + 1;
 target_phys_addr_t p = s->offset_cmdlines;
+char *b = (char *)s->mb_buf + p;
 
-pstrcpy((char *)s->mb_buf + p, len, cmdline);
-s->offset_cmdlines += len;
+get_opt_value(b, strlen(cmdline) + 1, cmdline);
+s->offset_cmdlines += strlen(b) + 1;
 return s->mb_buf_phys + p;
 }
 
@@ -238,7 +238,7 @@ int load_multiboot(void *fw_cfg,
 const char *r = initrd_filename;
 mbs.mb_buf_size += strlen(r) + 1;
 mbs.mb_mods_avail = 1;
-while ((r = strchr(r, ','))) {
+while (*(r = get_opt_value(NULL, 0, r))) {
mbs.mb_mods_avail++;
r++;
 }
@@ -252,7 +252,7 @@ int load_multiboot(void *fw_cfg,
 mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE;
 
 if (initrd_filename) {
-char *next_initrd;
+char *next_initrd, not_last;
 
 mbs.offset_mods = mbs.mb_buf_size;
 
@@ -261,9 +261,9 @@ int load_multiboot(void *fw_cfg,
 int mb_mod_length;
 uint32_t offs = mbs.mb_buf_size;
 
-next_initrd = strchr(initrd_filename, ',');
-if (next_initrd)
-*next_initrd = '\0';
+next_initrd = (char *)get_opt_value(NULL, 0, initrd_filename);
+not_last = *next_initrd;
+*next_initrd = '\0';
 /* if a space comes after the module filename, treat everything
after that as parameters */
 target_phys_addr_t c = mb_add_cmdline(&mbs, initrd_filename);
@@ -287,7 +287,7 @@ int load_multiboot(void *fw_cfg,
  (char *)mbs.mb_buf + offs,
  (char *)mbs.mb_buf + offs + mb_mod_length, c);
 initrd_filename = next_initrd+1;
-} while (next_initrd);
+} while (not_last);
 }
 
 /* Commandline support */



Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] multiboot: Support quotable commas in module list

2011-04-15 Thread Adam Lackorzynski
Support quoting of ',' (and '\') to allow commas in the parameter list of
modules.

Signed-off-by: Adam Lackorzynski 
---
 hw/multiboot.c |   33 +
 1 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index 394ed01..73f01aa 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -95,13 +95,26 @@ typedef struct {
 int mb_mods_count;
 } MultibootState;
 
+static int mb_is_cmdline_quote(const char *c)
+{
+return c[0] == '\\' && (c[1] == '\\' || c[1] == ',');
+}
+
 static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
 {
 int len = strlen(cmdline) + 1;
+int ci, bi;
 target_phys_addr_t p = s->offset_cmdlines;
+char *b = (char *)s->mb_buf + p;
 
-pstrcpy((char *)s->mb_buf + p, len, cmdline);
-s->offset_cmdlines += len;
+for (ci = 0, bi = 0; ci < len - 1; ci++, bi++) {
+if (mb_is_cmdline_quote(&cmdline[ci])) {
+ci++;
+}
+b[bi] = cmdline[ci];
+}
+b[bi] = 0;
+s->offset_cmdlines += bi + 1;
 return s->mb_buf_phys + p;
 }
 
@@ -124,6 +137,18 @@ static void mb_add_mod(MultibootState *s,
 s->mb_mods_count++;
 }
 
+static const char *mb_cmdline_next_module(const char *c)
+{
+for (; *c; c++) {
+if (mb_is_cmdline_quote(c)) {
+c++;
+} else if (c[0] == ',') {
+return c;
+}
+}
+return 0;
+}
+
 int load_multiboot(void *fw_cfg,
FILE *f,
const char *kernel_filename,
@@ -238,7 +263,7 @@ int load_multiboot(void *fw_cfg,
 const char *r = initrd_filename;
 mbs.mb_buf_size += strlen(r) + 1;
 mbs.mb_mods_avail = 1;
-while ((r = strchr(r, ','))) {
+while ((r = mb_cmdline_next_module(r))) {
mbs.mb_mods_avail++;
r++;
 }
@@ -261,7 +286,7 @@ int load_multiboot(void *fw_cfg,
 int mb_mod_length;
 uint32_t offs = mbs.mb_buf_size;
 
-next_initrd = strchr(initrd_filename, ',');
+next_initrd = (char *)mb_cmdline_next_module(initrd_filename);
 if (next_initrd)
 *next_initrd = '\0';
 /* if a space comes after the module filename, treat everything
-- 
1.7.4.1




Re: [Qemu-devel] [PATCH] multiboot: Quote filename in error message.

2011-04-07 Thread Adam Lackorzynski

On Fri Apr 08, 2011 at 00:44:36 +0200, Alexander Graf wrote:
> 
> On 07.04.2011, at 20:22, Adam Lackorzynski wrote:
> 
> > Quote filename in error message to spot possible whitespace character in
> > the filename.
> > 
> > Signed-off-by: Adam Lackorzynski 
> > ---
> > hw/multiboot.c |2 +-
> > 1 files changed, 1 insertions(+), 1 deletions(-)
> > 
> > diff --git a/hw/multiboot.c b/hw/multiboot.c
> > index 0d2bfb4..6be6fa0 100644
> > --- a/hw/multiboot.c
> > +++ b/hw/multiboot.c
> > @@ -272,7 +272,7 @@ int load_multiboot(void *fw_cfg,
> > mb_debug("multiboot loading module: %s\n", initrd_filename);
> > mb_mod_length = get_image_size(initrd_filename);
> > if (mb_mod_length < 0) {
> > -fprintf(stderr, "failed to get %s image size\n", 
> > initrd_filename);
> > +fprintf(stderr, "failed to get image size of '%s'\n", 
> > initrd_filename);
> 
> I'd like to see something telling the user that the most likely reason is 
> that the file isn't there :). It might even make sense to only say "Failed to 
> open file '%s'".

Looking at get_image_size() it's the right thing to do...



Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] multiboot: Quote filename in error message.

2011-04-07 Thread Adam Lackorzynski
Quote filename in error message to spot possible whitespace character in
the filename and make error message more meaningful.

Signed-off-by: Adam Lackorzynski 
---
 hw/multiboot.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index 0d2bfb4..394ed01 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -272,7 +272,7 @@ int load_multiboot(void *fw_cfg,
 mb_debug("multiboot loading module: %s\n", initrd_filename);
 mb_mod_length = get_image_size(initrd_filename);
 if (mb_mod_length < 0) {
-fprintf(stderr, "failed to get %s image size\n", 
initrd_filename);
+fprintf(stderr, "Failed to open file '%s'\n", initrd_filename);
 exit(1);
 }
 
-- 
1.7.4.1




[Qemu-devel] [PATCH] multiboot: Quote filename in error message.

2011-04-07 Thread Adam Lackorzynski
Quote filename in error message to spot possible whitespace character in
the filename.

Signed-off-by: Adam Lackorzynski 
---
 hw/multiboot.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index 0d2bfb4..6be6fa0 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -272,7 +272,7 @@ int load_multiboot(void *fw_cfg,
 mb_debug("multiboot loading module: %s\n", initrd_filename);
 mb_mod_length = get_image_size(initrd_filename);
 if (mb_mod_length < 0) {
-fprintf(stderr, "failed to get %s image size\n", 
initrd_filename);
+fprintf(stderr, "failed to get image size of '%s'\n", 
initrd_filename);
 exit(1);
 }
 
-- 
1.7.4.1




Re: [Qemu-devel] [PATCH] hw: improve multiboot module loading

2011-04-07 Thread Adam Lackorzynski

On Thu Apr 07, 2011 at 14:52:34 +0100, Stefan Hajnoczi wrote:
> On Thu, Apr 7, 2011 at 1:56 PM, Ralf Ramsauer
>  wrote:
> > On 07.04.2011, at 14:48, Stefan Hajnoczi wrote:
> >
> >> Out of curiousity, why are you trying to kill spaces at all?
> >>
> >> Why not just use a correct command-line to invoke QEMU?
> >>
> >> Stefan
> >
> > Well it took me 2 days to find out why -initrd "module1, module2" didn't 
> > work. If there's a space after the comma you'll always
> > get the error message "Failed to get  image size".
> 
> How about improving the error message?

I'll send a patch shortly fixing the message.
 
> > And if you want to pass a comma in a multiboot argument you've no way to do 
> > this.
> > So -initrd"module1 settings=use_foo,use_bar" won't work!
> 
> >From what I can tell your patch does not change this.

It should be possible to put commas on the mb command line.
Do we want to escape commas?



Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] target-i386: Do not announce extended mwait features

2011-03-16 Thread Adam Lackorzynski
CPUID claims that extended monitor/mwait features are available but the
mwait helper instantly raises a GPF if they are used. Thus do not announce
that the extension are available.

Signed-off-by: Adam Lackorzynski 
---
 target-i386/cpuid.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 5382a28..28275a6 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -1104,7 +1104,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 /* mwait info: needed for Core compatibility */
 *eax = 0; /* Smallest monitor-line size in bytes */
 *ebx = 0; /* Largest monitor-line size in bytes */
-*ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
+*ecx = 0; /* Supported extensions */
 *edx = 0;
 break;
 case 6:
-- 
1.7.4.1




[Qemu-devel] [PATCH 1/4] target-arm: Fix soft interrupt in GIC distributor

2011-03-05 Thread Adam Lackorzynski
Fix selection of target list filter mode.

Signed-off-by: Adam Lackorzynski 
Reviewed-by: Peter Maydell 
---
 hw/arm_gic.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index e6b1953..0e934ec 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -549,10 +549,10 @@ static void gic_dist_writel(void *opaque, 
target_phys_addr_t offset,
 mask = (value >> 16) & ALL_CPU_MASK;
 break;
 case 1:
-mask = 1 << cpu;
+mask = ALL_CPU_MASK ^ (1 << cpu);
 break;
 case 2:
-mask = ALL_CPU_MASK ^ (1 << cpu);
+mask = 1 << cpu;
 break;
 default:
 DPRINTF("Bad Soft Int target filter\n");
-- 
1.7.4.1




[Qemu-devel] [PATCH 4/4] target-arm: Integrate secondary CPU reset in arm_boot

2011-03-05 Thread Adam Lackorzynski
Integrate secondary CPU reset into arm_boot, removing it from realview.c.
On non-Linux systems secondary CPUs start with the same entry as the boot
CPU.

Signed-off-by: Adam Lackorzynski 
---
 hw/arm_boot.c |   23 +++
 hw/realview.c |   14 --
 2 files changed, 15 insertions(+), 22 deletions(-)

diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 620550b..41e99d1 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -175,7 +175,7 @@ static void set_kernel_args_old(struct arm_boot_info *info,
 }
 }
 
-static void main_cpu_reset(void *opaque)
+static void do_cpu_reset(void *opaque)
 {
 CPUState *env = opaque;
 struct arm_boot_info *info = env->boot_info;
@@ -187,16 +187,20 @@ static void main_cpu_reset(void *opaque)
 env->regs[15] = info->entry & 0xfffe;
 env->thumb = info->entry & 1;
 } else {
-env->regs[15] = info->loader_start;
-if (old_param) {
-set_kernel_args_old(info, info->initrd_size,
+if (env == first_cpu) {
+env->regs[15] = info->loader_start;
+if (old_param) {
+set_kernel_args_old(info, info->initrd_size,
+info->loader_start);
+} else {
+set_kernel_args(info, info->initrd_size,
 info->loader_start);
+}
 } else {
-set_kernel_args(info, info->initrd_size, info->loader_start);
+env->regs[15] = info->smp_loader_start;
 }
 }
 }
-/* TODO:  Reset secondary CPUs.  */
 }
 
 void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
@@ -217,7 +221,6 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info 
*info)
 
 if (info->nb_cpus == 0)
 info->nb_cpus = 1;
-env->boot_info = info;
 
 #ifdef TARGET_WORDS_BIGENDIAN
 big_endian = 1;
@@ -279,5 +282,9 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info 
*info)
 info->initrd_size = initrd_size;
 }
 info->is_linux = is_linux;
-qemu_register_reset(main_cpu_reset, env);
+
+for (; env; env = env->next_cpu) {
+env->boot_info = info;
+qemu_register_reset(do_cpu_reset, env);
+}
 }
diff --git a/hw/realview.c b/hw/realview.c
index 6eb6c6a..fae444a 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -104,17 +104,6 @@ static struct arm_boot_info realview_binfo = {
 .smp_loader_start = SMP_BOOT_ADDR,
 };
 
-static void secondary_cpu_reset(void *opaque)
-{
-  CPUState *env = opaque;
-
-  cpu_reset(env);
-  /* Set entry point for secondary CPUs.  This assumes we're using
- the init code from arm_boot.c.  Real hardware resets all CPUs
- the same.  */
-  env->regs[15] = SMP_BOOT_ADDR;
-}
-
 /* The following two lists must be consistent.  */
 enum realview_board_type {
 BOARD_EB,
@@ -176,9 +165,6 @@ static void realview_init(ram_addr_t ram_size,
 }
 irqp = arm_pic_init_cpu(env);
 cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
-if (n > 0) {
-qemu_register_reset(secondary_cpu_reset, env);
-}
 }
 if (arm_feature(env, ARM_FEATURE_V7)) {
 if (is_mpcore) {
-- 
1.7.4.1




[Qemu-devel] [PATCH 3/4] target-arm: Implement cp15 VA->PA translation

2011-03-05 Thread Adam Lackorzynski
Implement VA->PA translations by cp15-c7 that went through unchanged
previously.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/cpu.h |3 ++-
 target-arm/helper.c  |   48 ++--
 target-arm/machine.c |2 ++
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c9febfa..1ae7982 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -126,6 +126,7 @@ typedef struct CPUARMState {
 uint32_t c6_region[8]; /* MPU base/size registers.  */
 uint32_t c6_insn; /* Fault address registers.  */
 uint32_t c6_data;
+uint32_t c7_par;  /* Translation result. */
 uint32_t c9_insn; /* Cache lockdown registers.  */
 uint32_t c9_data;
 uint32_t c13_fcse; /* FCSE PID.  */
@@ -428,7 +429,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
-#define CPU_SAVE_VERSION 2
+#define CPU_SAVE_VERSION 3
 
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1852352..d360121 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1456,8 +1456,49 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, 
uint32_t val)
 case 7: /* Cache control.  */
 env->cp15.c15_i_max = 0x000;
 env->cp15.c15_i_min = 0xff0;
-/* No cache, so nothing to do.  */
-/* ??? MPCore has VA to PA translation functions.  */
+if (op1 != 0) {
+goto bad_reg;
+}
+/* No cache, so nothing to do except VA->PA translations. */
+if (arm_feature(env, ARM_FEATURE_V6K)) {
+switch (crm) {
+case 4:
+if (arm_feature(env, ARM_FEATURE_V7)) {
+env->cp15.c7_par = val & 0xf6ff;
+} else {
+env->cp15.c7_par = val & 0xf1ff;
+}
+break;
+case 8: {
+uint32_t phys_addr;
+target_ulong page_size;
+int prot;
+int ret, is_user = op2 & 2;
+int access_type = op2 & 1;
+
+if (op2 & 4) {
+/* Other states are only available with TrustZone */
+goto bad_reg;
+}
+ret = get_phys_addr(env, val, access_type, is_user,
+&phys_addr, &prot, &page_size);
+if (ret == 0) {
+/* We do not set any attribute bits in the PAR */
+if (page_size == (1 << 24)
+&& arm_feature(env, ARM_FEATURE_V7)) {
+env->cp15.c7_par = (phys_addr & 0xff00) | 1 << 1;
+} else {
+env->cp15.c7_par = phys_addr & 0xf000;
+}
+} else {
+env->cp15.c7_par = ((ret & (10 << 1)) >> 5) |
+   ((ret & (12 << 1)) >> 6) |
+   ((ret & 0xf) << 1) | 1;
+}
+break;
+}
+}
+}
 break;
 case 8: /* MMU TLB control.  */
 switch (op2) {
@@ -1789,6 +1830,9 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
}
 }
 case 7: /* Cache control.  */
+if (crm == 4 && op1 == 0 && op2 == 0) {
+return env->cp15.c7_par;
+}
 /* FIXME: Should only clear Z flag if destination is r15.  */
 env->ZF = 0;
 return 0;
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 3925d3a..a18b7dc 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -41,6 +41,7 @@ void cpu_save(QEMUFile *f, void *opaque)
 }
 qemu_put_be32(f, env->cp15.c6_insn);
 qemu_put_be32(f, env->cp15.c6_data);
+qemu_put_be32(f, env->cp15.c7_par);
 qemu_put_be32(f, env->cp15.c9_insn);
 qemu_put_be32(f, env->cp15.c9_data);
 qemu_put_be32(f, env->cp15.c13_fcse);
@@ -148,6 +149,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
 }
 env->cp15.c6_insn = qemu_get_be32(f);
 env->cp15.c6_data = qemu_get_be32(f);
+env->cp15.c7_par = qemu_get_be32(f);
 env->cp15.c9_insn = qemu_get_be32(f);
 env->cp15.c9_data = qemu_get_be32(f);
 env->cp15.c13_fcse = qemu_get_be32(f);
-- 
1.7.4.1




[Qemu-devel] [PATCH 0/4] ARM additions and fixes

2011-03-05 Thread Adam Lackorzynski
The following patches fix and enhance ARM related functionality.

Adam Lackorzynski (3):
  target-arm: Fix soft interrupt in GIC distributor
  target-arm: Implement cp15 VA->PA translation
  target-arm: Integrate secondary CPU reset in arm_boot

Peter Maydell (1):
  target-arm: Don't decode old cp15 WFI instructions on v7 cores

 hw/arm_boot.c  |   23 +++
 hw/arm_gic.c   |4 ++--
 hw/realview.c  |   14 --
 target-arm/cpu.h   |3 ++-
 target-arm/helper.c|   48 ++--
 target-arm/machine.c   |2 ++
 target-arm/translate.c |   35 ++-
 7 files changed, 97 insertions(+), 32 deletions(-)

-- 
1.7.4.1




[Qemu-devel] [PATCH 2/4] target-arm: Don't decode old cp15 WFI instructions on v7 cores

2011-03-05 Thread Adam Lackorzynski
From: Peter Maydell 

In v7 of the ARM architecture, WFI (wait for interrupt) is a first-class
instruction, but in previous versions this functionality was provided
via a cp15 coprocessor register. Add correct feature checks to the
decoding of the cp15 WFI instructions so that they behave correctly
for newer cores. In particular, the old 0,c7,c8,2 encoding used on
ARM940 has been reused for VA-to-PA translation in v6 and v7.

Signed-off-by: Peter Maydell 
Reviewed-by: Adam Lackorzynski 
---
 target-arm/translate.c |   35 ++-
 1 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 5abf4d4..a684067 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2538,13 +2538,38 @@ static int disas_cp15_insn(CPUState *env, DisasContext 
*s, uint32_t insn)
 if (IS_USER(s) && !cp15_user_ok(insn)) {
 return 1;
 }
-if ((insn & 0x0fff0fff) == 0x0e070f90
-|| (insn & 0x0fff0fff) == 0x0e070f58) {
-/* Wait for interrupt.  */
-gen_set_pc_im(s->pc);
-s->is_jmp = DISAS_WFI;
+
+/* Pre-v7 versions of the architecture implemented WFI via coprocessor
+ * instructions rather than a separate instruction.
+ */
+if ((insn & 0x0fff0fff) == 0x0e070f90) {
+/* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
+ * In v7, this must NOP.
+ */
+if (!arm_feature(env, ARM_FEATURE_V7)) {
+/* Wait for interrupt.  */
+gen_set_pc_im(s->pc);
+s->is_jmp = DISAS_WFI;
+}
 return 0;
 }
+
+if ((insn & 0x0fff0fff) == 0x0e070f58) {
+/* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
+ * so this is slightly over-broad.
+ */
+if (!arm_feature(env, ARM_FEATURE_V6)) {
+/* Wait for interrupt.  */
+gen_set_pc_im(s->pc);
+s->is_jmp = DISAS_WFI;
+return 0;
+}
+/* Otherwise fall through to handle via helper function.
+ * In particular, on v7 and some v6 cores this is one of
+ * the VA-PA registers.
+ */
+}
+
 rd = (insn >> 12) & 0xf;
 
 if (cp15_tls_load_store(env, s, insn, rd))
-- 
1.7.4.1




Re: [Qemu-devel] [PATCH 2/3] target-arm: Implement cp15 VA->PA translation

2011-03-03 Thread Adam Lackorzynski

On Thu Mar 03, 2011 at 22:59:03 +, Peter Maydell wrote:
> On 21 February 2011 23:19, Adam Lackorzynski  
> wrote:
> > diff --git a/target-arm/machine.c b/target-arm/machine.c
> > index 3925d3a..a18b7dc 100644
> > --- a/target-arm/machine.c
> > +++ b/target-arm/machine.c
> > @@ -41,6 +41,7 @@ void cpu_save(QEMUFile *f, void *opaque)
> >     }
> >     qemu_put_be32(f, env->cp15.c6_insn);
> >     qemu_put_be32(f, env->cp15.c6_data);
> > +    qemu_put_be32(f, env->cp15.c7_par);
> >     qemu_put_be32(f, env->cp15.c9_insn);
> >     qemu_put_be32(f, env->cp15.c9_data);
> >     qemu_put_be32(f, env->cp15.c13_fcse);
> > @@ -148,6 +149,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
> >     }
> >     env->cp15.c6_insn = qemu_get_be32(f);
> >     env->cp15.c6_data = qemu_get_be32(f);
> > +    env->cp15.c7_par = qemu_get_be32(f);
> >     env->cp15.c9_insn = qemu_get_be32(f);
> >     env->cp15.c9_data = qemu_get_be32(f);
> >     env->cp15.c13_fcse = qemu_get_be32(f);
> 
> Comments on another patch left me wondering whether we should
> be bumping a version number here somewhere[*], since we're changing
> the load/store state format by adding another field. Anybody
> care to agree/disagree?

Looks like a reasonable thing to do. I'll add it to my patch set.
 

Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] Re: [PATCH] target-arm: Don't decode old cp15 WFI instructions on v7 cores

2011-02-25 Thread Adam Lackorzynski

On Fri Feb 25, 2011 at 15:04:12 +, Peter Maydell wrote:
> In v7 of the ARM architecture, WFI (wait for interrupt) is a first-class
> instruction, but in previous versions this functionality was provided
> via a cp15 coprocessor register. Add correct feature checks to the
> decoding of the cp15 WFI instructions so that they behave correctly
> for newer cores. In particular, the old 0,c7,c8,2 encoding used on
> ARM940 has been reused for VA-to-PA translation in v6 and v7.
> 
> Signed-off-by: Peter Maydell 

Reviewed-by: Adam Lackorzynski 

> ---
> This patch stands alone as a fix to target-arm; it's a prerequisite
> for Adam's VA->PA translation patch, because otherwise attempting a
> user-read translation will get you a WFI instead...

Thanks, (un)fortunately I never triggered this case in my setup.



Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH 1/3] target-arm: Fix soft interrupt in GIC distributor

2011-02-21 Thread Adam Lackorzynski
Fix selection of target list filter mode.

Signed-off-by: Adam Lackorzynski 
Reviewed-by: Peter Maydell 
---
 hw/arm_gic.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index e6b1953..0e934ec 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -549,10 +549,10 @@ static void gic_dist_writel(void *opaque, 
target_phys_addr_t offset,
 mask = (value >> 16) & ALL_CPU_MASK;
 break;
 case 1:
-mask = 1 << cpu;
+mask = ALL_CPU_MASK ^ (1 << cpu);
 break;
 case 2:
-mask = ALL_CPU_MASK ^ (1 << cpu);
+mask = 1 << cpu;
 break;
 default:
 DPRINTF("Bad Soft Int target filter\n");
-- 
1.7.2.3




[Qemu-devel] [PATCH 0/3] ARM additions and fixes

2011-02-21 Thread Adam Lackorzynski
The following patches fix and enhance ARM related functionality.

Adam Lackorzynski (3):
  target-arm: Fix soft interrupt in GIC distributor
  target-arm: Implement cp15 VA->PA translation
  target-arm: Integrate secondary CPU reset in arm_boot

 hw/arm_boot.c|   23 +++
 hw/arm_gic.c |4 ++--
 hw/realview.c|   14 --
 target-arm/cpu.h |1 +
 target-arm/helper.c  |   48 ++--
 target-arm/machine.c |2 ++
 6 files changed, 66 insertions(+), 26 deletions(-)

-- 
1.7.2.3




[Qemu-devel] [PATCH 2/3] target-arm: Implement cp15 VA->PA translation

2011-02-21 Thread Adam Lackorzynski
Implement VA->PA translations by cp15-c7 that went through unchanged
previously.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/cpu.h |1 +
 target-arm/helper.c  |   48 ++--
 target-arm/machine.c |2 ++
 3 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c9febfa..603574b 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -126,6 +126,7 @@ typedef struct CPUARMState {
 uint32_t c6_region[8]; /* MPU base/size registers.  */
 uint32_t c6_insn; /* Fault address registers.  */
 uint32_t c6_data;
+uint32_t c7_par;  /* Translation result. */
 uint32_t c9_insn; /* Cache lockdown registers.  */
 uint32_t c9_data;
 uint32_t c13_fcse; /* FCSE PID.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7f63a28..23c719b 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1456,8 +1456,49 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, 
uint32_t val)
 case 7: /* Cache control.  */
 env->cp15.c15_i_max = 0x000;
 env->cp15.c15_i_min = 0xff0;
-/* No cache, so nothing to do.  */
-/* ??? MPCore has VA to PA translation functions.  */
+if (op1 != 0) {
+goto bad_reg;
+}
+/* No cache, so nothing to do except VA->PA translations. */
+if (arm_feature(env, ARM_FEATURE_V6K)) {
+switch (crm) {
+case 4:
+if (arm_feature(env, ARM_FEATURE_V7)) {
+env->cp15.c7_par = val & 0xf6ff;
+} else {
+env->cp15.c7_par = val & 0xf1ff;
+}
+break;
+case 8: {
+uint32_t phys_addr;
+target_ulong page_size;
+int prot;
+int ret, is_user = op2 & 2;
+int access_type = op2 & 1;
+
+if (op2 & 4) {
+/* Other states are only available with TrustZone */
+goto bad_reg;
+}
+ret = get_phys_addr(env, val, access_type, is_user,
+&phys_addr, &prot, &page_size);
+if (ret == 0) {
+/* We do not set any attribute bits in the PAR */
+if (page_size == (1 << 24)
+&& arm_feature(env, ARM_FEATURE_V7)) {
+env->cp15.c7_par = (phys_addr & 0xff00) | 1 << 1;
+} else {
+env->cp15.c7_par = phys_addr & 0xf000;
+}
+} else {
+env->cp15.c7_par = ((ret & (10 << 1)) >> 5) |
+   ((ret & (12 << 1)) >> 6) |
+   ((ret & 0xf) << 1) | 1;
+}
+break;
+}
+}
+}
 break;
 case 8: /* MMU TLB control.  */
 switch (op2) {
@@ -1789,6 +1830,9 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
}
 }
 case 7: /* Cache control.  */
+if (crm == 4 && op1 == 0 && op2 == 0) {
+return env->cp15.c7_par;
+}
 /* FIXME: Should only clear Z flag if destination is r15.  */
 env->ZF = 0;
 return 0;
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 3925d3a..a18b7dc 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -41,6 +41,7 @@ void cpu_save(QEMUFile *f, void *opaque)
 }
 qemu_put_be32(f, env->cp15.c6_insn);
 qemu_put_be32(f, env->cp15.c6_data);
+qemu_put_be32(f, env->cp15.c7_par);
 qemu_put_be32(f, env->cp15.c9_insn);
 qemu_put_be32(f, env->cp15.c9_data);
 qemu_put_be32(f, env->cp15.c13_fcse);
@@ -148,6 +149,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
 }
 env->cp15.c6_insn = qemu_get_be32(f);
 env->cp15.c6_data = qemu_get_be32(f);
+env->cp15.c7_par = qemu_get_be32(f);
 env->cp15.c9_insn = qemu_get_be32(f);
 env->cp15.c9_data = qemu_get_be32(f);
 env->cp15.c13_fcse = qemu_get_be32(f);
-- 
1.7.2.3




[Qemu-devel] [PATCH 3/3] target-arm: Integrate secondary CPU reset in arm_boot

2011-02-21 Thread Adam Lackorzynski
Integrate secondary CPU reset into arm_boot, removing it from realview.c.
On non-Linux systems secondary CPUs start with the same entry as the boot
CPU.

Signed-off-by: Adam Lackorzynski 
---
 hw/arm_boot.c |   23 +++
 hw/realview.c |   14 --
 2 files changed, 15 insertions(+), 22 deletions(-)

diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 620550b..41e99d1 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -175,7 +175,7 @@ static void set_kernel_args_old(struct arm_boot_info *info,
 }
 }
 
-static void main_cpu_reset(void *opaque)
+static void do_cpu_reset(void *opaque)
 {
 CPUState *env = opaque;
 struct arm_boot_info *info = env->boot_info;
@@ -187,16 +187,20 @@ static void main_cpu_reset(void *opaque)
 env->regs[15] = info->entry & 0xfffe;
 env->thumb = info->entry & 1;
 } else {
-env->regs[15] = info->loader_start;
-if (old_param) {
-set_kernel_args_old(info, info->initrd_size,
+if (env == first_cpu) {
+env->regs[15] = info->loader_start;
+if (old_param) {
+set_kernel_args_old(info, info->initrd_size,
+info->loader_start);
+} else {
+set_kernel_args(info, info->initrd_size,
 info->loader_start);
+}
 } else {
-set_kernel_args(info, info->initrd_size, info->loader_start);
+env->regs[15] = info->smp_loader_start;
 }
 }
 }
-/* TODO:  Reset secondary CPUs.  */
 }
 
 void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
@@ -217,7 +221,6 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info 
*info)
 
 if (info->nb_cpus == 0)
 info->nb_cpus = 1;
-env->boot_info = info;
 
 #ifdef TARGET_WORDS_BIGENDIAN
 big_endian = 1;
@@ -279,5 +282,9 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info 
*info)
 info->initrd_size = initrd_size;
 }
 info->is_linux = is_linux;
-qemu_register_reset(main_cpu_reset, env);
+
+for (; env; env = env->next_cpu) {
+env->boot_info = info;
+qemu_register_reset(do_cpu_reset, env);
+}
 }
diff --git a/hw/realview.c b/hw/realview.c
index 6eb6c6a..fae444a 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -104,17 +104,6 @@ static struct arm_boot_info realview_binfo = {
 .smp_loader_start = SMP_BOOT_ADDR,
 };
 
-static void secondary_cpu_reset(void *opaque)
-{
-  CPUState *env = opaque;
-
-  cpu_reset(env);
-  /* Set entry point for secondary CPUs.  This assumes we're using
- the init code from arm_boot.c.  Real hardware resets all CPUs
- the same.  */
-  env->regs[15] = SMP_BOOT_ADDR;
-}
-
 /* The following two lists must be consistent.  */
 enum realview_board_type {
 BOARD_EB,
@@ -176,9 +165,6 @@ static void realview_init(ram_addr_t ram_size,
 }
 irqp = arm_pic_init_cpu(env);
 cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
-if (n > 0) {
-qemu_register_reset(secondary_cpu_reset, env);
-}
 }
 if (arm_feature(env, ARM_FEATURE_V7)) {
 if (is_mpcore) {
-- 
1.7.2.3




Re: [Qemu-devel] [PATCH 3/3] target-arm: Implement cp15 VA->PA translation

2011-02-17 Thread Adam Lackorzynski
Hi,

thanks for the review!

On Wed Feb 16, 2011 at 15:57:59 +, Peter Maydell wrote:
> On 15 February 2011 10:49, Adam Lackorzynski  
> wrote:
> > Implement VA->PA translations by cp15-c7 that went through unchanged
> > previously.
> 
> > +        uint32_t c7_par;  /* Translation result. */
> 
> I think this new env field needs extra code so it is saved
> and loaded by machine.c:cpu_save() and cpu_load().

Yes, noticed already myself.
 
> >     case 7: /* Cache control.  */
> 
> We should be insisting that op1 == 0 (otherwise bad_reg).

Ok.

> >         env->cp15.c15_i_max = 0x000;
> >         env->cp15.c15_i_min = 0xff0;
> > -        /* No cache, so nothing to do.  */
> > -        /* ??? MPCore has VA to PA translation functions.  */
> > +        /* No cache, so nothing to do except VA->PA translations. */
> > +        if (arm_feature(env, ARM_FEATURE_V6)) {
> 
> This is the wrong feature switch. The VA-PA translation registers
> are only architectural in v7. Before that, they exist in 11MPcore
> and 1176 but not 1136. So we should be testing for v7 or
> 11MPcore (since we don't model 1176).
> 
> Also, the format of the PAR is different in 1176/11MPcore!
> (in the comments below I'm generally talking about the v7
> format, not 1176/mpcore).

I tried to add this too, should just be two more if expressions.

> > +            switch (crm) {
> > +            case 4:
> > +                env->cp15.c7_par = val;
> 
> We shouldn't be allowing the reserved and impdef bits
> to be set here.

Ok.

> I think it would be cleaner to write:
>  access_type = op2 & 1;
>  is_user = op2 & 2;
>  other_sec_state = op2 & 4;
>  if (other_sec_state) {
> /* Only supported with TrustZone */
> goto bad_reg;
>  }
> 
> rather than have this big switch statement.

Good idea.

> > +                ret = get_phys_addr_v6(env, val, access_type, is_user,
> > +                                       &phys_addr, &prot, &page_size);
> 
> This will do the wrong thing when the MMU is disabled,
> and it doesn't account for the FSCE either. I think that
> just using get_phys_addr() will fix both of these.
> 
> > +                if (ret == 0) {
> > +                    env->cp15.c7_par = phys_addr;
> 
> You need to mask out bits [11..0] of phys_addr here:
> if the caller passed in a VA with them set then
> get_phys_addr* will pass them back out to you again.
> 
> Also we ought ideally to be setting the various
> attributes bits based on the TLB entry, although
> I appreciate that since qemu doesn't currently do
> any of that decoding it would be a bit tedious to
> have to add it just for the benefit of VA-PA translation.

So for the time being a comment is ok?

> > +                    if (page_size > TARGET_PAGE_SIZE)
> > +                        env->cp15.c7_par |= 1 << 1;
> 
> This isn't correct: the SS bit should only be set if this
> was a SuperSection, not for anything larger than a page.
> (And if it is a SuperSection then the meaning of the
> PAR PA field changes, which for us means that we
> need to zero bits [23:12] since we don't support
> >32bit physaddrs.)
> 
> Also, coding style mandates braces.

Ok.

> > +                } else {
> > +                    env->cp15.c7_par = ret | 1;
> 
> This isn't quite right -- the return value from
> get_phys_addr*() is in the same format as the
> DFSR (eg with the domain in bits [7:4]), and
> the PAR bits [6:1] should be the equivalent
> of DFSR bits [12,10,3:0]. So you need a bit
> of shifting and masking here.
> 
> > @@ -1789,6 +1833,9 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t 
> > insn)
> >            }
> >         }
> >     case 7: /* Cache control.  */
> > +        if (crm == 4 && op2 == 0) {
> > +            return env->cp15.c7_par;
> > +        }
> 
> Again, we want op1 == 0 as well.

Ok.

I'm not really sure about the cp15.c15_i_max and cp15.c15_i_min, they
only seem to be used with ARM_FEATURE_OMAPCP so an if could be put
around them.

New version:
 Subject: [PATCH 2/3] target-arm: Implement cp15 VA->PA translation

Implement VA->PA translations by cp15-c7 that went through unchanged
previously.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/cpu.h |1 +
 target-arm/helper.c  |   48 ++--
 target-arm/machine.c |2 ++
 3 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c9febfa..603574b 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -126,6 +126,7 @@ typedef stru

Re: [Qemu-devel] [PATCH 1/3] target-arm: Setup smpboot code in all setups

2011-02-15 Thread Adam Lackorzynski
Hi,

On Tue Feb 15, 2011 at 10:02:05 -0500, Vincent Palatin wrote:
> >> Moving in the right direction, but it would be cleaner if the secondary
> >> CPU reset was handled inside arm_boot.c, I think (there is a TODO
> >> in that file to that effect). Then we could get rid of the cpu reset
> >> hook from realview.c.
> >
> > Like the following?
> 
> This assumes that all the ARM SMP platforms are booting their
> secondary CPU the same way as the emulated Realview.
> For example, I'm currently writing a Tegra2 (dual A9) SoC emulation
> and the second CPU is halted when the platform starts and I cannot
> re-use the current smpboot firmware chunk. My current workaround is to
> use "info->nb_cpus = 1" and do the init in the board code. Forcing the
> reset function will probably not help.

The smpboot code also halts the CPUs, i.e. they are waiting in wfi.
What would you like to have instead? Maybe it's not so different...


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



Re: [Qemu-devel] [PATCH 1/3] target-arm: Setup smpboot code in all setups

2011-02-15 Thread Adam Lackorzynski

On Tue Feb 15, 2011 at 13:37:44 +, Peter Maydell wrote:
> On 15 February 2011 13:12, Adam Lackorzynski  
> wrote:
> >
> > On Tue Feb 15, 2011 at 13:01:08 +, Peter Maydell wrote:
> >> On 15 February 2011 10:48, Adam Lackorzynski  
> >> wrote:
> >> > Make smpboot available not only for Linux but for all setups.
> >>
> >> I'm not convinced about this. I think if you're providing a raw
> >> image for an SMP system (rather than a Linux kernel) then it's
> >> your job to provide an image which handles the bootup of the
> >> secondary CPUs, the same way it would be if you were providing
> >> a ROM image for real hardware.
> >
> > Ok, this is one possibility. Another one would be something like this:
> 
> > @@ -112,7 +112,11 @@ static void secondary_cpu_reset(void *opaque)
> >   /* Set entry point for secondary CPUs.  This assumes we're using
> >      the init code from arm_boot.c.  Real hardware resets all CPUs
> >      the same.  */
> > -  env->regs[15] = SMP_BOOT_ADDR;
> > +  if (realview_binfo.is_linux) {
> > +      env->regs[15] = SMP_BOOT_ADDR;
> > +  } else {
> > +      env->regs[15] = realview_binfo.entry;
> > +  }
> >  }
> 
> Moving in the right direction, but it would be cleaner if the secondary
> CPU reset was handled inside arm_boot.c, I think (there is a TODO
> in that file to that effect). Then we could get rid of the cpu reset
> hook from realview.c.

Like the following?

 Subject: [PATCH] target-arm: Integrate secondary CPU reset in arm_boot

Integrate secondary CPU reset into arm_boot, removing it from realview.c.
On non-Linux systems secondary CPUs start with the same entry as the boot
CPU.

Signed-off-by: Adam Lackorzynski 
---
 hw/arm_boot.c |   23 +++
 hw/realview.c |   14 --
 2 files changed, 15 insertions(+), 22 deletions(-)

diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 620550b..41e99d1 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -175,7 +175,7 @@ static void set_kernel_args_old(struct arm_boot_info *info,
 }
 }
 
-static void main_cpu_reset(void *opaque)
+static void do_cpu_reset(void *opaque)
 {
 CPUState *env = opaque;
 struct arm_boot_info *info = env->boot_info;
@@ -187,16 +187,20 @@ static void main_cpu_reset(void *opaque)
 env->regs[15] = info->entry & 0xfffe;
 env->thumb = info->entry & 1;
 } else {
-env->regs[15] = info->loader_start;
-if (old_param) {
-set_kernel_args_old(info, info->initrd_size,
+if (env == first_cpu) {
+env->regs[15] = info->loader_start;
+if (old_param) {
+set_kernel_args_old(info, info->initrd_size,
+info->loader_start);
+} else {
+set_kernel_args(info, info->initrd_size,
 info->loader_start);
+}
 } else {
-set_kernel_args(info, info->initrd_size, info->loader_start);
+env->regs[15] = info->smp_loader_start;
 }
 }
 }
-/* TODO:  Reset secondary CPUs.  */
 }
 
 void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
@@ -217,7 +221,6 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info 
*info)
 
 if (info->nb_cpus == 0)
 info->nb_cpus = 1;
-env->boot_info = info;
 
 #ifdef TARGET_WORDS_BIGENDIAN
 big_endian = 1;
@@ -279,5 +282,9 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info 
*info)
 info->initrd_size = initrd_size;
 }
 info->is_linux = is_linux;
-qemu_register_reset(main_cpu_reset, env);
+
+for (; env; env = env->next_cpu) {
+env->boot_info = info;
+qemu_register_reset(do_cpu_reset, env);
+}
 }
diff --git a/hw/realview.c b/hw/realview.c
index 6eb6c6a..fae444a 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -104,17 +104,6 @@ static struct arm_boot_info realview_binfo = {
 .smp_loader_start = SMP_BOOT_ADDR,
 };
 
-static void secondary_cpu_reset(void *opaque)
-{
-  CPUState *env = opaque;
-
-  cpu_reset(env);
-  /* Set entry point for secondary CPUs.  This assumes we're using
- the init code from arm_boot.c.  Real hardware resets all CPUs
- the same.  */
-  env->regs[15] = SMP_BOOT_ADDR;
-}
-
 /* The following two lists must be consistent.  */
 enum realview_board_type {
 BOARD_EB,
@@ -176,9 +165,6 @@ static void realview_init(ram_addr_t ram_size,
 }
 irqp = arm_pic_init_cpu(env);
 cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
-if (n > 0) {
-qemu_register_reset(secondary_cpu_reset, env);
-}
 }
 if (arm_feature(env, ARM_FEATURE_V7)) {
 if (is_mpcore) {
-- 
1.7.2.3


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



Re: [Qemu-devel] [PATCH 1/3] target-arm: Setup smpboot code in all setups

2011-02-15 Thread Adam Lackorzynski

On Tue Feb 15, 2011 at 13:01:08 +, Peter Maydell wrote:
> On 15 February 2011 10:48, Adam Lackorzynski  
> wrote:
> > Make smpboot available not only for Linux but for all setups.
> 
> I'm not convinced about this. I think if you're providing a raw
> image for an SMP system (rather than a Linux kernel) then it's
> your job to provide an image which handles the bootup of the
> secondary CPUs, the same way it would be if you were providing
> a ROM image for real hardware.

Ok, this is one possibility. Another one would be something like this:

 Subject: [PATCH] target-arm: Provide entry vector for non-linux systems

Non-Linux systems must provide their own code for secondary CPU boot-up.
We use the same entry point as on the first CPU.

Signed-off-by: Adam Lackorzynski 
---
 hw/realview.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/hw/realview.c b/hw/realview.c
index 6eb6c6a..574bc11 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -112,7 +112,11 @@ static void secondary_cpu_reset(void *opaque)
   /* Set entry point for secondary CPUs.  This assumes we're using
  the init code from arm_boot.c.  Real hardware resets all CPUs
  the same.  */
-  env->regs[15] = SMP_BOOT_ADDR;
+  if (realview_binfo.is_linux) {
+  env->regs[15] = SMP_BOOT_ADDR;
+  } else {
+  env->regs[15] = realview_binfo.entry;
+  }
 }
 
 /* The following two lists must be consistent.  */
-- 
1.7.2.3


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH 3/3] target-arm: Implement cp15 VA->PA translation

2011-02-15 Thread Adam Lackorzynski

Implement VA->PA translations by cp15-c7 that went through unchanged
previously.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/cpu.h|1 +
 target-arm/helper.c |   51 +--
 2 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c9febfa..603574b 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -126,6 +126,7 @@ typedef struct CPUARMState {
 uint32_t c6_region[8]; /* MPU base/size registers.  */
 uint32_t c6_insn; /* Fault address registers.  */
 uint32_t c6_data;
+uint32_t c7_par;  /* Translation result. */
 uint32_t c9_insn; /* Cache lockdown registers.  */
 uint32_t c9_data;
 uint32_t c13_fcse; /* FCSE PID.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7f63a28..32cc795 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1456,8 +1456,52 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, 
uint32_t val)
 case 7: /* Cache control.  */
 env->cp15.c15_i_max = 0x000;
 env->cp15.c15_i_min = 0xff0;
-/* No cache, so nothing to do.  */
-/* ??? MPCore has VA to PA translation functions.  */
+/* No cache, so nothing to do except VA->PA translations. */
+if (arm_feature(env, ARM_FEATURE_V6)) {
+switch (crm) {
+case 4:
+env->cp15.c7_par = val;
+break;
+case 8: {
+uint32_t phys_addr;
+target_ulong page_size;
+int prot;
+int ret, is_user;
+int access_type;
+
+switch (op2) {
+case 0: /* priv read */
+is_user = 0;
+access_type = 0;
+break;
+case 1: /* priv write */
+is_user = 0;
+access_type = 1;
+break;
+case 2: /* user read */
+is_user = 1;
+access_type = 0;
+break;
+case 3: /* user write */
+is_user = 1;
+access_type = 1;
+break;
+default: /* 4-7 are only available with TZ */
+goto bad_reg;
+}
+ret = get_phys_addr_v6(env, val, access_type, is_user,
+   &phys_addr, &prot, &page_size);
+if (ret == 0) {
+env->cp15.c7_par = phys_addr;
+if (page_size > TARGET_PAGE_SIZE)
+env->cp15.c7_par |= 1 << 1;
+} else {
+env->cp15.c7_par = ret | 1;
+}
+break;
+}
+}
+}
 break;
 case 8: /* MMU TLB control.  */
 switch (op2) {
@@ -1789,6 +1833,9 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
}
 }
 case 7: /* Cache control.  */
+if (crm == 4 && op2 == 0) {
+return env->cp15.c7_par;
+}
 /* FIXME: Should only clear Z flag if destination is r15.  */
 env->ZF = 0;
 return 0;
-- 
1.7.2.3


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH 2/3] target-arm: Fix soft interrupt in GIC distributor

2011-02-15 Thread Adam Lackorzynski
Fix selection of target list filter mode.

Signed-off-by: Adam Lackorzynski 
---
 hw/arm_gic.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index e6b1953..0e934ec 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -549,10 +549,10 @@ static void gic_dist_writel(void *opaque, 
target_phys_addr_t offset,
 mask = (value >> 16) & ALL_CPU_MASK;
 break;
 case 1:
-mask = 1 << cpu;
+mask = ALL_CPU_MASK ^ (1 << cpu);
 break;
 case 2:
-mask = ALL_CPU_MASK ^ (1 << cpu);
+mask = 1 << cpu;
 break;
 default:
 DPRINTF("Bad Soft Int target filter\n");
-- 
1.7.2.3


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH 1/3] target-arm: Setup smpboot code in all setups

2011-02-15 Thread Adam Lackorzynski
Make smpboot available not only for Linux but for all setups.

Signed-off-by: Adam Lackorzynski 
---
 hw/arm_boot.c |   17 +
 1 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 620550b..a68b396 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -268,16 +268,17 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info 
*info)
 }
 rom_add_blob_fixed("bootloader", bootloader, sizeof(bootloader),
info->loader_start);
-if (info->nb_cpus > 1) {
-smpboot[10] = info->smp_priv_base;
-for (n = 0; n < sizeof(smpboot) / 4; n++) {
-smpboot[n] = tswap32(smpboot[n]);
-}
-rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
-   info->smp_loader_start);
-}
 info->initrd_size = initrd_size;
 }
+
+if (info->nb_cpus > 1) {
+smpboot[10] = info->smp_priv_base;
+for (n = 0; n < sizeof(smpboot) / 4; n++) {
+smpboot[n] = tswap32(smpboot[n]);
+}
+rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
+   info->smp_loader_start);
+}
 info->is_linux = is_linux;
 qemu_register_reset(main_cpu_reset, env);
 }
-- 
1.7.2.3


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] multiboot: Prevent loading of x86_64 images

2010-11-04 Thread Adam Lackorzynski

A via -kernel supplied x86_64 ELF image is being started in 32bit mode.
Detect and exit if a 64bit image has been supplied.

Signed-off-by: Adam Lackorzynski 
Acked-by: Alexander Graf 
---
 hw/multiboot.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index f9097a2..e710bbb 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -171,6 +171,12 @@ int load_multiboot(void *fw_cfg,
 uint64_t elf_low, elf_high;
 int kernel_size;
 fclose(f);
+
+if (((struct elf64_hdr*)header)->e_machine == EM_X86_64) {
+fprintf(stderr, "Cannot load x86-64 image, give a 32bit one.\n");
+exit(1);
+}
+
 kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,
&elf_low, &elf_high, 0, ELF_MACHINE, 0);
 if (kernel_size < 0) {
-- 
1.7.2.3


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] target-arm: Handle 'smc' as an undefined instruction

2010-11-04 Thread Adam Lackorzynski

Refine check on bkpt so that smc and undefined instruction encodings are
handled as an undefined instruction and trap.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/translate.c |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 99464ab..c7283e3 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6346,7 +6346,14 @@ static void disas_arm_insn(CPUState * env, DisasContext 
*s)
 dead_tmp(tmp2);
 store_reg(s, rd, tmp);
 break;
-case 7: /* bkpt */
+case 7:
+/* SMC instruction (op1 == 3)
+   and undefined instructions (op1 == 0 || op1 == 2)
+   will trap */
+if (op1 != 1) {
+goto illegal_op;
+}
+/* bkpt */
 gen_set_condexec(s);
 gen_set_pc_im(s->pc - 4);
 gen_exception(EXCP_BKPT);
-- 
1.7.2.3


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] multiboot: Prevent loading of x86_64 images

2010-09-25 Thread Adam Lackorzynski

A via -kernel supplied x86_64 ELF image is being started in 32bit mode.
Detect and exit if a 64bit image has been supplied.

Signed-off-by: Adam Lackorzynski 
Acked-by: Alexander Graf 
---
 hw/multiboot.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index f9097a2..e710bbb 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -171,6 +171,12 @@ int load_multiboot(void *fw_cfg,
 uint64_t elf_low, elf_high;
 int kernel_size;
 fclose(f);
+
+if (((struct elf64_hdr*)header)->e_machine == EM_X86_64) {
+fprintf(stderr, "Cannot load x86-64 image, give a 32bit one.\n");
+exit(1);
+}
+
 kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,
&elf_low, &elf_high, 0, ELF_MACHINE, 0);
 if (kernel_size < 0) {
-- 
1.7.1


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] target-arm: Handle 'smc' as an undefined instruction

2010-09-25 Thread Adam Lackorzynski

Refine check on bkpt so that smc and undefined instruction encodings are
handled as an undefined instruction and trap.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/translate.c |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6fcdd7e..9ac1f8b 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6346,7 +6346,14 @@ static void disas_arm_insn(CPUState * env, DisasContext 
*s)
 dead_tmp(tmp2);
 store_reg(s, rd, tmp);
 break;
-case 7: /* bkpt */
+case 7:
+/* SMC instruction (op1 == 3)
+   and undefined instructions (op1 == 0 || op1 == 2)
+   will trap */
+if (op1 != 1) {
+goto illegal_op;
+}
+/* bkpt */
 gen_set_condexec(s);
 gen_set_pc_im(s->pc - 4);
 gen_exception(EXCP_BKPT);
-- 
1.7.1


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



Re: [Qemu-devel] [PATCH] target-arm: Handle 'smc' as an undefined instruction

2010-09-02 Thread Adam Lackorzynski

On Thu Sep 02, 2010 at 23:14:23 +0100, Peter Maydell wrote:
> On Thu, Sep 02, 2010 at 11:40:50PM +0200, Adam Lackorzynski wrote:
> > +case 7:
> > +/* SMC? */
> > +if ((insn & 0xfff0) == 0xe1600070) {
> > +goto illegal_op;
> > +}
> > +/* bkpt */
> 
> This doesn't look right to me. SMC in the ARM encoding is a standard
> conditionalised instruction, so you shouldn't be mandating that the
> cond field is 0xe.

True.

> I think the correct way to distinguish BKPT from SMC is to look at
> bits [22..21] of the instruction: 01 for BKPT, 11 for SMC and
> other combinations are UNDEFINED. This is in 'op1' at this point
> in the code...

target-arm: Handle 'smc' as an undefined instruction

Refine check on bkpt so that smc is handled as an undefined instruction.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/translate.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6fcdd7e..fac4f5d 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6346,7 +6346,11 @@ static void disas_arm_insn(CPUState * env, DisasContext 
*s)
 dead_tmp(tmp2);
 store_reg(s, rd, tmp);
 break;
-case 7: /* bkpt */
+case 7:
+if (op1 != 1) {
+goto illegal_op;
+}
+/* bkpt */
 gen_set_condexec(s);
 gen_set_pc_im(s->pc - 4);
 gen_exception(EXCP_BKPT);
-- 
1.7.1


Thanks,
Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] target-arm: Handle 'smc' as an undefined instruction

2010-09-02 Thread Adam Lackorzynski
Handle smc as an undefined instruction instead of having it wrongly
interpreted as some other one.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/translate.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6fcdd7e..c1d55ed 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6346,7 +6346,12 @@ static void disas_arm_insn(CPUState * env, DisasContext 
*s)
 dead_tmp(tmp2);
 store_reg(s, rd, tmp);
 break;
-case 7: /* bkpt */
+case 7:
+/* SMC? */
+if ((insn & 0xfff0) == 0xe1600070) {
+goto illegal_op;
+}
+/* bkpt */
 gen_set_condexec(s);
 gen_set_pc_im(s->pc - 4);
 gen_exception(EXCP_BKPT);
-- 
1.7.1



[Qemu-devel] [PATCH] multiboot: Prevent loading of x86_64 images

2010-09-02 Thread Adam Lackorzynski

A via -kernel supplied x86_64 ELF image is being started in 32bit mode.
Detect and exit if a 64bit image has been supplied.

Signed-off-by: Adam Lackorzynski 
Acked-by: Alexander Graf 
---
 hw/multiboot.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index dc980e6..e9dcbc9 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -171,6 +171,12 @@ int load_multiboot(void *fw_cfg,
 uint64_t elf_low, elf_high;
 int kernel_size;
 fclose(f);
+
+if (((struct elf64_hdr*)header)->e_machine == EM_X86_64) {
+fprintf(stderr, "Cannot load x86-64 image, give a 32bit one.\n");
+exit(1);
+}
+
 kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,
&elf_low, &elf_high, 0, ELF_MACHINE, 0);
 if (kernel_size < 0) {
-- 
1.7.1



[Qemu-devel] [PATCH] target-arm: Handle 'smc' as an undefined instruction

2010-09-02 Thread Adam Lackorzynski

Handle smc as an undefined instruction instead of having it wrongly
interpreted as some other one.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/translate.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6fcdd7e..9b5d650 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6346,7 +6346,11 @@ static void disas_arm_insn(CPUState * env, DisasContext 
*s)
 dead_tmp(tmp2);
 store_reg(s, rd, tmp);
 break;
-case 7: /* bkpt */
+case 7:
+/* SMC? */
+if ((insn & 0xfff0) == 0xe1600070)
+  goto illegal_op;
+/* bkpt */
 gen_set_condexec(s);
 gen_set_pc_im(s->pc - 4);
 gen_exception(EXCP_BKPT);
-- 
1.7.1



Re: [Qemu-devel] [PATCH] multiboot: Prevent loading of x86_64 images

2010-08-19 Thread Adam Lackorzynski

On Thu Aug 19, 2010 at 14:34:10 +0200, Alexander Graf wrote:
> 
> On 19.08.2010, at 14:32, Adam Lackorzynski wrote:
> 
> > 
> > On Thu Aug 19, 2010 at 13:40:54 +0200, Alexander Graf wrote:
> >> 
> >> On 19.08.2010, at 13:36, Adam Lackorzynski wrote:
> >> 
> >>> 
> >>> On Thu Aug 19, 2010 at 13:27:32 +0200, Alexander Graf wrote:
> >>>> 
> >>>> On 19.08.2010, at 13:24, Adam Lackorzynski wrote:
> >>>> 
> >>>>> A via -kernel supplied x86_64 ELF image is being started in 32bit mode.
> >>>>> Detect and exit if a 64bit image has been supplied.
> >>>> 
> >>>> According to the multiboot spec, this is the expected behavior, no? At 
> >>>> least Xen does it that way...
> >>> 
> >>> Yes, but then the supplied ELF-image should say it's a 32bit one and
> >>> switch to 64bit mode itself. That's at least how we do load a 64bit
> >>> kernel.
> >> 
> >> Hrm - maybe you're right:
> >> 
> >> busu:~ # readelf -a /boot/xen
> >> ELF Header:
> >>  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
> >>  Class: ELF32
> >> 
> >> What does the spec say here? What does grub do?
> > 
> > Grub starts the (multiboot-)OS in 32bit mode. Starting directly in 64bit
> > mode would require to setup page-tables etc. which is not done.
> > The Spec doesn't mention 64bit OS at all, and says that 32bit OSs are
> > fine ("An OS image may be an ordinary 32-bit executable file in the
> > standard format for that particular operating system, except that it may
> > be linked at a non-default load address to avoid loading on top of the
> > ...");
> 
> I think we should do the same grub does here. If grub loads 64-bit elf
> binaries and runs them in 32-bit mode, we should too. If it refuses to
> load them, we should too.

grub1:

grub> kernel (nd)/tftpboot/adam/bootstrap.elf  

Error 13: Invalid or unsupported executable format

grub>


grub2 loads it but then it crashes and reboots. Looks like a bug to me.



Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



Re: [Qemu-devel] [PATCH] multiboot: Prevent loading of x86_64 images

2010-08-19 Thread Adam Lackorzynski

On Thu Aug 19, 2010 at 13:40:54 +0200, Alexander Graf wrote:
> 
> On 19.08.2010, at 13:36, Adam Lackorzynski wrote:
> 
> > 
> > On Thu Aug 19, 2010 at 13:27:32 +0200, Alexander Graf wrote:
> >> 
> >> On 19.08.2010, at 13:24, Adam Lackorzynski wrote:
> >> 
> >>> A via -kernel supplied x86_64 ELF image is being started in 32bit mode.
> >>> Detect and exit if a 64bit image has been supplied.
> >> 
> >> According to the multiboot spec, this is the expected behavior, no? At 
> >> least Xen does it that way...
> > 
> > Yes, but then the supplied ELF-image should say it's a 32bit one and
> > switch to 64bit mode itself. That's at least how we do load a 64bit
> > kernel.
> 
> Hrm - maybe you're right:
> 
> busu:~ # readelf -a /boot/xen
> ELF Header:
>   Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
>   Class: ELF32
> 
> What does the spec say here? What does grub do?

Grub starts the (multiboot-)OS in 32bit mode. Starting directly in 64bit
mode would require to setup page-tables etc. which is not done.
The Spec doesn't mention 64bit OS at all, and says that 32bit OSs are
fine ("An OS image may be an ordinary 32-bit executable file in the
standard format for that particular operating system, except that it may
be linked at a non-default load address to avoid loading on top of the
...");




Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



Re: [Qemu-devel] [PATCH] multiboot: Prevent loading of x86_64 images

2010-08-19 Thread Adam Lackorzynski

On Thu Aug 19, 2010 at 13:27:32 +0200, Alexander Graf wrote:
> 
> On 19.08.2010, at 13:24, Adam Lackorzynski wrote:
> 
> > A via -kernel supplied x86_64 ELF image is being started in 32bit mode.
> > Detect and exit if a 64bit image has been supplied.
> 
> According to the multiboot spec, this is the expected behavior, no? At least 
> Xen does it that way...

Yes, but then the supplied ELF-image should say it's a 32bit one and
switch to 64bit mode itself. That's at least how we do load a 64bit
kernel.



Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] multiboot: Prevent loading of x86_64 images

2010-08-19 Thread Adam Lackorzynski
A via -kernel supplied x86_64 ELF image is being started in 32bit mode.
Detect and exit if a 64bit image has been supplied.

Signed-off-by: Adam Lackorzynski 
---
 hw/multiboot.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index dc980e6..e9dcbc9 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -171,6 +171,12 @@ int load_multiboot(void *fw_cfg,
 uint64_t elf_low, elf_high;
 int kernel_size;
 fclose(f);
+
+if (((struct elf64_hdr*)header)->e_machine == EM_X86_64) {
+fprintf(stderr, "Cannot load x86-64 image, give a 32bit one.\n");
+exit(1);
+}
+
 kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,
&elf_low, &elf_high, 0, ELF_MACHINE, 0);
 if (kernel_size < 0) {
-- 
1.7.1


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] target-i386: svm: Fix MSRPM check

2010-08-15 Thread Adam Lackorzynski

Correct the calculation of the offset in the msrpm
for the MSR range 0 - 0x1fff.

Signed-off-by: Adam Lackorzynski 
---
 target-i386/op_helper.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index c50e818..ec6b3e9 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -5237,7 +5237,7 @@ void helper_svm_check_intercept_param(uint32_t type, 
uint64_t param)
 switch((uint32_t)ECX) {
 case 0 ... 0x1fff:
 t0 = (ECX * 2) % 8;
-t1 = ECX / 8;
+t1 = (ECX * 2) / 8;
 break;
 case 0xc000 ... 0xc0001fff:
 t0 = (8192 + ECX - 0xc000) * 2;
-- 
1.7.1



[Qemu-devel] [PATCH] Resend-3: target-arm: Handle 'smc' as an undefined instruction

2010-08-02 Thread Adam Lackorzynski
Handle smc as an undefined instruction instead of having it wrongly
interpreted as some other one.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/translate.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6fcdd7e..9b5d650 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6346,7 +6346,11 @@ static void disas_arm_insn(CPUState * env, DisasContext 
*s)
 dead_tmp(tmp2);
 store_reg(s, rd, tmp);
 break;
-case 7: /* bkpt */
+case 7:
+/* SMC? */
+if ((insn & 0xfff0) == 0xe1600070)
+  goto illegal_op;
+/* bkpt */
 gen_set_condexec(s);
 gen_set_pc_im(s->pc - 4);
 gen_exception(EXCP_BKPT);
-- 
1.7.1




[Qemu-devel] [PATCH] Resend: target-arm: Handle 'smc' as an undefined instruction

2010-07-04 Thread Adam Lackorzynski
Handle smc as an undefined instruction instead of having it wrongly
interpreted as some other one.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/translate.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6fcdd7e..9b5d650 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6346,7 +6346,11 @@ static void disas_arm_insn(CPUState * env, DisasContext 
*s)
 dead_tmp(tmp2);
 store_reg(s, rd, tmp);
 break;
-case 7: /* bkpt */
+case 7:
+/* SMC? */
+if ((insn & 0xfff0) == 0xe1600070)
+  goto illegal_op;
+/* bkpt */
 gen_set_condexec(s);
 gen_set_pc_im(s->pc - 4);
 gen_exception(EXCP_BKPT);
-- 
1.7.1



[Qemu-devel] [PATCH] target-arm: Handle 'smc' as an undefined instruction

2010-06-04 Thread Adam Lackorzynski

Handle smc as undefined instruction instead of having it wrongly interpreted
as some other instruction.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/translate.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 0eccca5..afd6716 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6344,7 +6344,11 @@ static void disas_arm_insn(CPUState * env, DisasContext 
*s)
 dead_tmp(tmp2);
 store_reg(s, rd, tmp);
 break;
-case 7: /* bkpt */
+case 7:
+/* SMC? */
+if ((insn & 0xfff0) == 0xe1600070)
+  goto illegal_op;
+/* bkpt */
 gen_set_condexec(s);
 gen_set_pc_im(s->pc - 4);
 gen_exception(EXCP_BKPT);
-- 
1.7.1




[Qemu-devel] [PATCH] target-arm: Handle 'smc' as an undefined instruction

2010-05-10 Thread Adam Lackorzynski


Signed-off-by: Adam Lackorzynski 
---
 target-arm/translate.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 0eccca5..afd6716 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6344,7 +6344,11 @@ static void disas_arm_insn(CPUState * env, DisasContext 
*s)
 dead_tmp(tmp2);
 store_reg(s, rd, tmp);
 break;
-case 7: /* bkpt */
+case 7:
+/* SMC? */
+if ((insn & 0xfff0) == 0xe1600070)
+  goto illegal_op;
+/* bkpt */
 gen_set_condexec(s);
 gen_set_pc_im(s->pc - 4);
 gen_exception(EXCP_BKPT);
-- 
1.7.1


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/



[Qemu-devel] [PATCH] target-i386: Fix variable in (disabled) debugging code

2010-04-01 Thread Adam Lackorzynski

Signed-off-by: Adam Lackorzynski 
---
 target-i386/op_helper.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 22259df..dcbdfe7 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -1231,7 +1231,7 @@ void do_interrupt(int intno, int is_int, int error_code,
 #if 0
 {
 int i;
-uint8_t *ptr;
+target_ulong ptr;
 qemu_log("   code=");
 ptr = env->segs[R_CS].base + env->eip;
 for(i = 0; i < 16; i++) {
-- 
1.7.0.3


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/




[Qemu-devel] [PATCH] Debugcon: Fix debugging printf

2010-04-01 Thread Adam Lackorzynski
Signed-off-by: Adam Lackorzynski 
---
 hw/debugcon.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/debugcon.c b/hw/debugcon.c
index d549091..5ee6821 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -60,7 +60,7 @@ static uint32_t debugcon_ioport_read(void *opaque, uint32_t 
addr)
 DebugconState *s = opaque;
 
 #ifdef DEBUG_DEBUGCON
-printf("debugcon: read addr=0x%04x\n", addr, val);
+printf("debugcon: read addr=0x%04x\n", addr);
 #endif
 
 return s->readback;
-- 
1.7.0.3


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/




[Qemu-devel] [PATCH] arm: make RFE usable with any register

2010-03-01 Thread Adam Lackorzynski
The rfe instruction can be used with any register, not just sp. Adjust the
condition check accordingly.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/translate.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 0c650b2..cdfe946 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6132,7 +6132,7 @@ static void disas_arm_insn(CPUState * env, DisasContext 
*s)
 dead_tmp(addr);
 }
 return;
-} else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
+} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
 /* rfe */
 int32_t offset;
 if (IS_USER(s))
-- 
1.7.0

Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/




[Qemu-devel] [PATCH] arm: Fix missing 'return' in SRS handling.

2010-03-01 Thread Adam Lackorzynski

There's a return missing in the srs handling which leads to srs always being
treated an an invalid op.

Signed-off-by: Adam Lackorzynski 
---
 target-arm/translate.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 9607aae..0c650b2 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6131,6 +6131,7 @@ static void disas_arm_insn(CPUState * env, DisasContext 
*s)
 } else {
 dead_tmp(addr);
 }
+return;
 } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
 /* rfe */
 int32_t offset;
-- 
1.7.0



Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/




[Qemu-devel] [PATCH 2/2] multiboot: Separate multiboot loading into separate file

2009-12-26 Thread Adam Lackorzynski
Move multiboot loading code into separate files as suggested by Alex Graf.

Signed-off-by: Adam Lackorzynski 
---
 Makefile.target |2 +-
 hw/multiboot.c  |  331 +++
 hw/multiboot.h  |   12 ++
 hw/pc.c |  305 +--
 4 files changed, 347 insertions(+), 303 deletions(-)
 create mode 100644 hw/multiboot.c
 create mode 100644 hw/multiboot.h

diff --git a/Makefile.target b/Makefile.target
index 7c1f30c..7f3e497 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -194,7 +194,7 @@ obj-i386-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o 
pcspk.o pc.o
 obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o
 obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o
 obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
-obj-i386-y += ne2000-isa.o
+obj-i386-y += ne2000-isa.o multiboot.o
 
 # shared objects
 obj-ppc-y = ppc.o ide/core.o ide/qdev.o ide/isa.o ide/pci.o ide/macio.o
diff --git a/hw/multiboot.c b/hw/multiboot.c
new file mode 100644
index 000..a25fbf6
--- /dev/null
+++ b/hw/multiboot.c
@@ -0,0 +1,331 @@
+/*
+ * QEMU PC System Emulator
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw.h"
+#include "fw_cfg.h"
+#include "multiboot.h"
+#include "loader.h"
+#include "elf.h"
+#include "sysemu.h"
+
+/* Show multiboot debug output */
+//#define DEBUG_MULTIBOOT
+
+#ifdef DEBUG_MULTIBOOT
+#define mb_debug(a...) fprintf(stderr, ## a)
+#else
+#define mb_debug(a...)
+#endif
+
+#define MULTIBOOT_STRUCT_ADDR 0x9000
+
+#if MULTIBOOT_STRUCT_ADDR > 0xf
+#error multiboot struct needs to fit in 16 bit real mode
+#endif
+
+enum {
+/* Multiboot info */
+MBI_FLAGS   = 0,
+MBI_MEM_LOWER   = 4,
+MBI_MEM_UPPER   = 8,
+MBI_BOOT_DEVICE = 12,
+MBI_CMDLINE = 16,
+MBI_MODS_COUNT  = 20,
+MBI_MODS_ADDR   = 24,
+MBI_MMAP_ADDR   = 48,
+
+MBI_SIZE= 88,
+
+/* Multiboot modules */
+MB_MOD_START= 0,
+MB_MOD_END  = 4,
+MB_MOD_CMDLINE  = 8,
+
+MB_MOD_SIZE = 16,
+
+/* Region offsets */
+ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
+ADDR_MBI  = ADDR_E820_MAP + 0x500,
+
+/* Multiboot flags */
+MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
+MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
+MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
+MULTIBOOT_FLAGS_MODULES = 1 << 3,
+MULTIBOOT_FLAGS_MMAP= 1 << 6,
+};
+
+typedef struct {
+/* buffer holding kernel, cmdlines and mb_infos */
+void *mb_buf;
+/* address in target */
+target_phys_addr_t mb_buf_phys;
+/* size of mb_buf in bytes */
+unsigned mb_buf_size;
+/* offset of mb-info's in bytes */
+target_phys_addr_t offset_mbinfo;
+/* offset in buffer for cmdlines in bytes */
+target_phys_addr_t offset_cmdlines;
+/* offset of modules in bytes */
+target_phys_addr_t offset_mods;
+/* available slots for mb modules infos */
+int mb_mods_avail;
+/* currently used slots of mb modules */
+int mb_mods_count;
+} MultibootState;
+
+static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
+{
+int len = strlen(cmdline) + 1;
+target_phys_addr_t p = s->offset_cmdlines;
+
+pstrcpy((char *)s->mb_buf + p, len, cmdline);
+s->offset_cmdlines += len;
+return s->mb_buf_phys + p;
+}
+
+static void mb_add_mod(MultibootState *s,
+   target_phys_addr_t start, target_phys_addr_t end,
+   target_phys_addr_t cmdline_phys)
+{
+char *p;
+assert(s->mb_mods_count < s->mb_mods_avail);
+
+p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_SIZE * s->mb_mods_count;
+
+stl_p(p + MB_MOD_START,   s

[Qemu-devel] [PATCH 1/2] multiboot: Support arbitrary number of modules.

2009-12-26 Thread Adam Lackorzynski
Signed-off-by: Adam Lackorzynski 
---
 hw/pc.c |  268 +++
 1 files changed, 167 insertions(+), 101 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 83f8dd0..2dca777 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -51,6 +51,12 @@
 /* Show multiboot debug output */
 //#define DEBUG_MULTIBOOT
 
+#ifdef DEBUG_MULTIBOOT
+#define mb_debug(a...) fprintf(stderr, ## a)
+#else
+#define mb_debug(a...)
+#endif
+
 #define BIOS_FILENAME "bios.bin"
 
 #define PC_MAX_BIOS_SIZE (4 * 1024 * 1024)
@@ -512,6 +518,85 @@ static long get_file_size(FILE *f)
 #error multiboot struct needs to fit in 16 bit real mode
 #endif
 
+enum {
+/* Multiboot info */
+MBI_FLAGS   = 0,
+MBI_MEM_LOWER   = 4,
+MBI_MEM_UPPER   = 8,
+MBI_BOOT_DEVICE = 12,
+MBI_CMDLINE = 16,
+MBI_MODS_COUNT  = 20,
+MBI_MODS_ADDR   = 24,
+MBI_MMAP_ADDR   = 48,
+
+MBI_SIZE= 88,
+
+/* Multiboot modules */
+MB_MOD_START= 0,
+MB_MOD_END  = 4,
+MB_MOD_CMDLINE  = 8,
+
+MB_MOD_SIZE = 16,
+
+/* Region offsets */
+ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
+ADDR_MBI  = ADDR_E820_MAP + 0x500,
+
+/* Multiboot flags */
+MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
+MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
+MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
+MULTIBOOT_FLAGS_MODULES = 1 << 3,
+MULTIBOOT_FLAGS_MMAP= 1 << 6,
+};
+
+typedef struct {
+/* buffer holding kernel, cmdlines and mb_infos */
+void *mb_buf;
+/* address in target */
+target_phys_addr_t mb_buf_phys;
+/* size of mb_buf in bytes */
+unsigned mb_buf_size;
+/* offset of mb-info's in bytes */
+target_phys_addr_t offset_mbinfo;
+/* offset in buffer for cmdlines in bytes */
+target_phys_addr_t offset_cmdlines;
+/* offset of modules in bytes */
+target_phys_addr_t offset_mods;
+/* available slots for mb modules infos */
+int mb_mods_avail;
+/* currently used slots of mb modules */
+int mb_mods_count;
+} MultibootState;
+
+static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
+{
+int len = strlen(cmdline) + 1;
+target_phys_addr_t p = s->offset_cmdlines;
+
+pstrcpy((char *)s->mb_buf + p, len, cmdline);
+s->offset_cmdlines += len;
+return s->mb_buf_phys + p;
+}
+
+static void mb_add_mod(MultibootState *s,
+   target_phys_addr_t start, target_phys_addr_t end,
+   target_phys_addr_t cmdline_phys)
+{
+char *p;
+assert(s->mb_mods_count < s->mb_mods_avail);
+
+p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_SIZE * s->mb_mods_count;
+
+stl_p(p + MB_MOD_START,   start);
+stl_p(p + MB_MOD_END, end);
+stl_p(p + MB_MOD_CMDLINE, cmdline_phys);
+
+mb_debug("mod%02d: %08x - %08x\n", s->mb_mods_count, start, end);
+
+s->mb_mods_count++;
+}
+
 static int load_multiboot(void *fw_cfg,
   FILE *f,
   const char *kernel_filename,
@@ -524,12 +609,8 @@ static int load_multiboot(void *fw_cfg,
 uint32_t mh_entry_addr;
 uint32_t mh_load_addr;
 uint32_t mb_kernel_size;
-uint32_t mmap_addr = MULTIBOOT_STRUCT_ADDR;
-uint32_t mb_bootinfo = MULTIBOOT_STRUCT_ADDR + 0x500;
-uint32_t mb_mod_end;
-uint8_t bootinfo[0x500];
-uint32_t cmdline = 0x200;
-uint8_t *mb_kernel_data;
+MultibootState mbs;
+uint8_t bootinfo[MBI_SIZE];
 uint8_t *mb_bootinfo_data;
 
 /* Ok, let's see if it is a multiboot image.
@@ -550,10 +631,9 @@ static int load_multiboot(void *fw_cfg,
 if (!is_multiboot)
 return 0; /* no multiboot */
 
-#ifdef DEBUG_MULTIBOOT
-fprintf(stderr, "qemu: I believe we found a multiboot image!\n");
-#endif
+mb_debug("qemu: I believe we found a multiboot image!\n");
 memset(bootinfo, 0, sizeof(bootinfo));
+memset(&mbs, 0, sizeof(mbs));
 
 if (flags & 0x0004) { /* MULTIBOOT_HEADER_HAS_VBE */
 fprintf(stderr, "qemu: multiboot knows VBE. we don't.\n");
@@ -573,24 +653,18 @@ static int load_multiboot(void *fw_cfg,
 mb_kernel_size = elf_high - elf_low;
 mh_entry_addr = elf_entry;
 
-mb_kernel_data = qemu_malloc(mb_kernel_size);
-if (rom_copy(mb_kernel_data, mh_load_addr, mb_kernel_size) != 
mb_kernel_size) {
+mbs.mb_buf = qemu_malloc(mb_kernel_size);
+if (rom_copy(mbs.mb_buf, mh_load_addr, mb_kernel_size) != 
mb_kernel_size) {
 fprintf(stderr, "Error while fetching elf kernel from rom\n");
 exit(1);
 }
 
-#ifdef DEBUG_MULTIBOOT
-fprintf(stderr, "qemu: loading multiboot-elf kernel (%#x bytes) with 
entry %#zx\n",
-mb_kernel_size, (size_t)mh_entry_addr);
-#endif
+mb_debug("qemu: loadi

[Qemu-devel] [PATCH 2/2] multiboot: Separate multiboot loading into separate file

2009-12-18 Thread Adam Lackorzynski
multiboot: Separate multiboot loading into separate file

Move multiboot loading code into a separate file as suggested by Alex Graf.

Signed-off-by: Adam Lackorzynski 
---
 Makefile.target |2 +-
 hw/multiboot.c  |  326 +++
 hw/multiboot.h  |   12 ++
 hw/pc.c |  302 +--
 4 files changed, 342 insertions(+), 300 deletions(-)
 create mode 100644 hw/multiboot.c
 create mode 100644 hw/multiboot.h

diff --git a/Makefile.target b/Makefile.target
index 7c1f30c..7f3e497 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -194,7 +194,7 @@ obj-i386-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o 
pcspk.o pc.o
 obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o
 obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o
 obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
-obj-i386-y += ne2000-isa.o
+obj-i386-y += ne2000-isa.o multiboot.o
 
 # shared objects
 obj-ppc-y = ppc.o ide/core.o ide/qdev.o ide/isa.o ide/pci.o ide/macio.o
diff --git a/hw/multiboot.c b/hw/multiboot.c
new file mode 100644
index 000..04d224e
--- /dev/null
+++ b/hw/multiboot.c
@@ -0,0 +1,326 @@
+/*
+ * QEMU PC System Emulator
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw.h"
+#include "fw_cfg.h"
+#include "multiboot.h"
+#include "loader.h"
+#include "elf.h"
+#include "sysemu.h"
+
+/* Show multiboot debug output */
+//#define DEBUG_MULTIBOOT
+
+#ifdef DEBUG_MULTIBOOT
+#define mb_debug(a...) fprintf(stderr, ## a)
+#else
+#define mb_debug(a...)
+#endif
+
+#define MULTIBOOT_STRUCT_ADDR 0x9000
+
+#if MULTIBOOT_STRUCT_ADDR > 0xf
+#error multiboot struct needs to fit in 16 bit real mode
+#endif
+
+enum {
+/* Multiboot info */
+MBI_FLAGS   = 0,
+MBI_MEM_LOWER   = 4,
+MBI_MEM_UPPER   = 8,
+MBI_BOOT_DEVICE = 12,
+MBI_CMDLINE = 16,
+MBI_MODS_COUNT  = 20,
+MBI_MODS_ADDR   = 24,
+MBI_MMAP_ADDR   = 48,
+
+MBI_SIZE= 88,
+
+/* Multiboot modules */
+MB_MOD_START= 0,
+MB_MOD_END  = 4,
+MB_MOD_CMDLINE  = 8,
+
+MB_MOD_SIZE = 16,
+
+/* Region offsets */
+ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
+ADDR_MBI  = ADDR_E820_MAP + 0x500,
+
+/* Multiboot flags */
+MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
+MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
+MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
+MULTIBOOT_FLAGS_MODULES = 1 << 3,
+MULTIBOOT_FLAGS_MMAP= 1 << 6,
+};
+
+typedef struct {
+/* buffer holding kernel, cmdlines and mb_infos */
+void *mb_buf;
+/* address in target */
+target_phys_addr_t mb_buf_phys;
+/* size of mb_buf in bytes */
+unsigned mb_buf_size;
+/* offset of mb-info's in bytes */
+target_phys_addr_t offset_mbinfo;
+/* offset in buffer for cmdlines in bytes */
+target_phys_addr_t offset_cmdlines;
+/* offset of modules in bytes */
+target_phys_addr_t offset_mods;
+/* available slots for mb modules infos */
+int mb_mods_avail;
+/* currently used slots of mb modules */
+int mb_mods_count;
+} MultibootState;
+
+static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
+{
+int len = strlen(cmdline) + 1;
+target_phys_addr_t p = s->offset_cmdlines;
+
+pstrcpy((char *)s->mb_buf + p, len, cmdline);
+s->offset_cmdlines += len;
+return s->mb_buf_phys + p;
+}
+
+static void mb_add_mod(MultibootState *s,
+   target_phys_addr_t start, target_phys_addr_t end,
+   target_phys_addr_t cmdline_phys)
+{
+char *p;
+assert(s->mb_mods_count < s->mb_mods_avail);
+
+p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_S

[Qemu-devel] [PATCH 1/2] multiboot: Support arbitrary number of modules.

2009-12-18 Thread Adam Lackorzynski
multiboot: Support arbitrary number of modules.

Signed-off-by: Adam Lackorzynski 
---
 hw/pc.c |  268 +++
 1 files changed, 167 insertions(+), 101 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index db7d58e..2f5b3a1 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -51,6 +51,12 @@
 /* Show multiboot debug output */
 //#define DEBUG_MULTIBOOT
 
+#ifdef DEBUG_MULTIBOOT
+#define mb_debug(a...) fprintf(stderr, ## a)
+#else
+#define mb_debug(a...)
+#endif
+
 #define BIOS_FILENAME "bios.bin"
 
 #define PC_MAX_BIOS_SIZE (4 * 1024 * 1024)
@@ -512,6 +518,85 @@ static long get_file_size(FILE *f)
 #error multiboot struct needs to fit in 16 bit real mode
 #endif
 
+enum {
+/* Multiboot info */
+MBI_FLAGS   = 0,
+MBI_MEM_LOWER   = 4,
+MBI_MEM_UPPER   = 8,
+MBI_BOOT_DEVICE = 12,
+MBI_CMDLINE = 16,
+MBI_MODS_COUNT  = 20,
+MBI_MODS_ADDR   = 24,
+MBI_MMAP_ADDR   = 48,
+
+MBI_SIZE= 88,
+
+/* Multiboot modules */
+MB_MOD_START= 0,
+MB_MOD_END  = 4,
+MB_MOD_CMDLINE  = 8,
+
+MB_MOD_SIZE = 16,
+
+/* Region offsets */
+ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
+ADDR_MBI  = ADDR_E820_MAP + 0x500,
+
+/* Multiboot flags */
+MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
+MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
+MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
+MULTIBOOT_FLAGS_MODULES = 1 << 3,
+MULTIBOOT_FLAGS_MMAP= 1 << 6,
+};
+
+typedef struct {
+/* buffer holding kernel, cmdlines and mb_infos */
+void *mb_buf;
+/* address in target */
+target_phys_addr_t mb_buf_phys;
+/* size of mb_buf in bytes */
+unsigned mb_buf_size;
+/* offset of mb-info's in bytes */
+target_phys_addr_t offset_mbinfo;
+/* offset in buffer for cmdlines in bytes */
+target_phys_addr_t offset_cmdlines;
+/* offset of modules in bytes */
+target_phys_addr_t offset_mods;
+/* available slots for mb modules infos */
+int mb_mods_avail;
+/* currently used slots of mb modules */
+int mb_mods_count;
+} MultibootState;
+
+static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
+{
+int len = strlen(cmdline) + 1;
+target_phys_addr_t p = s->offset_cmdlines;
+
+pstrcpy((char *)s->mb_buf + p, len, cmdline);
+s->offset_cmdlines += len;
+return s->mb_buf_phys + p;
+}
+
+static void mb_add_mod(MultibootState *s,
+   target_phys_addr_t start, target_phys_addr_t end,
+   target_phys_addr_t cmdline_phys)
+{
+char *p;
+assert(s->mb_mods_count < s->mb_mods_avail);
+
+p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_SIZE * s->mb_mods_count;
+
+stl_p(p + MB_MOD_START,   start);
+stl_p(p + MB_MOD_END, end);
+stl_p(p + MB_MOD_CMDLINE, cmdline_phys);
+
+mb_debug("mod%02d: %08x - %08x\n", s->mb_mods_count, start, end);
+
+s->mb_mods_count++;
+}
+
 static int load_multiboot(void *fw_cfg,
   FILE *f,
   const char *kernel_filename,
@@ -524,12 +609,8 @@ static int load_multiboot(void *fw_cfg,
 uint32_t mh_entry_addr;
 uint32_t mh_load_addr;
 uint32_t mb_kernel_size;
-uint32_t mmap_addr = MULTIBOOT_STRUCT_ADDR;
-uint32_t mb_bootinfo = MULTIBOOT_STRUCT_ADDR + 0x500;
-uint32_t mb_mod_end;
-uint8_t bootinfo[0x500];
-uint32_t cmdline = 0x200;
-uint8_t *mb_kernel_data;
+MultibootState mbs;
+uint8_t bootinfo[MBI_SIZE];
 uint8_t *mb_bootinfo_data;
 
 /* Ok, let's see if it is a multiboot image.
@@ -550,10 +631,9 @@ static int load_multiboot(void *fw_cfg,
 if (!is_multiboot)
 return 0; /* no multiboot */
 
-#ifdef DEBUG_MULTIBOOT
-fprintf(stderr, "qemu: I believe we found a multiboot image!\n");
-#endif
+mb_debug("qemu: I believe we found a multiboot image!\n");
 memset(bootinfo, 0, sizeof(bootinfo));
+memset(&mbs, 0, sizeof(mbs));
 
 if (flags & 0x0004) { /* MULTIBOOT_HEADER_HAS_VBE */
 fprintf(stderr, "qemu: multiboot knows VBE. we don't.\n");
@@ -573,24 +653,18 @@ static int load_multiboot(void *fw_cfg,
 mb_kernel_size = elf_high - elf_low;
 mh_entry_addr = elf_entry;
 
-mb_kernel_data = qemu_malloc(mb_kernel_size);
-if (rom_copy(mb_kernel_data, mh_load_addr, mb_kernel_size) != 
mb_kernel_size) {
+mbs.mb_buf = qemu_malloc(mb_kernel_size);
+if (rom_copy(mbs.mb_buf, mh_load_addr, mb_kernel_size) != 
mb_kernel_size) {
 fprintf(stderr, "Error while fetching elf kernel from rom\n");
 exit(1);
 }
 
-#ifdef DEBUG_MULTIBOOT
-fprintf(stderr, "qemu: loading multiboot-elf kernel (%#x bytes) with 
entry %#zx\n",
-mb_kernel_size, (size_t)mh_entry_addr);
-#endi

[Qemu-devel] [PATCH 2/2] multiboot: Separate multiboot loading into separate file

2009-12-06 Thread Adam Lackorzynski

Move multiboot loading code into a separate files as suggested by Alex Graf.

Signed-off-by: Adam Lackorzynski 
---
 Makefile.target |2 +-
 hw/multiboot.c  |  326 +++
 hw/multiboot.h  |   12 ++
 hw/pc.c |  300 +--
 4 files changed, 342 insertions(+), 298 deletions(-)
 create mode 100644 hw/multiboot.c
 create mode 100644 hw/multiboot.h

diff --git a/Makefile.target b/Makefile.target
index 7c1f30c..7f3e497 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -194,7 +194,7 @@ obj-i386-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o 
pcspk.o pc.o
 obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o
 obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o
 obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
-obj-i386-y += ne2000-isa.o
+obj-i386-y += ne2000-isa.o multiboot.o
 
 # shared objects
 obj-ppc-y = ppc.o ide/core.o ide/qdev.o ide/isa.o ide/pci.o ide/macio.o
diff --git a/hw/multiboot.c b/hw/multiboot.c
new file mode 100644
index 000..04d224e
--- /dev/null
+++ b/hw/multiboot.c
@@ -0,0 +1,326 @@
+/*
+ * QEMU PC System Emulator
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw.h"
+#include "fw_cfg.h"
+#include "multiboot.h"
+#include "loader.h"
+#include "elf.h"
+#include "sysemu.h"
+
+/* Show multiboot debug output */
+//#define DEBUG_MULTIBOOT
+
+#ifdef DEBUG_MULTIBOOT
+#define mb_debug(a...) fprintf(stderr, ## a)
+#else
+#define mb_debug(a...)
+#endif
+
+#define MULTIBOOT_STRUCT_ADDR 0x9000
+
+#if MULTIBOOT_STRUCT_ADDR > 0xf
+#error multiboot struct needs to fit in 16 bit real mode
+#endif
+
+enum {
+/* Multiboot info */
+MBI_FLAGS   = 0,
+MBI_MEM_LOWER   = 4,
+MBI_MEM_UPPER   = 8,
+MBI_BOOT_DEVICE = 12,
+MBI_CMDLINE = 16,
+MBI_MODS_COUNT  = 20,
+MBI_MODS_ADDR   = 24,
+MBI_MMAP_ADDR   = 48,
+
+MBI_SIZE= 88,
+
+/* Multiboot modules */
+MB_MOD_START= 0,
+MB_MOD_END  = 4,
+MB_MOD_CMDLINE  = 8,
+
+MB_MOD_SIZE = 16,
+
+/* Region offsets */
+ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
+ADDR_MBI  = ADDR_E820_MAP + 0x500,
+
+/* Multiboot flags */
+MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
+MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
+MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
+MULTIBOOT_FLAGS_MODULES = 1 << 3,
+MULTIBOOT_FLAGS_MMAP= 1 << 6,
+};
+
+typedef struct {
+/* buffer holding kernel, cmdlines and mb_infos */
+void *mb_buf;
+/* address in target */
+target_phys_addr_t mb_buf_phys;
+/* size of mb_buf in bytes */
+unsigned mb_buf_size;
+/* offset of mb-info's in bytes */
+target_phys_addr_t offset_mbinfo;
+/* offset in buffer for cmdlines in bytes */
+target_phys_addr_t offset_cmdlines;
+/* offset of modules in bytes */
+target_phys_addr_t offset_mods;
+/* available slots for mb modules infos */
+int mb_mods_avail;
+/* currently used slots of mb modules */
+int mb_mods_count;
+} MultibootState;
+
+static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
+{
+int len = strlen(cmdline) + 1;
+target_phys_addr_t p = s->offset_cmdlines;
+
+pstrcpy((char *)s->mb_buf + p, len, cmdline);
+s->offset_cmdlines += len;
+return s->mb_buf_phys + p;
+}
+
+static void mb_add_mod(MultibootState *s,
+   target_phys_addr_t start, target_phys_addr_t end,
+   target_phys_addr_t cmdline_phys)
+{
+char *p;
+assert(s->mb_mods_count < s->mb_mods_avail);
+
+p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_SIZE * s->mb_mods_count;
+
+stl_p(p + MB

[Qemu-devel] [PATCH 1/2] multiboot: Support arbitrary number of modules.

2009-12-06 Thread Adam Lackorzynski

On Thu Dec 03, 2009 at 17:24:59 -0600, Anthony Liguori wrote:
> >+struct MultibootState {
> >+void *mb_buf; /* buffer holding kernel, cmdlines and mb_infos */
> >+uint32_t mb_buf_phys; /* address in target */
> >+int mb_buf_size;  /* size of mb_buf in bytes */
> >+int mb_mods_avail;/* available slots for mb modules infos */
> >+int mb_mods_count;/* currently used slots of mb modules */
> >+int offset_mbinfo;/* offset of mb-info's in bytes */
> >+int offset_cmdlines;  /* offset in buffer for cmdlines */
> >+int offset_mods;  /* offset of modules in bytes */
> >+};
> 
> Should be typedef struct MultibootState.  See CODING_STYLE.  Also,
> shouldn't these offsets be something other than int?  Does multiboot
> always load in 32-bit mode (never 64-bit mode?).
> 
> mb_buf_phys should not be a u32.  It should be a target address type.

The spec defines all values as u32 but since the offsets are relative to
mb_buf_phys I've made them of type target_phys_addr_t too.


Signed-off-by: Adam Lackorzynski 
---
 hw/pc.c |  268 +++
 1 files changed, 167 insertions(+), 101 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 8c1b7ea..44f3193 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -51,6 +51,12 @@
 /* Show multiboot debug output */
 //#define DEBUG_MULTIBOOT
 
+#ifdef DEBUG_MULTIBOOT
+#define mb_debug(a...) fprintf(stderr, ## a)
+#else
+#define mb_debug(a...)
+#endif
+
 #define BIOS_FILENAME "bios.bin"
 
 #define PC_MAX_BIOS_SIZE (4 * 1024 * 1024)
@@ -512,6 +518,85 @@ static long get_file_size(FILE *f)
 #error multiboot struct needs to fit in 16 bit real mode
 #endif
 
+enum {
+/* Multiboot info */
+MBI_FLAGS   = 0,
+MBI_MEM_LOWER   = 4,
+MBI_MEM_UPPER   = 8,
+MBI_BOOT_DEVICE = 12,
+MBI_CMDLINE = 16,
+MBI_MODS_COUNT  = 20,
+MBI_MODS_ADDR   = 24,
+MBI_MMAP_ADDR   = 48,
+
+MBI_SIZE= 88,
+
+/* Multiboot modules */
+MB_MOD_START= 0,
+MB_MOD_END  = 4,
+MB_MOD_CMDLINE  = 8,
+
+MB_MOD_SIZE = 16,
+
+/* Region offsets */
+ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
+ADDR_MBI  = ADDR_E820_MAP + 0x500,
+
+/* Multiboot flags */
+MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
+MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
+MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
+MULTIBOOT_FLAGS_MODULES = 1 << 3,
+MULTIBOOT_FLAGS_MMAP= 1 << 6,
+};
+
+typedef struct {
+/* buffer holding kernel, cmdlines and mb_infos */
+void *mb_buf;
+/* address in target */
+target_phys_addr_t mb_buf_phys;
+/* size of mb_buf in bytes */
+unsigned mb_buf_size;
+/* offset of mb-info's in bytes */
+target_phys_addr_t offset_mbinfo;
+/* offset in buffer for cmdlines in bytes */
+target_phys_addr_t offset_cmdlines;
+/* offset of modules in bytes */
+target_phys_addr_t offset_mods;
+/* available slots for mb modules infos */
+int mb_mods_avail;
+/* currently used slots of mb modules */
+int mb_mods_count;
+} MultibootState;
+
+static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
+{
+int len = strlen(cmdline) + 1;
+target_phys_addr_t p = s->offset_cmdlines;
+
+pstrcpy((char *)s->mb_buf + p, len, cmdline);
+s->offset_cmdlines += len;
+return s->mb_buf_phys + p;
+}
+
+static void mb_add_mod(MultibootState *s,
+   target_phys_addr_t start, target_phys_addr_t end,
+   target_phys_addr_t cmdline_phys)
+{
+char *p;
+assert(s->mb_mods_count < s->mb_mods_avail);
+
+p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_SIZE * s->mb_mods_count;
+
+stl_p(p + MB_MOD_START,   start);
+stl_p(p + MB_MOD_END, end);
+stl_p(p + MB_MOD_CMDLINE, cmdline_phys);
+
+mb_debug("mod%02d: %08x - %08x\n", s->mb_mods_count, start, end);
+
+s->mb_mods_count++;
+}
+
 static int load_multiboot(void *fw_cfg,
   FILE *f,
   const char *kernel_filename,
@@ -524,12 +609,8 @@ static int load_multiboot(void *fw_cfg,
 uint32_t mh_entry_addr;
 uint32_t mh_load_addr;
 uint32_t mb_kernel_size;
-uint32_t mmap_addr = MULTIBOOT_STRUCT_ADDR;
-uint32_t mb_bootinfo = MULTIBOOT_STRUCT_ADDR + 0x500;
-uint32_t mb_mod_end;
-uint8_t bootinfo[0x500];
-uint32_t cmdline = 0x200;
-uint8_t *mb_kernel_data;
+MultibootState mbs;
+uint8_t bootinfo[MBI_SIZE];
 uint8_t *mb_bootinfo_data;
 
 /* Ok, let's see if it is a multiboot image.
@@ -550,10 +631,9 @@ static int load_multiboot(void *fw_cfg,
 if (!is_multiboot)
 return 0; /* no multiboot */
 
-#ifdef DEBUG_MULTIBOOT
-fprintf(stderr, "qemu: I believe we found a multiboo

[Qemu-devel] [PATCH 2/2] multiboot: Separate multiboot loading into separate file

2009-12-03 Thread Adam Lackorzynski
multiboot: Separate multiboot loading into separate file

Move multiboot loading functionality to a separate file as suggested by
Alex Graf.


Signed-off-by: Adam Lackorzynski 
---
 Makefile.target |2 +-
 hw/multiboot.c  |  318 +++
 hw/multiboot.h  |   12 ++
 hw/pc.c |  292 +--
 4 files changed, 334 insertions(+), 290 deletions(-)
 create mode 100644 hw/multiboot.c
 create mode 100644 hw/multiboot.h

diff --git a/Makefile.target b/Makefile.target
index 891ea08..20e4145 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -194,7 +194,7 @@ obj-i386-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o 
pcspk.o pc.o
 obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o
 obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o
 obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
-obj-i386-y += ne2000-isa.o
+obj-i386-y += ne2000-isa.o multiboot.o
 
 # shared objects
 obj-ppc-y = ppc.o ide/core.o ide/qdev.o ide/isa.o ide/pci.o ide/macio.o
diff --git a/hw/multiboot.c b/hw/multiboot.c
new file mode 100644
index 000..bde477d
--- /dev/null
+++ b/hw/multiboot.c
@@ -0,0 +1,318 @@
+/*
+ * QEMU PC System Emulator
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw.h"
+#include "fw_cfg.h"
+#include "multiboot.h"
+#include "loader.h"
+#include "elf.h"
+#include "sysemu.h"
+
+/* Show multiboot debug output */
+#define DEBUG_MULTIBOOT
+
+#ifdef DEBUG_MULTIBOOT
+#define mb_debug(a...) fprintf(stderr, ## a)
+#else
+#define mb_debug(a...)
+#endif
+
+#define MULTIBOOT_STRUCT_ADDR 0x9000
+
+#if MULTIBOOT_STRUCT_ADDR > 0xf
+#error multiboot struct needs to fit in 16 bit real mode
+#endif
+
+enum {
+/* Multiboot info */
+MBI_FLAGS   = 0,
+MBI_MEM_LOWER   = 4,
+MBI_MEM_UPPER   = 8,
+MBI_BOOT_DEVICE = 12,
+MBI_CMDLINE = 16,
+MBI_MODS_COUNT  = 20,
+MBI_MODS_ADDR   = 24,
+MBI_MMAP_ADDR   = 48,
+
+MBI_SIZE= 88,
+
+/* Multiboot modules */
+MB_MOD_START= 0,
+MB_MOD_END  = 4,
+MB_MOD_CMDLINE  = 8,
+
+MB_MOD_SIZE = 16,
+
+/* Region offsets */
+ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
+ADDR_MBI  = ADDR_E820_MAP + 0x500,
+
+/* Multiboot flags */
+MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
+MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
+MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
+MULTIBOOT_FLAGS_MODULES = 1 << 3,
+MULTIBOOT_FLAGS_MMAP= 1 << 6,
+};
+
+struct MultibootState {
+void *mb_buf; /* buffer holding kernel, cmdlines and mb_infos */
+uint32_t mb_buf_phys; /* address in target */
+int mb_buf_size;  /* size of mb_buf in bytes */
+int mb_mods_avail;/* available slots for mb modules infos */
+int mb_mods_count;/* currently used slots of mb modules */
+int offset_mbinfo;/* offset of mb-info's in bytes */
+int offset_cmdlines;  /* offset in buffer for cmdlines */
+int offset_mods;  /* offset of modules in bytes */
+};
+
+static uint32_t mb_add_cmdline(struct MultibootState *s, const char *cmdline)
+{
+int len = strlen(cmdline) + 1;
+uint32_t p = s->offset_cmdlines;
+
+pstrcpy((char *)s->mb_buf + p, len, cmdline);
+s->offset_cmdlines += len;
+return s->mb_buf_phys + p;
+}
+
+static void mb_add_mod(struct MultibootState *s,
+   uint32_t start, uint32_t end,
+   uint32_t cmdline_phys)
+{
+char *p;
+assert(s->mb_mods_count < s->mb_mods_avail);
+
+p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_SIZE * s->mb_mods_count;
+
+stl_p(p + MB_MOD_START,   start);
+stl_p(p + MB_MOD_END, end);
+st

[Qemu-devel] [PATCH 1/2] multiboot: Support arbitrary number of modules.

2009-12-03 Thread Adam Lackorzynski
multiboot: Support arbitrary number of modules.

Addressed comments by Anthony.

Signed-off-by: Adam Lackorzynski 
---
 hw/pc.c |  260 ++
 1 files changed, 159 insertions(+), 101 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 8c1b7ea..47d7796 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -51,6 +51,12 @@
 /* Show multiboot debug output */
 //#define DEBUG_MULTIBOOT
 
+#ifdef DEBUG_MULTIBOOT
+#define mb_debug(a...) fprintf(stderr, ## a)
+#else
+#define mb_debug(a...)
+#endif
+
 #define BIOS_FILENAME "bios.bin"
 
 #define PC_MAX_BIOS_SIZE (4 * 1024 * 1024)
@@ -512,6 +518,77 @@ static long get_file_size(FILE *f)
 #error multiboot struct needs to fit in 16 bit real mode
 #endif
 
+enum {
+/* Multiboot info */
+MBI_FLAGS   = 0,
+MBI_MEM_LOWER   = 4,
+MBI_MEM_UPPER   = 8,
+MBI_BOOT_DEVICE = 12,
+MBI_CMDLINE = 16,
+MBI_MODS_COUNT  = 20,
+MBI_MODS_ADDR   = 24,
+MBI_MMAP_ADDR   = 48,
+
+MBI_SIZE= 88,
+
+/* Multiboot modules */
+MB_MOD_START= 0,
+MB_MOD_END  = 4,
+MB_MOD_CMDLINE  = 8,
+
+MB_MOD_SIZE = 16,
+
+/* Region offsets */
+ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
+ADDR_MBI  = ADDR_E820_MAP + 0x500,
+
+/* Multiboot flags */
+MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
+MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
+MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
+MULTIBOOT_FLAGS_MODULES = 1 << 3,
+MULTIBOOT_FLAGS_MMAP= 1 << 6,
+};
+
+struct MultibootState {
+void *mb_buf; /* buffer holding kernel, cmdlines and mb_infos */
+uint32_t mb_buf_phys; /* address in target */
+int mb_buf_size;  /* size of mb_buf in bytes */
+int mb_mods_avail;/* available slots for mb modules infos */
+int mb_mods_count;/* currently used slots of mb modules */
+int offset_mbinfo;/* offset of mb-info's in bytes */
+int offset_cmdlines;  /* offset in buffer for cmdlines */
+int offset_mods;  /* offset of modules in bytes */
+};
+
+static uint32_t mb_add_cmdline(struct MultibootState *s, const char *cmdline)
+{
+int len = strlen(cmdline) + 1;
+uint32_t p = s->offset_cmdlines;
+
+pstrcpy((char *)s->mb_buf + p, len, cmdline);
+s->offset_cmdlines += len;
+return s->mb_buf_phys + p;
+}
+
+static void mb_add_mod(struct MultibootState *s,
+   uint32_t start, uint32_t end,
+   uint32_t cmdline_phys)
+{
+char *p;
+assert(s->mb_mods_count < s->mb_mods_avail);
+
+p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_SIZE * s->mb_mods_count;
+
+stl_p(p + MB_MOD_START,   start);
+stl_p(p + MB_MOD_END, end);
+stl_p(p + MB_MOD_CMDLINE, cmdline_phys);
+
+mb_debug("mod%02d: %08x - %08x\n", s->mb_mods_count, start, end);
+
+s->mb_mods_count++;
+}
+
 static int load_multiboot(void *fw_cfg,
   FILE *f,
   const char *kernel_filename,
@@ -524,12 +601,8 @@ static int load_multiboot(void *fw_cfg,
 uint32_t mh_entry_addr;
 uint32_t mh_load_addr;
 uint32_t mb_kernel_size;
-uint32_t mmap_addr = MULTIBOOT_STRUCT_ADDR;
-uint32_t mb_bootinfo = MULTIBOOT_STRUCT_ADDR + 0x500;
-uint32_t mb_mod_end;
-uint8_t bootinfo[0x500];
-uint32_t cmdline = 0x200;
-uint8_t *mb_kernel_data;
+struct MultibootState mbs;
+uint8_t bootinfo[MBI_SIZE];
 uint8_t *mb_bootinfo_data;
 
 /* Ok, let's see if it is a multiboot image.
@@ -550,10 +623,9 @@ static int load_multiboot(void *fw_cfg,
 if (!is_multiboot)
 return 0; /* no multiboot */
 
-#ifdef DEBUG_MULTIBOOT
-fprintf(stderr, "qemu: I believe we found a multiboot image!\n");
-#endif
+mb_debug("qemu: I believe we found a multiboot image!\n");
 memset(bootinfo, 0, sizeof(bootinfo));
+memset(&mbs, 0, sizeof(mbs));
 
 if (flags & 0x0004) { /* MULTIBOOT_HEADER_HAS_VBE */
 fprintf(stderr, "qemu: multiboot knows VBE. we don't.\n");
@@ -571,24 +643,18 @@ static int load_multiboot(void *fw_cfg,
 mh_load_addr = mh_entry_addr = elf_entry;
 mb_kernel_size = kernel_size;
 
-mb_kernel_data = qemu_malloc(mb_kernel_size);
-if (rom_copy(mb_kernel_data, elf_entry, kernel_size) != kernel_size) {
+mbs.mb_buf = qemu_malloc(mb_kernel_size);
+if (rom_copy(mbs.mb_buf, elf_entry, kernel_size) != kernel_size) {
 fprintf(stderr, "Error while fetching elf kernel from rom\n");
 exit(1);
 }
 
-#ifdef DEBUG_MULTIBOOT
-fprintf(stderr, "qemu: loading multiboot-elf kernel (%#x bytes) with 
entry %#zx\n",
-mb_kernel_size, (size_t)mh_entry_addr);
-#endif
+mb_debug("qemu: loading multiboot-elf kernel (%#x bytes) with entry 
%#zx\n",
+

[Qemu-devel] [PATCH 2/2] multiboot: Support arbitrary number of modules

2009-11-30 Thread Adam Lackorzynski
multiboot: Support arbitrary number of modules


Signed-off-by: Adam Lackorzynski 
---
 hw/pc.c |  216 +-
 1 files changed, 143 insertions(+), 73 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 6bcfe1b..163bec1 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -507,6 +507,79 @@ static long get_file_size(FILE *f)
 #error multiboot struct needs to fit in 16 bit real mode
 #endif
 
+enum {
+/* Multiboot info */
+MBI_FLAGS   = 0,
+MBI_MEM_LOWER   = 4,
+MBI_MEM_UPPER   = 8,
+MBI_BOOT_DEVICE = 12,
+MBI_CMDLINE = 16,
+MBI_MODS_COUNT  = 20,
+MBI_MODS_ADDR   = 24,
+MBI_MMAP_ADDR   = 48,
+
+MBI_SIZE= 88,
+
+/* Multiboot modules */
+MB_MOD_START= 0,
+MB_MOD_END  = 4,
+MB_MOD_CMDLINE  = 8,
+
+MB_MOD_SIZE = 16,
+
+/* Region offsets */
+ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
+ADDR_MBI  = ADDR_E820_MAP + 0x500,
+
+/* Multiboot flags */
+MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
+MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
+MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
+MULTIBOOT_FLAGS_MODULES = 1 << 3,
+MULTIBOOT_FLAGS_MMAP= 1 << 6,
+};
+
+struct mb_state {
+void *mb_buf; /* buffer holding kernel, cmdlines and mb_infos */
+uint32_t mb_buf_phys; /* address in target */
+int mb_buf_size;  /* size of mb_buf in bytes */
+int mb_mods_avail;/* available slots for mb modules infos */
+int mb_mods_count;/* currently used slots of mb modules */
+int offset_mbinfo;/* offset of mb-info's in bytes */
+int offset_cmdlines;  /* offset in buffer for cmdlines */
+int offset_mods;  /* offset of modules in bytes */
+};
+
+static uint32_t mb_add_cmdline(struct mb_state *s, const char *cmdline)
+{
+int len = strlen(cmdline) + 1;
+uint32_t p = s->offset_cmdlines;
+
+pstrcpy((char *)s->mb_buf + p, len, cmdline);
+s->offset_cmdlines += len;
+return s->mb_buf_phys + p;
+}
+
+static void mb_add_mod(struct mb_state *s,
+   uint32_t start, uint32_t end,
+   uint32_t cmdline_phys)
+{
+char *p;
+assert(s->mb_mods_count < s->mb_mods_avail);
+
+p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_SIZE * s->mb_mods_count;
+
+stl_p(p + MB_MOD_START,   start);
+stl_p(p + MB_MOD_END, end);
+stl_p(p + MB_MOD_CMDLINE, cmdline_phys);
+
+#ifdef DEBUG_MULTIBOOT
+fprintf(stderr, "mod%02d: %08x - %08x\n", s->mb_mods_count, start, end);
+#endif
+
+s->mb_mods_count++;
+}
+
 static int load_multiboot(void *fw_cfg,
   FILE *f,
   const char *kernel_filename,
@@ -519,12 +592,8 @@ static int load_multiboot(void *fw_cfg,
 uint32_t mh_entry_addr;
 uint32_t mh_load_addr;
 uint32_t mb_kernel_size;
-uint32_t mmap_addr = MULTIBOOT_STRUCT_ADDR;
-uint32_t mb_bootinfo = MULTIBOOT_STRUCT_ADDR + 0x500;
-uint32_t mb_mod_end;
-uint8_t bootinfo[0x500];
-uint32_t cmdline = 0x200;
-uint8_t *mb_kernel_data;
+struct mb_state mbs;
+uint8_t bootinfo[MBI_SIZE];
 uint8_t *mb_bootinfo_data;
 
 /* Ok, let's see if it is a multiboot image.
@@ -549,6 +618,7 @@ static int load_multiboot(void *fw_cfg,
 fprintf(stderr, "qemu: I believe we found a multiboot image!\n");
 #endif
 memset(bootinfo, 0, sizeof(bootinfo));
+memset(&mbs, 0, sizeof(mbs));
 
 if (flags & 0x0004) { /* MULTIBOOT_HEADER_HAS_VBE */
 fprintf(stderr, "qemu: multiboot knows VBE. we don't.\n");
@@ -566,8 +636,8 @@ static int load_multiboot(void *fw_cfg,
 mh_load_addr = mh_entry_addr = elf_entry;
 mb_kernel_size = kernel_size;
 
-mb_kernel_data = qemu_malloc(mb_kernel_size);
-if (rom_copy(mb_kernel_data, elf_entry, kernel_size) != kernel_size) {
+mbs.mb_buf = qemu_malloc(mb_kernel_size);
+if (rom_copy(mbs.mb_buf, elf_entry, kernel_size) != kernel_size) {
 fprintf(stderr, "Error while fetching elf kernel from rom\n");
 exit(1);
 }
@@ -604,104 +674,104 @@ static int load_multiboot(void *fw_cfg,
 mb_kernel_size, mh_load_addr);
 #endif
 
-mb_kernel_data = qemu_malloc(mb_kernel_size);
+mbs.mb_buf = qemu_malloc(mb_kernel_size);
 fseek(f, mb_kernel_text_offset, SEEK_SET);
-fread(mb_kernel_data, 1, mb_kernel_size, f);
+fread(mbs.mb_buf, 1, mb_kernel_size, f);
 fclose(f);
 }
 
-/* blob size is only the kernel for now */
-mb_mod_end = mh_load_addr + mb_kernel_size;
+mbs.mb_buf_phys = mh_load_addr;
+
+mbs.mb_buf_size = TARGET_PAGE_ALIGN(mb_kernel_size);
+mbs.offset_mbinfo = mbs.mb_buf_size;
+
+/* Calculate space for cmdlines and mb_mods */
+mbs.mb_buf_size += strlen(kernel_filena

[Qemu-devel] [PATCH 1/2] multiboot: Fix module loading and setting of mmap.

2009-11-30 Thread Adam Lackorzynski
multiboot: Fix module loading and setting of mmap.

Signed-off-by: Adam Lackorzynski 
Acked-by: Alexander Graf 
---
 hw/pc.c   |2 +-
 pc-bios/multiboot.bin |  Bin 512 -> 1024 bytes
 pc-bios/optionrom/multiboot.S |5 -
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 7c791c4..6bcfe1b 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -661,7 +661,7 @@ static int load_multiboot(void *fw_cfg,
 
 /* append module data at the end of last module */
 mb_kernel_data = qemu_realloc(mb_kernel_data,
-  mh_load_addr - mb_mod_end);
+  mb_mod_end - mh_load_addr);
 load_image(initrd_filename,
mb_kernel_data + mb_mod_start - mh_load_addr);
 
diff --git a/pc-bios/multiboot.bin b/pc-bios/multiboot.bin
index 
59737c3c6798f83c1b35534d7865c79ba9ca3bc8..d7da6e04ad6d71d26f577d9d6a019719bcce8766
 100644
GIT binary patch
delta 261
zcmXZVu}Z^G6vpv$F1I0cu#I9V4%gzY#MMa$cNeJ-(0mTo!A)Em=wfIHT=E32KEb6f
z...@wzaa%&fDzannbhA>QS4*9nc|err{)-{caFW
zkS-*`52Rlb!8dr0Vcx-T=_1W#lw+iR82s)bP(*Jwd4ZBNQf*NVi%LEaTeb=1pTyK@
z+^ns}PHl-)KRP1F^qtxdQnO1ag{ZR4?YeL3`o3c=dU$b3KcBZeG`LkZ4HHr0DDm)j
sLZm;BWd>vGLhU(Kng}aYiFF^Qsf$Z-!SNZpqTu*}quA%c_PYG^4_6gol>h($

delta 120
zcmZqRXkd{DUB#FdAZK`>??&3f6b8Mt#U_l$*-{u3C-RF+cFSckrZFB)>jcr=au!gI
z1>?ls...@bcmvop_`zccfo8p3eq2v^2o|Rm1HaM%y|n*&7L1b}8FeS`W7J{=3f^Ow
r{ee?...@dqbgy6>MgYdxBLx5e

diff --git a/pc-bios/optionrom/multiboot.S b/pc-bios/optionrom/multiboot.S
index be5c9fc..9131837 100644
--- a/pc-bios/optionrom/multiboot.S
+++ b/pc-bios/optionrom/multiboot.S
@@ -62,6 +62,9 @@ run_multiboot:
add %eax, %ebx
movl%ebx, %gs:GS_GDT_DESC + 2
 
+   xor %eax, %eax
+   mov %eax, %es
+
/* Read the bootinfo struct into RAM */
read_fw_blob(FW_CFG_INITRD)
 
@@ -71,7 +74,7 @@ run_multiboot:
mov %ax, %fs
 
/* ES = mmap_addr */
-   mov %eax, %fs:0x48
+   mov %fs:48, %eax
shr $4, %eax
mov %ax, %es
 
-- 
1.6.5.3


Adam
-- 
Adam a...@os.inf.tu-dresden.de
  Lackorzynski http://os.inf.tu-dresden.de/~adam/




  1   2   >