diff -r -N -u /usr/src/linux/Documentation/Configure.help linux-2.2.9/Documentation/Configure.help --- /usr/src/linux/Documentation/Configure.help Tue May 11 12:57:14 1999 +++ linux-2.2.9/Documentation/Configure.help Sat Aug 14 18:38:35 1999 @@ -1217,9 +1217,12 @@ Alpha system type CONFIG_ALPHA_GENERIC This is the system type of your hardware. A "generic" kernel will - run on any supported Alpha system. However, if you configure a + run on any supported Alpha system expect for "Flamingo" and "Pelican" + family machines (DEC 3000). However, if you configure a kernel for your specific system, it will be faster and smaller. + For the DEC 3000 systems, you *must* build a system-specific kernel. + To find out what type of Alpha system you have, you may want to check out the Linux/Alpha FAQ, accessible on the WWW from http://www.alphalinux.org (To browse the WWW, you need to @@ -1236,6 +1239,8 @@ EB64+ EB64+ 21064 evaluation board EB66 EB66 21066 evaluation board EB66+ EB66+ 21066 evaluation board + Flamingo DEC 3000 models 400, 500, 500X, 600, + 700, 800 or 900 Jensen DECpc 150, DEC 2000 model 300, DEC 2000 model 500 LX164 AlphaPC164-LX @@ -1245,6 +1250,7 @@ Noname AXPpci33, UDB (Multia) Noritake AS 1000A, AS 600A, AS 800 PC164 AlphaPC164 + Pelican DEC 3000 models 300, 300L, 300X, 300LX Rawhide AS 1200, AS 4000, AS 4100 Ruffian RPX164-2, AlphaPC164-UX, AlphaPC164-BX SX164 AlphaPC164-SX @@ -1260,6 +1266,34 @@ EV5 CPU(s) CONFIG_ALPHA_GAMMA Say Y if you have an AS 2000 5/xxx or an AS 2100 5/xxx. + +DEC 3000/300 series (Pelican family) system type +CONFIG_ALPHA_PELICAN_PELICAN + There are four models in the DEC 3000/300 series (aka "Pelican" family) + of Alphas. Choose your system type from this table: + + Model Alias + ----- ----- + DEC 3000/300 Pelican + DEC 3000/300L Pelica + DEC 3000/300X Pelican+ + DEC 3000/300LX Pelica+ + +DEC 3000/[4-9]00 series (Flamingo family) system type +CONFIG_ALPHA_FLAMINGO_SANDPIPER + DEC 3000 models 400, 500, 500X, 600, 700, 800, and 900 are all + part of the "Flamingo" family of DEC 3000 machines. Choose your + system type from this table: + + Model Alias + ----- ----- + DEC 3000/400 Sandpiper + DEC 3000/500 Flamingo + DEC 3000/500X Hot Pink + DEC 3000/600 Sandpiper+ + DEC 3000/700 Sandpiper45 + DEC 3000/800 Flamingo+ + DEC 3000/900 Flamingo45 Using SRM as bootloader CONFIG_ALPHA_SRM diff -r -N -u /usr/src/linux/Makefile linux-2.2.9/Makefile --- /usr/src/linux/Makefile Wed May 12 11:50:12 1999 +++ linux-2.2.9/Makefile Sat Aug 14 18:36:36 1999 @@ -138,6 +138,10 @@ DRIVERS := $(DRIVERS) drivers/pci/pci.a endif +ifdef CONFIG_TC +DRIVERS := $(DRIVERS) drivers/tc/tc.a +endif + ifdef CONFIG_DIO DRIVERS := $(DRIVERS) drivers/dio/dio.a endif diff -r -N -u /usr/src/linux/arch/alpha/config.in linux-2.2.9/arch/alpha/config.in --- /usr/src/linux/arch/alpha/config.in Mon May 10 12:55:21 1999 +++ linux-2.2.9/arch/alpha/config.in Sat Aug 14 18:34:58 1999 @@ -33,6 +33,7 @@ EB64+ CONFIG_ALPHA_EB64P \ EB66 CONFIG_ALPHA_EB66 \ EB66+ CONFIG_ALPHA_EB66P \ + Flamingo CONFIG_ALPHA_FLAMINGO \ Jensen CONFIG_ALPHA_JENSEN \ LX164 CONFIG_ALPHA_LX164 \ Miata CONFIG_ALPHA_MIATA \ @@ -40,6 +41,7 @@ Noname CONFIG_ALPHA_NONAME \ Noritake CONFIG_ALPHA_NORITAKE \ PC164 CONFIG_ALPHA_PC164 \ + Pelican CONFIG_ALPHA_PELICAN \ Platform2000 CONFIG_ALPHA_P2K \ Rawhide CONFIG_ALPHA_RAWHIDE \ Ruffian CONFIG_ALPHA_RUFFIAN \ @@ -50,10 +52,11 @@ # clear all implied options (don't want default values for those): unset CONFIG_ALPHA_EV4 CONFIG_ALPHA_EV5 CONFIG_ALPHA_EV6 -unset CONFIG_PCI CONFIG_ALPHA_EISA +unset CONFIG_PCI CONFIG_TC CONFIG_ALPHA_EISA unset CONFIG_ALPHA_LCA CONFIG_ALPHA_APECS CONFIG_ALPHA_CIA unset CONFIG_ALPHA_T2 CONFIG_ALPHA_PYXIS CONFIG_ALPHA_POLARIS -unset CONFIG_ALPHA_TSUNAMI CONFIG_ALPHA_MCPCIA +unset CONFIG_ALPHA_TSUNAMI CONFIG_ALPHA_MCPCIA CONFIG_ALPHA_TCASIC +unset CONFIG_ZS if [ "$CONFIG_ALPHA_GENERIC" = "y" ] then @@ -164,6 +167,34 @@ if [ "$CONFIG_ALPHA_XL" = "y" ] then define_bool CONFIG_ALPHA_AVANTI y +fi +if [ "$CONFIG_ALPHA_PELICAN" = "y" -o "$CONFIG_ALPHA_FLAMINGO" = "y" ] +then + define_bool CONFIG_ALPHA_EV4 y + define_bool CONFIG_ALPHA_SRM y + define_bool CONFIG_PCI n + define_bool CONFIG_TC y + define_bool CONFIG_ALPHA_TCASIC y + define_bool CONFIG_ZS y + if [ "$CONFIG_ALPHA_PELICAN" = "y" ] + then + choice 'Pelican family system type' \ + "Pelican CONFIG_ALPHA_PELICAN_PELICAN \ + Pelica CONFIG_ALPHA_PELICAN_PELICA \ + Pelican+ CONFIG_ALPHA_PELICAN_PELICANPLUS \ + Pelica+ CONFIG_ALPHA_PELICAN_PELICAPLUS" \ + Pelican + else + choice 'Flamingo family system type' \ + "Sandpiper CONFIG_ALPHA_FLAMINGO_SANDPIPER \ + Flamingo CONFIG_ALPHA_FLAMINGO_FLAMINGO \ + HotPink CONFIG_ALPHA_FLAMINGO_HOTPINK \ + Sandpiper+ CONFIG_ALPHA_FLAMINGO_SANDPIPERPLUS \ + Sandpiper45 CONFIG_ALPHA_FLAMINGO_SANDPIPER45 \ + Flamingo+ CONFIG_ALPHA_FLAMINGO_FLAMINGOPLUS \ + Flamingo45 CONFIG_ALPHA_FLAMINGO_FLAMINGO45" \ + Sandpiper + fi fi bool 'Symmetric multi-processing support' CONFIG_SMP diff -r -N -u /usr/src/linux/arch/alpha/kernel/Makefile linux-2.2.9/arch/alpha/kernel/Makefile --- /usr/src/linux/arch/alpha/kernel/Makefile Sun Jan 10 12:59:54 1999 +++ linux-2.2.9/arch/alpha/kernel/Makefile Sat Aug 14 18:34:58 1999 @@ -23,11 +23,12 @@ ifdef CONFIG_ALPHA_GENERIC O_OBJS += core_apecs.o core_cia.o core_lca.o core_mcpcia.o core_pyxis.o \ - core_t2.o core_tsunami.o core_polaris.o \ + core_t2.o core_tsunami.o core_polaris.o core_tcasic.o serial.o \ sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o \ sys_jensen.o sys_miata.o sys_mikasa.o sys_noritake.o \ sys_rawhide.o sys_ruffian.o sys_sable.o sys_sio.o \ sys_sx164.o sys_takara.o sys_rx164.o \ + sys_pelican.o sys_flamingo.o \ es1888.o smc37c669.o smc37c93x.o else @@ -56,6 +57,9 @@ ifdef CONFIG_ALPHA_POLARIS O_OBJS += core_polaris.o endif +ifdef CONFIG_ALPHA_TCASIC +O_OBJS += core_tcasic.o +endif # Board support ifneq ($(CONFIG_ALPHA_ALCOR)$(CONFIG_ALPHA_XLT),) @@ -102,6 +106,12 @@ endif ifdef CONFIG_ALPHA_TAKARA O_OBJS += sys_takara.o +endif +ifdef CONFIG_ALPHA_PELICAN +O_OBJS += sys_pelican.o serial.o +endif +ifdef CONFIG_ALPHA_FLAMINGO +O_OBJS += sys_flamingo.o serial.o endif # Device support diff -r -N -u /usr/src/linux/arch/alpha/kernel/core_tcasic.c linux-2.2.9/arch/alpha/kernel/core_tcasic.c --- /usr/src/linux/arch/alpha/kernel/core_tcasic.c Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/arch/alpha/kernel/core_tcasic.c Sun Aug 15 02:18:35 1999 @@ -0,0 +1,122 @@ +/* + * linux/arch/alpha/kernel/core_tcasic.c + * + * adapted from linux/arch/alpha/kernel/core_apecs.c + * + * This has been gutted thoroughly... + */ +#include +#include +#include +#include + +#include +#include + +#define __EXTERN_INLINE inline +#include +#include +#undef __EXTERN_INLINE + +#include "proto.h" + +#ifdef DEBUG +# define DBG(args) printk args +#else +# define DBG(args) +#endif + +#define vuip volatile unsigned int * + +volatile unsigned int tcasic_mcheck_expected = 0; +volatile unsigned int tcasic_mcheck_taken = 0; +static unsigned int tcasic_jd, tcasic_jd1, tcasic_jd2; + +static int +mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *tc_addr, + unsigned char *type1) +{ + return 0; +} + +static unsigned int +conf_read(unsigned long addr, unsigned char type1) +{ + return 0; +} + +static void +conf_write(unsigned long addr, unsigned int value, unsigned char type1) +{ + +} + +int +tcasic_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value, + struct linux_hose_info *hose) +{ + return 0; +} + +int +tcasic_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value, + struct linux_hose_info *hose) +{ + return 0; +} + +int +tcasic_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value, + struct linux_hose_info *hose) +{ + return 0; +} + +int +tcasic_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value, + struct linux_hose_info *hose) +{ + return 0; +} + +int +tcasic_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value, + struct linux_hose_info *hose) +{ + return 0; +} + +int +tcasic_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value, + struct linux_hose_info *hose) +{ + return 0; +} + +void __init +tcasic_init_arch(unsigned long *mem_start, unsigned long *mem_end) +{ + switch (alpha_use_srm_setup) + { + default: + printk("tcasic_init: alpha_use_srm_setup = default\n"); + break; + case 0: + printk("tcasic_init: alpha_use_srm_setup = 0\n"); + break; + } +} + +int +tcasic_tc_clr_err(void) +{ + return 0; +} + +void +tcasic_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) +{ + printk("tcasic_machine_check: vector=0x%lx la_ptr=0x%lx\n", + vector, la_ptr); +} diff -r -N -u /usr/src/linux/arch/alpha/kernel/machvec.h linux-2.2.9/arch/alpha/kernel/machvec.h --- /usr/src/linux/arch/alpha/kernel/machvec.h Fri May 21 08:20:45 1999 +++ linux-2.2.9/arch/alpha/kernel/machvec.h Mon Aug 16 01:08:57 1999 @@ -92,6 +92,7 @@ instructions. So always use them for PYXIS I/O. */ #define DO_APECS_IO IO(APECS,apecs,apecs) +#define DO_TCASIC_IO IO(TCASIC,tcasic,tcasic) #define DO_CIA_IO IO(CIA,cia,cia) #define DO_LCA_IO IO(LCA,lca,lca) #define DO_MCPCIA_IO IO(MCPCIA,mcpcia,mcpcia) @@ -105,6 +106,7 @@ mv_bus_to_virt: CAT(which,_bus_to_virt) #define DO_APECS_BUS BUS(apecs) +#define DO_TCASIC_BUS BUS(tcasic) #define DO_CIA_BUS BUS(cia) #define DO_LCA_BUS BUS(lca) #define DO_MCPCIA_BUS BUS(mcpcia) diff -r -N -u /usr/src/linux/arch/alpha/kernel/proto.h linux-2.2.9/arch/alpha/kernel/proto.h --- /usr/src/linux/arch/alpha/kernel/proto.h Sun Feb 21 22:06:36 1999 +++ linux-2.2.9/arch/alpha/kernel/proto.h Sat Aug 14 18:34:58 1999 @@ -144,6 +144,25 @@ extern void tsunami_init_arch(unsigned long *, unsigned long *); extern void tsunami_machine_check(u64, u64, struct pt_regs *); +/* core_tcasic.c */ +extern int tcasic_hose_read_config_byte (u8, u8, u8, u8 *value, + struct linux_hose_info *hose); +extern int tcasic_hose_read_config_word (u8, u8, u8, u16 *value, + struct linux_hose_info *hose); +extern int tcasic_hose_read_config_dword (u8, u8, u8, u32 *value, + struct linux_hose_info *hose); +extern int tcasic_hose_write_config_byte (u8, u8, u8, u8 value, + struct linux_hose_info *hose); +extern int tcasic_hose_write_config_word (u8, u8, u8, u16 value, + struct linux_hose_info *hose); +extern int tcasic_hose_write_config_dword (u8, u8, u8, u32 value, + struct linux_hose_info *hose); +extern void tcasic_init_arch(unsigned long *, unsigned long *); + +extern volatile unsigned int tcasic_mcheck_expected; +extern volatile unsigned int tcasic_mcheck_taken; +extern void tcasic_machine_check(u64, u64, struct pt_regs *); + /* setup.c */ extern unsigned long srm_hae; diff -r -N -u /usr/src/linux/arch/alpha/kernel/serial.c linux-2.2.9/arch/alpha/kernel/serial.c --- /usr/src/linux/arch/alpha/kernel/serial.c Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/arch/alpha/kernel/serial.c Sat Aug 14 18:03:19 1999 @@ -0,0 +1,48 @@ +/* + * sercons.c + * choose the right serial device at boot time + * + * triemer 6-SEP-1998 + * sercons.c is designed to allow the three different kinds + * of serial devices under the decstation world to co-exist + * in the same kernel. The idea here is to abstract + * the pieces of the drivers that are common to this file + * so that they do not clash at compile time and runtime. + * + * HK 16-SEP-1998 v0.002 + * removed the PROM console as this is not a real serial + * device. Added support for PROM console in drivers/char/tty_io.c + * instead. Although it may work to enable more than one + * console device I strongly recommend to use only one. + */ + +#include +#include + +extern int zs_init(void); + +#ifdef CONFIG_SERIAL_CONSOLE +extern long srm_printk(const char *fmt, ...); +extern long zs_serial_console_init(long, long); +#endif + +/* rs_init - starts up the serial interface - + handle normal case of starting up the serial interface */ + +__initfunc(int rs_init(void)) +{ + return zs_init(); +} + +#ifdef CONFIG_SERIAL_CONSOLE + +/* serial_console_init handles the special case of starting + * up the console on the serial port + */ +__initfunc(long serial_console_init(long kmem_start, long kmem_end)) +{ + kmem_start = zs_serial_console_init(kmem_start, kmem_end); + return kmem_start; +} + +#endif diff -r -N -u /usr/src/linux/arch/alpha/kernel/setup.c linux-2.2.9/arch/alpha/kernel/setup.c --- /usr/src/linux/arch/alpha/kernel/setup.c Sat Apr 24 20:54:08 1999 +++ linux-2.2.9/arch/alpha/kernel/setup.c Sat Aug 14 18:34:58 1999 @@ -39,7 +39,7 @@ #include #include #include - +#include #include "proto.h" @@ -111,6 +111,7 @@ WEAK(eb64p_mv); WEAK(eb66_mv); WEAK(eb66p_mv); +WEAK(flamingo_mv); WEAK(jensen_mv); WEAK(lx164_mv); WEAK(miata_mv); @@ -122,6 +123,7 @@ WEAK(noritake_primo_mv); WEAK(p2k_mv); WEAK(pc164_mv); +WEAK(pelican_mv); WEAK(rawhide_mv); WEAK(ruffian_mv); WEAK(rx164_mv); @@ -169,6 +171,8 @@ * Process command-line arguments. */ + srm_printk("Processing command line args\n"); + for (p = strtok(command_line, " \t"); p ; p = strtok(NULL, " \t")) { #ifndef alpha_use_srm_setup /* Allow a command-line option to respect the @@ -180,11 +184,13 @@ #endif if (strncmp(p, "alpha_mv=", 9) == 0) { + srm_printk("Calling get_sysvec_byname\n"); vec = get_sysvec_byname(p+9); continue; } if (strncmp(p, "cycle=", 6) == 0) { + srm_printk("Estimating cycle freq\n"); est_cycle_freq = simple_strtol(p+6, NULL, 0); continue; } @@ -217,12 +223,17 @@ if (vec != &alpha_mv) alpha_mv = *vec; + srm_printk("hwrpb->ssn: %s\n",(char*)hwrpb->ssn); #ifdef CONFIG_ALPHA_GENERIC /* Assume that we've booted from SRM if we havn't booted from MILO. Detect the later by looking for "MILO" in the system serial nr. */ alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0; #endif + srm_printk("Booting on %s%s%s using machine vector %s\n", + type_name, (*var_name ? " variation " : ""), + var_name, alpha_mv.vector_name); + srm_printk("Command line: %s\n", command_line); printk("Booting on %s%s%s using machine vector %s\n", type_name, (*var_name ? " variation " : ""), var_name, alpha_mv.vector_name); @@ -232,16 +243,22 @@ * Sync with the HAE */ +#if !defined(CONFIG_ALPHA_FLAMINGO) && !defined(CONFIG_ALPHA_PELICAN) + srm_printk("Sync with HAE...\n"); /* Save the SRM's current value for restoration. */ srm_hae = *alpha_mv.hae_register; __set_hae(alpha_mv.hae_cache); + srm_printk("...done\n"); +#endif /* Reset enable correctable error reports. */ wrmces(0x7); /* Find our memory. */ + srm_printk("Finding memory...\n"); *memory_end_p = find_end_memory(); *memory_start_p = (unsigned long) _end; + srm_printk("...done\n"); #ifdef CONFIG_BLK_DEV_INITRD initrd_start = INITRD_START; @@ -261,8 +278,11 @@ /* Initialize the machine. Usually has to do with setting up DMA windows and the like. */ + srm_printk("Inititalizing machine...\n"); + srm_printk("alpha_use_srm_setup: %d\n",alpha_use_srm_setup); if (alpha_mv.init_arch) alpha_mv.init_arch(memory_start_p, memory_end_p); + srm_printk("...done\n"); /* Initialize the timers. */ /* ??? There is some circumstantial evidence that this needs @@ -295,8 +315,8 @@ * FIXME: how was this failing? Should we trust it instead, * and copy the value into alpha_mv.max_asn? */ - if (hwrpb->max_asn != MAX_ASN) { + srm_printk("Max ASN from HWRPB is bad (0x%lx)\n", hwrpb->max_asn); printk("Max ASN from HWRPB is bad (0x%lx)\n", hwrpb->max_asn); } @@ -307,6 +327,7 @@ #ifdef __SMP__ setup_smp(); #endif + srm_printk("Done with setup_arch.\n"); } static unsigned long __init @@ -381,10 +402,10 @@ NULL, /* ADU */ NULL, /* Cobra */ NULL, /* Ruby */ - NULL, /* Flamingo */ + &flamingo_mv, /* Flamingo */ NULL, /* Mannequin */ &jensen_mv, - NULL, /* Pelican */ + &pelican_mv, /* Pelican */ NULL, /* Morgan */ NULL, /* Sable -- see below. */ NULL, /* Medulla */ @@ -542,6 +563,7 @@ &eb64p_mv, &eb66_mv, &eb66p_mv, + &flamingo_mv, &jensen_mv, &lx164_mv, &miata_mv, @@ -553,6 +575,7 @@ &noritake_primo_mv, &p2k_mv, &pc164_mv, + &pelican_mv, &rawhide_mv, &ruffian_mv, &rx164_mv, @@ -743,4 +766,87 @@ #endif return len; +} + +void dump_cpuinfo(void) +{ + extern struct unaligned_stat { + unsigned long count, va, pc; + } unaligned[2]; + + static char cpu_names[][8] = { + "EV3", "EV4", "Simulate", "LCA4", "EV5", "EV45", "EV56", + "EV6", "PCA56", "PCA57", "EV67" + }; + + struct percpu_struct *cpu; + unsigned int cpu_index; + char *cpu_name; + char *systype_name; + char *sysvariation_name; + + int i; + unsigned long tot, tot_good; + struct memclust_struct * cluster; + struct memdesc_struct * memdesc; + + cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset); + cpu_index = (unsigned) (cpu->type - 1); + cpu_name = "Unknown"; + if (cpu_index < N(cpu_names)) + cpu_name = cpu_names[cpu_index]; + + get_sysnames(hwrpb->sys_type, hwrpb->sys_variation, + &systype_name, &sysvariation_name); + + srm_printk("cpu\t\t\t: Alpha\n"); + srm_printk("cpu model\t\t: %s\n", + cpu_name); + srm_printk("cpu variation\t\t: %ld\n", + cpu->variation); + srm_printk("cpu revision\t\t: %ld\n", + cpu->revision); + srm_printk("cpu serial number\t: %s\n", + (char*)cpu->serial_no); + srm_printk("system type\t\t: %s\n", + systype_name); + srm_printk("system variation\t: %s\n", + sysvariation_name); + srm_printk("system revision\t\t: %ld\n", + hwrpb->sys_revision); + srm_printk("system serial number\t: %s\n", + (char*)hwrpb->ssn); + srm_printk("cycle frequency [Hz]\t: %lu %s\n", + est_cycle_freq ? : hwrpb->cycle_freq, + est_cycle_freq ? "est." : ""); + srm_printk("timer frequency [Hz]\t: %lu.%02lu\n", + hwrpb->intr_freq / 4096, + (100 * hwrpb->intr_freq / 4096) % 100); + srm_printk("page size [bytes]\t: %ld\n", + hwrpb->pagesize); + srm_printk("phys. address bits\t: %ld\n", + hwrpb->pa_bits); + srm_printk("max. addr. space #\t: %ld\n", + hwrpb->max_asn); + srm_printk("BogoMIPS\t\t: %lu.%02lu\n", + loops_per_sec / 500000, (loops_per_sec / 5000) % 100); + srm_printk("kernel unaligned acc\t: %ld (pc=%lx,va=%lx)\n", + unaligned[0].count, unaligned[0].pc, unaligned[0].va); + srm_printk("user unaligned acc\t: %ld (pc=%lx,va=%lx)\n", + unaligned[1].count, unaligned[1].pc, unaligned[1].va); + srm_printk("platform string\t\t: %s\n", + platform_string()); + + tot = 0; + tot_good = 0; + memdesc = (struct memdesc_struct *) + (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB); + cluster = memdesc->cluster; + for (i = 1; i < memdesc->numclusters; ++i) { + tot = tot + cluster->numpages; + tot_good = tot_good + cluster->numtested; + } + srm_printk("Total number of pages\t\t: %lu (%lu K)\n",tot, tot * 8); + srm_printk("Total number of tested pages\t: %lu (%lu K)\n", + tot_good, tot_good * 8); } diff -r -N -u /usr/src/linux/arch/alpha/kernel/sys_flamingo.c linux-2.2.9/arch/alpha/kernel/sys_flamingo.c --- /usr/src/linux/arch/alpha/kernel/sys_flamingo.c Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/arch/alpha/kernel/sys_flamingo.c Mon Aug 16 02:30:34 1999 @@ -0,0 +1,180 @@ +/* + * linux/arch/alpha/kernel/sys_flamingo.c + * + * adapted from linux/arch/alpha/kernel/sys_eb64p.c + * + * Code supporting the Flamingo. + * + * But not very well presently... + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Get rid of */ +#include + +#include "proto.h" +#include "irq.h" +#include "bios32.h" +#include "machvec.h" + + +static void +flamingo_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p) +{ + if (irq >= 16) + if (irq >= 24) + outb(mask >> 24, 0x27); + else + outb(mask >> 16, 0x26); + else if (irq >= 8) + outb(mask >> 8, 0xA1); + else + outb(mask, 0x21); +} + +static void +flamingo_device_interrupt(unsigned long vector, struct pt_regs *regs) +{ + unsigned long pld; + unsigned int i; + + /* Read the interrupt summary registers */ + pld = inb(0x26) | (inb(0x27) << 8); + /* + * Now, for every possible bit set, work through + * them and call the appropriate interrupt handler. + */ + while (pld) { + i = ffz(~pld); + pld &= pld - 1; /* clear least bit set */ + + if (i == 5) { + isa_device_interrupt(vector, regs); + } else { + handle_irq(16 + i, 16 + i, regs); + } + } +} + +static void __init +flamingo_init_irq(void) +{ + STANDARD_INIT_IRQ_PROLOG; + + outb(alpha_irq_mask >> 16, 0x26); + outb(alpha_irq_mask >> 24, 0x27); + enable_irq(16 + 5); /* enable SIO cascade */ + enable_irq(2); /* enable cascade */ +} + +/* + * PCI Fixup configuration. + * + * There are two 8 bit external summary registers as follows: + * + * Summary @ 0x26: + * Bit Meaning + * 0 Interrupt Line A from slot 0 + * 1 Interrupt Line A from slot 1 + * 2 Interrupt Line B from slot 0 + * 3 Interrupt Line B from slot 1 + * 4 Interrupt Line C from slot 0 + * 5 Interrupt line from the two ISA PICs + * 6 Tulip (slot + * 7 NCR SCSI + * + * Summary @ 0x27 + * Bit Meaning + * 0 Interrupt Line C from slot 1 + * 1 Interrupt Line D from slot 0 + * 2 Interrupt Line D from slot 1 + * 3 RAZ + * 4 RAZ + * 5 RAZ + * 6 RAZ + * 7 RAZ + * + * The device to slot mapping looks like: + * + * Slot Device + * 5 NCR SCSI controller + * 6 PCI on board slot 0 + * 7 PCI on board slot 1 + * 8 Intel SIO PCI-ISA bridge chip + * 9 Tulip - DECchip 21040 Ethernet controller + * + * + * This two layered interrupt approach means that we allocate IRQ 16 and + * above for PCI interrupts. The IRQ relates to which bit the interrupt + * comes in on. This makes interrupt processing much easier. + */ + +static int __init +flamingo_map_irq(struct pci_dev *dev, int slot, int pin) +{ + static char irq_tab[5][5] __initlocaldata = { + /*INT INTA INTB INTC INTD */ + {16+7, 16+7, 16+7, 16+7, 16+7}, /* IdSel 5, slot ?, ?? */ + {16+0, 16+0, 16+2, 16+4, 16+9}, /* IdSel 6, slot ?, ?? */ + {16+1, 16+1, 16+3, 16+8, 16+10}, /* IdSel 7, slot ?, ?? */ + { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */ + {16+6, 16+6, 16+6, 16+6, 16+6}, /* IdSel 9, TULIP */ + }; + const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5; + return COMMON_TABLE_LOOKUP; +} + +static void __init +flamingo_pci_fixup(void) +{ +/* + * Not a PCI machine. + */ +} + +/* + * The System Vector + * + * cpp: most of this leads to incorrect code (PCI stuff everywhere). + * And I dunno if the RTC stuff is ok or not, either. + */ + +#if defined(CONFIG_ALPHA_FLAMINGO) +struct alpha_machine_vector flamingo_mv __initmv = { + vector_name: "FLAMINGO", + DO_EV4_MMU, + DO_DEFAULT_RTC, + DO_TCASIC_IO, + DO_TCASIC_BUS, + machine_check: tcasic_machine_check, + max_dma_address: ALPHA_MAX_DMA_ADDRESS, + + nr_irqs: 32, + irq_probe_mask: _PROBE_MASK(32), + update_irq_hw: flamingo_update_irq_hw, + ack_irq: generic_ack_irq, + device_interrupt: flamingo_device_interrupt, + + init_arch: tcasic_init_arch, + init_irq: flamingo_init_irq, + init_pit: generic_init_pit, + pci_fixup: flamingo_pci_fixup, + kill_arch: generic_kill_arch, +}; +ALIAS_MV(flamingo) +#endif diff -r -N -u /usr/src/linux/arch/alpha/kernel/sys_pelican.c linux-2.2.9/arch/alpha/kernel/sys_pelican.c --- /usr/src/linux/arch/alpha/kernel/sys_pelican.c Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/arch/alpha/kernel/sys_pelican.c Sat Aug 14 18:03:34 1999 @@ -0,0 +1,188 @@ +/* + * linux/arch/alpha/kernel/sys_pelican.c + * + * adapted from linux/arch/alpha/kernel/sys_eb64p.c + * + * Code supporting the Pelican. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "proto.h" +#include "irq.h" +#include "bios32.h" +#include "machvec.h" + + +static void +pelican_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p) +{ + if (irq >= 16) + if (irq >= 24) + outb(mask >> 24, 0x27); + else + outb(mask >> 16, 0x26); + else if (irq >= 8) + outb(mask >> 8, 0xA1); + else + outb(mask, 0x21); +} + +static void +pelican_device_interrupt(unsigned long vector, struct pt_regs *regs) +{ + unsigned long pld; + unsigned int i; + + /* Read the interrupt summary registers */ + pld = inb(0x26) | (inb(0x27) << 8); + /* + * Now, for every possible bit set, work through + * them and call the appropriate interrupt handler. + */ + while (pld) { + i = ffz(~pld); + pld &= pld - 1; /* clear least bit set */ + + if (i == 5) { + isa_device_interrupt(vector, regs); + } else { + handle_irq(16 + i, 16 + i, regs); + } + } +} + +static void __init +pelican_init_irq(void) +{ +#ifdef CONFIG_ALPHA_GENERIC + /* + * CABRIO SRM may not set variation correctly, so here we test + * the high word of the interrupt summary register for the RAZ + * bits, and hope that a true EB64+ would read all ones... + */ + if (inw(0x806) != 0xffff) { + extern struct alpha_machine_vector cabriolet_mv; +#if 1 + printk("pelican_init_irq: resetting for CABRIO\n"); +#endif + alpha_mv = cabriolet_mv; + alpha_mv.init_irq(); + return; + } +#endif /* GENERIC */ + + STANDARD_INIT_IRQ_PROLOG; + + outb(alpha_irq_mask >> 16, 0x26); + outb(alpha_irq_mask >> 24, 0x27); + enable_irq(16 + 5); /* enable SIO cascade */ + enable_irq(2); /* enable cascade */ +} + +/* + * PCI Fixup configuration. + * + * There are two 8 bit external summary registers as follows: + * + * Summary @ 0x26: + * Bit Meaning + * 0 Interrupt Line A from slot 0 + * 1 Interrupt Line A from slot 1 + * 2 Interrupt Line B from slot 0 + * 3 Interrupt Line B from slot 1 + * 4 Interrupt Line C from slot 0 + * 5 Interrupt line from the two ISA PICs + * 6 Tulip (slot + * 7 NCR SCSI + * + * Summary @ 0x27 + * Bit Meaning + * 0 Interrupt Line C from slot 1 + * 1 Interrupt Line D from slot 0 + * 2 Interrupt Line D from slot 1 + * 3 RAZ + * 4 RAZ + * 5 RAZ + * 6 RAZ + * 7 RAZ + * + * The device to slot mapping looks like: + * + * Slot Device + * 5 NCR SCSI controller + * 6 PCI on board slot 0 + * 7 PCI on board slot 1 + * 8 Intel SIO PCI-ISA bridge chip + * 9 Tulip - DECchip 21040 Ethernet controller + * + * + * This two layered interrupt approach means that we allocate IRQ 16 and + * above for PCI interrupts. The IRQ relates to which bit the interrupt + * comes in on. This makes interrupt processing much easier. + */ + +static int __init +pelican_map_irq(struct pci_dev *dev, int slot, int pin) +{ + static char irq_tab[5][5] __initlocaldata = { + /*INT INTA INTB INTC INTD */ + {16+7, 16+7, 16+7, 16+7, 16+7}, /* IdSel 5, slot ?, ?? */ + {16+0, 16+0, 16+2, 16+4, 16+9}, /* IdSel 6, slot ?, ?? */ + {16+1, 16+1, 16+3, 16+8, 16+10}, /* IdSel 7, slot ?, ?? */ + { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */ + {16+6, 16+6, 16+6, 16+6, 16+6}, /* IdSel 9, TULIP */ + }; + const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5; + return COMMON_TABLE_LOOKUP; +} + +static void __init +pelican_pci_fixup(void) +{ +} + +/* + * The System Vector + */ + +#if defined(CONFIG_ALPHA_PELICAN) +struct alpha_machine_vector pelican_mv __initmv = { + vector_name: "PELICAN", + DO_EV4_MMU, + DO_DEFAULT_RTC, + DO_TCASIC_IO, + DO_TCASIC_BUS, + machine_check: apecs_machine_check, + max_dma_address: ALPHA_MAX_DMA_ADDRESS, + + nr_irqs: 32, + irq_probe_mask: _PROBE_MASK(32), + update_irq_hw: pelican_update_irq_hw, + ack_irq: generic_ack_irq, + device_interrupt: pelican_device_interrupt, + + init_arch: apecs_init_arch, + init_irq: pelican_init_irq, + init_pit: generic_init_pit, + pci_fixup: pelican_pci_fixup, + kill_arch: generic_kill_arch, +}; +ALIAS_MV(pelican) +#endif diff -r -N -u /usr/src/linux/arch/alpha/mm/init.c linux-2.2.9/arch/alpha/mm/init.c --- /usr/src/linux/arch/alpha/mm/init.c Mon Oct 12 14:40:12 1998 +++ linux-2.2.9/arch/alpha/mm/init.c Mon Aug 16 01:36:45 1999 @@ -178,7 +178,9 @@ load_PCB(struct thread_struct * pcb) { register unsigned long sp __asm__("$30"); + pcb->ksp = sp; + return __reload_tss(pcb); } diff -r -N -u /usr/src/linux/drivers/Makefile linux-2.2.9/drivers/Makefile --- /usr/src/linux/drivers/Makefile Mon May 10 13:18:34 1999 +++ linux-2.2.9/drivers/Makefile Sat Aug 14 18:34:58 1999 @@ -10,7 +10,7 @@ SUB_DIRS := block char net misc sound MOD_SUB_DIRS := $(SUB_DIRS) ALL_SUB_DIRS := $(SUB_DIRS) pci scsi sbus cdrom isdn pnp \ - macintosh video dio zorro fc4 usb + macintosh video dio zorro fc4 usb tc ifdef CONFIG_DIO SUB_DIRS += dio @@ -19,6 +19,10 @@ ifdef CONFIG_PCI SUB_DIRS += pci +endif + +ifdef CONFIG_TC +SUB_DIRS += tc endif ifdef CONFIG_SBUS diff -r -N -u /usr/src/linux/drivers/tc/Makefile linux-2.2.9/drivers/tc/Makefile --- /usr/src/linux/drivers/tc/Makefile Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/drivers/tc/Makefile Mon Aug 2 03:53:07 1999 @@ -0,0 +1,33 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +SUB_DIRS := +MOD_SUB_DIRS := +ALL_SUB_DIRS := + +L_TARGET := tc.a +L_OBJS := tc.o + +# Nasty trick as nobody references tcsyms.o, but we still want it linked. +# Stolen from pci Makefile +ifeq ($(CONFIG_MODULES),y) +O_TARGET = tc_syms.o +OX_OBJS = tcsyms.o +O_OBJS = tc.o +L_OBJS := tc_syms.o +else +L_OBJS := tc.o +endif + +ifdef CONFIG_ZS +L_OBJS += zs.o +endif + +include $(TOPDIR)/Rules.make + diff -r -N -u /usr/src/linux/drivers/tc/tc.c linux-2.2.9/drivers/tc/tc.c --- /usr/src/linux/drivers/tc/tc.c Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/drivers/tc/tc.c Wed Aug 4 01:37:57 1999 @@ -0,0 +1,273 @@ +/* $Id: $ + * tc-init: We assume the TURBOchannel to be up and running so + * just probe for Modules and fill in the global data structure + * tc_bus. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) Harald Koerfgen, 1998 + * + */ + +#include + +#include +#include +#include +/* + * If we are not an Alpha, assume MIPS + */ +#if defined(CONFIG_ALPHA_FLAMINGO)||defined(CONFIG_ALPHA_PELICAN) + +#include +#include +#include +#else +#include +#include +#include +#include +#include +#endif + +#include +#include + +#define TC_DEBUG + +slot_info tc_bus[MAX_SLOT]; +static int max_tcslot = 0; +static tcinfo *info = (tcinfo *)0; + +unsigned long system_base = 0; + +extern void (*dbe_board_handler)(struct pt_regs *regs); +extern unsigned long *(*rex_slot_address)(int); +extern void *(*rex_gettcinfo)(void); + +/* + * Interface to the world. Read comment in include/asm-mips/tc.h. + */ + +int search_tc_card(char *name) +{ + int slot; + slot_info *sip; + + for (slot = 0; slot <= max_tcslot; slot++) { + sip = &tc_bus[slot]; + if ((sip->flags & FREE) && (strncmp(sip->name, name, strlen(name)) == 0)) { + return slot; + } + } + + return -ENODEV; +} + +void claim_tc_card(int slot) +{ + if (tc_bus[slot].flags & IN_USE) { + printk("claim_tc_card: attempting to claim a card already in use\n"); + return; + } + tc_bus[slot].flags &= ~FREE; + tc_bus[slot].flags |= IN_USE; +} + +void release_tc_card(int slot) +{ + if (tc_bus[slot].flags & FREE) { + printk("release_tc_card: attempting to release a card already free\n"); + return; + } + tc_bus[slot].flags &= ~IN_USE; + tc_bus[slot].flags |= FREE; +} + +unsigned long get_tc_base_addr(int slot) +{ + return tc_bus[slot].base_addr; +} + +unsigned long get_tc_irq_nr(int slot) +{ + return tc_bus[slot].interrupt; +} + +unsigned long get_tc_speed(void) +{ + return 100000 * (10000 / (unsigned long)info->clk_period); +} + +/* + * Probing for TURBOchannel modules + */ +#if !defined(CONFIG_ALPHA_FLAMINGO) && !defined(CONFIG_ALPHA_PELICAN) +__initfunc(static void my_dbe_handler(struct pt_regs *regs)) +{ + regs->cp0_epc += 4; +} +#endif + +__initfunc(static void tc_probe(unsigned long startaddr, unsigned long size, int max_slot)) +{ + int i, slot; + long offset; + unsigned char *module; +#if !defined(CONFIG_ALPHA_FLAMINGO) && !defined(CONFIG_ALPHA_PELICAN) + void (*old_be_handler)(struct pt_regs *regs); + + /* Install our exception handler temporarily */ + + old_be_handler = dbe_board_handler; + dbe_board_handler = my_dbe_handler; +#endif + for (slot = 0; slot <= max_slot; slot++) { + module = (char *)(startaddr + slot * size); + offset = -1; + if (module[OLDCARD + PATTERN0] == 0x55 && module[OLDCARD + PATTERN1] == 0x00 + && module[OLDCARD + PATTERN2] == 0xaa && module[OLDCARD + PATTERN3] == 0xff) + offset = OLDCARD; + if (module[PATTERN0] == 0x55 && module[PATTERN1] == 0x00 + && module[PATTERN2] == 0xaa && module[PATTERN3] == 0xff) + offset = 0; + + if (offset != -1) { + tc_bus[slot].base_addr = (unsigned long)module; + for(i = 0; i < 8; i++) { + tc_bus[slot].firmware[i] = module[FIRM_VER + offset + 4 * i]; + tc_bus[slot].vendor[i] = module[VENDOR + offset + 4 * i]; + tc_bus[slot].name[i] = module[MODULE + offset + 4 * i]; + } + tc_bus[slot].firmware[8] = 0; + tc_bus[slot].vendor[8] = 0; + tc_bus[slot].name[8] = 0; + /* + * Looks unneccesary, but we may change + * TC? in the future + */ + switch (slot) { + case 0: + tc_bus[slot].interrupt = TC0; + break; + case 1: + tc_bus[slot].interrupt = TC1; + break; + case 2: + tc_bus[slot].interrupt = TC2; + break; + /* + * Yuck! DS5000/200 onboard devices + */ + case 5: + tc_bus[slot].interrupt = SCSI_INT; + break; + case 6: + tc_bus[slot].interrupt = ETHER; + break; + default: + tc_bus[slot].interrupt = -1; + break; + } + } + } + +#if !defined(CONFIG_ALPHA_FLAMINGO) && !defined(CONFIG_ALPHA_PELICAN) + dbe_board_handler = old_be_handler; +#endif +} + +/* + * the main entry + */ +__initfunc(void tc_init(void)) +{ + int tc_clock; + int i; + unsigned long slot0addr; + unsigned long slot_size; + +#if !defined(CONFIG_ALPHA_FLAMINGO) && !defined(CONFIG_ALPHA_PELICAN) + if (!TURBOCHANNEL) + return; +#endif + + for (i = 0; i < MAX_SLOT; i++) { + tc_bus[i].base_addr = 0; + tc_bus[i].name[0] = 0; + tc_bus[i].vendor[0] = 0; + tc_bus[i].firmware[0] = 0; + tc_bus[i].interrupt = -1; + tc_bus[i].flags = FREE; + } + +#if defined(CONFIG_ALPHA_FLAMINGO) || defined(CONFIG_ALPHA_PELICAN) + /* + * cpp: needs work + */ + /* info = (tcinfo *) rex_gettcinfo(); + slot0addr = (unsigned long)KSEG1ADDR(rex_slot_address(0)); */ + + max_tcslot = 3; +#else + + info = (tcinfo *) rex_gettcinfo(); + slot0addr = (unsigned long)KSEG1ADDR(rex_slot_address(0)); + + switch (mips_machtype) { + case MACH_DS5000_200: + max_tcslot = 6; + break; + case MACH_DS5000_1XX: + case MACH_DS5000_2X0: + max_tcslot = 2; + break; + case MACH_DS5000_XX: + default: + max_tcslot = 1; + break; + } +#endif + tc_clock = 10000 / info->clk_period; + + if (info->slot_size && slot0addr) { + printk("TURBOchannel rev. %1d at %2d.%1d MHz ", info->revision, + tc_clock / 10, tc_clock % 10); + printk("(%sparity)\n", info->parity ? "" : "no "); + + slot_size = info->slot_size << 20; + + tc_probe(slot0addr, slot_size, max_tcslot); + +#if defined(CONFIG_ALPHA_FLAMINGO) || defined(CONFIG_ALPHA_PELICAN) + /* + * cpp: Fix me. + */ + i = 2; +#else + /* + * All TURBOchannel DECstations have the onboard devices + * where the (max_tcslot + 1 or 2 on DS5k/xx) Option Module + * would be. + */ + if(mips_machtype == MACH_DS5000_XX) + i = 2; + else + i = 1; +#endif + + system_base = slot0addr + slot_size * (max_tcslot + i); + +#ifdef TC_DEBUG + for (i = 0; i <= max_tcslot; i++) + if (tc_bus[i].base_addr) { + printk(" slot %d: ", i); + printk("%s %s %s\n", tc_bus[i].vendor, + tc_bus[i].name, tc_bus[i].firmware); + } +#endif + } + +} diff -r -N -u /usr/src/linux/drivers/tc/tcsyms.c linux-2.2.9/drivers/tc/tcsyms.c --- /usr/src/linux/drivers/tc/tcsyms.c Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/drivers/tc/tcsyms.c Mon Aug 2 03:53:07 1999 @@ -0,0 +1,13 @@ +/* + * Turbo Channel Services -- Exported Symbols + * + */ + +#include +#include + +EXPORT_SYMBOL(get_tc_irq_nr); +EXPORT_SYMBOL(claim_tc_card); +EXPORT_SYMBOL(search_tc_card); +EXPORT_SYMBOL(get_tc_speed); +EXPORT_SYMBOL(get_tc_base_addr); diff -r -N -u /usr/src/linux/drivers/tc/zs.c linux-2.2.9/drivers/tc/zs.c --- /usr/src/linux/drivers/tc/zs.c Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/drivers/tc/zs.c Wed Aug 4 01:45:26 1999 @@ -0,0 +1,2126 @@ +/* + * decserial.c: Serial port driver for IOASIC DECsatations. + * + * Derived from drivers/macintosh/macserial.c by Harald Koerfgen. + * Derived from drivers/sbus/char/sunserial.c by Paul Mackerras. + * + * DECstation changes + * Copyright (C) 1998 Harald Koerfgen (Harald.Koerfgen@home.ivm.de) + * + * For the rest of the code the original Copyright applies: + * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * + * Keyboard and mouse are not supported right now. If you want to change this, + * you might want to have a look at drivers/sbus/char/sunserial.c to see + * how this might be done. HK + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SERIAL_CONSOLE +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_DECSTATION) +#include +#endif +#include +#include + +#ifdef CONFIG_KGDB +#include +#endif + +#include "zs.h" + + +/* + * It would be nice to dynamically allocate everything that + * depends on NUM_SERIAL, so we could support any number of + * Z8530s, but for now... + */ +#define NUM_SERIAL 2 /* Max number of ZS chips supported */ +#define NUM_CHANNELS (NUM_SERIAL * 2) /* 2 channels per chip */ + +#define RECOVERY_DELAY udelay(2) + +struct dec_zschannel zs_channels[NUM_CHANNELS]; + +struct dec_serial zs_soft[NUM_CHANNELS]; +int zs_channels_found; +struct dec_serial *zs_chain; /* list of all channels */ + +struct tty_struct zs_ttys[NUM_CHANNELS]; + +#ifdef CONFIG_SERIAL_CONSOLE +static struct console sercons; +#endif + +#ifdef CONFIG_KGDB +struct dec_zschannel *zs_kgdbchan; +static unsigned char scc_inittab[] = { + 9, 0x80, /* reset A side (CHRA) */ + 13, 0, /* set baud rate divisor */ + 12, 1, + 14, 1, /* baud rate gen enable, src=rtxc (BRENABL) */ + 11, 0x50, /* clocks = br gen (RCBR | TCBR) */ + 5, 0x6a, /* tx 8 bits, assert RTS (Tx8 | TxENAB | RTS) */ + 4, 0x44, /* x16 clock, 1 stop (SB1 | X16CLK)*/ + 3, 0xc1, /* rx enable, 8 bits (RxENABLE | Rx8)*/ +}; +#endif + +static unsigned char zs_init_regs[16] __initdata = { + 0, /* write 0 */ + 0, /* write 1 */ + 0xf0, /* write 2 */ + (Rx8), /* write 3 */ + (X16CLK | SB1), /* write 4 */ + (Tx8), /* write 5 */ + 0, 0, 0, /* write 6, 7, 8 */ + (VIS), /* write 9 */ + (NRZ), /* write 10 */ + (TCBR | RCBR), /* write 11 */ + 0, 0, /* BRG time constant, write 12 + 13 */ + (BRSRC | BRENABL), /* write 14 */ + 0 /* write 15 */ +}; + +#define ZS_CLOCK 7372800 /* Z8530 RTxC input clock rate */ + +DECLARE_TASK_QUEUE(tq_zs_serial); + +struct tty_driver serial_driver, callout_driver; +static int serial_refcount; + +/* serial subtype definitions */ +#define SERIAL_TYPE_NORMAL 1 +#define SERIAL_TYPE_CALLOUT 2 + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +/* + * Debugging. + */ +#undef SERIAL_DEBUG_INTR +#undef SERIAL_DEBUG_OPEN +#undef SERIAL_DEBUG_FLOW +#undef SERIAL_DEBUG_THROTTLE +#undef SERIAL_PARANOIA_CHECK + +#define RS_STROBE_TIME 10 +#define RS_ISR_PASS_LIMIT 256 + +#define _INLINE_ inline + +static void probe_sccs(void); +static void change_speed(struct dec_serial *info); +static void rs_wait_until_sent(struct tty_struct *tty, int timeout); + +static struct tty_struct *serial_table[NUM_CHANNELS]; +static struct termios *serial_termios[NUM_CHANNELS]; +static struct termios *serial_termios_locked[NUM_CHANNELS]; + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +/* + * tmp_buf is used as a temporary buffer by serial_write. We need to + * lock it in case the copy_from_user blocks while swapping in a page, + * and some other program tries to do a serial write at the same time. + * Since the lock will only come under contention when the system is + * swapping and available memory is low, it makes sense to share one + * buffer across all the serial ports, since it significantly saves + * memory if large numbers of serial ports are open. + */ +static unsigned char tmp_buf[4096]; /* This is cheating */ +static struct semaphore tmp_buf_sem = MUTEX; + +static inline int serial_paranoia_check(struct dec_serial *info, + dev_t device, const char *routine) +{ +#ifdef SERIAL_PARANOIA_CHECK + static const char *badmagic = + "Warning: bad magic number for serial struct (%d, %d) in %s\n"; + static const char *badinfo = + "Warning: null mac_serial for (%d, %d) in %s\n"; + + if (!info) { + printk(badinfo, MAJOR(device), MINOR(device), routine); + return 1; + } + if (info->magic != SERIAL_MAGIC) { + printk(badmagic, MAJOR(device), MINOR(device), routine); + return 1; + } +#endif + return 0; +} + +/* + * This is used to figure out the divisor speeds and the timeouts + */ +static int baud_table[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, + 9600, 19200, 38400, 57600, 0, 0 }; + +/* + * Reading and writing Z8530 registers. + */ +static inline unsigned char read_zsreg(struct dec_zschannel *channel, + unsigned char reg) +{ + unsigned char retval; + + if (reg != 0) { + *channel->control = reg & 0xf; + RECOVERY_DELAY; + } + retval = *channel->control; + RECOVERY_DELAY; + return retval; +} + +static inline void write_zsreg(struct dec_zschannel *channel, + unsigned char reg, unsigned char value) +{ + if (reg != 0) { + *channel->control = reg & 0xf; + RECOVERY_DELAY; + } + *channel->control = value; + RECOVERY_DELAY; + return; +} + +static inline unsigned char read_zsdata(struct dec_zschannel *channel) +{ + unsigned char retval; + + retval = *channel->data; + RECOVERY_DELAY; + return retval; +} + +static inline void write_zsdata(struct dec_zschannel *channel, + unsigned char value) +{ + *channel->data = value; + RECOVERY_DELAY; + return; +} + +static inline void load_zsregs(struct dec_zschannel *channel, + unsigned char *regs) +{ +/* ZS_CLEARERR(channel); + ZS_CLEARFIFO(channel); */ + /* Load 'em up */ + write_zsreg(channel, R4, regs[R4]); + write_zsreg(channel, R3, regs[R3] & ~RxENABLE); + write_zsreg(channel, R5, regs[R5] & ~TxENAB); + write_zsreg(channel, R9, regs[R9]); + write_zsreg(channel, R1, regs[R1]); + write_zsreg(channel, R2, regs[R2]); + write_zsreg(channel, R10, regs[R10]); + write_zsreg(channel, R11, regs[R11]); + write_zsreg(channel, R12, regs[R12]); + write_zsreg(channel, R13, regs[R13]); + write_zsreg(channel, R14, regs[R14]); + write_zsreg(channel, R15, regs[R15]); + write_zsreg(channel, R3, regs[R3]); + write_zsreg(channel, R5, regs[R5]); + return; +} + +/* Sets or clears DTR/RTS on the requested line */ +static inline void zs_rtsdtr(struct dec_serial *ss, int set) +{ + if (ss->zs_channel != ss->zs_chan_a) { + if (set) + ss->zs_chan_a->curregs[5] |= (RTS | DTR); + else + ss->zs_chan_a->curregs[5] &= ~(RTS | DTR); + write_zsreg(ss->zs_chan_a, 5, ss->zs_chan_a->curregs[5]); + } + return; +} + +/* Utility routines for the Zilog */ +static inline int get_zsbaud(struct dec_serial *ss) +{ + struct dec_zschannel *channel = ss->zs_channel; + int brg; + + /* The baud rate is split up between two 8-bit registers in + * what is termed 'BRG time constant' format in my docs for + * the chip, it is a function of the clk rate the chip is + * receiving which happens to be constant. + */ + brg = (read_zsreg(channel, 13) << 8); + brg |= read_zsreg(channel, 12); + return BRG_TO_BPS(brg, (ZS_CLOCK/(ss->clk_divisor))); +} + +/* On receive, this clears errors and the receiver interrupts */ +static inline void rs_recv_clear(struct dec_zschannel *zsc) +{ + write_zsreg(zsc, 0, ERR_RES); + write_zsreg(zsc, 0, RES_H_IUS); /* XXX this is unnecessary */ +} + +/* + * ---------------------------------------------------------------------- + * + * Here starts the interrupt handling routines. All of the following + * subroutines are declared as inline and are folded into + * rs_interrupt(). They were separated out for readability's sake. + * + * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 + * ----------------------------------------------------------------------- + */ + +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. + */ +static _INLINE_ void rs_sched_event(struct dec_serial *info, + int event) +{ + info->event |= 1 << event; + queue_task(&info->tqueue, &tq_zs_serial); + mark_bh(SERIAL_BH); +} + +static _INLINE_ void receive_chars(struct dec_serial *info, + struct pt_regs *regs) +{ + struct tty_struct *tty = info->tty; + unsigned char ch, stat, flag; + + while ((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) != 0) { + + stat = read_zsreg(info->zs_channel, R1); + ch = read_zsdata(info->zs_channel); + +#ifdef CONFIG_KGDB + if (info->kgdb_channel) { + if (ch == 0x03 || ch == '$') + breakpoint(); + if (stat & (Rx_OVR|FRM_ERR|PAR_ERR)) + write_zsreg(info->zs_channel, 0, ERR_RES); + return; + } +#endif + if (!tty) + continue; + + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + static int flip_buf_ovf; + ++flip_buf_ovf; + continue; + } + tty->flip.count++; + { + static int flip_max_cnt; + if (flip_max_cnt < tty->flip.count) + flip_max_cnt = tty->flip.count; + } + if (stat & Rx_OVR) { + flag = TTY_OVERRUN; + } else if (stat & FRM_ERR) { + flag = TTY_FRAME; + } else if (stat & PAR_ERR) { + flag = TTY_PARITY; + } else + flag = 0; + if (flag) + /* reset the error indication */ + write_zsreg(info->zs_channel, 0, ERR_RES); + *tty->flip.flag_buf_ptr++ = flag; + *tty->flip.char_buf_ptr++ = ch; + } + tty_flip_buffer_push(tty); +} + +static void transmit_chars(struct dec_serial *info) +{ + if ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP) == 0) + return; + info->tx_active = 0; + + if (info->x_char) { + /* Send next char */ + write_zsdata(info->zs_channel, info->x_char); + info->x_char = 0; + info->tx_active = 1; + return; + } + + if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tx_stopped) { + write_zsreg(info->zs_channel, 0, RES_Tx_P); + return; + } + /* Send char */ + write_zsdata(info->zs_channel, info->xmit_buf[info->xmit_tail++]); + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt--; + info->tx_active = 1; + + if (info->xmit_cnt < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); +} + +static _INLINE_ void status_handle(struct dec_serial *info) +{ + unsigned char status; + + /* Get status from Read Register 0 */ + status = read_zsreg(info->zs_channel, 0); + + /* FIXEM: Check for DCD transitions */ + if (((status ^ info->read_reg_zero) & DCD) != 0 + && info->tty && !C_CLOCAL(info->tty)) { + if (status & DCD) { + wake_up_interruptible(&info->open_wait); + } else if (!(info->flags & ZILOG_CALLOUT_ACTIVE)) { + if (info->tty) + tty_hangup(info->tty); + } + } + + /* Check for CTS transitions */ + if (info->tty && C_CRTSCTS(info->tty)) { + /* + * For some reason, on the Power Macintosh, + * it seems that the CTS bit is 1 when CTS is + * *negated* and 0 when it is asserted. + * The DCD bit doesn't seem to be inverted + * like this. + */ + if ((status & CTS) != 0) { + if (info->tx_stopped) { + info->tx_stopped = 0; + if (!info->tx_active) + transmit_chars(info); + } + } else { + info->tx_stopped = 1; + } + } + + /* Clear status condition... */ + write_zsreg(info->zs_channel, 0, RES_EXT_INT); + info->read_reg_zero = status; +} + +/* + * This is the serial driver's generic interrupt routine + */ +void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) +{ + struct dec_serial *info = (struct dec_serial *) dev_id; + unsigned char zs_intreg; + int shift; + + /* NOTE: The read register 3, which holds the irq status, + * does so for both channels on each chip. Although + * the status value itself must be read from the A + * channel and is only valid when read from channel A. + * Yes... broken hardware... + */ +#define CHAN_IRQMASK (CHBRxIP | CHBTxIP | CHBEXT) + + if (info->zs_chan_a == info->zs_channel) + shift = 3; /* Channel A */ + else + shift = 0; /* Channel B */ + + for (;;) { + zs_intreg = read_zsreg(info->zs_chan_a, 3) >> shift; + if ((zs_intreg & CHAN_IRQMASK) == 0) + break; + + if (zs_intreg & CHBRxIP) { + receive_chars(info, regs); + } + if (zs_intreg & CHBTxIP) { + transmit_chars(info); + } + if (zs_intreg & CHBEXT) { + status_handle(info); + } + } +} + +/* + * ------------------------------------------------------------------- + * Here ends the serial interrupt routines. + * ------------------------------------------------------------------- + */ + +/* + * ------------------------------------------------------------ + * rs_stop() and rs_start() + * + * This routines are called before setting or resetting tty->stopped. + * ------------------------------------------------------------ + */ +static void rs_stop(struct tty_struct *tty) +{ + struct dec_serial *info = (struct dec_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_stop")) + return; + +#if 1 + save_flags(flags); cli(); + if (info->zs_channel->curregs[5] & TxENAB) { + info->zs_channel->curregs[5] &= ~TxENAB; + write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); + } + restore_flags(flags); +#endif +} + +static void rs_start(struct tty_struct *tty) +{ + struct dec_serial *info = (struct dec_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_start")) + return; + + save_flags(flags); cli(); +#if 1 + if (info->xmit_cnt && info->xmit_buf && !(info->zs_channel->curregs[5] & TxENAB)) { + info->zs_channel->curregs[5] |= TxENAB; + write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); + } +#else + if (info->xmit_cnt && info->xmit_buf && !info->tx_active) { + transmit_chars(info); + } +#endif + restore_flags(flags); +} + +/* + * This routine is used to handle the "bottom half" processing for the + * serial driver, known also the "software interrupt" processing. + * This processing is done at the kernel interrupt level, after the + * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This + * is where time-consuming activities which can not be done in the + * interrupt driver proper are done; the interrupt driver schedules + * them using rs_sched_event(), and they get done here. + */ +static void do_serial_bh(void) +{ + run_task_queue(&tq_zs_serial); +} + +static void do_softint(void *private_) +{ + struct dec_serial *info = (struct dec_serial *) private_; + struct tty_struct *tty; + + tty = info->tty; + if (!tty) + return; + + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + wake_up_interruptible(&tty->write_wait); + } +} + +static void rs_timer(void) +{ +} + +static int startup(struct dec_serial * info) +{ + unsigned long flags; + + if (info->flags & ZILOG_INITIALIZED) + return 0; + + if (!info->xmit_buf) { + info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL); + if (!info->xmit_buf) + return -ENOMEM; + } + + save_flags(flags); cli(); + +#ifdef SERIAL_DEBUG_OPEN + printk("starting up ttyS%d (irq %d)...", info->line, info->irq); +#endif + + /* + * Clear the receive FIFO. + */ + ZS_CLEARFIFO(info->zs_channel); + info->xmit_fifo_size = 1; + + /* + * Clear the interrupt registers. + */ + write_zsreg(info->zs_channel, 0, ERR_RES); + write_zsreg(info->zs_channel, 0, RES_H_IUS); + + /* + * Turn on RTS and DTR. + */ + zs_rtsdtr(info, 1); + + /* + * Finally, enable sequencing and interrupts + */ + info->zs_channel->curregs[1] = (info->zs_channel->curregs[1] & ~0x18) | (EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB); + info->zs_channel->curregs[3] |= (RxENABLE | Rx8); + info->zs_channel->curregs[5] |= (TxENAB | Tx8); + info->zs_channel->curregs[15] |= (DCDIE | CTSIE | TxUIE | BRKIE); + info->zs_channel->curregs[9] |= (VIS | MIE); + write_zsreg(info->zs_channel, 1, info->zs_channel->curregs[1]); + write_zsreg(info->zs_channel, 3, info->zs_channel->curregs[3]); + write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); + write_zsreg(info->zs_channel, 15, info->zs_channel->curregs[15]); + write_zsreg(info->zs_channel, 9, info->zs_channel->curregs[9]); + + /* + * And clear the interrupt registers again for luck. + */ + write_zsreg(info->zs_channel, 0, ERR_RES); + write_zsreg(info->zs_channel, 0, RES_H_IUS); + + if (info->tty) + clear_bit(TTY_IO_ERROR, &info->tty->flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + /* + * Set the speed of the serial port + */ + change_speed(info); + + /* Save the current value of RR0 */ + info->read_reg_zero = read_zsreg(info->zs_channel, 0); + + info->flags |= ZILOG_INITIALIZED; + restore_flags(flags); + return 0; +} + +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void shutdown(struct dec_serial * info) +{ + unsigned long flags; + + if (!(info->flags & ZILOG_INITIALIZED)) + return; + +#ifdef SERIAL_DEBUG_OPEN + printk("Shutting down serial port %d (irq %d)....", info->line, + info->irq); +#endif + + save_flags(flags); cli(); /* Disable interrupts */ + + if (info->xmit_buf) { + free_page((unsigned long) info->xmit_buf); + info->xmit_buf = 0; + } + + info->zs_channel->curregs[1] = 0; + write_zsreg(info->zs_channel, 1, info->zs_channel->curregs[1]); /* no interrupts */ + + info->zs_channel->curregs[3] &= ~RxENABLE; + write_zsreg(info->zs_channel, 3, info->zs_channel->curregs[3]); + + info->zs_channel->curregs[5] &= ~TxENAB; + write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); + if (!info->tty || C_HUPCL(info->tty)) { + info->zs_chan_a->curregs[5] &= ~(DTR | RTS); + write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]); + } + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + info->flags &= ~ZILOG_INITIALIZED; + restore_flags(flags); +} + +/* + * This routine is called to set the UART divisor registers to match + * the specified baud rate for a serial port. + */ +static void change_speed(struct dec_serial *info) +{ + unsigned short port; + unsigned cflag; + int i; + int brg; + unsigned long flags; + + if (!info->tty || !info->tty->termios) + return; + cflag = info->tty->termios->c_cflag; + if (!(port = info->port)) + return; + i = cflag & CBAUD; + + save_flags(flags); cli(); + info->zs_baud = baud_table[i]; + info->clk_divisor = 16; + + switch (info->zs_baud) { + default: + info->zs_channel->curregs[4] = X16CLK; + brg = BPS_TO_BRG(info->zs_baud, ZS_CLOCK/info->clk_divisor); + info->zs_channel->curregs[12] = (brg & 255); + info->zs_channel->curregs[13] = ((brg >> 8) & 255); + } + + /* byte size and parity */ + info->zs_channel->curregs[3] &= ~RxNBITS_MASK; + info->zs_channel->curregs[5] &= ~TxNBITS_MASK; + switch (cflag & CSIZE) { + case CS5: + info->zs_channel->curregs[3] |= Rx5; + info->zs_channel->curregs[5] |= Tx5; + break; + case CS6: + info->zs_channel->curregs[3] |= Rx6; + info->zs_channel->curregs[5] |= Tx6; + break; + case CS7: + info->zs_channel->curregs[3] |= Rx7; + info->zs_channel->curregs[5] |= Tx7; + break; + case CS8: + default: /* defaults to 8 bits */ + info->zs_channel->curregs[3] |= Rx8; + info->zs_channel->curregs[5] |= Tx8; + break; + } + + info->zs_channel->curregs[4] &= ~(SB_MASK | PAR_ENA | PAR_EVEN); + if (cflag & CSTOPB) { + info->zs_channel->curregs[4] |= SB2; + } else { + info->zs_channel->curregs[4] |= SB1; + } + if (cflag & PARENB) { + info->zs_channel->curregs[4] |= PAR_ENA; + } + if (!(cflag & PARODD)) { + info->zs_channel->curregs[4] |= PAR_EVEN; + } + + if (!(cflag & CLOCAL)) { + if (!(info->zs_channel->curregs[15] & DCDIE)) + info->read_reg_zero = read_zsreg(info->zs_channel, 0); + info->zs_channel->curregs[15] |= DCDIE; + } else + info->zs_channel->curregs[15] &= ~DCDIE; + if (cflag & CRTSCTS) { + info->zs_channel->curregs[15] |= CTSIE; + if ((read_zsreg(info->zs_channel, 0) & CTS) != 0) + info->tx_stopped = 1; + } else { + info->zs_channel->curregs[15] &= ~CTSIE; + info->tx_stopped = 0; + } + + /* Load up the new values */ + load_zsregs(info->zs_channel, info->zs_channel->curregs); + + restore_flags(flags); +} + +static void rs_flush_chars(struct tty_struct *tty) +{ + struct dec_serial *info = (struct dec_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) + return; + + if (info->xmit_cnt <= 0 || tty->stopped || info->tx_stopped || + !info->xmit_buf) + return; + + /* Enable transmitter */ + save_flags(flags); cli(); + transmit_chars(info); + restore_flags(flags); +} + +static int rs_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) +{ + int c, total = 0; + struct dec_serial *info = (struct dec_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_write")) + return 0; + + if (!tty || !info->xmit_buf) + return 0; + + save_flags(flags); + while (1) { + cli(); + c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) + break; + + if (from_user) { + down(&tmp_buf_sem); + copy_from_user(tmp_buf, buf, c); + c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); + up(&tmp_buf_sem); + } else + memcpy(info->xmit_buf + info->xmit_head, buf, c); + info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt += c; + restore_flags(flags); + buf += c; + count -= c; + total += c; + } + + if (info->xmit_cnt && !tty->stopped && !info->tx_stopped + && !info->tx_active) + transmit_chars(info); + restore_flags(flags); + return total; +} + +static int rs_write_room(struct tty_struct *tty) +{ + struct dec_serial *info = (struct dec_serial *)tty->driver_data; + int ret; + + if (serial_paranoia_check(info, tty->device, "rs_write_room")) + return 0; + ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; + if (ret < 0) + ret = 0; + return ret; +} + +static int rs_chars_in_buffer(struct tty_struct *tty) +{ + struct dec_serial *info = (struct dec_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) + return 0; + return info->xmit_cnt; +} + +static void rs_flush_buffer(struct tty_struct *tty) +{ + struct dec_serial *info = (struct dec_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) + return; + cli(); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + sti(); + wake_up_interruptible(&tty->write_wait); + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); +} + +/* + * ------------------------------------------------------------ + * rs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void rs_throttle(struct tty_struct * tty) +{ + struct dec_serial *info = (struct dec_serial *)tty->driver_data; + unsigned long flags; + +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("throttle %s: %d....\n", _tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_throttle")) + return; + + if (I_IXOFF(tty)) { + save_flags(flags); cli(); + info->x_char = STOP_CHAR(tty); + if (!info->tx_active) + transmit_chars(info); + restore_flags(flags); + } + + if (C_CRTSCTS(tty)) { + /* + * Here we want to turn off the RTS line. On Macintoshes, + * we only get the DTR line, which goes to both DTR and + * RTS on the modem. RTS doesn't go out to the serial + * port socket. So you should make sure your modem is + * set to ignore DTR if you're using CRTSCTS. + */ + save_flags(flags); cli(); + info->zs_chan_a->curregs[5] &= ~(DTR | RTS); + write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]); + restore_flags(flags); + } +} + +static void rs_unthrottle(struct tty_struct * tty) +{ + struct dec_serial *info = (struct dec_serial *)tty->driver_data; + unsigned long flags; + +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("unthrottle %s: %d....\n", _tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) + return; + + if (I_IXOFF(tty)) { + save_flags(flags); cli(); + if (info->x_char) + info->x_char = 0; + else { + info->x_char = START_CHAR(tty); + if (!info->tx_active) + transmit_chars(info); + } + restore_flags(flags); + } + + if (C_CRTSCTS(tty)) { + /* Assert RTS and DTR lines */ + save_flags(flags); cli(); + info->zs_chan_a->curregs[5] |= DTR | RTS; + write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]); + restore_flags(flags); + } +} + +/* + * ------------------------------------------------------------ + * rs_ioctl() and friends + * ------------------------------------------------------------ + */ + +static int get_serial_info(struct dec_serial * info, + struct serial_struct * retinfo) +{ + struct serial_struct tmp; + + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof(tmp)); + tmp.type = info->type; + tmp.line = info->line; + tmp.port = info->port; + tmp.irq = info->irq; + tmp.flags = info->flags; + tmp.baud_base = info->baud_base; + tmp.close_delay = info->close_delay; + tmp.closing_wait = info->closing_wait; + tmp.custom_divisor = info->custom_divisor; + return copy_to_user(retinfo,&tmp,sizeof(*retinfo)); +} + +static int set_serial_info(struct dec_serial * info, + struct serial_struct * new_info) +{ + struct serial_struct new_serial; + struct dec_serial old_info; + int retval = 0; + + if (!new_info) + return -EFAULT; + copy_from_user(&new_serial,new_info,sizeof(new_serial)); + old_info = *info; + + if (!suser()) { + if ((new_serial.baud_base != info->baud_base) || + (new_serial.type != info->type) || + (new_serial.close_delay != info->close_delay) || + ((new_serial.flags & ~ZILOG_USR_MASK) != + (info->flags & ~ZILOG_USR_MASK))) + return -EPERM; + info->flags = ((info->flags & ~ZILOG_USR_MASK) | + (new_serial.flags & ZILOG_USR_MASK)); + info->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + if (info->count > 1) + return -EBUSY; + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + + info->baud_base = new_serial.baud_base; + info->flags = ((info->flags & ~ZILOG_FLAGS) | + (new_serial.flags & ZILOG_FLAGS)); + info->type = new_serial.type; + info->close_delay = new_serial.close_delay; + info->closing_wait = new_serial.closing_wait; + +check_and_exit: + retval = startup(info); + return retval; +} + +/* + * get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int get_lsr_info(struct dec_serial * info, unsigned int *value) +{ + unsigned char status; + + cli(); + status = read_zsreg(info->zs_channel, 0); + sti(); + put_user(status,value); + return 0; +} + +static int get_modem_info(struct dec_serial *info, unsigned int *value) +{ + unsigned char control, status; + unsigned int result; + + cli(); + control = info->zs_chan_a->curregs[5]; + status = read_zsreg(info->zs_channel, 0); + sti(); + result = ((control & RTS) ? TIOCM_RTS: 0) + | ((control & DTR) ? TIOCM_DTR: 0) + | ((status & DCD) ? TIOCM_CAR: 0) + | ((status & CTS) ? 0: TIOCM_CTS); + put_user(result,value); + return 0; +} + +static int set_modem_info(struct dec_serial *info, unsigned int cmd, + unsigned int *value) +{ + int error; + unsigned int arg, bits; + + error = verify_area(VERIFY_READ, value, sizeof(int)); + if (error) + return error; + get_user(arg, value); + bits = (arg & TIOCM_RTS? RTS: 0) + (arg & TIOCM_DTR? DTR: 0); + cli(); + switch (cmd) { + case TIOCMBIS: + info->zs_chan_a->curregs[5] |= bits; + break; + case TIOCMBIC: + info->zs_chan_a->curregs[5] &= ~bits; + break; + case TIOCMSET: + info->zs_chan_a->curregs[5] = (info->zs_chan_a->curregs[5] & ~(DTR | RTS)) | bits; + break; + default: + sti(); + return -EINVAL; + } + write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]); + sti(); + return 0; +} + +/* + * rs_break - turn transmit break condition on/off + */ +static void rs_break(struct tty_struct *tty, int break_state) +{ + struct dec_serial *info = (struct dec_serial *) tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_break")) + return; + if (!info->port) + return; + + save_flags(flags); cli(); + if (break_state == -1) + info->zs_channel->curregs[5] |= SND_BRK; + else + info->zs_channel->curregs[5] &= ~SND_BRK; + write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); + restore_flags(flags); +} + +static int rs_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + int error; + struct dec_serial * info = (struct dec_serial *)tty->driver_data; + +#ifdef CONFIG_KGDB + if (info->kgdb_channel) + return -ENODEV; +#endif + if (serial_paranoia_check(info, tty->device, "rs_ioctl")) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && + (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case TIOCMGET: + error = verify_area(VERIFY_WRITE, (void *) arg, + sizeof(unsigned int)); + if (error) + return error; + return get_modem_info(info, (unsigned int *) arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return set_modem_info(info, cmd, (unsigned int *) arg); + case TIOCGSERIAL: + error = verify_area(VERIFY_WRITE, (void *) arg, + sizeof(struct serial_struct)); + if (error) + return error; + return get_serial_info(info, + (struct serial_struct *) arg); + case TIOCSSERIAL: + return set_serial_info(info, + (struct serial_struct *) arg); + case TIOCSERGETLSR: /* Get line status register */ + error = verify_area(VERIFY_WRITE, (void *) arg, + sizeof(unsigned int)); + if (error) + return error; + else + return get_lsr_info(info, (unsigned int *) arg); + + case TIOCSERGSTRUCT: + error = verify_area(VERIFY_WRITE, (void *) arg, + sizeof(struct dec_serial)); + if (error) + return error; + copy_from_user((struct dec_serial *) arg, + info, sizeof(struct dec_serial)); + return 0; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ + struct dec_serial *info = (struct dec_serial *)tty->driver_data; + int was_stopped; + + if (tty->termios->c_cflag == old_termios->c_cflag) + return; + was_stopped = info->tx_stopped; + + change_speed(info); + + if (was_stopped && !info->tx_stopped) + rs_start(tty); +} + +/* + * ------------------------------------------------------------ + * rs_close() + * + * This routine is called when the serial port gets closed. + * Wait for the last remaining data to be sent. + * ------------------------------------------------------------ + */ +static void rs_close(struct tty_struct *tty, struct file * filp) +{ + struct dec_serial * info = (struct dec_serial *)tty->driver_data; + unsigned long flags; + + if (!info || serial_paranoia_check(info, tty->device, "rs_close")) + return; + + save_flags(flags); cli(); + + if (tty_hung_up_p(filp)) { + restore_flags(flags); + return; + } + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_close ttys%d, count = %d\n", info->line, info->count); +#endif + if ((tty->count == 1) && (info->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. Info->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk("rs_close: bad serial port count; tty->count is 1, " + "info->count is %d\n", info->count); + info->count = 1; + } + if (--info->count < 0) { + printk("rs_close: bad serial port count for ttys%d: %d\n", + info->line, info->count); + info->count = 0; + } + if (info->count) { + restore_flags(flags); + return; + } + info->flags |= ZILOG_CLOSING; + /* + * Save the termios structure, since this port may have + * separate termios for callout and dialin. + */ + if (info->flags & ZILOG_NORMAL_ACTIVE) + info->normal_termios = *tty->termios; + if (info->flags & ZILOG_CALLOUT_ACTIVE) + info->callout_termios = *tty->termios; + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + if (info->closing_wait != ZILOG_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, info->closing_wait); + /* + * At this point we stop accepting input. To do this, we + * disable the receiver and receive interrupts. + */ + info->zs_channel->curregs[3] &= ~RxENABLE; + write_zsreg(info->zs_channel, 3, info->zs_channel->curregs[3]); + info->zs_channel->curregs[1] = 0; /* disable any rx ints */ + write_zsreg(info->zs_channel, 1, info->zs_channel->curregs[1]); + ZS_CLEARFIFO(info->zs_channel); + if (info->flags & ZILOG_INITIALIZED) { + /* + * Before we drop DTR, make sure the SCC transmitter + * has completely drained. + */ + rs_wait_until_sent(tty, info->timeout); + } + + shutdown(info); + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + info->event = 0; + info->tty = 0; + if (info->blocked_open) { + if (info->close_delay) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(info->close_delay); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE| + ZILOG_CLOSING); + wake_up_interruptible(&info->close_wait); + restore_flags(flags); +} + +/* + * rs_wait_until_sent() --- wait until the transmitter is empty + */ +static void rs_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct dec_serial *info = (struct dec_serial *) tty->driver_data; + unsigned long orig_jiffies, char_time; + + if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) + return; + + orig_jiffies = jiffies; + /* + * Set the check interval to be 1/5 of the estimated time to + * send a single character, and make it at least 1. The check + * interval should also be less than the timeout. + */ + char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; + char_time = char_time / 5; + if (char_time == 0) + char_time = 1; + if (timeout) + char_time = MIN(char_time, timeout); + while ((read_zsreg(info->zs_channel, 1) & ALL_SNT) == 0) { + current->state = TASK_INTERRUPTIBLE; + current->counter = 0; /* make us low-priority */ + schedule_timeout(char_time); + if (signal_pending(current)) + break; + if (timeout && ((orig_jiffies + timeout) < jiffies)) + break; + } + current->state = TASK_RUNNING; +} + +/* + * rs_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +void rs_hangup(struct tty_struct *tty) +{ + struct dec_serial * info = (struct dec_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_hangup")) + return; + + rs_flush_buffer(tty); + shutdown(info); + info->event = 0; + info->count = 0; + info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE); + info->tty = 0; + wake_up_interruptible(&info->open_wait); +} + +/* + * ------------------------------------------------------------ + * rs_open() and friends + * ------------------------------------------------------------ + */ +static int block_til_ready(struct tty_struct *tty, struct file * filp, + struct dec_serial *info) +{ + struct wait_queue wait = { current, NULL }; + int retval; + int do_clocal = 0; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (info->flags & ZILOG_CLOSING) { + interruptible_sleep_on(&info->close_wait); +#ifdef SERIAL_DO_RESTART + return ((info->flags & ZILOG_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * If this is a callout device, then just make sure the normal + * device isn't being used. + */ + if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { + if (info->flags & ZILOG_NORMAL_ACTIVE) + return -EBUSY; + if ((info->flags & ZILOG_CALLOUT_ACTIVE) && + (info->flags & ZILOG_SESSION_LOCKOUT) && + (info->session != current->session)) + return -EBUSY; + if ((info->flags & ZILOG_CALLOUT_ACTIVE) && + (info->flags & ZILOG_PGRP_LOCKOUT) && + (info->pgrp != current->pgrp)) + return -EBUSY; + info->flags |= ZILOG_CALLOUT_ACTIVE; + return 0; + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + if (info->flags & ZILOG_CALLOUT_ACTIVE) + return -EBUSY; + info->flags |= ZILOG_NORMAL_ACTIVE; + return 0; + } + + if (info->flags & ZILOG_CALLOUT_ACTIVE) { + if (info->normal_termios.c_cflag & CLOCAL) + do_clocal = 1; + } else { + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + } + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, info->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready before block: ttys%d, count = %d\n", + info->line, info->count); +#endif + cli(); + if (!tty_hung_up_p(filp)) + info->count--; + sti(); + info->blocked_open++; + while (1) { + cli(); + if (!(info->flags & ZILOG_CALLOUT_ACTIVE) && + (tty->termios->c_cflag & CBAUD)) + zs_rtsdtr(info, 1); + sti(); + current->state = TASK_INTERRUPTIBLE; + if (tty_hung_up_p(filp) || + !(info->flags & ZILOG_INITIALIZED)) { +#ifdef SERIAL_DO_RESTART + if (info->flags & ZILOG_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; +#else + retval = -EAGAIN; +#endif + break; + } + if (!(info->flags & ZILOG_CALLOUT_ACTIVE) && + !(info->flags & ZILOG_CLOSING) && + (do_clocal || (read_zsreg(info->zs_channel, 0) & DCD))) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready blocking: ttys%d, count = %d\n", + info->line, info->count); +#endif + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&info->open_wait, &wait); + if (!tty_hung_up_p(filp)) + info->count++; + info->blocked_open--; +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready after blocking: ttys%d, count = %d\n", + info->line, info->count); +#endif + if (retval) + return retval; + info->flags |= ZILOG_NORMAL_ACTIVE; + return 0; +} + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its ZILOG structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +int rs_open(struct tty_struct *tty, struct file * filp) +{ + struct dec_serial *info; + int retval, line; + + line = MINOR(tty->device) - tty->driver.minor_start; + if ((line < 0) || (line >= zs_channels_found)) + return -ENODEV; + info = zs_soft + line; + +#ifdef CONFIG_KGDB + if (info->kgdb_channel) + return -ENODEV; +#endif + if (serial_paranoia_check(info, tty->device, "rs_open")) + return -ENODEV; +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line, + info->count); +#endif + + info->count++; + tty->driver_data = info; + info->tty = tty; + + /* + * If the port is the middle of closing, bail out now + */ + if (tty_hung_up_p(filp) || + (info->flags & ZILOG_CLOSING)) { + if (info->flags & ZILOG_CLOSING) + interruptible_sleep_on(&info->close_wait); +#ifdef SERIAL_DO_RESTART + return ((info->flags & ZILOG_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * Start up serial port + */ + retval = startup(info); + if (retval) + return retval; + + retval = block_til_ready(tty, filp, info); + if (retval) { +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open returning after block_til_ready with %d\n", + retval); +#endif + return retval; + } + + if ((info->count == 1) && (info->flags & ZILOG_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) + *tty->termios = info->normal_termios; + else + *tty->termios = info->callout_termios; + change_speed(info); + } +#ifdef CONFIG_SERIAL_CONSOLE + if (sercons.cflag && sercons.index == line) { + tty->termios->c_cflag = sercons.cflag; + sercons.cflag = 0; + change_speed(info); + } +#endif + + info->session = current->session; + info->pgrp = current->pgrp; + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open ttys%d successful...", info->line); +#endif +/* tty->low_latency = 1; */ + return 0; +} + +/* Finally, routines used to initialize the serial driver. */ + +__initfunc(static void show_serial_version(void)) +{ + printk("DECstation Z8530 serial driver version 0.03\n"); +} + +/* Initialize Z8530s zs_channels + */ + +__initfunc(static void probe_sccs(void)) +{ + struct dec_serial **pp; + int i, n, n_chips = 0, n_channels, chip, channel; + unsigned long flags; + + /* + * did we get here by accident? + */ +#if defined(CONFIG_DECSTATION) + if(!IOASIC) { + printk("Not on JUNKIO machine, skipping probe_sccs\n"); + return; + } +#else + printk("probe_sccs: Initializing for DEC 3000\n"); +#endif + + /* + * When serial console is activated, tc_init has not been called yet + * and system_base is undefined. Unfortunately we have to hardcode + * system_base for this case :-(. HK + */ +#if defined(CONFIG_DECSTATION) + switch(mips_machtype) { + case MACH_DS5000_2X0: + system_base = 0xbf800000; + n_chips = 2; + break; + case MACH_DS5000_1XX: + system_base = 0xbc000000; + n_chips = 2; + break; + case MACH_DS5000_XX: + system_base = 0xbc000000; + n_chips = 1; + break; + } +#else + /* + * cpp: Must fix. + */ + system_base = 0xbf800000; + n_chips = 2; +#endif + + pp = &zs_chain; + + n_channels = 0; + + for (chip = 0; chip < n_chips; chip++) { + for (channel = 0; channel <= 1; channel++) { + /* + * The sccs reside on the high byte of the 16 bit IOBUS + */ + zs_channels[n_channels].control = (volatile unsigned char *) + system_base + (0 == chip ? SCC0 : SCC1) + (0 == channel ? 1 : 9); + zs_channels[n_channels].data = zs_channels[n_channels].control + 4; + zs_soft[n_channels].zs_channel = &zs_channels[n_channels]; + zs_soft[n_channels].irq = SERIAL; + + if (0 == channel) + zs_soft[n_channels].zs_chan_a = &zs_channels[n_channels+1]; + else + zs_soft[n_channels].zs_chan_a = &zs_channels[n_channels]; + + *pp = &zs_soft[n_channels]; + pp = &zs_soft[n_channels].zs_next; + n_channels++; + } + } + + *pp = 0; + zs_channels_found = n_channels; + + for (n = 0; n < zs_channels_found; n++) { + for (i = 0; i < 16; i++) { + zs_soft[n].zs_channel->curregs[i] = zs_init_regs[i]; + } + } + +/* save_and_cli(flags); + for (n = 0; n < zs_channels_found; n++) { + if (((int)zs_channels[n].control & 0xf) == 1) { + write_zsreg(zs_soft[channel].zs_chan_a, R9, FHWRES); + udelay(10000); + write_zsreg(zs_soft[channel].zs_chan_a, R9, 0); + } + load_zsregs(zs_soft[n].zs_channel, zs_soft[n].zs_channel->curregs); + } + restore_flags(flags); */ +} + +/* zs_init inits the driver */ +__initfunc(int zs_init(void)) +{ + int channel, i; + unsigned long flags; + struct dec_serial *info; + +#if defined(CONFIG_DECSTATION) + if(!IOASIC) + return -ENODEV; +#endif + + /* Setup base handler, and timer table. */ + init_bh(SERIAL_BH, do_serial_bh); + timer_table[RS_TIMER].fn = rs_timer; + timer_table[RS_TIMER].expires = 0; + + /* Find out how many Z8530 SCCs we have */ + if (zs_chain == 0) + probe_sccs(); + + show_serial_version(); + + /* Initialize the tty_driver structure */ + /* Not all of this is exactly right for us. */ + + memset(&serial_driver, 0, sizeof(struct tty_driver)); + serial_driver.magic = TTY_DRIVER_MAGIC; + serial_driver.name = "ttyS"; + serial_driver.major = TTY_MAJOR; + serial_driver.minor_start = 64; + serial_driver.num = zs_channels_found; + serial_driver.type = TTY_DRIVER_TYPE_SERIAL; + serial_driver.subtype = SERIAL_TYPE_NORMAL; + serial_driver.init_termios = tty_std_termios; + + serial_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver.flags = TTY_DRIVER_REAL_RAW; + serial_driver.refcount = &serial_refcount; + serial_driver.table = serial_table; + serial_driver.termios = serial_termios; + serial_driver.termios_locked = serial_termios_locked; + + serial_driver.open = rs_open; + serial_driver.close = rs_close; + serial_driver.write = rs_write; + serial_driver.flush_chars = rs_flush_chars; + serial_driver.write_room = rs_write_room; + serial_driver.chars_in_buffer = rs_chars_in_buffer; + serial_driver.flush_buffer = rs_flush_buffer; + serial_driver.ioctl = rs_ioctl; + serial_driver.throttle = rs_throttle; + serial_driver.unthrottle = rs_unthrottle; + serial_driver.set_termios = rs_set_termios; + serial_driver.stop = rs_stop; + serial_driver.start = rs_start; + serial_driver.hangup = rs_hangup; + serial_driver.break_ctl = rs_break; + serial_driver.wait_until_sent = rs_wait_until_sent; + + /* + * The callout device is just like normal device except for + * major number and the subtype code. + */ + callout_driver = serial_driver; + callout_driver.name = "cua"; + callout_driver.major = TTYAUX_MAJOR; + callout_driver.subtype = SERIAL_TYPE_CALLOUT; + + if (tty_register_driver(&serial_driver)) + panic("Couldn't register serial driver\n"); + if (tty_register_driver(&callout_driver)) + panic("Couldn't register callout driver\n"); + + save_flags(flags); cli(); + + for (channel = 0; channel < zs_channels_found; ++channel) { +#ifdef CONFIG_KGDB + if (zs_soft[channel].kgdb_channel) { + continue; + } +#endif + zs_soft[channel].clk_divisor = 16; + zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]); + + if (request_irq(SERIAL, rs_interrupt, SA_SHIRQ, + "SCC", &zs_soft[channel])) + printk(KERN_ERR "decserial: can't get irq %d\n", + SERIAL); + + /* If console serial line, then enable interrupts. */ +/* if (zs_soft[channel].is_cons) { + write_zsreg(zs_soft[channel].zs_channel, R1, + (EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB)); + write_zsreg(zs_soft[channel].zs_channel, R9, + (VIS | MIE)); + } +*/ + } + + for (info = zs_chain, i = 0; info; info = info->zs_next, i++) + { +#ifdef CONFIG_KGDB + if (info->kgdb_channel) { + continue; + } +#endif + info->magic = SERIAL_MAGIC; + info->port = (int) info->zs_channel->control; + info->line = i; + info->tty = 0; + info->custom_divisor = 16; + info->close_delay = 50; + info->closing_wait = 3000; + info->x_char = 0; + info->event = 0; + info->count = 0; + info->blocked_open = 0; + info->tqueue.routine = do_softint; + info->tqueue.data = info; + info->callout_termios =callout_driver.init_termios; + info->normal_termios = serial_driver.init_termios; + info->open_wait = 0; + info->close_wait = 0; + printk("tty%02d at 0x%08x (irq = %d)", info->line, + info->port, info->irq); + printk(" is a Z85C30 SCC\n"); + } + + restore_flags(flags); + + return 0; +} + +/* + * register_serial and unregister_serial allows for serial ports to be + * configured at run-time, to support PCMCIA modems. + */ +/* PowerMac: Unused at this time, just here to make things link. */ +int register_serial(struct serial_struct *req) +{ + return -1; +} + +void unregister_serial(int line) +{ + return; +} + +/* + * ------------------------------------------------------------ + * Serial console driver + * ------------------------------------------------------------ + */ +#ifdef CONFIG_SERIAL_CONSOLE + + +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + */ + +/* This is for console output */ +static void +zs_console_putchar(struct dec_serial *info, char ch) +{ + int loops = 10000; + unsigned long flags; + + if(!info->zs_channel) + return; + + save_flags(flags); cli(); + + while (!(*(info->zs_channel->control) & Tx_BUF_EMP) && --loops) + RECOVERY_DELAY; + *(info->zs_channel->data) = ch; + RECOVERY_DELAY; + + restore_flags(flags); +} + +static void serial_console_write(struct console *co, const char *s, + unsigned count) +{ + struct dec_serial *info; + int i; + unsigned char nine; + + info = zs_soft + co->index; + +#if 0 + /* + * disable master interrupt if necessary + */ + nine = info->zs_channel->curregs[9]; + if(nine & MIE) + write_zsreg(info->zs_channel, R9, nine & ~MIE); +#endif + /* + * do it + */ + for (i = 0; i < count; i++, s++) { + if(*s == '\n') + zs_console_putchar(info, '\r'); + zs_console_putchar(info, *s); + } + /* + * restore master interrupt enable + */ +#if 0 + write_zsreg(info->zs_channel, R9, nine); +#endif +} + +/* + * Receive character from the serial port + */ +static int serial_console_wait_key(struct console *co) +{ + return 0; +} + +static kdev_t serial_console_device(struct console *c) +{ + return MKDEV(TTY_MAJOR, 64 + c->index); +} + +/* + * Setup initial baud/bits/parity. We do two things here: + * - construct a cflag setting for the first rs_open() + * - initialize the serial port + * Return non-zero if we didn't find a serial port. + */ +__initfunc(static int serial_console_setup(struct console *co, char *options)) +{ + struct dec_serial *info; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int cflag = CREAD | HUPCL | CLOCAL; + char *s; + unsigned long flags; + +#if defined(CONFIG_DECSTATION) + if(!IOASIC) + return -ENODEV; +#endif + + info = zs_soft + co->index; + + if (zs_chain == 0) + probe_sccs(); + + info->is_cons = 1; + + if (options) { + baud = simple_strtoul(options, NULL, 10); + s = options; + while(*s >= '0' && *s <= '9') + s++; + if (*s) + parity = *s++; + if (*s) + bits = *s - '0'; + } + + /* + * Now construct a cflag setting. + */ + switch(baud) { + case 1200: + cflag |= B1200; + break; + case 2400: + cflag |= B2400; + break; + case 4800: + cflag |= B4800; + break; + case 19200: + cflag |= B19200; + break; + case 38400: + cflag |= B38400; + break; + case 57600: + cflag |= B57600; + break; + case 115200: + cflag |= B115200; + break; + case 9600: + default: + cflag |= B9600; + break; + } + switch(bits) { + case 7: + cflag |= CS7; + break; + default: + case 8: + cflag |= CS8; + break; + } + switch(parity) { + case 'o': case 'O': + cflag |= PARODD; + break; + case 'e': case 'E': + cflag |= PARENB; + break; + } + co->cflag = cflag; +#if 1 + save_and_cli(flags); + + /* + * Turn on RTS and DTR. + */ + zs_rtsdtr(info, 1); + + /* + * Finally, enable sequencing + */ + info->zs_channel->curregs[3] |= (RxENABLE | Rx8); + info->zs_channel->curregs[5] |= (TxENAB | Tx8); + info->zs_channel->curregs[9] |= (VIS); + write_zsreg(info->zs_channel, 3, info->zs_channel->curregs[3]); + write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); + write_zsreg(info->zs_channel, 9, info->zs_channel->curregs[9]); + + /* + * Clear the interrupt registers. + */ + write_zsreg(info->zs_channel, 0, ERR_RES); + write_zsreg(info->zs_channel, 0, RES_H_IUS); + + /* + * Set the speed of the serial port + */ + change_speed(info); + + /* Save the current value of RR0 */ + info->read_reg_zero = read_zsreg(info->zs_channel, 0); + + zs_soft[co->index].clk_divisor = 16; + zs_soft[co->index].zs_baud = get_zsbaud(&zs_soft[co->index]); + + restore_flags(flags); +#endif + return 0; +} + +static struct console sercons = { + "ttyS", + serial_console_write, + NULL, + serial_console_device, + serial_console_wait_key, + NULL, + serial_console_setup, + CON_PRINTBUFFER, + -1, + 0, + NULL +}; + +/* + * Register console. + */ +__initfunc (long zs_serial_console_init(long kmem_start, long kmem_end)) +{ + register_console(&sercons); + return kmem_start; +} +#endif /* ifdef CONFIG_SERIAL_CONSOLE */ + +#ifdef CONFIG_KGDB +/* These are for receiving and sending characters under the kgdb + * source level kernel debugger. + */ +void putDebugChar(char kgdb_char) +{ + struct dec_zschannel *chan = zs_kgdbchan; + while ((read_zsreg(chan, 0) & Tx_BUF_EMP) == 0) + RECOVERY_DELAY; + write_zsdata(chan, kgdb_char); +} +char getDebugChar(void) +{ + struct dec_zschannel *chan = zs_kgdbchan; + while((read_zsreg(chan, 0) & Rx_CH_AV) == 0) + eieio(); /*barrier();*/ + return read_zsdata(chan); +} +void kgdb_interruptible(int yes) +{ + struct dec_zschannel *chan = zs_kgdbchan; + int one, nine; + nine = read_zsreg(chan, 9); + if (yes == 1) { + one = EXT_INT_ENAB|INT_ALL_Rx; + nine |= MIE; + printk("turning serial ints on\n"); + } else { + one = RxINT_DISAB; + nine &= ~MIE; + printk("turning serial ints off\n"); + } + write_zsreg(chan, 1, one); + write_zsreg(chan, 9, nine); +} +/* This sets up the serial port we're using, and turns on + * interrupts for that channel, so kgdb is usable once we're done. + */ +static inline void kgdb_chaninit(struct dec_zschannel *ms, int intson, int bps) +{ + int brg; + int i, x; + volatile char *sccc = ms->control; + brg = BPS_TO_BRG(bps, ZS_CLOCK/16); + printk("setting bps on kgdb line to %d [brg=%x]\n", bps, brg); + for (i = 20000; i != 0; --i) { + x = *sccc; eieio(); + } + for (i = 0; i < sizeof(scc_inittab); ++i) { + write_zsreg(ms, scc_inittab[i], scc_inittab[i+1]); + i++; + } +} +/* This is called at boot time to prime the kgdb serial debugging + * serial line. The 'tty_num' argument is 0 for /dev/ttya and 1 + * for /dev/ttyb which is determined in setup_arch() from the + * boot command line flags. + */ +__initfunc(void zs_kgdb_hook(int tty_num)) +{ + /* Find out how many Z8530 SCCs we have */ + if (zs_chain == 0) + probe_sccs(); + zs_soft[tty_num].zs_channel = &zs_channels[tty_num]; + zs_kgdbchan = zs_soft[tty_num].zs_channel; + zs_soft[tty_num].change_needed = 0; + zs_soft[tty_num].clk_divisor = 16; + zs_soft[tty_num].zs_baud = 38400; + zs_soft[tty_num].kgdb_channel = 1; /* This runs kgdb */ + zs_soft[tty_num ^ 1].kgdb_channel = 0; /* This does not */ + /* Turn on transmitter/receiver at 8-bits/char */ + kgdb_chaninit(zs_soft[tty_num].zs_channel, 1, 38400); + printk("KGDB: on channel %d initialized\n", tty_num); + set_debug_traps(); /* init stub */ +} +#endif /* ifdef CONFIG_KGDB */ diff -r -N -u /usr/src/linux/drivers/tc/zs.h linux-2.2.9/drivers/tc/zs.h --- /usr/src/linux/drivers/tc/zs.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/drivers/tc/zs.h Mon Aug 2 03:53:07 1999 @@ -0,0 +1,405 @@ +/* + * macserial.h: Definitions for the Macintosh Z8530 serial driver. + * + * Adapted from drivers/sbus/char/sunserial.h by Paul Mackerras. + * + * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _DECSERIAL_H +#define _DECSERIAL_H + +#define NUM_ZSREGS 16 + +struct serial_struct { + int type; + int line; + int port; + int irq; + int flags; + int xmit_fifo_size; + int custom_divisor; + int baud_base; + unsigned short close_delay; + char reserved_char[2]; + int hub6; + unsigned short closing_wait; /* time to wait before closing */ + unsigned short closing_wait2; /* no longer used... */ + int reserved[4]; +}; + +/* + * For the close wait times, 0 means wait forever for serial port to + * flush its output. 65535 means don't wait at all. + */ +#define ZILOG_CLOSING_WAIT_INF 0 +#define ZILOG_CLOSING_WAIT_NONE 65535 + +/* + * Definitions for ZILOG_struct (and serial_struct) flags field + */ +#define ZILOG_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes + on the callout port */ +#define ZILOG_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */ +#define ZILOG_SAK 0x0004 /* Secure Attention Key (Orange book) */ +#define ZILOG_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */ + +#define ZILOG_SPD_MASK 0x0030 +#define ZILOG_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */ + +#define ZILOG_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */ +#define ZILOG_SPD_CUST 0x0030 /* Use user-specified divisor */ + +#define ZILOG_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */ +#define ZILOG_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */ +#define ZILOG_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */ +#define ZILOG_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */ +#define ZILOG_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */ + +#define ZILOG_FLAGS 0x0FFF /* Possible legal ZILOG flags */ +#define ZILOG_USR_MASK 0x0430 /* Legal flags that non-privileged + * users can set or reset */ + +/* Internal flags used only by kernel/chr_drv/serial.c */ +#define ZILOG_INITIALIZED 0x80000000 /* Serial port was initialized */ +#define ZILOG_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */ +#define ZILOG_NORMAL_ACTIVE 0x20000000 /* Normal device is active */ +#define ZILOG_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */ +#define ZILOG_CLOSING 0x08000000 /* Serial port is closing */ +#define ZILOG_CTS_FLOW 0x04000000 /* Do CTS flow control */ +#define ZILOG_CHECK_CD 0x02000000 /* i.e., CLOCAL */ + +/* Software state per channel */ + +#ifdef __KERNEL__ +/* + * This is our internal structure for each serial port's state. + * + * Many fields are paralleled by the structure used by the serial_struct + * structure. + * + * For definitions of the flags field, see tty.h + */ + +struct dec_zschannel { + volatile unsigned char *control; + volatile unsigned char *data; + + /* Current write register values */ + unsigned char curregs[NUM_ZSREGS]; +}; + +struct dec_serial { + struct dec_serial *zs_next; /* For IRQ servicing chain */ + struct dec_zschannel *zs_channel; /* Channel registers */ + struct dec_zschannel *zs_chan_a; /* A side registers */ + unsigned char read_reg_zero; + + char soft_carrier; /* Use soft carrier on this channel */ + char break_abort; /* Is serial console in, so process brk/abrt */ + char kgdb_channel; /* Kgdb is running on this channel */ + char is_cons; /* Is this our console. */ + unsigned char tx_active; /* character is being xmitted */ + unsigned char tx_stopped; /* output is suspended */ + + /* We need to know the current clock divisor + * to read the bps rate the chip has currently + * loaded. + */ + unsigned char clk_divisor; /* May be 1, 16, 32, or 64 */ + int zs_baud; + + char change_needed; + + int magic; + int baud_base; + int port; + int irq; + int flags; /* defined in tty.h */ + int type; /* UART type */ + struct tty_struct *tty; + int read_status_mask; + int ignore_status_mask; + int timeout; + int xmit_fifo_size; + int custom_divisor; + int x_char; /* xon/xoff character */ + int close_delay; + unsigned short closing_wait; + unsigned short closing_wait2; + unsigned long event; + unsigned long last_active; + int line; + int count; /* # of fd on device */ + int blocked_open; /* # of blocked opens */ + long session; /* Session of opening process */ + long pgrp; /* pgrp of opening process */ + unsigned char *xmit_buf; + int xmit_head; + int xmit_tail; + int xmit_cnt; + struct tq_struct tqueue; + struct tq_struct tqueue_hangup; + struct termios normal_termios; + struct termios callout_termios; + struct wait_queue *open_wait; + struct wait_queue *close_wait; +}; + + +#define SERIAL_MAGIC 0x5301 + +/* + * The size of the serial xmit buffer is 1 page, or 4096 bytes + */ +#define SERIAL_XMIT_SIZE 4096 + +/* + * Events are used to schedule things to happen at timer-interrupt + * time, instead of at rs interrupt time. + */ +#define RS_EVENT_WRITE_WAKEUP 0 + +#endif /* __KERNEL__ */ + +/* Conversion routines to/from brg time constants from/to bits + * per second. + */ +#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2)) +#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2) + +/* The Zilog register set */ + +#define FLAG 0x7e + +/* Write Register 0 */ +#define R0 0 /* Register selects */ +#define R1 1 +#define R2 2 +#define R3 3 +#define R4 4 +#define R5 5 +#define R6 6 +#define R7 7 +#define R8 8 +#define R9 9 +#define R10 10 +#define R11 11 +#define R12 12 +#define R13 13 +#define R14 14 +#define R15 15 + +#define NULLCODE 0 /* Null Code */ +#define POINT_HIGH 0x8 /* Select upper half of registers */ +#define RES_EXT_INT 0x10 /* Reset Ext. Status Interrupts */ +#define SEND_ABORT 0x18 /* HDLC Abort */ +#define RES_RxINT_FC 0x20 /* Reset RxINT on First Character */ +#define RES_Tx_P 0x28 /* Reset TxINT Pending */ +#define ERR_RES 0x30 /* Error Reset */ +#define RES_H_IUS 0x38 /* Reset highest IUS */ + +#define RES_Rx_CRC 0x40 /* Reset Rx CRC Checker */ +#define RES_Tx_CRC 0x80 /* Reset Tx CRC Checker */ +#define RES_EOM_L 0xC0 /* Reset EOM latch */ + +/* Write Register 1 */ + +#define EXT_INT_ENAB 0x1 /* Ext Int Enable */ +#define TxINT_ENAB 0x2 /* Tx Int Enable */ +#define PAR_SPEC 0x4 /* Parity is special condition */ + +#define RxINT_DISAB 0 /* Rx Int Disable */ +#define RxINT_FCERR 0x8 /* Rx Int on First Character Only or Error */ +#define INT_ALL_Rx 0x10 /* Int on all Rx Characters or error */ +#define INT_ERR_Rx 0x18 /* Int on error only */ + +#define WT_RDY_RT 0x20 /* Wait/Ready on R/T */ +#define WT_FN_RDYFN 0x40 /* Wait/FN/Ready FN */ +#define WT_RDY_ENAB 0x80 /* Wait/Ready Enable */ + +/* Write Register #2 (Interrupt Vector) */ + +/* Write Register 3 */ + +#define RxENABLE 0x1 /* Rx Enable */ +#define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */ +#define ADD_SM 0x4 /* Address Search Mode (SDLC) */ +#define RxCRC_ENAB 0x8 /* Rx CRC Enable */ +#define ENT_HM 0x10 /* Enter Hunt Mode */ +#define AUTO_ENAB 0x20 /* Auto Enables */ +#define Rx5 0x0 /* Rx 5 Bits/Character */ +#define Rx7 0x40 /* Rx 7 Bits/Character */ +#define Rx6 0x80 /* Rx 6 Bits/Character */ +#define Rx8 0xc0 /* Rx 8 Bits/Character */ +#define RxNBITS_MASK 0xc0 + +/* Write Register 4 */ + +#define PAR_ENA 0x1 /* Parity Enable */ +#define PAR_EVEN 0x2 /* Parity Even/Odd* */ + +#define SYNC_ENAB 0 /* Sync Modes Enable */ +#define SB1 0x4 /* 1 stop bit/char */ +#define SB15 0x8 /* 1.5 stop bits/char */ +#define SB2 0xc /* 2 stop bits/char */ +#define SB_MASK 0xc + +#define MONSYNC 0 /* 8 Bit Sync character */ +#define BISYNC 0x10 /* 16 bit sync character */ +#define SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */ +#define EXTSYNC 0x30 /* External Sync Mode */ + +#define X1CLK 0x0 /* x1 clock mode */ +#define X16CLK 0x40 /* x16 clock mode */ +#define X32CLK 0x80 /* x32 clock mode */ +#define X64CLK 0xC0 /* x64 clock mode */ +#define XCLK_MASK 0xC0 + +/* Write Register 5 */ + +#define TxCRC_ENAB 0x1 /* Tx CRC Enable */ +#define RTS 0x2 /* RTS */ +#define SDLC_CRC 0x4 /* SDLC/CRC-16 */ +#define TxENAB 0x8 /* Tx Enable */ +#define SND_BRK 0x10 /* Send Break */ +#define Tx5 0x0 /* Tx 5 bits (or less)/character */ +#define Tx7 0x20 /* Tx 7 bits/character */ +#define Tx6 0x40 /* Tx 6 bits/character */ +#define Tx8 0x60 /* Tx 8 bits/character */ +#define TxNBITS_MASK 0x60 +#define DTR 0x80 /* DTR */ + +/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */ + +/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */ + +/* Write Register 8 (transmit buffer) */ + +/* Write Register 9 (Master interrupt control) */ +#define VIS 1 /* Vector Includes Status */ +#define NV 2 /* No Vector */ +#define DLC 4 /* Disable Lower Chain */ +#define MIE 8 /* Master Interrupt Enable */ +#define STATHI 0x10 /* Status high */ +#define SOFTACK 0x20 /* Software Interrupt Acknowledge */ +#define NORESET 0 /* No reset on write to R9 */ +#define CHRB 0x40 /* Reset channel B */ +#define CHRA 0x80 /* Reset channel A */ +#define FHWRES 0xc0 /* Force hardware reset */ + +/* Write Register 10 (misc control bits) */ +#define BIT6 1 /* 6 bit/8bit sync */ +#define LOOPMODE 2 /* SDLC Loop mode */ +#define ABUNDER 4 /* Abort/flag on SDLC xmit underrun */ +#define MARKIDLE 8 /* Mark/flag on idle */ +#define GAOP 0x10 /* Go active on poll */ +#define NRZ 0 /* NRZ mode */ +#define NRZI 0x20 /* NRZI mode */ +#define FM1 0x40 /* FM1 (transition = 1) */ +#define FM0 0x60 /* FM0 (transition = 0) */ +#define CRCPS 0x80 /* CRC Preset I/O */ + +/* Write Register 11 (Clock Mode control) */ +#define TRxCXT 0 /* TRxC = Xtal output */ +#define TRxCTC 1 /* TRxC = Transmit clock */ +#define TRxCBR 2 /* TRxC = BR Generator Output */ +#define TRxCDP 3 /* TRxC = DPLL output */ +#define TRxCOI 4 /* TRxC O/I */ +#define TCRTxCP 0 /* Transmit clock = RTxC pin */ +#define TCTRxCP 8 /* Transmit clock = TRxC pin */ +#define TCBR 0x10 /* Transmit clock = BR Generator output */ +#define TCDPLL 0x18 /* Transmit clock = DPLL output */ +#define RCRTxCP 0 /* Receive clock = RTxC pin */ +#define RCTRxCP 0x20 /* Receive clock = TRxC pin */ +#define RCBR 0x40 /* Receive clock = BR Generator output */ +#define RCDPLL 0x60 /* Receive clock = DPLL output */ +#define RTxCX 0x80 /* RTxC Xtal/No Xtal */ + +/* Write Register 12 (lower byte of baud rate generator time constant) */ + +/* Write Register 13 (upper byte of baud rate generator time constant) */ + +/* Write Register 14 (Misc control bits) */ +#define BRENABL 1 /* Baud rate generator enable */ +#define BRSRC 2 /* Baud rate generator source */ +#define DTRREQ 4 /* DTR/Request function */ +#define AUTOECHO 8 /* Auto Echo */ +#define LOOPBAK 0x10 /* Local loopback */ +#define SEARCH 0x20 /* Enter search mode */ +#define RMC 0x40 /* Reset missing clock */ +#define DISDPLL 0x60 /* Disable DPLL */ +#define SSBR 0x80 /* Set DPLL source = BR generator */ +#define SSRTxC 0xa0 /* Set DPLL source = RTxC */ +#define SFMM 0xc0 /* Set FM mode */ +#define SNRZI 0xe0 /* Set NRZI mode */ + +/* Write Register 15 (external/status interrupt control) */ +#define ZCIE 2 /* Zero count IE */ +#define DCDIE 8 /* DCD IE */ +#define SYNCIE 0x10 /* Sync/hunt IE */ +#define CTSIE 0x20 /* CTS IE */ +#define TxUIE 0x40 /* Tx Underrun/EOM IE */ +#define BRKIE 0x80 /* Break/Abort IE */ + + +/* Read Register 0 */ +#define Rx_CH_AV 0x1 /* Rx Character Available */ +#define ZCOUNT 0x2 /* Zero count */ +#define Tx_BUF_EMP 0x4 /* Tx Buffer empty */ +#define DCD 0x8 /* DCD */ +#define SYNC_HUNT 0x10 /* Sync/hunt */ +#define CTS 0x20 /* CTS */ +#define TxEOM 0x40 /* Tx underrun */ +#define BRK_ABRT 0x80 /* Break/Abort */ + +/* Read Register 1 */ +#define ALL_SNT 0x1 /* All sent */ +/* Residue Data for 8 Rx bits/char programmed */ +#define RES3 0x8 /* 0/3 */ +#define RES4 0x4 /* 0/4 */ +#define RES5 0xc /* 0/5 */ +#define RES6 0x2 /* 0/6 */ +#define RES7 0xa /* 0/7 */ +#define RES8 0x6 /* 0/8 */ +#define RES18 0xe /* 1/8 */ +#define RES28 0x0 /* 2/8 */ +/* Special Rx Condition Interrupts */ +#define PAR_ERR 0x10 /* Parity error */ +#define Rx_OVR 0x20 /* Rx Overrun Error */ +#define FRM_ERR 0x40 /* CRC/Framing Error */ +#define END_FR 0x80 /* End of Frame (SDLC) */ + +/* Read Register 2 (channel b only) - Interrupt vector */ + +/* Read Register 3 (interrupt pending register) ch a only */ +#define CHBEXT 0x1 /* Channel B Ext/Stat IP */ +#define CHBTxIP 0x2 /* Channel B Tx IP */ +#define CHBRxIP 0x4 /* Channel B Rx IP */ +#define CHAEXT 0x8 /* Channel A Ext/Stat IP */ +#define CHATxIP 0x10 /* Channel A Tx IP */ +#define CHARxIP 0x20 /* Channel A Rx IP */ + +/* Read Register 8 (receive data register) */ + +/* Read Register 10 (misc status bits) */ +#define ONLOOP 2 /* On loop */ +#define LOOPSEND 0x10 /* Loop sending */ +#define CLK2MIS 0x40 /* Two clocks missing */ +#define CLK1MIS 0x80 /* One clock missing */ + +/* Read Register 12 (lower byte of baud rate generator constant) */ + +/* Read Register 13 (upper byte of baud rate generator constant) */ + +/* Read Register 15 (value of WR 15) */ + +/* Misc macros */ +#define ZS_CLEARERR(channel) (write_zsreg(channel, 0, ERR_RES)) +#define ZS_CLEARFIFO(channel) do { volatile unsigned char garbage; \ + garbage = read_zsdata(channel); \ + garbage = read_zsdata(channel); \ + garbage = read_zsdata(channel); \ + } while(0) + +#endif /* !(_DECSERIAL_H) */ diff -r -N -u /usr/src/linux/include/asm/addrspace.h linux-2.2.9/include/asm/addrspace.h --- /usr/src/linux/include/asm/addrspace.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm/addrspace.h Sat Aug 14 18:04:27 1999 @@ -0,0 +1,52 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + * + * Defitions for the address spaces of the MIPS CPUs. + */ +#ifndef __ASM_MIPS_ADDRSPACE_H +#define __ASM_MIPS_ADDRSPACE_H + +/* + * Memory segments (32bit kernel mode addresses) + */ +#define KUSEG 0x00000000 +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 +#define KSEG2 0xc0000000 +#define KSEG3 0xe0000000 + +/* + * Returns the kernel segment base of a given address + */ +#define KSEGX(a) (((unsigned long)(a)) & 0xe0000000) + +/* + * Returns the physical address of a KSEG0/KSEG1 address + */ +#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff) + +/* + * Map an address to a certain kernel segment + */ +#define KSEG0ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG0)) +#define KSEG1ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG1)) +#define KSEG2ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG2)) +#define KSEG3ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG3)) + +/* + * Memory segments (64bit kernel mode addresses) + */ +#define XKUSEG 0x0000000000000000 +#define XKSSEG 0x4000000000000000 +#define XKPHYS 0x8000000000000000 +#define XKSEG 0xc000000000000000 +#define CKSEG0 0xffffffff80000000 +#define CKSEG1 0xffffffffa0000000 +#define CKSSEG 0xffffffffc0000000 +#define CKSEG3 0xffffffffe0000000 + +#endif /* __ASM_MIPS_ADDRSPACE_H */ diff -r -N -u /usr/src/linux/include/asm/bootinfo.h linux-2.2.9/include/asm/bootinfo.h --- /usr/src/linux/include/asm/bootinfo.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm/bootinfo.h Sat Aug 14 18:04:33 1999 @@ -0,0 +1,192 @@ +/* $Id: bootinfo.h,v 1.7 1999/04/12 18:59:14 harald Exp $ + * + * bootinfo.h -- Definition of the Linux/MIPS boot information structure + * + * Copyright (C) 1995, 1996 by Ralf Baechle, Andreas Busse, + * Stoned Elipot and Paul M. Antoine. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ +#ifndef __ASM_MIPS_BOOTINFO_H +#define __ASM_MIPS_BOOTINFO_H + +/* XXX */ +#include + +/* + * Values for machgroup + */ +#define MACH_GROUP_UNKNOWN 0 /* whatever... */ +#define MACH_GROUP_JAZZ 1 /* Jazz */ +#define MACH_GROUP_DEC 2 /* Digital Equipment */ +#define MACH_GROUP_ARC 3 /* Wreckstation Tyne, rPC44, possibly other */ +#define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */ +#define MACH_GROUP_ACN 5 +#define MACH_GROUP_SGI 6 /* Silicon Graphics workstations and servers */ +#define MACH_GROUP_COBALT 7 /* Cobalt servers */ + +#define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", \ + "SNI", "ACN", "SGI", "Cobalt" } + +/* + * Valid machtype values for group unknown (low order halfword of mips_machtype) + */ +#define MACH_UNKNOWN 0 /* whatever... */ + +#define GROUP_UNKNOWN_NAMES { "unknown" } + +/* + * Valid machtype values for group JAZZ + */ +#define MACH_ACER_PICA_61 0 /* Acer PICA-61 (PICA1) */ +#define MACH_MIPS_MAGNUM_4000 1 /* Mips Magnum 4000 "RC4030" */ +#define MACH_OLIVETTI_M700 2 /* Olivetti M700-10 (-15 ??) */ + +#define GROUP_JAZZ_NAMES { "Acer PICA 61", "Mips Magnum 4000", "Olivetti M700" } + +/* + * Valid machtype for group DEC + */ +#define MACH_DSUNKNOWN 0 +#define MACH_DS23100 1 /* DECstation 2100 or 3100 */ +#define MACH_DS5100 2 /* DECstation 5100 */ +#define MACH_DS5000_200 3 /* DECstation 5000/200 */ +#define MACH_DS5000_1XX 4 /* DECstation 5000/120, 125, 133, 150 */ +#define MACH_DS5000_XX 5 /* DECstation 5000/20, 25, 33, 50 */ +#define MACH_DS5000_2X0 6 /* DECstation 5000/240, 260 */ +#define MACH_DS5400 7 /* DECstation 5400 */ +#define MACH_DS5500 8 /* DECstation 5500 */ +#define MACH_DS5800 9 /* DECstation 5800 */ + +#define GROUP_DEC_NAMES { "unknown", "DECstation 2100/3100", "DECstation 5100", \ + "DECstation 5000/200", "DECstation 5000/1xx", "Personal DECstation 5000/xx", \ + "DECstation 5000/2x0", "DECstation 5400", "DECstation 5500", \ + "DECstation 5800" } + +/* + * Valid machtype for group ARC + */ +#define MACH_DESKSTATION_RPC44 0 /* Deskstation rPC44 */ +#define MACH_DESKSTATION_TYNE 1 /* Deskstation Tyne */ + +#define GROUP_ARC_NAMES { "Deskstation rPC44", "Deskstation Tyne" } + +/* + * Valid machtype for group SNI_RM + */ +#define MACH_SNI_RM200_PCI 0 /* RM200/RM300/RM400 PCI series */ + +#define GROUP_SNI_RM_NAMES { "RM200 PCI" } + +/* + * Valid machtype for group ACN + */ +#define MACH_ACN_MIPS_BOARD 0 /* ACN MIPS single board */ + +#define GROUP_ACN_NAMES { "ACN" } + +/* + * Valid machtype for group SGI + */ +#define MACH_SGI_INDY 0 /* R4?K and R5K Indy workstaions */ + +#define GROUP_SGI_NAMES { "Indy" } + +/* + * Valid machtype for group COBALT + */ +#define MACH_COBALT_27 0 /* Proto "27" hardware */ + +#define GROUP_COBALT_NAMES { "Microserver 27" } + +/* + * Valid cputype values + */ +#define CPU_UNKNOWN 0 +#define CPU_R2000 1 +#define CPU_R3000 2 +#define CPU_R3000A 3 +#define CPU_R3041 4 +#define CPU_R3051 5 +#define CPU_R3052 6 +#define CPU_R3081 7 +#define CPU_R3081E 8 +#define CPU_R4000PC 9 +#define CPU_R4000SC 10 +#define CPU_R4000MC 11 +#define CPU_R4200 12 +#define CPU_R4400PC 13 +#define CPU_R4400SC 14 +#define CPU_R4400MC 15 +#define CPU_R4600 16 +#define CPU_R6000 17 +#define CPU_R6000A 18 +#define CPU_R8000 19 +#define CPU_R10000 20 +#define CPU_R4300 21 +#define CPU_R4650 22 +#define CPU_R4700 23 +#define CPU_R5000 24 +#define CPU_R5000A 25 +#define CPU_R4640 26 +#define CPU_NEVADA 27 /* RM5230, RM5260 */ +#define CPU_LAST 27 + +#define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \ + "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC", \ + "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000", \ + "R6000A", "R8000", "R10000", "R4300", "R4650", "R4700", "R5000", \ + "R5000A", "R4640", "Nevada" } + +#define CL_SIZE (80) + +#ifndef _LANGUAGE_ASSEMBLY + +/* + * Some machine parameters passed by the bootloaders. + */ + +struct drive_info_struct { + char dummy[32]; +}; + +/* This is the same as in Milo but renamed for the sake of kernel's */ +/* namespace */ +typedef struct mips_arc_DisplayInfo { /* video adapter information */ + unsigned short cursor_x; + unsigned short cursor_y; + unsigned short columns; + unsigned short lines; +} mips_arc_DisplayInfo; + +#ifdef CONFIG_SGI +/* screen info will dissapear... soon */ +//#define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 158, 0, 0, 0, 62, 0, 16} +#define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 160, 0, 0, 0, 64, 0, 16} +#define DEFAULT_DRIVE_INFO { {0,}} +#else +/* default values for screen_info variable (Colour VGA) */ +#define DEFAULT_SCREEN_INFO {0, 0, 0, 52, 3, 80, 4626, 3, 9, 50, 0x22, 16} +#endif + +/* default values for drive info */ +#define DEFAULT_DRIVE_INFO { {0,}} + + +/* + * These are the kernel variables initialized from + * the tag. And they have to be initialized to dummy/default + * values in setup.c (or whereever suitable) so they are in + * .data section + */ +extern unsigned long mips_memory_upper; +extern unsigned long mips_cputype; +extern unsigned long mips_machtype; +extern unsigned long mips_machgroup; +extern unsigned long mips_tlb_entries; + +#endif /* _LANGUAGE_ASSEMBLY */ + +#endif /* __ASM_MIPS_BOOTINFO_H */ diff -r -N -u /usr/src/linux/include/asm/core_tcasic.h linux-2.2.9/include/asm/core_tcasic.h --- /usr/src/linux/include/asm/core_tcasic.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm/core_tcasic.h Sun Aug 15 02:18:09 1999 @@ -0,0 +1,256 @@ +/* + * Initial adaptation from core_apecs.h - this will not come close to working. + * + * Oh, dear - this will require some work. + */ +#ifndef __ALPHA_TCASIC_H +#define __ALPHA_TCASIC_H + +#include +#include +#include + +/* These are for DEC 3000 machines (Pelican & Flamingo family systems) */ + +#define TCASIC_DMA_WIN_BASE_DEFAULT (1024*1024*1024) +#define TCASIC_DMA_WIN_SIZE_DEFAULT (1024*1024*1024) + +#define TCASIC_DMA_WIN_BASE TCASIC_DMA_WIN_BASE_DEFAULT +#define TCASIC_DMA_WIN_SIZE TCASIC_DMA_WIN_SIZE_DEFAULT + +#define TCASIC_IOC_HAXR0 (IDENT_ADDR + 0x1A0000180UL) +#define TCASIC_IOC_HAXR1 (IDENT_ADDR + 0x1A00001A0UL) +#define TCASIC_IOC_HAXR2 (IDENT_ADDR + 0x1A00001C0UL) + +#define TCASIC_IACK_SC (IDENT_ADDR + 0x1b0000000UL) +#define TCASIC_IO (IDENT_ADDR + 0x1c0000000UL) +#define TCASIC_BUS (IDENT_ADDR + 0x1c0000000UL) +#define TCASIC_SPARSE_MEM (IDENT_ADDR + 0x200000000UL) +#define TCASIC_DENSE_MEM (IDENT_ADDR + 0x300000000UL) + +#define TCASIC_HAE_ADDRESS TCASIC_IOC_HAXR1 + +#ifdef __KERNEL__ + +#ifndef __EXTERN_INLINE +#define __EXTERN_INLINE extern inline +#define __IO_EXTERN_INLINE +#endif + +/* + * Translate physical memory address as seen on (PCI) bus into + * a kernel virtual address and vv. + */ + +/* + * NOTE: we fudge the window 1 maximum as 48Mb instead of 64Mb, to prevent + * virt_to_bus() from returning an address in the first window, for a + * data area that goes beyond the 64Mb first DMA window. Sigh... + * This MUST match with MAX_DMA_ADDRESS for consistency, but + * we can't just use that here, because of header file looping... :-( + */ + +__EXTERN_INLINE unsigned long tcasic_virt_to_bus(void * address) +{ + unsigned long paddr = virt_to_phys(address); + return paddr + TCASIC_DMA_WIN_BASE; +} + +__EXTERN_INLINE void * tcasic_bus_to_virt(unsigned long address) +{ + /* + * This check is a sanity check but also ensures that bus + * address 0 maps to virtual address 0 which is useful to + * detect null "pointers" (the NCR driver is much simpler if + * NULL pointers are preserved). + */ + if (address < TCASIC_DMA_WIN_BASE) + return 0; + return phys_to_virt(address - TCASIC_DMA_WIN_BASE); +} + +/* + * I/O functions: + * + * Unlike Jensen, the TCASIC machines have no concept of local + * I/O---everything goes over the PCI bus. + * + * There is plenty room for optimization here. In particular, + * the Alpha's insb/insw/extb/extw should be useful in moving + * data to/from the right byte-lanes. + */ + +#define vip volatile int * +#define vuip volatile unsigned int * +#define vulp volatile unsigned long * + +__EXTERN_INLINE unsigned int tcasic_inb(unsigned long addr) +{ + long result = *(vip) ((addr << 5) + TCASIC_IO + 0x00); + return __kernel_extbl(result, addr & 3); +} + +__EXTERN_INLINE void tcasic_outb(unsigned char b, unsigned long addr) +{ + unsigned long w; + + w = __kernel_insbl(b, addr & 3); + *(vuip) ((addr << 5) + TCASIC_IO + 0x00) = w; + mb(); +} + +__EXTERN_INLINE unsigned int tcasic_inw(unsigned long addr) +{ + long result = *(vip) ((addr << 5) + TCASIC_IO + 0x08); + return __kernel_extwl(result, addr & 3); +} + +__EXTERN_INLINE void tcasic_outw(unsigned short b, unsigned long addr) +{ + unsigned long w; + + w = __kernel_inswl(b, addr & 3); + *(vuip) ((addr << 5) + TCASIC_IO + 0x08) = w; + mb(); +} + +__EXTERN_INLINE unsigned int tcasic_inl(unsigned long addr) +{ + return *(vuip) ((addr << 5) + TCASIC_IO + 0x18); +} + +__EXTERN_INLINE void tcasic_outl(unsigned int b, unsigned long addr) +{ + *(vuip) ((addr << 5) + TCASIC_IO + 0x18) = b; + mb(); +} + + +/* + * Memory functions. 64-bit and 32-bit accesses are done through + * dense memory space, everything else through sparse space. + */ + +__EXTERN_INLINE unsigned long tcasic_readb(unsigned long addr) +{ + unsigned long result, msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + set_hae(msb); + } + result = *(vip) ((addr << 5) + TCASIC_SPARSE_MEM + 0x00); + return __kernel_extbl(result, addr & 3); +} + +__EXTERN_INLINE unsigned long tcasic_readw(unsigned long addr) +{ + unsigned long result, msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + set_hae(msb); + } + result = *(vip) ((addr << 5) + TCASIC_SPARSE_MEM + 0x08); + return __kernel_extwl(result, addr & 3); +} + +__EXTERN_INLINE unsigned long tcasic_readl(unsigned long addr) +{ + return *(vuip) (addr + TCASIC_DENSE_MEM); +} + +__EXTERN_INLINE unsigned long tcasic_readq(unsigned long addr) +{ + return *(vulp) (addr + TCASIC_DENSE_MEM); +} + +__EXTERN_INLINE void tcasic_writeb(unsigned char b, unsigned long addr) +{ + unsigned long msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + set_hae(msb); + } + *(vuip) ((addr << 5) + TCASIC_SPARSE_MEM + 0x00) = b * 0x01010101; +} + +__EXTERN_INLINE void tcasic_writew(unsigned short b, unsigned long addr) +{ + unsigned long msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + set_hae(msb); + } + *(vuip) ((addr << 5) + TCASIC_SPARSE_MEM + 0x08) = b * 0x00010001; +} + +__EXTERN_INLINE void tcasic_writel(unsigned int b, unsigned long addr) +{ + *(vuip) (addr + TCASIC_DENSE_MEM) = b; +} + +__EXTERN_INLINE void tcasic_writeq(unsigned long b, unsigned long addr) +{ + *(vulp) (addr + TCASIC_DENSE_MEM) = b; +} + +/* Find the DENSE memory area for a given bus address. */ + +__EXTERN_INLINE unsigned long tcasic_dense_mem(unsigned long addr) +{ + return TCASIC_DENSE_MEM; +} + +#undef vip +#undef vuip +#undef vulp + +#ifdef __WANT_IO_DEF + +#define virt_to_bus tcasic_virt_to_bus +#define bus_to_virt tcasic_bus_to_virt + +#define __inb tcasic_inb +#define __inw tcasic_inw +#define __inl tcasic_inl +#define __outb tcasic_outb +#define __outw tcasic_outw +#define __outl tcasic_outl +#define __readb tcasic_readb +#define __readw tcasic_readw +#define __readl tcasic_readl +#define __readq tcasic_readq +#define __writeb tcasic_writeb +#define __writew tcasic_writew +#define __writel tcasic_writel +#define __writeq tcasic_writeq +#define dense_mem tcasic_dense_mem + +#define inb(port) \ +(__builtin_constant_p((port))?__inb(port):_inb(port)) + +#define outb(x, port) \ +(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) + +#define readl(a) __readl((unsigned long)(a)) +#define readq(a) __readq((unsigned long)(a)) +#define writel(v,a) __writel((v),(unsigned long)(a)) +#define writeq(v,a) __writeq((v),(unsigned long)(a)) + +#endif /* __WANT_IO_DEF */ + +#ifdef __IO_EXTERN_INLINE +#undef __EXTERN_INLINE +#undef __IO_EXTERN_INLINE +#endif + +#endif /* __KERNEL__ */ + +#endif /* __ALPHA_TCASIC_H */ diff -r -N -u /usr/src/linux/include/asm/dec/interrupts.h linux-2.2.9/include/asm/dec/interrupts.h --- /usr/src/linux/include/asm/dec/interrupts.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm/dec/interrupts.h Mon Aug 2 04:07:11 1999 @@ -0,0 +1,80 @@ +/* + * Miscellaneous definitions used to initialise the interrupt vector table + * with the machine-specific interrupt routines. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1997 by Paul M. Antoine. + * reworked 1998 by Harald Koerfgen. + */ + +#ifndef __ASM_DEC_INTERRUPTS_H +#define __ASM_DEC_INTERRUPTS_H + +/* + * DECstation Interrupts + */ + +/* + * This list reflects the priority of the Interrupts. + * Exception: on kmins we have to handle Memory Error + * Interrupts before the TC Interrupts. + */ +#define CLOCK 0 +#define SCSI_DMA_INT 1 +#define SCSI_INT 2 +#define ETHER 3 +#define SERIAL 4 +#define TC0 5 +#define TC1 6 +#define TC2 7 +#define MEMORY 8 +#define FPU 9 +#define HALT 10 + +#define NR_INTS 11 + +#ifndef _LANGUAGE_ASSEMBLY +/* + * Data structure to hide the differences between the DECstation Interrupts + * + * If asic_mask == NULL, the interrupt is directly handled by the CPU. + * Otherwise this Interrupt is handled the IRQ Controller. + */ + +typedef struct +{ + unsigned int cpu_mask; /* checking and enabling interrupts in CP0 */ + unsigned int iemask; /* enabling interrupts in IRQ Controller */ +} decint_t; + +/* + * Interrupt table structure to hide differences between different + * systems such. + */ +extern void *cpu_ivec_tbl[8]; +extern long cpu_mask_tbl[8]; +extern long cpu_irq_nr[8]; +extern long asic_irq_nr[32]; +extern long asic_mask_tbl[32]; + +/* + * Common interrupt routine prototypes for all DECStations + */ +extern void dec_intr_unimplemented(void); +extern void dec_intr_fpu(void); +extern void dec_intr_rtc(void); + +extern void kn02_io_int(void); +extern void kn02ba_io_int(void); +extern void kn03_io_int(void); + +extern void intr_halt(void); + +extern void asic_intr_unimplemented(void); + +#endif +#endif + diff -r -N -u /usr/src/linux/include/asm/dec/ioasic_addrs.h linux-2.2.9/include/asm/dec/ioasic_addrs.h --- /usr/src/linux/include/asm/dec/ioasic_addrs.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm/dec/ioasic_addrs.h Sat Aug 14 15:03:11 1999 @@ -0,0 +1,82 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Definitions for the address map in the JUNKIO Asic + * + * Created with Information from: + * + * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" + * + * and the Mach Sources + * + * Modified from Linux/DECstation sources + */ + +#ifndef IOASIC_ADDRS_H +#define IOASIC_ADDRS_H + +/* + * This is from section 7.1 (table 16) in the + * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" + * + * These are the start addresses (relative to the base address of the IOCTL + * address map) for the various partitions of I/O space. + * + * Note that the base of the IOCTL address map is different on the + * 300 models and the 400/500/600/700/800/900 Models: + * + * Model 300 base address: 1.A000.0000 + * Model [4-9]00 base address: 1.E000.0000 + * + */ +#define CHUNK_SIZE 0x00040000 + +#define SYSTEM_ROM 00*CHUNK_SIZE +#define IOCTL 01*CHUNK_SIZE +#define ESAR 02*CHUNK_SIZE +#define LANCE 03*CHUNK_SIZE +#define SCC0 04*CHUNK_SIZE +#define RESERVED_1 05*CHUNK_SIZE +#define SCC1 06*CHUNK_SIZE +#define RESERVED_2 07*CHUNK_SIZE +#define TOY 08*CHUNK_SIZE +#define ISDN 09*CHUNK_SIZE +#define RESERVED_3 10*CHUNK_SIZE /* Goes out to 1.E1FF.FFFF */ + /* (1.A1FF.FFFF on the 300s) */ +/* + * Offsets for IOCTL registers (relative to (system_base + IOCTL)) + * + * From section 7.3 of + * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" + */ +#define SCSI_DMA_P 0x00 /* SCSI DMA Pointer */ +#define SCSI_DMA_BP 0x10 /* SCSI DMA Buffer Pointer */ +#define LANCE_DMA_P 0x20 /* LANCE DMA Pointer */ +#define SCC0_T_DMA_P 0x30 /* Communication Port 1 Transmit DMA Pointer */ +#define SCC0_R_DMA_P 0x40 /* Communication Port 1 Receive DMA Pointer */ +#define SCC1_T_DMA_P 0x50 /* Communication Port 2 Transmit DMA Pointer */ +#define SCC1_R_DMA_P 0x60 /* Communication Port 2 Receive DMA Pointer */ +/* 0x70 Reserved */ +#define ISDN_T_DMA_P 0x80 /* ISDN Transmit DMA Pointer */ +#define ISDN_T_DMA_BP 0x90 /* ISDN Transmit DMA Buffer Pointer */ +#define ISDN_R_DMA_P 0xa0 /* ISDN Receive DMA Pointer */ +#define ISDN_R_DMA_BP 0xb0 /* ISDN Receive DMA Buffer Pointer */ +#define SDB0 0xc0 /* System Data Buffer 0 */ +#define SDB2 0xd0 /* System Data Buffer 1 */ +#define SDB2 0xe0 /* System Data Buffer 2 */ +#define SDB3 0xf0 /* System Data Buffer 3 */ +#define SSR 0x100 /* System Support Register */ +#define SIR 0x110 /* System Interrupt Register */ +#define SIMR 0x120 /* System Interrupt Mask Register */ +#define SAR 0x130 /* Systerm Address Register */ +#define ISDN_T_REG 0x140 /* ISDN Data Transmit Register */ +#define ISDN_R_REG 0x150 /* ISDN Data Receive Register */ +#define LANCE_IO_SLOT 0x160 /* System LANCE I/O Slot */ +/* 0x170 Reserved */ +#define SCC0_DMA_SLOT 0x180 /* System SCC0 DMA Slot */ +#define SCC1_DMA_SLOT 0x190 /* System SCC1 DMA Slot */ + +/* 0x1A0 through 0x1d0 are reserved */ +#endif diff -r -N -u /usr/src/linux/include/asm/dec/ioasic_ints.h linux-2.2.9/include/asm/dec/ioasic_ints.h --- /usr/src/linux/include/asm/dec/ioasic_ints.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm/dec/ioasic_ints.h Fri Jun 25 21:53:07 1999 @@ -0,0 +1,108 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Definitions for the interrupt related bits in the JUNKIO Asic + * interrupt status register (and the interrupt mask register, of course) + * + * Created with Information from: + * + * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" + * + * and the Mach Sources + */ + +/* + * the upper 16 bits are common to all JUNKIO machines + * (except the FLOPPY and ISDN bits, which are Maxine sepcific) + */ +#define SCC0_TRANS_PAGEEND 0x80000000 /* Serial DMA Errors */ +#define SCC0_TRANS_MEMRDERR 0x40000000 /* see below */ +#define SCC0_RECV_HALFPAGE 0x20000000 +#define SCC0_RECV_PAGOVRRUN 0x10000000 +#define SCC1_TRANS_PAGEEND 0x08000000 /* end of page reached */ +#define SCC1_TRANS_MEMRDERR 0x04000000 /* SCC1 DMA memory err */ +#define SCC1_RECV_HALFPAGE 0x02000000 /* SCC1 half page */ +#define SCC1_RECV_PAGOVRRUN 0x01000000 /* SCC1 receive overrun */ +#define FLOPPY_DMA_ERROR 0x00800000 /* FDI DMA error */ +#define ISDN_TRANS_PTR_LOADED 0x00400000 /* xmitbuf ptr loaded */ +#define ISDN_RECV_PTR_LOADED 0x00200000 /* rcvbuf ptr loaded */ +#define ISDN_DMA_MEMRDERR 0x00100000 /* read or ovrrun error */ +#define SCSI_PTR_LOADED 0x00080000 +#define SCSI_PAGOVRRUN 0x00040000 /* page overrun? */ +#define SCSI_DMA_MEMRDERR 0x00020000 +#define LANCE_DMA_MEMRDERR 0x00010000 + +/* + * the lower 16 bits are system specific + */ + +/* + * The following three seem to be in common + */ +#define SCSI_CHIP 0x00000200 +#define LANCE_CHIP 0x00000100 +#define SCC1_CHIP 0x00000080 /* NOT on maxine */ +#define SCC0_CHIP 0x00000040 + +/* + * The rest is different + */ + +/* kmin aka 3min aka kn02ba aka DS5000_1xx */ +#define KMIN_TIMEOUT 0x00001000 /* CPU IO-Write Timeout */ +#define KMIN_CLOCK 0x00000020 +#define KMIN_SCSI_FIFO 0x00000004 /* SCSI Data Ready */ + +/* kn02ca aka maxine */ +#define MAXINE_FLOPPY 0x00008000 /* FDI Interrupt */ +#define MAXINE_TC0 0x00001000 /* TC Option 0 */ +#define MAXINE_ISDN 0x00000800 /* ISDN Chip */ +#define MAXINE_FLOPPY_HDS 0x00000080 /* Floppy Status */ +#define MAXINE_TC1 0x00000020 /* TC Option 1 */ +#define MAXINE_FLOPPY_XDS 0x00000010 /* Floppy Status */ +#define MAXINE_VINT 0x00000008 /* Video Frame */ +#define MAXINE_N_VINT 0x00000004 /* Not Video frame */ +#define MAXINE_DTOP_TRANS 0x00000002 /* DTI Xmit-Rdy */ +#define MAXINE_DTOP_RECV 0x00000001 /* DTI Recv-Available */ + +/* kn03 aka 3max+ aka DS5000_2x0 */ +#define KN03_TC2 0x00004000 +#define KN03_TC1 0x00002000 +#define KN03_TC0 0x00001000 +#define KN03_SCSI_FIFO 0x00000004 /* ??? Info from Mach */ + +/* + * Now form groups, i.e. all serial interrupts, all SCSI interrupts and so on. + */ +#define SERIAL_INTS (SCC0_TRANS_PAGEEND | SCC0_TRANS_MEMRDERR | \ + SCC0_RECV_HALFPAGE | SCC0_RECV_PAGOVRRUN | \ + SCC1_TRANS_PAGEEND | SCC1_TRANS_MEMRDERR | \ + SCC1_RECV_HALFPAGE | SCC1_RECV_PAGOVRRUN | \ + SCC1_CHIP | SCC0_CHIP) + +#define XINE_SERIAL_INTS (SCC0_TRANS_PAGEEND | SCC0_TRANS_MEMRDERR | \ + SCC0_RECV_HALFPAGE | SCC0_RECV_PAGOVRRUN | \ + SCC0_CHIP) + +#define SCSI_INTS (SCSI_PTR_LOADED | SCSI_PAGOVRRUN | \ + SCSI_DMA_MEMRDERR | SCSI_CHIP) + +#define KMIN_SCSI_INTS (SCSI_PTR_LOADED | SCSI_PAGOVRRUN | \ + SCSI_DMA_MEMRDERR | SCSI_CHIP | KMIN_SCSI_FIFO) + +#define LANCE_INTS (LANCE_DMA_MEMRDERR | LANCE_CHIP) + +/* + * For future use ... + */ +#define XINE_FLOPPY_INTS (MAXINE_FLOPPY | MAXINE_FLOPPY_HDS | \ + FLOPPY_DMA_ERROR | MAXINE_FLOPPY_XDS) + +#define XINE_ISDN_INTS (MAXINE_ISDN | ISDN_TRANS_PTR_LOADED | \ + ISDN_RECV_PTR_LOADED | ISDN_DMA_MEMRDERR) + +#define XINE_DTOP_INTS (MAXINE_DTOP_TRANS | DTOP_RECV | \ + ISDN_TRANS_PTR_LOADED | ISDN_RECV_PTR_LOADED | \ + ISDN_DMA_MEMRDERR) diff -r -N -u /usr/src/linux/include/asm/dec/machtype.h linux-2.2.9/include/asm/dec/machtype.h --- /usr/src/linux/include/asm/dec/machtype.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm/dec/machtype.h Sat Aug 14 18:56:54 1999 @@ -0,0 +1,20 @@ +/* + * Various machine type definitions + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 1998 Harald Koerfgen + */ +#include + +#define TURBOCHANNEL (mips_machtype == MACH_DS5000_200 || \ + mips_machtype == MACH_DS5000_1XX || \ + mips_machtype == MACH_DS5000_XX || \ + mips_machtype == MACH_DS5000_2X0) + +#define IOASIC (mips_machtype == MACH_DS5000_1XX || \ + mips_machtype == MACH_DS5000_XX || \ + mips_machtype == MACH_DS5000_2X0) + diff -r -N -u /usr/src/linux/include/asm/dec/tc.h linux-2.2.9/include/asm/dec/tc.h --- /usr/src/linux/include/asm/dec/tc.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm/dec/tc.h Fri Jun 25 21:53:07 1999 @@ -0,0 +1,43 @@ +/* + * Interface to the TURBOchannel related routines + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 1998 Harald Koerfgen + */ +#ifndef ASM_TC_H +#define ASM_TC_H + +extern unsigned long system_base; + +/* + * Search for a TURBOchannel Option Module + * with a certain name. Returns slot number + * of the first card not in use or -ENODEV + * if none found. + */ +extern int search_tc_card(const char *); +/* + * Marks the card in slot as used + */ +extern void claim_tc_card(int); +/* + * Marks the card in slot as free + */ +extern void release_tc_card(int); +/* + * Return base address of card in slot + */ +extern unsigned long get_tc_base_addr(int); +/* + * Return interrupt number of slot + */ +extern unsigned long get_tc_irq_nr(int); +/* + * Return TURBOchannel clock frequency in hz + */ +extern unsigned long get_tc_speed(void); + +#endif diff -r -N -u /usr/src/linux/include/asm/dec/tcinfo.h linux-2.2.9/include/asm/dec/tcinfo.h --- /usr/src/linux/include/asm/dec/tcinfo.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm/dec/tcinfo.h Fri Jun 25 21:53:07 1999 @@ -0,0 +1,47 @@ +/* + * Various TURBOchannel related stuff + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Information obtained through the get_tcinfo prom call + * created from: + * + * TURBOchannel Firmware Specification + * + * EK-TCAAD-FS-004 + * from Digital Equipment Corporation + * + * Copyright (c) 1998 Harald Koerfgen + */ + +typedef struct { + int revision; + int clk_period; + int slot_size; + int io_timeout; + int dma_range; + int max_dma_burst; + int parity; + int reserved[4]; +} tcinfo; + +#define MAX_SLOT 7 + +typedef struct { + unsigned long base_addr; + unsigned char name[9]; + unsigned char vendor[9]; + unsigned char firmware[9]; + int interrupt; + int flags; +} slot_info; + +/* + * Values for flags + */ +#define FREE 1<<0 +#define IN_USE 1<<1 + + diff -r -N -u /usr/src/linux/include/asm/dec/tcmodule.h linux-2.2.9/include/asm/dec/tcmodule.h --- /usr/src/linux/include/asm/dec/tcmodule.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm/dec/tcmodule.h Fri Jun 25 21:53:07 1999 @@ -0,0 +1,35 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Offsets for the ROM header locations for + * TURBOchannel cards + * + * created from: + * + * TURBOchannel Firmware Specification + * + * EK-TCAAD-FS-004 + * from Digital Equipment Corporation + * + * Jan.1998 Harald Koerfgen + */ + +#define OLDCARD 0x3c0000 + +#define ROM_WIDTH 0x3e0 +#define ROM_STRIDE 0x3e4 +#define ROM_SIZE 0x3e8 +#define SLOT_SIZE 0x3ec +#define PATTERN0 0x3f0 +#define PATTERN1 0x3f4 +#define PATTERN2 0x3f8 +#define PATTERN3 0x3fc +#define FIRM_VER 0x400 +#define VENDOR 0x420 +#define MODULE 0x440 +#define FIRM_TYPE 0x460 +#define FLAGS 0x470 + +#define ROM_OBJECTS 0x480 diff -r -N -u /usr/src/linux/include/asm/io.h linux-2.2.9/include/asm/io.h --- /usr/src/linux/include/asm/io.h Fri May 21 08:15:47 1999 +++ linux-2.2.9/include/asm/io.h Mon Aug 16 03:03:32 1999 @@ -143,6 +143,8 @@ # include #elif defined(CONFIG_ALPHA_RX164) # include +#elif defined(CONFIG_ALPHA_PELICAN) || defined(CONFIG_ALPHA_FLAMINGO) +# include #else #error "What system is this?" #endif diff -r -N -u /usr/src/linux/include/asm/system.h linux-2.2.9/include/asm/system.h --- /usr/src/linux/include/asm/system.h Fri May 21 08:15:45 1999 +++ linux-2.2.9/include/asm/system.h Mon Aug 16 03:02:19 1999 @@ -264,9 +264,29 @@ #define tbisi(x) __tbi(1,__r17=(x),"1" (__r17)) #define tbisd(x) __tbi(2,__r17=(x),"1" (__r17)) #define tbis(x) __tbi(3,__r17=(x),"1" (__r17)) +#if defined(CONFIG_ALPHA_FLAMINGO) || defined(CONFIG_ALPHA_PELICAN) +#define tbiap() \ +({ \ + register unsigned long __r16 __asm__("$16") = -1; \ + __asm__ __volatile__( \ + "call_pal 0x0033" \ + : \ + : \ + :"$1", "$16", "$17", "$22", "$23", "$24", "$25"); \ +}) +#define tbia() \ +({ \ + register unsigned long __r16 __asm__("$16") = -2; \ + __asm__ __volatile__( \ + "call_pal 0x0033" \ + : \ + : \ + :"$1", "$16", "$17", "$22", "$23", "$24", "$25"); \ +}) +#else #define tbiap() __tbi(-1, /* no second argument */) #define tbia() __tbi(-2, /* no second argument */) - +#endif /* * Give prototypes to shut up gcc. */ diff -r -N -u /usr/src/linux/include/asm-alpha/addrspace.h linux-2.2.9/include/asm-alpha/addrspace.h --- /usr/src/linux/include/asm-alpha/addrspace.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm-alpha/addrspace.h Sat Aug 14 18:04:27 1999 @@ -0,0 +1,52 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996 by Ralf Baechle + * + * Defitions for the address spaces of the MIPS CPUs. + */ +#ifndef __ASM_MIPS_ADDRSPACE_H +#define __ASM_MIPS_ADDRSPACE_H + +/* + * Memory segments (32bit kernel mode addresses) + */ +#define KUSEG 0x00000000 +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 +#define KSEG2 0xc0000000 +#define KSEG3 0xe0000000 + +/* + * Returns the kernel segment base of a given address + */ +#define KSEGX(a) (((unsigned long)(a)) & 0xe0000000) + +/* + * Returns the physical address of a KSEG0/KSEG1 address + */ +#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff) + +/* + * Map an address to a certain kernel segment + */ +#define KSEG0ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG0)) +#define KSEG1ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG1)) +#define KSEG2ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG2)) +#define KSEG3ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG3)) + +/* + * Memory segments (64bit kernel mode addresses) + */ +#define XKUSEG 0x0000000000000000 +#define XKSSEG 0x4000000000000000 +#define XKPHYS 0x8000000000000000 +#define XKSEG 0xc000000000000000 +#define CKSEG0 0xffffffff80000000 +#define CKSEG1 0xffffffffa0000000 +#define CKSSEG 0xffffffffc0000000 +#define CKSEG3 0xffffffffe0000000 + +#endif /* __ASM_MIPS_ADDRSPACE_H */ diff -r -N -u /usr/src/linux/include/asm-alpha/bootinfo.h linux-2.2.9/include/asm-alpha/bootinfo.h --- /usr/src/linux/include/asm-alpha/bootinfo.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm-alpha/bootinfo.h Sat Aug 14 18:04:33 1999 @@ -0,0 +1,192 @@ +/* $Id: bootinfo.h,v 1.7 1999/04/12 18:59:14 harald Exp $ + * + * bootinfo.h -- Definition of the Linux/MIPS boot information structure + * + * Copyright (C) 1995, 1996 by Ralf Baechle, Andreas Busse, + * Stoned Elipot and Paul M. Antoine. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ +#ifndef __ASM_MIPS_BOOTINFO_H +#define __ASM_MIPS_BOOTINFO_H + +/* XXX */ +#include + +/* + * Values for machgroup + */ +#define MACH_GROUP_UNKNOWN 0 /* whatever... */ +#define MACH_GROUP_JAZZ 1 /* Jazz */ +#define MACH_GROUP_DEC 2 /* Digital Equipment */ +#define MACH_GROUP_ARC 3 /* Wreckstation Tyne, rPC44, possibly other */ +#define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */ +#define MACH_GROUP_ACN 5 +#define MACH_GROUP_SGI 6 /* Silicon Graphics workstations and servers */ +#define MACH_GROUP_COBALT 7 /* Cobalt servers */ + +#define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", \ + "SNI", "ACN", "SGI", "Cobalt" } + +/* + * Valid machtype values for group unknown (low order halfword of mips_machtype) + */ +#define MACH_UNKNOWN 0 /* whatever... */ + +#define GROUP_UNKNOWN_NAMES { "unknown" } + +/* + * Valid machtype values for group JAZZ + */ +#define MACH_ACER_PICA_61 0 /* Acer PICA-61 (PICA1) */ +#define MACH_MIPS_MAGNUM_4000 1 /* Mips Magnum 4000 "RC4030" */ +#define MACH_OLIVETTI_M700 2 /* Olivetti M700-10 (-15 ??) */ + +#define GROUP_JAZZ_NAMES { "Acer PICA 61", "Mips Magnum 4000", "Olivetti M700" } + +/* + * Valid machtype for group DEC + */ +#define MACH_DSUNKNOWN 0 +#define MACH_DS23100 1 /* DECstation 2100 or 3100 */ +#define MACH_DS5100 2 /* DECstation 5100 */ +#define MACH_DS5000_200 3 /* DECstation 5000/200 */ +#define MACH_DS5000_1XX 4 /* DECstation 5000/120, 125, 133, 150 */ +#define MACH_DS5000_XX 5 /* DECstation 5000/20, 25, 33, 50 */ +#define MACH_DS5000_2X0 6 /* DECstation 5000/240, 260 */ +#define MACH_DS5400 7 /* DECstation 5400 */ +#define MACH_DS5500 8 /* DECstation 5500 */ +#define MACH_DS5800 9 /* DECstation 5800 */ + +#define GROUP_DEC_NAMES { "unknown", "DECstation 2100/3100", "DECstation 5100", \ + "DECstation 5000/200", "DECstation 5000/1xx", "Personal DECstation 5000/xx", \ + "DECstation 5000/2x0", "DECstation 5400", "DECstation 5500", \ + "DECstation 5800" } + +/* + * Valid machtype for group ARC + */ +#define MACH_DESKSTATION_RPC44 0 /* Deskstation rPC44 */ +#define MACH_DESKSTATION_TYNE 1 /* Deskstation Tyne */ + +#define GROUP_ARC_NAMES { "Deskstation rPC44", "Deskstation Tyne" } + +/* + * Valid machtype for group SNI_RM + */ +#define MACH_SNI_RM200_PCI 0 /* RM200/RM300/RM400 PCI series */ + +#define GROUP_SNI_RM_NAMES { "RM200 PCI" } + +/* + * Valid machtype for group ACN + */ +#define MACH_ACN_MIPS_BOARD 0 /* ACN MIPS single board */ + +#define GROUP_ACN_NAMES { "ACN" } + +/* + * Valid machtype for group SGI + */ +#define MACH_SGI_INDY 0 /* R4?K and R5K Indy workstaions */ + +#define GROUP_SGI_NAMES { "Indy" } + +/* + * Valid machtype for group COBALT + */ +#define MACH_COBALT_27 0 /* Proto "27" hardware */ + +#define GROUP_COBALT_NAMES { "Microserver 27" } + +/* + * Valid cputype values + */ +#define CPU_UNKNOWN 0 +#define CPU_R2000 1 +#define CPU_R3000 2 +#define CPU_R3000A 3 +#define CPU_R3041 4 +#define CPU_R3051 5 +#define CPU_R3052 6 +#define CPU_R3081 7 +#define CPU_R3081E 8 +#define CPU_R4000PC 9 +#define CPU_R4000SC 10 +#define CPU_R4000MC 11 +#define CPU_R4200 12 +#define CPU_R4400PC 13 +#define CPU_R4400SC 14 +#define CPU_R4400MC 15 +#define CPU_R4600 16 +#define CPU_R6000 17 +#define CPU_R6000A 18 +#define CPU_R8000 19 +#define CPU_R10000 20 +#define CPU_R4300 21 +#define CPU_R4650 22 +#define CPU_R4700 23 +#define CPU_R5000 24 +#define CPU_R5000A 25 +#define CPU_R4640 26 +#define CPU_NEVADA 27 /* RM5230, RM5260 */ +#define CPU_LAST 27 + +#define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \ + "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC", \ + "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000", \ + "R6000A", "R8000", "R10000", "R4300", "R4650", "R4700", "R5000", \ + "R5000A", "R4640", "Nevada" } + +#define CL_SIZE (80) + +#ifndef _LANGUAGE_ASSEMBLY + +/* + * Some machine parameters passed by the bootloaders. + */ + +struct drive_info_struct { + char dummy[32]; +}; + +/* This is the same as in Milo but renamed for the sake of kernel's */ +/* namespace */ +typedef struct mips_arc_DisplayInfo { /* video adapter information */ + unsigned short cursor_x; + unsigned short cursor_y; + unsigned short columns; + unsigned short lines; +} mips_arc_DisplayInfo; + +#ifdef CONFIG_SGI +/* screen info will dissapear... soon */ +//#define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 158, 0, 0, 0, 62, 0, 16} +#define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 160, 0, 0, 0, 64, 0, 16} +#define DEFAULT_DRIVE_INFO { {0,}} +#else +/* default values for screen_info variable (Colour VGA) */ +#define DEFAULT_SCREEN_INFO {0, 0, 0, 52, 3, 80, 4626, 3, 9, 50, 0x22, 16} +#endif + +/* default values for drive info */ +#define DEFAULT_DRIVE_INFO { {0,}} + + +/* + * These are the kernel variables initialized from + * the tag. And they have to be initialized to dummy/default + * values in setup.c (or whereever suitable) so they are in + * .data section + */ +extern unsigned long mips_memory_upper; +extern unsigned long mips_cputype; +extern unsigned long mips_machtype; +extern unsigned long mips_machgroup; +extern unsigned long mips_tlb_entries; + +#endif /* _LANGUAGE_ASSEMBLY */ + +#endif /* __ASM_MIPS_BOOTINFO_H */ diff -r -N -u /usr/src/linux/include/asm-alpha/core_tcasic.h linux-2.2.9/include/asm-alpha/core_tcasic.h --- /usr/src/linux/include/asm-alpha/core_tcasic.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm-alpha/core_tcasic.h Sun Aug 15 02:18:09 1999 @@ -0,0 +1,256 @@ +/* + * Initial adaptation from core_apecs.h - this will not come close to working. + * + * Oh, dear - this will require some work. + */ +#ifndef __ALPHA_TCASIC_H +#define __ALPHA_TCASIC_H + +#include +#include +#include + +/* These are for DEC 3000 machines (Pelican & Flamingo family systems) */ + +#define TCASIC_DMA_WIN_BASE_DEFAULT (1024*1024*1024) +#define TCASIC_DMA_WIN_SIZE_DEFAULT (1024*1024*1024) + +#define TCASIC_DMA_WIN_BASE TCASIC_DMA_WIN_BASE_DEFAULT +#define TCASIC_DMA_WIN_SIZE TCASIC_DMA_WIN_SIZE_DEFAULT + +#define TCASIC_IOC_HAXR0 (IDENT_ADDR + 0x1A0000180UL) +#define TCASIC_IOC_HAXR1 (IDENT_ADDR + 0x1A00001A0UL) +#define TCASIC_IOC_HAXR2 (IDENT_ADDR + 0x1A00001C0UL) + +#define TCASIC_IACK_SC (IDENT_ADDR + 0x1b0000000UL) +#define TCASIC_IO (IDENT_ADDR + 0x1c0000000UL) +#define TCASIC_BUS (IDENT_ADDR + 0x1c0000000UL) +#define TCASIC_SPARSE_MEM (IDENT_ADDR + 0x200000000UL) +#define TCASIC_DENSE_MEM (IDENT_ADDR + 0x300000000UL) + +#define TCASIC_HAE_ADDRESS TCASIC_IOC_HAXR1 + +#ifdef __KERNEL__ + +#ifndef __EXTERN_INLINE +#define __EXTERN_INLINE extern inline +#define __IO_EXTERN_INLINE +#endif + +/* + * Translate physical memory address as seen on (PCI) bus into + * a kernel virtual address and vv. + */ + +/* + * NOTE: we fudge the window 1 maximum as 48Mb instead of 64Mb, to prevent + * virt_to_bus() from returning an address in the first window, for a + * data area that goes beyond the 64Mb first DMA window. Sigh... + * This MUST match with MAX_DMA_ADDRESS for consistency, but + * we can't just use that here, because of header file looping... :-( + */ + +__EXTERN_INLINE unsigned long tcasic_virt_to_bus(void * address) +{ + unsigned long paddr = virt_to_phys(address); + return paddr + TCASIC_DMA_WIN_BASE; +} + +__EXTERN_INLINE void * tcasic_bus_to_virt(unsigned long address) +{ + /* + * This check is a sanity check but also ensures that bus + * address 0 maps to virtual address 0 which is useful to + * detect null "pointers" (the NCR driver is much simpler if + * NULL pointers are preserved). + */ + if (address < TCASIC_DMA_WIN_BASE) + return 0; + return phys_to_virt(address - TCASIC_DMA_WIN_BASE); +} + +/* + * I/O functions: + * + * Unlike Jensen, the TCASIC machines have no concept of local + * I/O---everything goes over the PCI bus. + * + * There is plenty room for optimization here. In particular, + * the Alpha's insb/insw/extb/extw should be useful in moving + * data to/from the right byte-lanes. + */ + +#define vip volatile int * +#define vuip volatile unsigned int * +#define vulp volatile unsigned long * + +__EXTERN_INLINE unsigned int tcasic_inb(unsigned long addr) +{ + long result = *(vip) ((addr << 5) + TCASIC_IO + 0x00); + return __kernel_extbl(result, addr & 3); +} + +__EXTERN_INLINE void tcasic_outb(unsigned char b, unsigned long addr) +{ + unsigned long w; + + w = __kernel_insbl(b, addr & 3); + *(vuip) ((addr << 5) + TCASIC_IO + 0x00) = w; + mb(); +} + +__EXTERN_INLINE unsigned int tcasic_inw(unsigned long addr) +{ + long result = *(vip) ((addr << 5) + TCASIC_IO + 0x08); + return __kernel_extwl(result, addr & 3); +} + +__EXTERN_INLINE void tcasic_outw(unsigned short b, unsigned long addr) +{ + unsigned long w; + + w = __kernel_inswl(b, addr & 3); + *(vuip) ((addr << 5) + TCASIC_IO + 0x08) = w; + mb(); +} + +__EXTERN_INLINE unsigned int tcasic_inl(unsigned long addr) +{ + return *(vuip) ((addr << 5) + TCASIC_IO + 0x18); +} + +__EXTERN_INLINE void tcasic_outl(unsigned int b, unsigned long addr) +{ + *(vuip) ((addr << 5) + TCASIC_IO + 0x18) = b; + mb(); +} + + +/* + * Memory functions. 64-bit and 32-bit accesses are done through + * dense memory space, everything else through sparse space. + */ + +__EXTERN_INLINE unsigned long tcasic_readb(unsigned long addr) +{ + unsigned long result, msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + set_hae(msb); + } + result = *(vip) ((addr << 5) + TCASIC_SPARSE_MEM + 0x00); + return __kernel_extbl(result, addr & 3); +} + +__EXTERN_INLINE unsigned long tcasic_readw(unsigned long addr) +{ + unsigned long result, msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + set_hae(msb); + } + result = *(vip) ((addr << 5) + TCASIC_SPARSE_MEM + 0x08); + return __kernel_extwl(result, addr & 3); +} + +__EXTERN_INLINE unsigned long tcasic_readl(unsigned long addr) +{ + return *(vuip) (addr + TCASIC_DENSE_MEM); +} + +__EXTERN_INLINE unsigned long tcasic_readq(unsigned long addr) +{ + return *(vulp) (addr + TCASIC_DENSE_MEM); +} + +__EXTERN_INLINE void tcasic_writeb(unsigned char b, unsigned long addr) +{ + unsigned long msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + set_hae(msb); + } + *(vuip) ((addr << 5) + TCASIC_SPARSE_MEM + 0x00) = b * 0x01010101; +} + +__EXTERN_INLINE void tcasic_writew(unsigned short b, unsigned long addr) +{ + unsigned long msb; + + if (addr >= (1UL << 24)) { + msb = addr & 0xf8000000; + addr -= msb; + set_hae(msb); + } + *(vuip) ((addr << 5) + TCASIC_SPARSE_MEM + 0x08) = b * 0x00010001; +} + +__EXTERN_INLINE void tcasic_writel(unsigned int b, unsigned long addr) +{ + *(vuip) (addr + TCASIC_DENSE_MEM) = b; +} + +__EXTERN_INLINE void tcasic_writeq(unsigned long b, unsigned long addr) +{ + *(vulp) (addr + TCASIC_DENSE_MEM) = b; +} + +/* Find the DENSE memory area for a given bus address. */ + +__EXTERN_INLINE unsigned long tcasic_dense_mem(unsigned long addr) +{ + return TCASIC_DENSE_MEM; +} + +#undef vip +#undef vuip +#undef vulp + +#ifdef __WANT_IO_DEF + +#define virt_to_bus tcasic_virt_to_bus +#define bus_to_virt tcasic_bus_to_virt + +#define __inb tcasic_inb +#define __inw tcasic_inw +#define __inl tcasic_inl +#define __outb tcasic_outb +#define __outw tcasic_outw +#define __outl tcasic_outl +#define __readb tcasic_readb +#define __readw tcasic_readw +#define __readl tcasic_readl +#define __readq tcasic_readq +#define __writeb tcasic_writeb +#define __writew tcasic_writew +#define __writel tcasic_writel +#define __writeq tcasic_writeq +#define dense_mem tcasic_dense_mem + +#define inb(port) \ +(__builtin_constant_p((port))?__inb(port):_inb(port)) + +#define outb(x, port) \ +(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) + +#define readl(a) __readl((unsigned long)(a)) +#define readq(a) __readq((unsigned long)(a)) +#define writel(v,a) __writel((v),(unsigned long)(a)) +#define writeq(v,a) __writeq((v),(unsigned long)(a)) + +#endif /* __WANT_IO_DEF */ + +#ifdef __IO_EXTERN_INLINE +#undef __EXTERN_INLINE +#undef __IO_EXTERN_INLINE +#endif + +#endif /* __KERNEL__ */ + +#endif /* __ALPHA_TCASIC_H */ diff -r -N -u /usr/src/linux/include/asm-alpha/dec/interrupts.h linux-2.2.9/include/asm-alpha/dec/interrupts.h --- /usr/src/linux/include/asm-alpha/dec/interrupts.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm-alpha/dec/interrupts.h Mon Aug 2 04:07:11 1999 @@ -0,0 +1,80 @@ +/* + * Miscellaneous definitions used to initialise the interrupt vector table + * with the machine-specific interrupt routines. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1997 by Paul M. Antoine. + * reworked 1998 by Harald Koerfgen. + */ + +#ifndef __ASM_DEC_INTERRUPTS_H +#define __ASM_DEC_INTERRUPTS_H + +/* + * DECstation Interrupts + */ + +/* + * This list reflects the priority of the Interrupts. + * Exception: on kmins we have to handle Memory Error + * Interrupts before the TC Interrupts. + */ +#define CLOCK 0 +#define SCSI_DMA_INT 1 +#define SCSI_INT 2 +#define ETHER 3 +#define SERIAL 4 +#define TC0 5 +#define TC1 6 +#define TC2 7 +#define MEMORY 8 +#define FPU 9 +#define HALT 10 + +#define NR_INTS 11 + +#ifndef _LANGUAGE_ASSEMBLY +/* + * Data structure to hide the differences between the DECstation Interrupts + * + * If asic_mask == NULL, the interrupt is directly handled by the CPU. + * Otherwise this Interrupt is handled the IRQ Controller. + */ + +typedef struct +{ + unsigned int cpu_mask; /* checking and enabling interrupts in CP0 */ + unsigned int iemask; /* enabling interrupts in IRQ Controller */ +} decint_t; + +/* + * Interrupt table structure to hide differences between different + * systems such. + */ +extern void *cpu_ivec_tbl[8]; +extern long cpu_mask_tbl[8]; +extern long cpu_irq_nr[8]; +extern long asic_irq_nr[32]; +extern long asic_mask_tbl[32]; + +/* + * Common interrupt routine prototypes for all DECStations + */ +extern void dec_intr_unimplemented(void); +extern void dec_intr_fpu(void); +extern void dec_intr_rtc(void); + +extern void kn02_io_int(void); +extern void kn02ba_io_int(void); +extern void kn03_io_int(void); + +extern void intr_halt(void); + +extern void asic_intr_unimplemented(void); + +#endif +#endif + diff -r -N -u /usr/src/linux/include/asm-alpha/dec/ioasic_addrs.h linux-2.2.9/include/asm-alpha/dec/ioasic_addrs.h --- /usr/src/linux/include/asm-alpha/dec/ioasic_addrs.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm-alpha/dec/ioasic_addrs.h Sat Aug 14 15:03:11 1999 @@ -0,0 +1,82 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Definitions for the address map in the JUNKIO Asic + * + * Created with Information from: + * + * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" + * + * and the Mach Sources + * + * Modified from Linux/DECstation sources + */ + +#ifndef IOASIC_ADDRS_H +#define IOASIC_ADDRS_H + +/* + * This is from section 7.1 (table 16) in the + * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" + * + * These are the start addresses (relative to the base address of the IOCTL + * address map) for the various partitions of I/O space. + * + * Note that the base of the IOCTL address map is different on the + * 300 models and the 400/500/600/700/800/900 Models: + * + * Model 300 base address: 1.A000.0000 + * Model [4-9]00 base address: 1.E000.0000 + * + */ +#define CHUNK_SIZE 0x00040000 + +#define SYSTEM_ROM 00*CHUNK_SIZE +#define IOCTL 01*CHUNK_SIZE +#define ESAR 02*CHUNK_SIZE +#define LANCE 03*CHUNK_SIZE +#define SCC0 04*CHUNK_SIZE +#define RESERVED_1 05*CHUNK_SIZE +#define SCC1 06*CHUNK_SIZE +#define RESERVED_2 07*CHUNK_SIZE +#define TOY 08*CHUNK_SIZE +#define ISDN 09*CHUNK_SIZE +#define RESERVED_3 10*CHUNK_SIZE /* Goes out to 1.E1FF.FFFF */ + /* (1.A1FF.FFFF on the 300s) */ +/* + * Offsets for IOCTL registers (relative to (system_base + IOCTL)) + * + * From section 7.3 of + * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" + */ +#define SCSI_DMA_P 0x00 /* SCSI DMA Pointer */ +#define SCSI_DMA_BP 0x10 /* SCSI DMA Buffer Pointer */ +#define LANCE_DMA_P 0x20 /* LANCE DMA Pointer */ +#define SCC0_T_DMA_P 0x30 /* Communication Port 1 Transmit DMA Pointer */ +#define SCC0_R_DMA_P 0x40 /* Communication Port 1 Receive DMA Pointer */ +#define SCC1_T_DMA_P 0x50 /* Communication Port 2 Transmit DMA Pointer */ +#define SCC1_R_DMA_P 0x60 /* Communication Port 2 Receive DMA Pointer */ +/* 0x70 Reserved */ +#define ISDN_T_DMA_P 0x80 /* ISDN Transmit DMA Pointer */ +#define ISDN_T_DMA_BP 0x90 /* ISDN Transmit DMA Buffer Pointer */ +#define ISDN_R_DMA_P 0xa0 /* ISDN Receive DMA Pointer */ +#define ISDN_R_DMA_BP 0xb0 /* ISDN Receive DMA Buffer Pointer */ +#define SDB0 0xc0 /* System Data Buffer 0 */ +#define SDB2 0xd0 /* System Data Buffer 1 */ +#define SDB2 0xe0 /* System Data Buffer 2 */ +#define SDB3 0xf0 /* System Data Buffer 3 */ +#define SSR 0x100 /* System Support Register */ +#define SIR 0x110 /* System Interrupt Register */ +#define SIMR 0x120 /* System Interrupt Mask Register */ +#define SAR 0x130 /* Systerm Address Register */ +#define ISDN_T_REG 0x140 /* ISDN Data Transmit Register */ +#define ISDN_R_REG 0x150 /* ISDN Data Receive Register */ +#define LANCE_IO_SLOT 0x160 /* System LANCE I/O Slot */ +/* 0x170 Reserved */ +#define SCC0_DMA_SLOT 0x180 /* System SCC0 DMA Slot */ +#define SCC1_DMA_SLOT 0x190 /* System SCC1 DMA Slot */ + +/* 0x1A0 through 0x1d0 are reserved */ +#endif diff -r -N -u /usr/src/linux/include/asm-alpha/dec/ioasic_ints.h linux-2.2.9/include/asm-alpha/dec/ioasic_ints.h --- /usr/src/linux/include/asm-alpha/dec/ioasic_ints.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm-alpha/dec/ioasic_ints.h Fri Jun 25 21:53:07 1999 @@ -0,0 +1,108 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Definitions for the interrupt related bits in the JUNKIO Asic + * interrupt status register (and the interrupt mask register, of course) + * + * Created with Information from: + * + * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" + * + * and the Mach Sources + */ + +/* + * the upper 16 bits are common to all JUNKIO machines + * (except the FLOPPY and ISDN bits, which are Maxine sepcific) + */ +#define SCC0_TRANS_PAGEEND 0x80000000 /* Serial DMA Errors */ +#define SCC0_TRANS_MEMRDERR 0x40000000 /* see below */ +#define SCC0_RECV_HALFPAGE 0x20000000 +#define SCC0_RECV_PAGOVRRUN 0x10000000 +#define SCC1_TRANS_PAGEEND 0x08000000 /* end of page reached */ +#define SCC1_TRANS_MEMRDERR 0x04000000 /* SCC1 DMA memory err */ +#define SCC1_RECV_HALFPAGE 0x02000000 /* SCC1 half page */ +#define SCC1_RECV_PAGOVRRUN 0x01000000 /* SCC1 receive overrun */ +#define FLOPPY_DMA_ERROR 0x00800000 /* FDI DMA error */ +#define ISDN_TRANS_PTR_LOADED 0x00400000 /* xmitbuf ptr loaded */ +#define ISDN_RECV_PTR_LOADED 0x00200000 /* rcvbuf ptr loaded */ +#define ISDN_DMA_MEMRDERR 0x00100000 /* read or ovrrun error */ +#define SCSI_PTR_LOADED 0x00080000 +#define SCSI_PAGOVRRUN 0x00040000 /* page overrun? */ +#define SCSI_DMA_MEMRDERR 0x00020000 +#define LANCE_DMA_MEMRDERR 0x00010000 + +/* + * the lower 16 bits are system specific + */ + +/* + * The following three seem to be in common + */ +#define SCSI_CHIP 0x00000200 +#define LANCE_CHIP 0x00000100 +#define SCC1_CHIP 0x00000080 /* NOT on maxine */ +#define SCC0_CHIP 0x00000040 + +/* + * The rest is different + */ + +/* kmin aka 3min aka kn02ba aka DS5000_1xx */ +#define KMIN_TIMEOUT 0x00001000 /* CPU IO-Write Timeout */ +#define KMIN_CLOCK 0x00000020 +#define KMIN_SCSI_FIFO 0x00000004 /* SCSI Data Ready */ + +/* kn02ca aka maxine */ +#define MAXINE_FLOPPY 0x00008000 /* FDI Interrupt */ +#define MAXINE_TC0 0x00001000 /* TC Option 0 */ +#define MAXINE_ISDN 0x00000800 /* ISDN Chip */ +#define MAXINE_FLOPPY_HDS 0x00000080 /* Floppy Status */ +#define MAXINE_TC1 0x00000020 /* TC Option 1 */ +#define MAXINE_FLOPPY_XDS 0x00000010 /* Floppy Status */ +#define MAXINE_VINT 0x00000008 /* Video Frame */ +#define MAXINE_N_VINT 0x00000004 /* Not Video frame */ +#define MAXINE_DTOP_TRANS 0x00000002 /* DTI Xmit-Rdy */ +#define MAXINE_DTOP_RECV 0x00000001 /* DTI Recv-Available */ + +/* kn03 aka 3max+ aka DS5000_2x0 */ +#define KN03_TC2 0x00004000 +#define KN03_TC1 0x00002000 +#define KN03_TC0 0x00001000 +#define KN03_SCSI_FIFO 0x00000004 /* ??? Info from Mach */ + +/* + * Now form groups, i.e. all serial interrupts, all SCSI interrupts and so on. + */ +#define SERIAL_INTS (SCC0_TRANS_PAGEEND | SCC0_TRANS_MEMRDERR | \ + SCC0_RECV_HALFPAGE | SCC0_RECV_PAGOVRRUN | \ + SCC1_TRANS_PAGEEND | SCC1_TRANS_MEMRDERR | \ + SCC1_RECV_HALFPAGE | SCC1_RECV_PAGOVRRUN | \ + SCC1_CHIP | SCC0_CHIP) + +#define XINE_SERIAL_INTS (SCC0_TRANS_PAGEEND | SCC0_TRANS_MEMRDERR | \ + SCC0_RECV_HALFPAGE | SCC0_RECV_PAGOVRRUN | \ + SCC0_CHIP) + +#define SCSI_INTS (SCSI_PTR_LOADED | SCSI_PAGOVRRUN | \ + SCSI_DMA_MEMRDERR | SCSI_CHIP) + +#define KMIN_SCSI_INTS (SCSI_PTR_LOADED | SCSI_PAGOVRRUN | \ + SCSI_DMA_MEMRDERR | SCSI_CHIP | KMIN_SCSI_FIFO) + +#define LANCE_INTS (LANCE_DMA_MEMRDERR | LANCE_CHIP) + +/* + * For future use ... + */ +#define XINE_FLOPPY_INTS (MAXINE_FLOPPY | MAXINE_FLOPPY_HDS | \ + FLOPPY_DMA_ERROR | MAXINE_FLOPPY_XDS) + +#define XINE_ISDN_INTS (MAXINE_ISDN | ISDN_TRANS_PTR_LOADED | \ + ISDN_RECV_PTR_LOADED | ISDN_DMA_MEMRDERR) + +#define XINE_DTOP_INTS (MAXINE_DTOP_TRANS | DTOP_RECV | \ + ISDN_TRANS_PTR_LOADED | ISDN_RECV_PTR_LOADED | \ + ISDN_DMA_MEMRDERR) diff -r -N -u /usr/src/linux/include/asm-alpha/dec/machtype.h linux-2.2.9/include/asm-alpha/dec/machtype.h --- /usr/src/linux/include/asm-alpha/dec/machtype.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm-alpha/dec/machtype.h Sat Aug 14 18:56:54 1999 @@ -0,0 +1,20 @@ +/* + * Various machine type definitions + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 1998 Harald Koerfgen + */ +#include + +#define TURBOCHANNEL (mips_machtype == MACH_DS5000_200 || \ + mips_machtype == MACH_DS5000_1XX || \ + mips_machtype == MACH_DS5000_XX || \ + mips_machtype == MACH_DS5000_2X0) + +#define IOASIC (mips_machtype == MACH_DS5000_1XX || \ + mips_machtype == MACH_DS5000_XX || \ + mips_machtype == MACH_DS5000_2X0) + diff -r -N -u /usr/src/linux/include/asm-alpha/dec/tc.h linux-2.2.9/include/asm-alpha/dec/tc.h --- /usr/src/linux/include/asm-alpha/dec/tc.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm-alpha/dec/tc.h Fri Jun 25 21:53:07 1999 @@ -0,0 +1,43 @@ +/* + * Interface to the TURBOchannel related routines + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 1998 Harald Koerfgen + */ +#ifndef ASM_TC_H +#define ASM_TC_H + +extern unsigned long system_base; + +/* + * Search for a TURBOchannel Option Module + * with a certain name. Returns slot number + * of the first card not in use or -ENODEV + * if none found. + */ +extern int search_tc_card(const char *); +/* + * Marks the card in slot as used + */ +extern void claim_tc_card(int); +/* + * Marks the card in slot as free + */ +extern void release_tc_card(int); +/* + * Return base address of card in slot + */ +extern unsigned long get_tc_base_addr(int); +/* + * Return interrupt number of slot + */ +extern unsigned long get_tc_irq_nr(int); +/* + * Return TURBOchannel clock frequency in hz + */ +extern unsigned long get_tc_speed(void); + +#endif diff -r -N -u /usr/src/linux/include/asm-alpha/dec/tcinfo.h linux-2.2.9/include/asm-alpha/dec/tcinfo.h --- /usr/src/linux/include/asm-alpha/dec/tcinfo.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm-alpha/dec/tcinfo.h Fri Jun 25 21:53:07 1999 @@ -0,0 +1,47 @@ +/* + * Various TURBOchannel related stuff + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Information obtained through the get_tcinfo prom call + * created from: + * + * TURBOchannel Firmware Specification + * + * EK-TCAAD-FS-004 + * from Digital Equipment Corporation + * + * Copyright (c) 1998 Harald Koerfgen + */ + +typedef struct { + int revision; + int clk_period; + int slot_size; + int io_timeout; + int dma_range; + int max_dma_burst; + int parity; + int reserved[4]; +} tcinfo; + +#define MAX_SLOT 7 + +typedef struct { + unsigned long base_addr; + unsigned char name[9]; + unsigned char vendor[9]; + unsigned char firmware[9]; + int interrupt; + int flags; +} slot_info; + +/* + * Values for flags + */ +#define FREE 1<<0 +#define IN_USE 1<<1 + + diff -r -N -u /usr/src/linux/include/asm-alpha/dec/tcmodule.h linux-2.2.9/include/asm-alpha/dec/tcmodule.h --- /usr/src/linux/include/asm-alpha/dec/tcmodule.h Wed Dec 31 19:00:00 1969 +++ linux-2.2.9/include/asm-alpha/dec/tcmodule.h Fri Jun 25 21:53:07 1999 @@ -0,0 +1,35 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Offsets for the ROM header locations for + * TURBOchannel cards + * + * created from: + * + * TURBOchannel Firmware Specification + * + * EK-TCAAD-FS-004 + * from Digital Equipment Corporation + * + * Jan.1998 Harald Koerfgen + */ + +#define OLDCARD 0x3c0000 + +#define ROM_WIDTH 0x3e0 +#define ROM_STRIDE 0x3e4 +#define ROM_SIZE 0x3e8 +#define SLOT_SIZE 0x3ec +#define PATTERN0 0x3f0 +#define PATTERN1 0x3f4 +#define PATTERN2 0x3f8 +#define PATTERN3 0x3fc +#define FIRM_VER 0x400 +#define VENDOR 0x420 +#define MODULE 0x440 +#define FIRM_TYPE 0x460 +#define FLAGS 0x470 + +#define ROM_OBJECTS 0x480 diff -r -N -u /usr/src/linux/include/asm-alpha/io.h linux-2.2.9/include/asm-alpha/io.h --- /usr/src/linux/include/asm-alpha/io.h Fri May 21 08:15:47 1999 +++ linux-2.2.9/include/asm-alpha/io.h Mon Aug 16 03:03:32 1999 @@ -143,6 +143,8 @@ # include #elif defined(CONFIG_ALPHA_RX164) # include +#elif defined(CONFIG_ALPHA_PELICAN) || defined(CONFIG_ALPHA_FLAMINGO) +# include #else #error "What system is this?" #endif diff -r -N -u /usr/src/linux/include/asm-alpha/system.h linux-2.2.9/include/asm-alpha/system.h --- /usr/src/linux/include/asm-alpha/system.h Fri May 21 08:15:45 1999 +++ linux-2.2.9/include/asm-alpha/system.h Mon Aug 16 03:02:19 1999 @@ -264,9 +264,29 @@ #define tbisi(x) __tbi(1,__r17=(x),"1" (__r17)) #define tbisd(x) __tbi(2,__r17=(x),"1" (__r17)) #define tbis(x) __tbi(3,__r17=(x),"1" (__r17)) +#if defined(CONFIG_ALPHA_FLAMINGO) || defined(CONFIG_ALPHA_PELICAN) +#define tbiap() \ +({ \ + register unsigned long __r16 __asm__("$16") = -1; \ + __asm__ __volatile__( \ + "call_pal 0x0033" \ + : \ + : \ + :"$1", "$16", "$17", "$22", "$23", "$24", "$25"); \ +}) +#define tbia() \ +({ \ + register unsigned long __r16 __asm__("$16") = -2; \ + __asm__ __volatile__( \ + "call_pal 0x0033" \ + : \ + : \ + :"$1", "$16", "$17", "$22", "$23", "$24", "$25"); \ +}) +#else #define tbiap() __tbi(-1, /* no second argument */) #define tbia() __tbi(-2, /* no second argument */) - +#endif /* * Give prototypes to shut up gcc. */ diff -r -N -u /usr/src/linux/include/asm-mips/bootinfo.h linux-2.2.9/include/asm-mips/bootinfo.h --- /usr/src/linux/include/asm-mips/bootinfo.h Tue Oct 20 16:52:53 1998 +++ linux-2.2.9/include/asm-mips/bootinfo.h Sat Aug 14 18:34:58 1999 @@ -1,4 +1,4 @@ -/* $Id: bootinfo.h,v 1.5 1998/08/19 21:58:10 ralf Exp $ +/* $Id: bootinfo.h,v 1.7 1999/04/12 18:59:14 harald Exp $ * * bootinfo.h -- Definition of the Linux/MIPS boot information structure * @@ -25,10 +25,10 @@ #define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */ #define MACH_GROUP_ACN 5 #define MACH_GROUP_SGI 6 /* Silicon Graphics workstations and servers */ -#define MACH_GROUP_RESERVED 7 /* No Such Architecture */ +#define MACH_GROUP_COBALT 7 /* Cobalt servers */ #define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", \ - "SNI", "ACN", "SGI", "NSA" } + "SNI", "ACN", "SGI", "Cobalt" } /* * Valid machtype values for group unknown (low order halfword of mips_machtype) @@ -49,11 +49,21 @@ /* * Valid machtype for group DEC */ -/* FIXME: this is a very fuzzy name, and we got a big "name space now" */ -/* So otiginal DEC codes can be used -Stoned */ -#define MACH_DECSTATION 0 /* DECStation 5000/2x for now */ - -#define GROUP_DEC_NAMES { "3min" } +#define MACH_DSUNKNOWN 0 +#define MACH_DS23100 1 /* DECstation 2100 or 3100 */ +#define MACH_DS5100 2 /* DECstation 5100 */ +#define MACH_DS5000_200 3 /* DECstation 5000/200 */ +#define MACH_DS5000_1XX 4 /* DECstation 5000/120, 125, 133, 150 */ +#define MACH_DS5000_XX 5 /* DECstation 5000/20, 25, 33, 50 */ +#define MACH_DS5000_2X0 6 /* DECstation 5000/240, 260 */ +#define MACH_DS5400 7 /* DECstation 5400 */ +#define MACH_DS5500 8 /* DECstation 5500 */ +#define MACH_DS5800 9 /* DECstation 5800 */ + +#define GROUP_DEC_NAMES { "unknown", "DECstation 2100/3100", "DECstation 5100", \ + "DECstation 5000/200", "DECstation 5000/1xx", "Personal DECstation 5000/xx", \ + "DECstation 5000/2x0", "DECstation 5400", "DECstation 5500", \ + "DECstation 5800" } /* * Valid machtype for group ARC @@ -85,6 +95,13 @@ #define GROUP_SGI_NAMES { "Indy" } /* + * Valid machtype for group COBALT + */ +#define MACH_COBALT_27 0 /* Proto "27" hardware */ + +#define GROUP_COBALT_NAMES { "Microserver 27" } + +/* * Valid cputype values */ #define CPU_UNKNOWN 0 @@ -144,134 +161,14 @@ unsigned short lines; } mips_arc_DisplayInfo; -/* - * New style bootinfo - * - * Add new tags only at the end of the enum; *never* remove any tags - * or you'll break compatibility! - */ -enum bi_tag { - /* - * not a real tag - */ - tag_dummy, - - /* - * machine type - */ - tag_machtype, - - /* - * system CPU & FPU - */ - tag_cputype, - - /* - * Installed RAM - */ - tag_memlower, - tag_memupper, - - /* - * Cache Sizes (0xffffffff = unknown) - */ - tag_icache_size, - tag_icache_linesize, - tag_dcache_size, - tag_dcache_linesize, - tag_scache_size, - tag_scache_linesize, - - /* - * TLB Info - */ - tag_tlb_entries, - - /* - * DMA buffer size (Deskstation only) - */ - tag_dma_cache_size, - tag_dma_cache_base, - - /* - * Ramdisk Info - */ - tag_ramdisk_size, /* ramdisk size in 1024 byte blocks */ - tag_ramdisk_base, /* address of the ram disk in mem */ - - /* - * Boot flags for the kernel - */ - tag_mount_root_rdonly, - tag_drive_info, - - /* - * Video ram info (not in tty.h) - */ - tag_vram_base, /* video ram base address */ - - tag_command_line, /* kernel command line parameters */ - - /* - * machine group - */ - tag_machgroup, - - /* - * info on the display from the ARC BIOS - */ - tag_arcdisplayinfo, - - /* - * tag to pass a complete struct screen_info - */ - tag_screen_info -}; - -/* struct defining a tag */ -typedef struct { - enum bi_tag tag; - unsigned long size; -} tag; - -/* struct to define a tag and it's data */ -typedef struct { - tag t; - void* d; -} tag_def; - -/* macros for parsing tag list */ -#define TAGVALPTR(t) ((void*)(((void*)(t)) - ((t)->size))) -#define NEXTTAGPTR(t) ((void*)(TAGVALPTR(t) - (sizeof(tag)))) - -/* size macros for tag size field */ -#define UCHARSIZE (sizeof(unsigned char)) -#define ULONGSIZE (sizeof(unsigned long)) -#define UINTSIZE (sizeof(unsigned int)) -#define DRVINFOSIZE (sizeof(struct drive_info_struct)) -#define CMDLINESIZE (sizeof(char[CL_SIZE]) - -/* - * For tag readers aka the kernel - */ -tag *bi_TagFind(enum bi_tag type); -void bi_EarlySnarf(void); - -/* For tag creators aka bootloaders */ -/* Now implemented in Milo 0.26 */ -int bi_TagAdd(enum bi_tag type, unsigned long size, void *data); -int bi_TagAddList(tag_def* taglist); -void bi_TagWalk(void); - - #ifdef CONFIG_SGI /* screen info will dissapear... soon */ //#define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 158, 0, 0, 0, 62, 0, 16} #define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 160, 0, 0, 0, 64, 0, 16} #define DEFAULT_DRIVE_INFO { {0,}} #else -/* default values for screen_info variable */ -#define DEFAULT_SCREEN_INFO {0, 0, 0, 52, 3, 80, 4626, 3, 9, 50} +/* default values for screen_info variable (Colour VGA) */ +#define DEFAULT_SCREEN_INFO {0, 0, 0, 52, 3, 80, 4626, 3, 9, 50, 0x22, 16} #endif /* default values for drive info */ @@ -289,9 +186,6 @@ extern unsigned long mips_machtype; extern unsigned long mips_machgroup; extern unsigned long mips_tlb_entries; -extern unsigned long mips_vram_base; -extern unsigned long mips_dma_cache_size; -extern unsigned long mips_dma_cache_base; #endif /* _LANGUAGE_ASSEMBLY */ diff -r -N -u /usr/src/linux/init/main.c linux-2.2.9/init/main.c --- /usr/src/linux/init/main.c Tue May 11 12:57:14 1999 +++ linux-2.2.9/init/main.c Mon Aug 16 01:36:03 1999 @@ -345,6 +345,14 @@ #endif /* + * cpp: cheat + */ +#if defined(CONFIG_ALPHA_FLAMINGO) || defined(CONFIG_ALPHA_PELICAN) +extern long srm_printk(const char *fmt, ...); +extern void dump_cpuinfo(void); +#endif + +/* * Boot command-line arguments */ #define MAX_INIT_ARGS 8 @@ -1132,19 +1140,38 @@ */ printk(linux_banner); setup_arch(&command_line, &memory_start, &memory_end); + srm_printk("Back in init/main.c\n"); + dump_cpuinfo(); + srm_printk("memory_start: %lx\n", memory_start); + srm_printk("memory_end: %lx\n", memory_end); + srm_printk("paging_init...\n"); memory_start = paging_init(memory_start,memory_end); + srm_printk("done...\n"); + srm_printk("memory_start: %lx\n", memory_start); + srm_printk("trap_init...\n"); trap_init(); + srm_printk("done...\n"); + srm_printk("init_IRQ...\n"); init_IRQ(); + srm_printk("done...\n"); + srm_printk("sched_init...\n"); sched_init(); + srm_printk("done...\n"); + srm_printk("time_init...\n"); time_init(); + srm_printk("done...\n"); + srm_printk("parse_options...\n"); parse_options(command_line); + srm_printk("done...\n"); /* * HACK ALERT! This is early. We're enabling the console before * we've done PCI setups etc, and console_init() must be aware of * this. But we do want output early, in case something goes wrong. */ + srm_printk("console_init...\n"); memory_start = console_init(memory_start,memory_end); + srm_printk("done...\n"); #ifdef CONFIG_MODULES init_modules(); #endif