[Qemu-devel] [PATCH 2/2] multiboot: Separate multiboot loading into separate file
Move multiboot loading code into separate files as suggested by Alex Graf. Signed-off-by: Adam Lackorzynski a...@os.inf.tu-dresden.de --- 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, 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); +
[Qemu-devel] [PATCH 2/2] multiboot: Separate multiboot loading into separate file
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 a...@os.inf.tu-dresden.de --- 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_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); + +
[Qemu-devel] [PATCH 2/2] multiboot: Separate multiboot loading into separate file
Move multiboot loading code into a separate files as suggested by Alex Graf. Signed-off-by: Adam Lackorzynski a...@os.inf.tu-dresden.de --- 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_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);
[Qemu-devel] [PATCH 2/2] multiboot: Separate multiboot loading into separate file
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 a...@os.inf.tu-dresden.de --- 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); +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++; +} + +int
Re: [Qemu-devel] [PATCH 2/2] multiboot: Separate multiboot loading into separate file
On 03.12.2009, at 23:23, Adam Lackorzynski wrote: multiboot: Separate multiboot loading into separate file Move multiboot loading functionality to a separate file as suggested by Alex Graf. Awesome, thanks! Looks good to me. The code could use some cleanup (magic numbers), but we should keep that for later ;-). Alex