diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 01:05:20 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 01:05:20 +0000 |
commit | 546db14ee74118296f425f3b91634fb767d67290 (patch) | |
tree | 22b613a3da8d4bf663eec5e155af01b87fdf9094 /arch/ppc/kernel | |
parent | 1e25e41c4f5474e14452094492dbc169b800e4c8 (diff) |
Merge with Linux 2.3.23. The new bootmem stuff has broken various
platforms. At this time I've only verified that IP22 support compiles
and IP27 actually works.
Diffstat (limited to 'arch/ppc/kernel')
-rw-r--r-- | arch/ppc/kernel/apus_setup.c | 3 | ||||
-rw-r--r-- | arch/ppc/kernel/chrp_pci.c | 1 | ||||
-rw-r--r-- | arch/ppc/kernel/chrp_setup.c | 102 | ||||
-rw-r--r-- | arch/ppc/kernel/gemini_setup.c | 2 | ||||
-rw-r--r-- | arch/ppc/kernel/idle.c | 5 | ||||
-rw-r--r-- | arch/ppc/kernel/irq.c | 14 | ||||
-rw-r--r-- | arch/ppc/kernel/m8xx_setup.c | 10 | ||||
-rw-r--r-- | arch/ppc/kernel/mbx_setup.c | 11 | ||||
-rw-r--r-- | arch/ppc/kernel/misc.S | 4 | ||||
-rw-r--r-- | arch/ppc/kernel/pci.c | 22 | ||||
-rw-r--r-- | arch/ppc/kernel/pmac_pci.c | 22 | ||||
-rw-r--r-- | arch/ppc/kernel/pmac_pic.c | 9 | ||||
-rw-r--r-- | arch/ppc/kernel/pmac_setup.c | 8 | ||||
-rw-r--r-- | arch/ppc/kernel/ppc_ksyms.c | 1 | ||||
-rw-r--r-- | arch/ppc/kernel/prep_setup.c | 3 | ||||
-rw-r--r-- | arch/ppc/kernel/setup.c | 19 |
16 files changed, 95 insertions, 141 deletions
diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c index 80377490a..353482a18 100644 --- a/arch/ppc/kernel/apus_setup.c +++ b/arch/ppc/kernel/apus_setup.c @@ -255,8 +255,7 @@ struct pci_bus * __init pci_scan_peer_bridge(int bus) /*********************************************************** SETUP */ /* From arch/m68k/kernel/setup.c. */ -void __init apus_setup_arch(unsigned long * memory_start_p, - unsigned long * memory_end_p) +void __init apus_setup_arch(void) { #ifdef CONFIG_APUS extern char cmd_line[]; diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c index da752ccb6..983a9f2eb 100644 --- a/arch/ppc/kernel/chrp_pci.c +++ b/arch/ppc/kernel/chrp_pci.c @@ -16,7 +16,6 @@ #include <asm/hydra.h> #include <asm/prom.h> #include <asm/gg2.h> -#include <asm/ide.h> #include <asm/machdep.h> #include "pci.h" diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c index 4f71def9a..58d2003c4 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/kernel/chrp_setup.c @@ -28,6 +28,7 @@ #include <linux/reboot.h> #include <linux/init.h> #include <linux/blk.h> +#include <linux/ide.h> #include <linux/ioport.h> #include <linux/console.h> #include <linux/pci.h> @@ -35,13 +36,12 @@ #include <linux/version.h> #include <linux/adb.h> #include <linux/module.h> +#include <linux/delay.h> #include <asm/mmu.h> #include <asm/processor.h> #include <asm/io.h> #include <asm/pgtable.h> -#include <linux/ide.h> -#include <asm/ide.h> #include <asm/prom.h> #include <asm/gg2.h> #include <asm/pci-bridge.h> @@ -227,7 +227,7 @@ static void __init sio_init(void) void __init -chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) +chrp_setup_arch(void) { extern char cmd_line[]; struct device_node *device; @@ -278,7 +278,7 @@ chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif - *memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p); + pmac_find_bridges(); /* Get the event scan rate for the rtas so we know how * often it expects a heartbeat. -- Cort @@ -363,10 +363,7 @@ int chrp_get_irq( struct pt_regs *regs ) irq = *chrp_int_ack_special; else irq = i8259_irq( smp_processor_id() ); - /* - * Acknowledge as soon as possible to allow i8259 - * interrupt nesting */ - openpic_eoi( smp_processor_id() ); + openpic_eoi( smp_processor_id() ); } if (irq == OPENPIC_VEC_SPURIOUS) /* @@ -374,6 +371,11 @@ int chrp_get_irq( struct pt_regs *regs ) * acknowledged */ irq = -1; + /* + * I would like to openpic_eoi here but there seem to be timing problems + * between the openpic ack and the openpic eoi. + * -- Cort + */ return irq; } @@ -382,89 +384,15 @@ void chrp_post_irq(int irq) /* * If it's an i8259 irq then we've already done the * openpic irq. So we just check to make sure the controller - * is an openpic and if it is then eoi -- Cort + * is an openpic and if it is then eoi + * + * We do it this way since our irq_desc[irq].ctl can change + * with RTL and no longer be open_pic -- Cort */ - if ( irq_desc[irq].ctl == &open_pic ) + if ( irq >= open_pic.irq_offset) openpic_eoi( smp_processor_id() ); } -#if 0 -void -chrp_do_IRQ(struct pt_regs *regs, - int cpu, - int isfake) -{ - int irq; - unsigned long bits = 0; - int openpic_eoi_done = 0; - -#ifdef __SMP__ - { - unsigned int loops = 1000000; - while (test_bit(0, &global_irq_lock)) { - if (smp_processor_id() == global_irq_holder) { - printk("uh oh, interrupt while we hold global irq lock!\n"); -#ifdef CONFIG_XMON - xmon(0); -#endif - break; - } - if (loops-- == 0) { - printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder); -#ifdef CONFIG_XMON - xmon(0); -#endif - } - } - } -#endif /* __SMP__ */ - - irq = openpic_irq(0); - if (irq == IRQ_8259_CASCADE) - { - /* - * This magic address generates a PCI IACK cycle. - * - * This should go in the above mask/ack code soon. -- Cort - */ - if ( chrp_int_ack_special ) - irq = *chrp_int_ack_special; - else - irq = i8259_irq(0); - /* - * Acknowledge as soon as possible to allow i8259 - * interrupt nesting */ - openpic_eoi(0); - openpic_eoi_done = 1; - } - if (irq == OPENPIC_VEC_SPURIOUS) - { - /* - * Spurious interrupts should never be - * acknowledged - */ - ppc_spurious_interrupts++; - openpic_eoi_done = 1; - goto out; - } - bits = 1UL << irq; - - if (irq < 0) - { - printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", - irq, regs->nip); - ppc_spurious_interrupts++; - } - else - { - ppc_irq_dispatch_handler( regs, irq ); - } -out: - if (!openpic_eoi_done) - openpic_eoi(0); -} -#endif - void __init chrp_init_IRQ(void) { struct device_node *np; diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c index 6e599cff2..23060ba26 100644 --- a/arch/ppc/kernel/gemini_setup.c +++ b/arch/ppc/kernel/gemini_setup.c @@ -134,7 +134,7 @@ extern int root_mountflags; extern char cmd_line[]; -void __init gemini_setup_arch(unsigned long *memstart, unsigned long *memend) +void __init gemini_setup_arch(void) { unsigned int cpu; extern char cmd_line[]; diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index 09066a848..8f03ac79a 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -293,11 +293,8 @@ void power_save(void) /* set the POW bit in the MSR, and enable interrupts * so we wake up sometime! */ + __sti(); /* this keeps rtl from getting confused -- Cort */ _nmask_and_or_msr(0, MSR_POW | MSR_EE); - - /* Disable interrupts again so restore_flags will - * work. */ - _nmask_and_or_msr(MSR_EE, 0); } restore_flags(msr); default: diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index 9c157d41b..9ab3589f6 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -296,15 +296,19 @@ asmlinkage void do_IRQ(struct pt_regs *regs, int isfake) irq = ppc_md.get_irq( regs ); if ( irq < 0 ) { - printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", - irq, regs->nip); - ppc_spurious_interrupts++; - return; + /* -2 means ignore, already handled */ + if (irq != -2) { + printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", + irq, regs->nip); + ppc_spurious_interrupts++; + } + goto out; } ppc_irq_dispatch_handler( regs, irq ); if ( ppc_md.post_irq ) ppc_md.post_irq( irq ); - + + out: hardirq_exit( cpu ); } diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c index f99f5b335..4d510612b 100644 --- a/arch/ppc/kernel/m8xx_setup.c +++ b/arch/ppc/kernel/m8xx_setup.c @@ -33,6 +33,7 @@ #include <linux/blk.h> #include <linux/ioport.h> #include <linux/ide.h> +#include <linux/bootmem.h> #include <asm/mmu.h> #include <asm/processor.h> @@ -83,13 +84,12 @@ void __init adbdev_init(void) } void __init -m8xx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) +m8xx_setup_arch(void) { int cpm_page; extern char cmd_line[]; - cpm_page = *memory_start_p; - *memory_start_p += PAGE_SIZE; + cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE); printk("Boot arguments: %s\n", cmd_line); @@ -108,6 +108,9 @@ m8xx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) rd_doload = 1; rd_image_start = 0; #endif +#if 0 /* XXX this may need to be updated for the new bootmem stuff, + or possibly just deleted (see set_phys_avail() in init.c). + - paulus. */ /* initrd_start and size are setup by boot/head.S and kernel/head.S */ if ( initrd_start ) { @@ -120,6 +123,7 @@ m8xx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) } } #endif +#endif } void diff --git a/arch/ppc/kernel/mbx_setup.c b/arch/ppc/kernel/mbx_setup.c index 67cab4503..f6487783b 100644 --- a/arch/ppc/kernel/mbx_setup.c +++ b/arch/ppc/kernel/mbx_setup.c @@ -30,6 +30,7 @@ #include <linux/reboot.h> #include <linux/init.h> #include <linux/blk.h> +#include <linux/ide.h> #include <linux/ioport.h> #include <asm/mmu.h> @@ -37,7 +38,6 @@ #include <asm/residual.h> #include <asm/io.h> #include <asm/pgtable.h> -#include <asm/ide.h> #include <asm/mbx.h> #include <asm/machdep.h> @@ -76,13 +76,12 @@ void __init adbdev_init(void) } void __init -mbx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) +mbx_setup_arch(void) { int cpm_page; extern char cmd_line[]; - cpm_page = *memory_start_p; - *memory_start_p += PAGE_SIZE; + cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE); sprintf(cmd_line, "%s root=/dev/nfs nfsroot=/sys/mbxroot", @@ -104,6 +103,9 @@ mbx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) rd_doload = 1; rd_image_start = 0; #endif +#if 0 /* XXX this may need to be updated for the new bootmem stuff, + or possibly just deleted (see set_phys_avail() in init.c). + - paulus. */ /* initrd_start and size are setup by boot/head.S and kernel/head.S */ if ( initrd_start ) { @@ -116,6 +118,7 @@ mbx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) } } #endif +#endif #ifdef notdef request_region(0x20,0x20,"pic1"); diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 4d041cc98..89994881b 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -235,9 +235,9 @@ _GLOBAL(flush_dcache_range) * snoop from the data cache. * This is a no-op on the 601 which has a unified cache. * - * void flush_page_to_ram(void *page) + * void __flush_page_to_ram(void *page) */ -_GLOBAL(flush_page_to_ram) +_GLOBAL(__flush_page_to_ram) mfspr r5,PVR rlwinm r5,r5,16,16,31 cmpi 0,r5,1 diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index de0a0a36d..0d07c289d 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -146,3 +146,25 @@ int pcibios_assign_resource(struct pci_dev *pdev, int resource) { return 0; } + +/* the next two are stolen from the alpha port... */ +void __init +pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + unsigned long where, size; + u32 reg; + + where = PCI_BASE_ADDRESS_0 + (resource * 4); + size = res->end - res->start; + pci_read_config_dword(dev, where, ®); + reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); + pci_write_config_dword(dev, where, reg); +} + +void __init +pcibios_update_irq(struct pci_dev *dev, int irq) +{ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); + /* XXX FIXME - update OF device tree node interrupt property */ +} diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c index 932e7dbb6..62161f68a 100644 --- a/arch/ppc/kernel/pmac_pci.c +++ b/arch/ppc/kernel/pmac_pci.c @@ -17,6 +17,7 @@ #include <linux/delay.h> #include <linux/string.h> #include <linux/init.h> +#include <linux/bootmem.h> #include <asm/init.h> #include <asm/io.h> @@ -30,7 +31,7 @@ struct bridge_data **bridges, *bridge_list; static int max_bus; -static void add_bridges(struct device_node *dev, unsigned long *mem_ptr); +static void add_bridges(struct device_node *dev); /* * Magic constants for enabling cache coherency in the bandit/PSX bridge. @@ -362,24 +363,22 @@ static void __init init_bandit(struct bridge_data *bp) bp->io_base); } -unsigned long __init pmac_find_bridges(unsigned long mem_start, unsigned long mem_end) +void __init pmac_find_bridges(void) { int bus; struct bridge_data *bridge; bridge_list = 0; max_bus = 0; - add_bridges(find_devices("bandit"), &mem_start); - add_bridges(find_devices("chaos"), &mem_start); - add_bridges(find_devices("pci"), &mem_start); - bridges = (struct bridge_data **) mem_start; - mem_start += (max_bus + 1) * sizeof(struct bridge_data *); + add_bridges(find_devices("bandit")); + add_bridges(find_devices("chaos")); + add_bridges(find_devices("pci")); + bridges = (struct bridge_data **) + alloc_bootmem((max_bus + 1) * sizeof(struct bridge_data *)); memset(bridges, 0, (max_bus + 1) * sizeof(struct bridge_data *)); for (bridge = bridge_list; bridge != NULL; bridge = bridge->next) for (bus = bridge->bus_number; bus <= bridge->max_bus; ++bus) bridges[bus] = bridge; - - return mem_start; } /* @@ -387,7 +386,7 @@ unsigned long __init pmac_find_bridges(unsigned long mem_start, unsigned long me * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise, * if we have one or more bandit or chaos bridges, we don't have a MPC106. */ -static void __init add_bridges(struct device_node *dev, unsigned long *mem_ptr) +static void __init add_bridges(struct device_node *dev) { int *bus_range; int len; @@ -413,8 +412,7 @@ static void __init add_bridges(struct device_node *dev, unsigned long *mem_ptr) printk(KERN_INFO "PCI buses %d..%d", bus_range[0], bus_range[1]); printk(" controlled by %s at %x\n", dev->name, addr->address); - bp = (struct bridge_data *) *mem_ptr; - *mem_ptr += sizeof(struct bridge_data); + bp = (struct bridge_data *) alloc_bootmem(sizeof(*bp)); if (strcmp(dev->name, "pci") != 0) { bp->cfg_addr = (volatile unsigned int *) ioremap(addr->address + 0x800000, 0x1000); diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c index 683aac568..f7224f5dd 100644 --- a/arch/ppc/kernel/pmac_pic.c +++ b/arch/ppc/kernel/pmac_pic.c @@ -225,7 +225,7 @@ pmac_get_irq(struct pt_regs *regs) xmon(regs); #endif smp_message_recv(); - return -1; + return -2; /* ignore, already handled */ } { @@ -374,7 +374,7 @@ pmac_pic_init(void) } /* get addresses of second controller */ - irqctrler = (irqctrler->next) ? irqctrler->next : NULL; + irqctrler = irqctrler->next; if (irqctrler && irqctrler->n_addrs > 0) { addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); @@ -382,6 +382,11 @@ pmac_pic_init(void) pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) (addr + (4 - i) * 0x10); } + } else { + /* older powermacs have a GC (grand central) or ohare at + f3000000, with interrupt control registers at f3000020. */ + addr = (unsigned long) ioremap(0xf3000000, 0x40); + pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20); } /* disable all interrupts in all controllers */ diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c index 3418a7e8b..0a23c4473 100644 --- a/arch/ppc/kernel/pmac_setup.c +++ b/arch/ppc/kernel/pmac_setup.c @@ -39,6 +39,7 @@ #include <linux/ioport.h> #include <linux/major.h> #include <linux/blk.h> +#include <linux/ide.h> #include <linux/vt_kern.h> #include <linux/console.h> #include <linux/ide.h> @@ -57,7 +58,6 @@ #include <asm/ohare.h> #include <asm/mediabay.h> #include <asm/feature.h> -#include <asm/ide.h> #include <asm/machdep.h> #include <asm/keyboard.h> #include <asm/dma.h> @@ -238,7 +238,7 @@ pmac_mksound(unsigned int hz, unsigned int ticks) static volatile u32 *sysctrl_regs; void __init -pmac_setup_arch(unsigned long *memory_start_p, unsigned long *memory_end_p) +pmac_setup_arch(void) { struct device_node *cpu; int *fp; @@ -269,7 +269,7 @@ pmac_setup_arch(unsigned long *memory_start_p, unsigned long *memory_end_p) __ioremap(0xffc00000, 0x400000, pgprot_val(PAGE_READONLY)); ohare_init(); - *memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p); + pmac_find_bridges(); init_p2pbridge(); /* Checks "l2cr-value" property in the registry */ @@ -421,7 +421,7 @@ note_scsi_host(struct device_node *node, void *host) #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) extern int pmac_ide_count; extern struct device_node *pmac_ide_node[]; -static int ide_majors[] = { 3, 22, 33, 34, 56, 57, 88, 89 }; +static int ide_majors[] = { 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 }; kdev_t __init find_ide_boot(void) { diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index cabce054c..399b99052 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -60,7 +60,6 @@ EXPORT_SYMBOL(do_signal); EXPORT_SYMBOL(syscall_trace); EXPORT_SYMBOL(transfer_to_handler); EXPORT_SYMBOL(do_IRQ); -EXPORT_SYMBOL(init_task_union); EXPORT_SYMBOL(MachineCheckException); EXPORT_SYMBOL(AlignmentException); EXPORT_SYMBOL(ProgramCheckException); diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c index 53c859a16..fe7043206 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/kernel/prep_setup.c @@ -41,7 +41,6 @@ #include <asm/residual.h> #include <asm/io.h> #include <asm/pgtable.h> -#include <asm/ide.h> #include <asm/cache.h> #include <asm/dma.h> #include <asm/machdep.h> @@ -211,7 +210,7 @@ no_l2: } void __init -prep_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p) +prep_setup_arch() { extern char cmd_line[]; unsigned char reg; diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 57955efca..518446bf9 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -11,12 +11,11 @@ #include <linux/reboot.h> #include <linux/delay.h> #include <linux/blk.h> +#include <linux/ide.h> #include <asm/init.h> #include <asm/residual.h> #include <asm/io.h> -#include <linux/ide.h> -#include <asm/ide.h> #include <asm/prom.h> #include <asm/processor.h> #include <asm/pgtable.h> @@ -540,14 +539,12 @@ void __init ppc_init(void) } } -void __init setup_arch(char **cmdline_p, - unsigned long * memory_start_p, unsigned long * memory_end_p) +void __init setup_arch(char **cmdline_p) { extern int panic_timeout; extern char _etext[], _edata[]; extern char *klimit; - extern unsigned long find_available_memory(void); - extern unsigned long *end_of_DRAM; + extern void do_init_bootmem(void); #ifdef CONFIG_XMON extern void xmon_map_scc(void); @@ -556,22 +553,22 @@ void __init setup_arch(char **cmdline_p, xmon(0); #endif /* CONFIG_XMON */ - /* reboot on panic */ + /* reboot on panic */ panic_timeout = 180; init_mm.start_code = PAGE_OFFSET; init_mm.end_code = (unsigned long) _etext; init_mm.end_data = (unsigned long) _edata; - init_mm.brk = (unsigned long) klimit; + init_mm.brk = (unsigned long) klimit; /* Save unparsed command line copy for /proc/cmdline */ strcpy(saved_command_line, cmd_line); *cmdline_p = cmd_line; - *memory_start_p = find_available_memory(); - *memory_end_p = (unsigned long) end_of_DRAM; + /* set up the bootmem stuff with available memory */ + do_init_bootmem(); - ppc_md.setup_arch(memory_start_p, memory_end_p); + ppc_md.setup_arch(); /* clear the progress line */ if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); } |