Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S269825AbTGKIRj (ORCPT ); Fri, 11 Jul 2003 04:17:39 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S269823AbTGKIRj (ORCPT ); Fri, 11 Jul 2003 04:17:39 -0400 Received: from h55p111.delphi.afb.lu.se ([130.235.187.184]:3760 "EHLO gagarin.0x63.nu") by vger.kernel.org with ESMTP id S269818AbTGKIPN (ORCPT ); Fri, 11 Jul 2003 04:15:13 -0400 Date: Fri, 11 Jul 2003 10:29:37 +0200 To: Christoph Hellwig , torvalds@osdl.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] add xbox subarchitecture Message-ID: <20030711082937.GA2838@h55p111.delphi.afb.lu.se> References: <20030710172802.GB27744@h55p111.delphi.afb.lu.se> <20030710190918.A12653@infradead.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20030710190918.A12653@infradead.org> User-Agent: Mutt/1.5.4i From: Anders Gustafsson X-Scanner: exiscan *19atHd-0000tN-00*eyPARFY.YSM*0x63.nu Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 32335 Lines: 719 On Thu, Jul 10, 2003 at 07:09:18PM +0100, Christoph Hellwig wrote: > > targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o > > +ifeq ($(CONFIG_X86_XBOX),y) > > +#XXX Compiling with optimization makes 1.1-xboxen > > +# crash while decompressing the kernel > > +CFLAGS_misc.o := -O0 > > +endif > > I don't think this should go in until it's clear that it's not a gcc > problem. I don't really know how to make clear it's not a gcc problem. But if it was, why doesn't it crash on pc and 1.0 xboxen? And why does it crash on kernels compiled with 2.95, with or without optimization? I really wish I had the explaination to this problem. Updated patch according to other comments attached. (btw, everyone at LinuxTag should come to the xbox-linux booth and say hi :) -- Anders Gustafsson - andersg@0x63.nu - http://0x63.nu/ You can import this changeset into BK by piping this whole message to: '| bk receive [path to repository]' or apply the patch as usual. =================================================================== ChangeSet 1.1404 03/07/11 09:49:29 andersg@0x63.nu +10 -0 Added XBox Gaming System subarchitecture. include/asm-i386/mach-xbox/mach_pci_blacklist.h 1.1 03/07/11 09:42:47 andersg@0x63.nu +6 -0 include/asm-i386/mach-xbox/mach_pci_blacklist.h 1.0 03/07/11 09:42:47 andersg@0x63.nu +0 -0 BitKeeper file /data/dev/kernel/bk/xbox-2.5/include/asm-i386/mach-xbox/mach_pci_blacklist.h include/asm-i386/mach-default/mach_pci_blacklist.h 1.1 03/07/11 09:42:46 andersg@0x63.nu +6 -0 arch/i386/mach-xbox/setup.c 1.1 03/07/11 09:42:46 andersg@0x63.nu +79 -0 include/asm-i386/mach-default/mach_pci_blacklist.h 1.0 03/07/11 09:42:46 andersg@0x63.nu +0 -0 BitKeeper file /data/dev/kernel/bk/xbox-2.5/include/asm-i386/mach-default/mach_pci_blacklist.h arch/i386/mach-xbox/setup.c 1.0 03/07/11 09:42:46 andersg@0x63.nu +0 -0 BitKeeper file /data/dev/kernel/bk/xbox-2.5/arch/i386/mach-xbox/setup.c arch/i386/mach-xbox/reboot.c 1.1 03/07/11 09:42:45 andersg@0x63.nu +51 -0 arch/i386/mach-xbox/reboot.c 1.0 03/07/11 09:42:45 andersg@0x63.nu +0 -0 BitKeeper file /data/dev/kernel/bk/xbox-2.5/arch/i386/mach-xbox/reboot.c arch/i386/mach-xbox/Makefile 1.1 03/07/11 09:42:44 andersg@0x63.nu +5 -0 include/asm-i386/timex.h 1.6 03/07/11 09:42:44 andersg@0x63.nu +5 -1 The xbox has a different CLOCK_TICK_RATE. arch/i386/pci/direct.c 1.19 03/07/11 09:42:44 andersg@0x63.nu +4 -0 Added a mach-hook for blacklisting pci-devices. The xbox uses this to prevent it from touching some devices that makes it hang. arch/i386/mach-xbox/Makefile 1.0 03/07/11 09:42:44 andersg@0x63.nu +0 -0 BitKeeper file /data/dev/kernel/bk/xbox-2.5/arch/i386/mach-xbox/Makefile arch/i386/boot/compressed/Makefile 1.17 03/07/11 09:42:44 andersg@0x63.nu +5 -0 There is some strange interaction when paging is off, that makes 1.1 xboxen crash while decompressing kernel. Compiling the decompressor without optimization works around this problem. arch/i386/Makefile 1.53 03/07/11 09:42:44 andersg@0x63.nu +4 -0 Added XBox Gaming System subarchitecture. arch/i386/Kconfig 1.66 03/07/11 09:42:44 andersg@0x63.nu +19 -2 Added configure option for the XBox Gaming System subarchitecture. arch/i386/Kconfig | 21 +++++ arch/i386/Makefile | 4 + arch/i386/boot/compressed/Makefile | 5 + arch/i386/mach-xbox/Makefile | 5 + arch/i386/mach-xbox/reboot.c | 51 +++++++++++++ arch/i386/mach-xbox/setup.c | 79 +++++++++++++++++++++ arch/i386/pci/direct.c | 4 + include/asm-i386/mach-default/mach_pci_blacklist.h | 6 + include/asm-i386/mach-xbox/mach_pci_blacklist.h | 6 + include/asm-i386/timex.h | 6 + 10 files changed, 184 insertions(+), 3 deletions(-) diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Fri Jul 11 09:56:33 2003 +++ b/arch/i386/Kconfig Fri Jul 11 09:56:33 2003 @@ -43,6 +43,22 @@ help Choose this option if your computer is a standard PC or compatible. +config X86_XBOX + bool "XBox Gaming System" + help + This option is needed to make Linux boot on XBox Gaming Systems. + + The XBox can be considered as a standard PC with a Coppermine-based Celeron 733 MHz, + IDE harddrive, DVD, Ethernet, USB and graphics. + + To boot the kernel you need "_romwell", either used as a replacement BIOS (cromwell) + or as a bootloader. + + For more information see http://xbox-linux.sourceforge.net/ + + If you do not specifically need a kernel for XBOX machine, + say N here otherwise the kernel you build will not be bootable. + config X86_VOYAGER bool "Voyager (NCR)" help @@ -409,6 +425,7 @@ Otherwise, say N. config SMP + depends on !X86_XBOX bool "Symmetric multi-processing support" ---help--- This enables support for systems with more than one CPU. If you have @@ -1104,7 +1121,7 @@ config MCA bool "MCA support" - depends on !(X86_VISWS || X86_VOYAGER) + depends on !(X86_VISWS || X86_VOYAGER || X86_XBOX) help MicroChannel Architecture is found in some IBM PS/2 machines and laptops. It is a bus system similar to PCI or ISA. See @@ -1410,7 +1427,7 @@ config X86_BIOS_REBOOT bool - depends on !(X86_VISWS || X86_VOYAGER) + depends on !(X86_VISWS || X86_VOYAGER || X86_XBOX) default y config X86_TRAMPOLINE diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile --- a/arch/i386/Makefile Fri Jul 11 09:56:33 2003 +++ b/arch/i386/Makefile Fri Jul 11 09:56:33 2003 @@ -53,6 +53,10 @@ # Default subarch .c files mcore-y := mach-default +# Xbox subarch support +mflags-$(CONFIG_X86_XBOX) := -Iinclude/asm-i386/mach-xbox +mcore-$(CONFIG_X86_XBOX) := mach-xbox + # Voyager subarch support mflags-$(CONFIG_X86_VOYAGER) := -Iinclude/asm-i386/mach-voyager mcore-$(CONFIG_X86_VOYAGER) := mach-voyager diff -Nru a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile --- a/arch/i386/boot/compressed/Makefile Fri Jul 11 09:56:33 2003 +++ b/arch/i386/boot/compressed/Makefile Fri Jul 11 09:56:33 2003 @@ -5,6 +5,11 @@ # targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o +ifeq ($(CONFIG_X86_XBOX),y) +#XXX Compiling with optimization makes 1.1-xboxen +# crash while decompressing the kernel +CFLAGS_misc.o := -O0 +endif EXTRA_AFLAGS := -traditional LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32 diff -Nru a/arch/i386/mach-xbox/Makefile b/arch/i386/mach-xbox/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/mach-xbox/Makefile Fri Jul 11 09:56:33 2003 @@ -0,0 +1,5 @@ +# +# Makefile for the linux kernel. +# + +obj-y := setup.o reboot.o diff -Nru a/arch/i386/mach-xbox/reboot.c b/arch/i386/mach-xbox/reboot.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/mach-xbox/reboot.c Fri Jul 11 09:56:33 2003 @@ -0,0 +1,51 @@ +/* + * arch/i386/mach-xbox/reboot.c + * Olivier Fauchon + * Anders Gustafsson + * + */ + +#include + +/* we don't use any of those, but dmi_scan.c needs 'em */ +void (*pm_power_off)(void); +int reboot_thru_bios; + +#define XBOX_SMB_IO_BASE 0xC000 +#define XBOX_SMB_HOST_ADDRESS (0x4 + XBOX_SMB_IO_BASE) +#define XBOX_SMB_HOST_COMMAND (0x8 + XBOX_SMB_IO_BASE) +#define XBOX_SMB_HOST_DATA (0x6 + XBOX_SMB_IO_BASE) +#define XBOX_SMB_GLOBAL_ENABLE (0x2 + XBOX_SMB_IO_BASE) + +#define XBOX_PIC_ADDRESS 0x10 + +#define SMC_CMD_POWER 0x02 +#define SMC_SUBCMD_POWER_RESET 0x01 +#define SMC_SUBCMD_POWER_CYCLE 0x40 +#define SMC_SUBCMD_POWER_OFF 0x80 + + +static void xbox_pic_cmd(u8 command) +{ + outw_p(((XBOX_PIC_ADDRESS) << 1),XBOX_SMB_HOST_ADDRESS); + outb_p(SMC_CMD_POWER, XBOX_SMB_HOST_COMMAND); + outw_p(command, XBOX_SMB_HOST_DATA); + outw_p(inw(XBOX_SMB_IO_BASE),XBOX_SMB_IO_BASE); + outb_p(0x0a,XBOX_SMB_GLOBAL_ENABLE); +} + +void machine_restart(char * __unused) +{ + printk(KERN_INFO "Sending POWER_RESET to XBOX-PIC.\n"); + xbox_pic_cmd(SMC_SUBCMD_POWER_RESET); +} + +void machine_power_off(void) +{ + printk(KERN_INFO "Sending POWER_OFF to XBOX-PIC.\n"); + xbox_pic_cmd(SMC_SUBCMD_POWER_OFF); +} + +void machine_halt(void) +{ +} diff -Nru a/arch/i386/mach-xbox/setup.c b/arch/i386/mach-xbox/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/mach-xbox/setup.c Fri Jul 11 09:56:33 2003 @@ -0,0 +1,79 @@ +/* + * Machine specific setup for xbox + */ + +#include +#include +#include +#include +#include +#include + +/** + * pre_intr_init_hook - initialisation prior to setting up interrupt vectors + * + * Description: + * Perform any necessary interrupt initialisation prior to setting up + * the "ordinary" interrupt call gates. For legacy reasons, the ISA + * interrupts should be initialised here if the machine emulates a PC + * in any way. + **/ +void __init pre_intr_init_hook(void) +{ + init_ISA_irqs(); +} + +/** + * intr_init_hook - post gate setup interrupt initialisation + * + * Description: + * Fill in any interrupts that may have been left out by the general + * init_IRQ() routine. interrupts having to do with the machine rather + * than the devices on the I/O bus (like APIC interrupts in intel MP + * systems) are started here. + **/ +void __init intr_init_hook(void) +{ +#ifdef CONFIG_X86_LOCAL_APIC + apic_intr_init(); +#endif + +} + +/** + * pre_setup_arch_hook - hook called prior to any setup_arch() execution + * + * Description: + * generally used to activate any machine specific identification + * routines that may be needed before setup_arch() runs. On VISWS + * this is used to get the board revision and type. + **/ +void __init pre_setup_arch_hook(void) +{ +} + +/** + * trap_init_hook - initialise system specific traps + * + * Description: + * Called as the final act of trap_init(). Used in VISWS to initialise + * the various board specific APIC traps. + **/ +void __init trap_init_hook(void) +{ +} + +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; + +/** + * time_init_hook - do any specific initialisations for the system timer. + * + * Description: + * Must plug the system timer interrupt source at HZ into the IRQ listed + * in irq_vectors.h:TIMER_IRQ + **/ +void __init time_init_hook(void) +{ + setup_irq(0, &irq0); +} + diff -Nru a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c --- a/arch/i386/pci/direct.c Fri Jul 11 09:56:33 2003 +++ b/arch/i386/pci/direct.c Fri Jul 11 09:56:33 2003 @@ -4,6 +4,7 @@ #include #include +#include "mach_pci_blacklist.h" #include "pci.h" /* @@ -20,6 +21,9 @@ if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; + if (mach_pci_is_blacklisted(bus,PCI_SLOT(devfn),PCI_FUNC(devfn))) + return -EINVAL; + spin_lock_irqsave(&pci_config_lock, flags); outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8); diff -Nru a/include/asm-i386/mach-default/mach_pci_blacklist.h b/include/asm-i386/mach-default/mach_pci_blacklist.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-i386/mach-default/mach_pci_blacklist.h Fri Jul 11 09:56:33 2003 @@ -0,0 +1,6 @@ +#ifndef __ASM_MACH_PCI_BLACKLIST_H +#define __ASM_MACH_PCI_BLACKLIST_H + +#define mach_pci_is_blacklisted(bus,dev,fn) 0 + +#endif diff -Nru a/include/asm-i386/mach-xbox/mach_pci_blacklist.h b/include/asm-i386/mach-xbox/mach_pci_blacklist.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-i386/mach-xbox/mach_pci_blacklist.h Fri Jul 11 09:56:33 2003 @@ -0,0 +1,6 @@ +#ifndef __ASM_MACH_PCI_BLACKLIST_H +#define __ASM_MACH_PCI_BLACKLIST_H + +#define mach_pci_is_blacklisted(bus,dev,fn) ( (bus>1) || (bus&&(dev||fn)) || ((bus==0 && dev==0) && ((fn==1)||(fn==2))) ) + +#endif diff -Nru a/include/asm-i386/timex.h b/include/asm-i386/timex.h --- a/include/asm-i386/timex.h Fri Jul 11 09:56:33 2003 +++ b/include/asm-i386/timex.h Fri Jul 11 09:56:33 2003 @@ -15,7 +15,11 @@ #ifdef CONFIG_MELAN # define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */ #else -# define CLOCK_TICK_RATE 1193182 /* Underlying HZ */ +# ifdef CONFIG_X86_XBOX +# define CLOCK_TICK_RATE 1124998 /* so has the Xbox */ +# else +# define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ +# endif #endif #endif =================================================================== This BitKeeper patch contains the following changesets: 1.1404 ## Wrapped with uu ## M(R!5&)O>"TR+C4*"B,@4&%T8V@@=F5R"!'86UI;F<@4WES=&5M('-U8F%R8VAI=&5C='5R92X*2R S-3(P. I0 M($-H86YG95-E= HM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM M+2TM+2TM+2TM+2TM+2T*"C!A, H^(&%N9&5R&)O>"]S971U<"YC M?#(P,#,P-S$Q,##8S+FYU?&%R8V@O:3,X-B]M86-H+7AB;W@O#8S+FYU?&%R8V@O:3,X-B]M86-H+7AB;W@O M36%K969I;&5\,C P,S W,3$P-S0R-#5\,#4R,S0*/B!T;W)V86QD"YH?#(P,#,P-S$Q,##8S+FYU?&%R8V@O:3,X M-B]B;V]T+V-O;7!R97-S960O36%K969I;&5\,C P,S W,3$P-S0R-#1\,# R M,CD*/B!Z:7!P96Q ;&EN=7@M;38X:RYO#8S+FYU?&%R8V@O:3,X-B]+8V]N9FEG?#(P,#,P-S$Q M,##8S+FYU?&%R8V@O:3,X-B]M86-H+7AB;W@O36%K969I M;&5\,C P,S W,3$P-S0R-#1\,#,X-35\,68W83,X835C-#-A9F0R-0I$(#$N M," P,R\P-R\Q,2 P.3HT,CHT-"LP,CHP,"!A;F1E&)O>"TR+C4O87)C:"]I M,S@V+VUA8V@M>&)O>"]-86ME9FEL90I+(#,X-34*4"!A#8S+FYU("LU M("TP"D(@=&]R=F%L9'- 871H;&]N+G1R86YS;65T82YC;VU\0VAA;F=E4V5T M?#(P,#(P,C U,3#8S+FYU("LU,2 M, I"('1O&)O>"]R96)O;W0N8PHM+2TM+2TM+2TM M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2T*"DDP(#4Q M"B\J"B J(&%R8V@O:3,X-B]M86-H+7AB;W@O$,P,# *(V1E9FEN92!80D]87U--0E](3U-4 M7T%$1%)%4U,@(" @(" @*#!X-" K(%A"3UA?4TU"7TE/7T)!4T4I"B-D969I M;F4@6$)/6%]334)?2$]35%]#3TU-04Y$(" @(" @("@P>#@@*R!80D]87U-- M0E])3U]"05-%*0HC9&5F:6YE(%A"3UA?4TU"7TA/4U1?1$%402 @(" @(" @ M(" H,'@V("L@6$)/6%]334)?24]?0D%312D*(V1E9FEN92!80D]87U--0E]' M3$]"04Q?14Y!0DQ%(" @(" @*#!X,B K(%A"3UA?4TU"7TE/7T)!4T4I"EP* M(V1E9FEN92!80D]87U!)0U]!1$1215-3(#!X,3 *7 HC9&5F:6YE(%--0U]# M341?4$]715(@,'@P,@HC9&5F:6YE(%--0U]354)#341?4$]715)?4D53150@ M,'@P,0HC9&5F:6YE(%--0U]354)#341?4$]715)?0UE#3$4@,'@T, HC9&5F M:6YE(%--0U]354)#341?4$]715)?3T9&(#!X.# *7 I<"G-T871I8R!V;VED M('AB;WA?<&EC7V-M9"AU."!C;VUM86YD*0I["@EO=71W7W H*"A80D]87U!) M0U]!1$1215-3*2 \/" Q*2Q80D]87U--0E](3U-47T%$1%)%4U,I.PH);W5T M8E]P*%--0U]#341?4$]715(L(%A"3UA?4TU"7TA/4U1?0T]-34%.1"D["@EO M=71W7W H8V]M;6%N9"P@6$)/6%]334)?2$]35%]$051!*3L*"6]U='=?<"AI M;GPH)<')I;G1K*$M%4DY? M24Y&3R B4V5N9&EN9R!03U=%4E]215-%5"!T;R!80D]8+5!)0RY<;B(I.PH) M>&)O>%]P:6-?8VUD*%--0U]354)#341?4$]715)?4D53150I.R @"GT*7 IV M;VED(&UA8VAI;F5?<&]W97)?;V9F*'9O:60I"GL*"7!R:6YT:RA+15).7TE. M1D\@(E-E;F1I;F<@4$]715)?3T9&('1O(%A"3U@M4$E#+EQN(BD["@EX8F]X M7W!I8U]C;60H4TU#7U-50D--1%]03U=%4E]/1D8I.R @"GT*7 IV;VED(&UA M8VAI;F5?:&%L="AV;VED*0I["GT*"CT](&%R8V@O:3,X-B]M86-H+7AB;W@O M&)O>"]S971U M<"YC"E8@- H*86YD97)S9T P>#8S+FYU?&%R8V@O:3,X-B]M86-H+7AB;W@O M&)O>"]S971U<"YC"E(@8C@Y.#EF-F)D-&4R.38U-@I8(#!X.#(Q M"BTM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM M+2TM+0H*"F%N9&5R"]I;G1E M2!I;G1E2X*("HJ+PIV;VED(%]?:6YI="!PPH):6YI=%])4T%?:7)Q2!S971U<%]A2!B92!N965D960@8F5F;W)E('-E='5P7V%R8V@H*2!R=6YS+B @3VX@5DE3 M5U,*("H)=&AI2!S<&5C:69I8R!I;FET:6%L:7-A=&EO;G,@9F]R('1H92!S M>7-T96T@=&EM97(N"B J"B J($1E#8S M+FYU?&EN8VQU9&4O87-M+6DS.#8O;6%C:"UD969A=6QT+VUA8VA?<&-I7V)L M86-K;&ES="YH?#(P,#,P-S$Q,##8S M+FYU("LV("TP"D(@=&]R=F%L9'- 871H;&]N+G1R86YS;65T82YC;VU\0VAA M;F=E4V5T?#(P,#(P,C U,3&)O>"]M86-H7W!C:5]B;&%C:VQI&)O>"TR+C4O:6YC;'5D92]A&)O>"]M86-H7W!C:5]B;&%C M:VQI&)O>"!U M#8S+FYU("LT("TP"D(@=&]R=F%L9'- M871H;&]N+G1R86YS;65T82YC;VU\0VAA;F=E4V5T?#(P,#(P,C U,3&)O> I<"@H]/2!A&)O M>&5N"F,@8W)AF%T:6]N(&UA:V5S(#$N,2UX8F]X96X@"B,@(" @8W)A M"YH?#(P,#,P-C Y,3(T,3(S?#4S.3 V"D0@,2XV(# S+S W+S$Q(# Y.C0R M.C0T*S R.C P(&%N9&5R&)O>"!H87,@82!D:69F M97)E;G0@0TQ/0TM?5$E#2U]2051%+@I+(#8P.3@X"D\@+7)W+7)W+7(M+0I0 M(&EN8VQU9&4O87-M+6DS.#8O=&EM97@N: HM+2TM+2TM+2TM+2TM+2TM+2TM M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2T*"D0Q." Q"DDQ." U"B,@ M(&EF9&5F($-/3D9)1U]8.#9?6$)/6 HC(" @(&1E9FEN92!#3$]#2U]424-+ M7U)!5$4@,3$R-#DY." O*B!S;R!H87,@=&AE(%AB;W@@*B\*(R @96QS92 * M(R @("!D969I;F4@0TQ/0TM?5$E#2U]2051%(#$Q.3,Q.# @+RH@56YD97)L M>6EN9R!(6B J+PHC("!E;F1I9@H*/3T@87)C:"]I,S@V+TMC;VYF:6<@/3T* M>FEP<&5L0&QI;G5X+6TV.&LN;W)G6W1O7-T96T@7-T96TB M"@EH96QP"@D@(%1H:7,@;W!T:6]N(&ES(&YE961E9"!T;R!M86ME($QI;G5X M(&)O;W0@;VX@6$)O>"!'86UI;F<@4WES=&5M