Index: head/sys/conf/files.sparc64 =================================================================== --- head/sys/conf/files.sparc64 (revision 206450) +++ head/sys/conf/files.sparc64 (revision 206451) @@ -1,139 +1,140 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # # $FreeBSD$ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # atkbdmap.h optional atkbd_dflt_keymap \ compile-with "/usr/sbin/kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "atkbdmap.h" # sunkbdmap.h optional sunkbd_dflt_keymap \ compile-with "/usr/sbin/kbdcontrol -L ${SUNKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > sunkbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "sunkbdmap.h" # ukbdmap.h optional ukbd_dflt_keymap \ compile-with "/usr/sbin/kbdcontrol -L ${UKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > ukbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "ukbdmap.h" # crypto/blowfish/bf_enc.c optional crypto | ipsec crypto/des/des_enc.c optional crypto | ipsec | netsmb dev/atkbdc/atkbd.c optional atkbd atkbdc dev/atkbdc/atkbd_atkbdc.c optional atkbd atkbdc dev/atkbdc/atkbdc.c optional atkbdc dev/atkbdc/atkbdc_ebus.c optional atkbdc ebus dev/atkbdc/atkbdc_isa.c optional atkbdc isa dev/atkbdc/atkbdc_subr.c optional atkbdc dev/atkbdc/psm.c optional psm atkbdc dev/auxio/auxio.c optional auxio sbus | auxio ebus dev/esp/esp_sbus.c optional esp sbus dev/fb/creator.c optional creator sc dev/fb/fb.c optional sc dev/fb/gallant12x22.c optional sc dev/fb/machfb.c optional machfb sc dev/hwpmc/hwpmc_sparc64.c optional hwpmc dev/kbd/kbd.c optional atkbd | sc | ukbd dev/le/if_le_lebuffer.c optional le sbus dev/le/if_le_ledma.c optional le sbus dev/le/lebuffer_sbus.c optional le sbus dev/ofw/ofw_if.m standard dev/ofw/ofw_bus_if.m standard dev/ofw/ofw_bus_subr.c standard dev/ofw/ofw_standard.c standard dev/ofw/ofw_console.c optional ofw_console dev/ofw/openfirm.c standard dev/ofw/openfirmio.c standard dev/ofw/openpromio.c standard dev/pcf/envctrl.c optional pcf ebus dev/pcf/pcf_ebus.c optional pcf ebus dev/sound/sbus/cs4231.c optional snd_audiocs ebus | \ snd_audiocs sbus dev/syscons/scgfbrndr.c optional sc dev/syscons/scterm-teken.c optional sc dev/syscons/scvtb.c optional sc dev/uart/uart_cpu_sparc64.c optional uart dev/uart/uart_kbd_sun.c optional uart sc kern/syscalls.c optional ktr libkern/ffs.c standard libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard libkern/memmove.c standard sparc64/central/central.c optional central sparc64/ebus/ebus.c optional ebus sparc64/ebus/epic.c optional epic ebus sparc64/fhc/clkbrd.c optional fhc sparc64/fhc/fhc.c optional fhc sparc64/isa/isa.c optional isa sparc64/isa/isa_dma.c optional isa sparc64/isa/ofw_isa.c optional ebus | isa sparc64/pci/apb.c optional pci sparc64/pci/fire.c optional pci sparc64/pci/ofw_pcib.c optional pci sparc64/pci/ofw_pcib_subr.c optional pci sparc64/pci/ofw_pcibus.c optional pci sparc64/pci/psycho.c optional pci +sparc64/pci/sbbc.c optional uart sbbc sparc64/pci/schizo.c optional pci sparc64/sbus/dma_sbus.c optional sbus sparc64/sbus/sbus.c optional sbus sparc64/sbus/lsi64854.c optional sbus sparc64/sparc64/ata_machdep.c optional atadisk sparc64/sparc64/autoconf.c standard sparc64/sparc64/bus_machdep.c standard sparc64/sparc64/cache.c standard sparc64/sparc64/cheetah.c standard sparc64/sparc64/clock.c standard sparc64/sparc64/counter.c standard sparc64/sparc64/db_disasm.c optional ddb sparc64/sparc64/db_interface.c optional ddb sparc64/sparc64/db_trace.c optional ddb sparc64/sparc64/db_hwwatch.c optional ddb sparc64/sparc64/dump_machdep.c standard sparc64/sparc64/elf_machdep.c standard sparc64/sparc64/exception.S standard no-obj \ compile-with "${NORMAL_S} -mcpu=ultrasparc" sparc64/sparc64/eeprom.c optional eeprom ebus | eeprom fhc | \ eeprom sbus sparc64/sparc64/gdb_machdep.c optional gdb sparc64/sparc64/identcpu.c standard sparc64/sparc64/in_cksum.c optional inet sparc64/sparc64/interrupt.S standard no-obj \ compile-with "${NORMAL_S} -mcpu=ultrasparc" sparc64/sparc64/intr_machdep.c standard sparc64/sparc64/iommu.c standard sparc64/sparc64/jbusppm.c standard sparc64/sparc64/locore.S standard no-obj sparc64/sparc64/machdep.c standard sparc64/sparc64/mem.c optional mem sparc64/sparc64/mp_exception.S optional smp \ compile-with "${NORMAL_S} -mcpu=ultrasparc" sparc64/sparc64/mp_locore.S optional smp sparc64/sparc64/mp_machdep.c optional smp sparc64/sparc64/nexus.c standard sparc64/sparc64/ofw_machdep.c standard sparc64/sparc64/pmap.c standard sparc64/sparc64/prof_machdep.c optional profiling-routine sparc64/sparc64/rtc.c optional rtc ebus | rtc isa sparc64/sparc64/rwindow.c standard sparc64/sparc64/sc_machdep.c optional sc sparc64/sparc64/schppm.c standard sparc64/sparc64/spitfire.c standard sparc64/sparc64/ssm.c standard sparc64/sparc64/stack_machdep.c optional ddb | stack sparc64/sparc64/support.S standard \ compile-with "${NORMAL_S} -mcpu=ultrasparc" sparc64/sparc64/sys_machdep.c standard sparc64/sparc64/swtch.S standard sparc64/sparc64/tick.c standard sparc64/sparc64/tlb.c standard sparc64/sparc64/trap.c standard sparc64/sparc64/tsb.c standard sparc64/sparc64/uio_machdep.c standard sparc64/sparc64/upa.c optional creator sparc64/sparc64/vm_machdep.c standard Index: head/sys/dev/uart/uart.h =================================================================== --- head/sys/dev/uart/uart.h (revision 206450) +++ head/sys/dev/uart/uart.h (revision 206451) @@ -1,95 +1,96 @@ /*- * Copyright (c) 2003 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _DEV_UART_H_ #define _DEV_UART_H_ /* * Bus access structure. This structure holds the minimum information needed * to access the UART. The rclk field, although not important to actually * access the UART, is important for baudrate programming, delay loops and * other timing related computations. */ struct uart_bas { bus_space_tag_t bst; bus_space_handle_t bsh; u_int chan; u_int rclk; u_int regshft; }; #define uart_regofs(bas, reg) ((reg) << (bas)->regshft) #define uart_getreg(bas, reg) \ bus_space_read_1((bas)->bst, (bas)->bsh, uart_regofs(bas, reg)) #define uart_setreg(bas, reg, value) \ bus_space_write_1((bas)->bst, (bas)->bsh, uart_regofs(bas, reg), value) /* * XXX we don't know the length of the bus space address range in use by * the UART. Since barriers don't use the length field currently, we put * a zero there for now. */ #define uart_barrier(bas) \ bus_space_barrier((bas)->bst, (bas)->bsh, 0, 0, \ BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE) /* * UART device classes. */ struct uart_class; extern struct uart_class uart_ns8250_class __attribute__((weak)); extern struct uart_class uart_quicc_class __attribute__((weak)); extern struct uart_class uart_sab82532_class __attribute__((weak)); +extern struct uart_class uart_sbbc_class __attribute__((weak)); extern struct uart_class uart_z8530_class __attribute__((weak)); #ifdef PC98 struct uart_class *uart_pc98_getdev(u_long port); #endif /* * Device flags. */ #define UART_FLAGS_CONSOLE(f) ((f) & 0x10) #define UART_FLAGS_DBGPORT(f) ((f) & 0x80) #define UART_FLAGS_FCR_RX_LOW(f) ((f) & 0x100) #define UART_FLAGS_FCR_RX_MEDL(f) ((f) & 0x200) #define UART_FLAGS_FCR_RX_MEDH(f) ((f) & 0x400) #define UART_FLAGS_FCR_RX_HIGH(f) ((f) & 0x800) /* * Data parity values (magical numbers related to ns8250). */ #define UART_PARITY_NONE 0 #define UART_PARITY_ODD 1 #define UART_PARITY_EVEN 3 #define UART_PARITY_MARK 5 #define UART_PARITY_SPACE 7 #endif /* _DEV_UART_H_ */ Index: head/sys/dev/uart/uart_cpu_sparc64.c =================================================================== --- head/sys/dev/uart/uart_cpu_sparc64.c (revision 206450) +++ head/sys/dev/uart/uart_cpu_sparc64.c (revision 206451) @@ -1,293 +1,304 @@ /*- * Copyright (c) 2003, 2004 Marcel Moolenaar * Copyright (c) 2004 - 2006 Marius Strobl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include bus_space_tag_t uart_bus_space_io; bus_space_tag_t uart_bus_space_mem; static struct bus_space_tag bst_store[3]; /* * Determine which channel of a SCC a device referenced by a full device * path or as an alias is (in the latter case we try to look up the device * path via the /aliases node). * Only the device paths of devices which are used for TTYs really allow * to do this as they look like these (taken from /aliases nodes): * ttya: '/central/fhc/zs@0,902000:a' * ttyc: '/pci@1f,0/pci@1,1/ebus@1/se@14,400000:a' * Additionally, for device paths of SCCs which are connected to a RSC * (Remote System Control) device we can hardcode the appropriate channel. * Such device paths look like these: * rsc: '/pci@1f,4000/ebus@1/se@14,200000:ssp' * ttyc: '/pci@1f,4000/ebus@1/se@14,200000:ssp' */ static int uart_cpu_channel(char *dev) { char alias[64]; phandle_t aliases; int len; const char *p; strcpy(alias, dev); if ((aliases = OF_finddevice("/aliases")) != -1) (void)OF_getprop(aliases, dev, alias, sizeof(alias)); len = strlen(alias); if ((p = rindex(alias, ':')) == NULL) return (0); p++; if (p - alias == len - 1 && (*p == 'a' || *p == 'b')) return (*p - 'a' + 1); if (strcmp(p, "ssp") == 0) return (1); return (0); } int uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) { return ((b1->bsh == b2->bsh) ? 1 : 0); } /* * Get the package handle of the UART that is selected as the console, if * the console is an UART of course. Note that we enforce that both input * and output are selected. * Note that the currently active console (i.e. /chosen/stdout and * /chosen/stdin) may not be the same as the device selected in the * environment (ie /options/output-device and /options/input-device) because * keyboard and screen were selected but the keyboard was unplugged or the * user has changed the environment. In the latter case I would assume that * the user expects that FreeBSD uses the new console setting. * For weirder configurations, use ofw_console(4). */ static phandle_t uart_cpu_getdev_console(phandle_t options, char *dev, size_t devsz) { char buf[sizeof("serial")]; ihandle_t inst; phandle_t chosen, input, output; if (OF_getprop(options, "input-device", dev, devsz) == -1) return (-1); input = OF_finddevice(dev); if (OF_getprop(options, "output-device", dev, devsz) == -1) return (-1); output = OF_finddevice(dev); if (input == -1 || output == -1 || OF_getproplen(input, "keyboard") >= 0) { if ((chosen = OF_finddevice("/chosen")) == -1) return (-1); if (OF_getprop(chosen, "stdin", &inst, sizeof(inst)) == -1) return (-1); if ((input = OF_instance_to_package(inst)) == -1) return (-1); if (OF_getprop(chosen, "stdout", &inst, sizeof(inst)) == -1) return (-1); if ((output = OF_instance_to_package(inst)) == -1) return (-1); snprintf(dev, devsz, "ttya"); } if (input != output) return (-1); if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) return (-1); if (strcmp(buf, "serial") != 0) return (-1); + /* For a Serengeti console device point to the bootbus controller. */ + if (OF_getprop(input, "name", buf, sizeof(buf)) > 0 && + !strcmp(buf, "sgcn")) { + if ((chosen = OF_finddevice("/chosen")) == -1) + return (-1); + if (OF_getprop(chosen, "iosram", &input, sizeof(input)) == -1) + return (-1); + } return (input); } /* * Get the package handle of the UART that's selected as the debug port. * Since there's no place for this in the OF, we use the kernel environment * variable "hw.uart.dbgport". Note however that the variable is not a * list of attributes. It's single device name or alias, as known by * the OF. */ static phandle_t uart_cpu_getdev_dbgport(char *dev, size_t devsz) { char buf[sizeof("serial")]; phandle_t input; if (!getenv_string("hw.uart.dbgport", dev, devsz)) return (-1); if ((input = OF_finddevice(dev)) == -1) return (-1); if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) return (-1); if (strcmp(buf, "serial") != 0) return (-1); return (input); } /* * Get the package handle of the UART that is selected as the keyboard port, * if it's actually used to connect the keyboard according to the OF. I.e. * this will return the UART used to connect the keyboard regardless whether * it's stdin or not, however not in case the user or the OF gave preference * to e.g. a PS/2 keyboard by setting /aliases/keyboard accordingly. */ static phandle_t uart_cpu_getdev_keyboard(char *dev, size_t devsz) { char buf[sizeof("serial")]; phandle_t input; if ((input = OF_finddevice("keyboard")) == -1) return (-1); if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) return (-1); if (strcmp(buf, "serial") != 0) return (-1); if (OF_getprop(input, "name", dev, devsz) == -1) return (-1); /* * So far this also matched PS/2 keyboard nodes so make sure it's * one of the SCCs/UARTs known to be used to connect keyboards. */ if (strcmp(dev, "su") && strcmp(dev, "su_pnp") && strcmp(dev, "zs")) return (-1); return (input); } int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { char buf[32], compat[32], dev[64]; struct uart_class *class; phandle_t input, options; bus_addr_t addr; int baud, bits, error, range, space, stop; char flag, par; if ((options = OF_finddevice("/options")) == -1) return (ENXIO); switch (devtype) { case UART_DEV_CONSOLE: input = uart_cpu_getdev_console(options, dev, sizeof(dev)); break; case UART_DEV_DBGPORT: input = uart_cpu_getdev_dbgport(dev, sizeof(dev)); break; case UART_DEV_KEYBOARD: input = uart_cpu_getdev_keyboard(dev, sizeof(dev)); break; default: input = -1; break; } if (input == -1) return (ENXIO); error = OF_decode_addr(input, 0, &space, &addr); if (error) return (error); /* Get the device class. */ if (OF_getprop(input, "name", buf, sizeof(buf)) == -1) return (ENXIO); if (OF_getprop(input, "compatible", compat, sizeof(compat)) == -1) compat[0] = '\0'; di->bas.regshft = 0; di->bas.rclk = 0; class = NULL; if (!strcmp(buf, "se") || !strcmp(compat, "sab82532")) { class = &uart_sab82532_class; /* SAB82532 are only known to be used for TTYs. */ if ((di->bas.chan = uart_cpu_channel(dev)) == 0) return (ENXIO); addr += uart_getrange(class) * (di->bas.chan - 1); } else if (!strcmp(buf, "zs")) { class = &uart_z8530_class; if ((di->bas.chan = uart_cpu_channel(dev)) == 0) { /* * There's no way to determine from OF which * channel has the keyboard. Should always be * on channel 1 however. */ if (devtype == UART_DEV_KEYBOARD) di->bas.chan = 1; else return (ENXIO); } di->bas.regshft = 1; range = uart_getrange(class) << di->bas.regshft; addr += range - range * (di->bas.chan - 1); } else if (!strcmp(buf, "lom-console") || !strcmp(buf, "su") || !strcmp(buf, "su_pnp") || !strcmp(compat, "rsc-console") || !strcmp(compat, "su") || !strcmp(compat, "su16550") || !strcmp(compat, "su16552")) { class = &uart_ns8250_class; + di->bas.chan = 0; + } else if (!strcmp(compat, "sgsbbc")) { + class = &uart_sbbc_class; di->bas.chan = 0; } if (class == NULL) return (ENXIO); /* Fill in the device info. */ di->ops = uart_getops(class); di->bas.bst = &bst_store[devtype]; di->bas.bsh = sparc64_fake_bustag(space, addr, di->bas.bst); /* Get the line settings. */ if (devtype == UART_DEV_KEYBOARD) di->baudrate = 1200; else if (!strcmp(compat, "rsc-console")) di->baudrate = 115200; else di->baudrate = 9600; di->databits = 8; di->stopbits = 1; di->parity = UART_PARITY_NONE; snprintf(buf, sizeof(buf), "%s-mode", dev); if (OF_getprop(options, buf, buf, sizeof(buf)) == -1 && OF_getprop(input, "ssp-console-modes", buf, sizeof(buf)) == -1) return (0); if (sscanf(buf, "%d,%d,%c,%d,%c", &baud, &bits, &par, &stop, &flag) != 5) return (0); di->baudrate = baud; di->databits = bits; di->stopbits = stop; di->parity = (par == 'n') ? UART_PARITY_NONE : (par == 'o') ? UART_PARITY_ODD : UART_PARITY_EVEN; return (0); } Index: head/sys/sparc64/conf/GENERIC =================================================================== --- head/sys/sparc64/conf/GENERIC (revision 206450) +++ head/sys/sparc64/conf/GENERIC (revision 206451) @@ -1,266 +1,269 @@ # # GENERIC -- Generic kernel configuration file for FreeBSD/sparc64 # # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the # FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the # device lines is also present in the ../../conf/NOTES and NOTES files. # If you are in doubt as to the purpose or necessity of a line, check first # in NOTES. # # $FreeBSD$ cpu SUN4U ident GENERIC makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols # Platforms supported # At this time all platforms are supported, as-is. options SCHED_4BSD # 4BSD scheduler #options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories options UFS_GJOURNAL # Enable gjournal-based UFS journaling options MD_ROOT # MD is a potential root device options NFSCLIENT # Network Filesystem Client options NFSSERVER # Network Filesystem Server options NFSLOCKD # Network Lock Manager options NFS_ROOT # NFS usable as /, requires NFSCLIENT #options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework options GEOM_PART_GPT # GUID Partition Tables. options GEOM_LABEL # Provides labelization options COMPAT_FREEBSD5 # Compatible with FreeBSD5 options COMPAT_FREEBSD6 # Compatible with FreeBSD6 options COMPAT_FREEBSD7 # Compatible with FreeBSD7 options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support options STACK # stack(9) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options P1003_1B_SEMAPHORES # POSIX-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) options AUDIT # Security event auditing options MAC # TrustedBSD MAC Framework options INCLUDE_CONFIG_FILE # Include this file in kernel # Debugging for use in -current options KDB # Enable kernel debugger support. options DDB # Support DDB. options GDB # Support remote GDB. options DEADLKRES # Enable the deadlock resolver options INVARIANTS # Enable calls of extra sanity checking options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS options WITNESS # Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed # Make an SMP-capable kernel by default options SMP # Symmetric MultiProcessor Kernel # Standard busses device ebus device isa device pci device sbus device central device fhc # Floppy drives #device fdc # ATA and ATAPI devices device ata device atadisk # ATA disk drives device atapicd # ATAPI CDROM drives #device atapifd # ATAPI floppy drives #device atapist # ATAPI tape drives # Do NOT enable ATA_STATIC_ID -- cmd646 controller will be !ata2!, # and you will not mount an ATA /. #options ATA_STATIC_ID # Static device numbering # SCSI Controllers device ahc # AHA2940 and onboard AIC7xxx devices options AHC_ALLOW_MEMIO # Attempt to use memory mapped I/O options AHC_REG_PRETTY_PRINT # Print register bitfields in debug # output. Adds ~128k to driver. device isp # Qlogic family device ispfw # Firmware module for Qlogic host adapters device mpt # LSI-Logic MPT-Fusion device sym # NCR/Symbios/LSI Logic 53C8XX/53C1010/53C1510D device esp # NCR53c9x (FEPS/FAS366) # SCSI peripherals device scbus # SCSI bus (required for SCSI) device ch # SCSI media changers device da # Direct Access (disks) device sa # Sequential Access (tape etc) device cd # CD device pass # Passthrough device (direct SCSI access) device ses # SCSI Environmental Services (and SAF-TE) # RAID controllers #device amr # AMI MegaRAID #device mlx # Mylex DAC960 family # atkbdc0 controls both the keyboard and the PS/2 mouse device atkbdc # AT keyboard controller device atkbd # AT keyboard device psm # PS/2 mouse device kbdmux # keyboard multiplexer # syscons is the default console driver, resembling an SCO console device sc device creator # Creator, Creator3D and Elite3D framebuffers device machfb # ATI Mach64 framebuffers device splash # Splash screen and screen saver support options KBD_INSTALL_CDEV # install a CDEV entry in /dev # Builtin hardware device auxio # auxiliary I/O device device eeprom # eeprom (really a front-end for the MK48Txx) device mk48txx # Mostek MK48Txx clocks device rtc # rtc (really a front-end for the MC146818) device mc146818 # Motorola MC146818 and compatible clocks device epic # Sun Fire V215/V245 LEDs +device sbbc # Sun BootBus controller (time-of-day clock for + # Serengeti and StarCat, console for Serengeti, + # requires device uart) # Serial (COM) ports device puc # Multi-channel uarts device scc # Serial communications controllers. device uart # Multi-uart driver # Parallel port #device ppc #device ppbus # Parallel port bus (required) #device lpt # Printer #device plip # TCP/IP over parallel #device ppi # Parallel port interface device #device vpo # Requires scbus and da # PCI Ethernet NICs. #device de # DEC/Intel DC21x4x (``Tulip'') device em # Intel PRO/1000 adapter Gigabit Ethernet Card #device ixgb # Intel PRO/10GbE Ethernet Card device le # AMD Am7900 LANCE and Am79C9xx PCnet device ti # Alteon Networks Tigon I/II gigabit Ethernet device txp # 3Com 3cR990 (``Typhoon'') #device vx # 3Com 3c590, 3c595 (``Vortex'') # PCI Ethernet NICs that use the common MII bus controller code. # NOTE: Be sure to keep the 'device miibus' line in order to use these NICs! device miibus # MII bus support #device bfe # Broadcom BCM440x 10/100 Ethernet device bge # Broadcom BCM570xx Gigabit Ethernet device cas # Sun Cassini/Cassini+ and NS DP83065 Saturn device dc # DEC/Intel 21143 and various workalikes device fxp # Intel EtherExpress PRO/100B (82557, 82558) device gem # Sun GEM/Sun ERI/Apple GMAC device hme # Sun HME (Happy Meal Ethernet) device nge # NatSemi DP83820 gigabit Ethernet #device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le') device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 device sf # Adaptec AIC-6915 (``Starfire'') #device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet device ste # Sundance ST201 (D-Link DFE-550TX) device stge # Sundance/Tamarack TC9021 gigabit Ethernet #device tl # Texas Instruments ThunderLAN #device tx # SMC EtherPower II (83c170 ``EPIC'') device vr # VIA Rhine, Rhine II #device wb # Winbond W89C840F device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') # Wireless NIC cards device wlan # 802.11 support options IEEE80211_DEBUG # enable debug msgs options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's options IEEE80211_SUPPORT_MESH # enable 802.11s D3.0 support device wlan_wep # 802.11 WEP support device wlan_ccmp # 802.11 CCMP support device wlan_tkip # 802.11 TKIP support device wlan_amrr # AMRR transmit rate control algorithm device ath # Atheros pci/cardbus NIC's device ath_hal # Atheros HAL (Hardware Access Layer) options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors device ath_rate_sample # SampleRate tx rate control for ath # Pseudo devices. device loop # Network loopback device random # Entropy device device ether # Ethernet support device vlan # 802.1Q VLAN support device tun # Packet tunnel. device pty # BSD-style compatibility pseudo ttys device md # Memory "disks" device gif # IPv6 and IPv4 tunneling device faith # IPv6-to-IPv4 relaying (translation) device firmware # firmware assist module # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! # Note that 'bpf' is required for DHCP. device bpf # Berkeley packet filter # USB support device uhci # UHCI PCI->USB interface device ohci # OHCI PCI->USB interface device ehci # EHCI PCI->USB interface (USB 2.0) device usb # USB Bus (required) #device udbp # USB Double Bulk Pipe devices device uhid # "Human Interface Devices" device ukbd # Keyboard device ulpt # Printer device umass # Disks/Mass storage - Requires scbus and da device ums # Mouse device urio # Diamond Rio 500 MP3 player # USB Serial devices device uark # Technologies ARK3116 based serial adapters device ubsa # Belkin F5U103 and compatible serial adapters device uftdi # For FTDI usb serial adapters device uipaq # Some WinCE based devices device uplcom # Prolific PL-2303 serial adapters device uslcom # SI Labs CP2101/CP2102 serial adapters device uvisor # Visor and Palm devices device uvscom # USB serial support for DDI pocket's PHS # USB Ethernet, requires miibus device aue # ADMtek USB Ethernet device axe # ASIX Electronics USB Ethernet device cdce # Generic USB over Ethernet device cue # CATC USB Ethernet device kue # Kawasaki LSI USB Ethernet device rue # RealTek RTL8150 USB Ethernet device udav # Davicom DM9601E USB # USB Wireless device rum # Ralink Technology RT2501USB wireless NICs device uath # Atheros AR5523 wireless NICs device ural # Ralink Technology RT2500USB wireless NICs device zyd # ZyDAS zb1211/zb1211b wireless NICs # FireWire support device firewire # FireWire bus code device sbp # SCSI over FireWire (Requires scbus and da) device fwe # Ethernet over FireWire (non-standard!) device fwip # IP over FireWire (RFC 2734,3146) device dcons # Dumb console driver device dcons_crom # Configuration ROM for dcons Index: head/sys/sparc64/conf/NOTES =================================================================== --- head/sys/sparc64/conf/NOTES (revision 206450) +++ head/sys/sparc64/conf/NOTES (revision 206451) @@ -1,152 +1,153 @@ # $FreeBSD$ # # This file contains machine dependent kernel configuration notes. For # machine independent notes, look in /sys/conf/NOTES. ##################################################################### # CPU OPTIONS # # You must specify at least one CPU (the one you intend to run on); # deleting the specification for CPUs you don't need to use may make # parts of the system run faster. # XXX: On the Sparc64, there is only one CPU type cpu SUN4U ##################################################################### # HARDWARE BUS CONFIGURATION device ebus device isa device pci device sbus device central device fhc ##################################################################### # HARDWARE DEVICE CONFIGURATION # # Mandatory devices: # device eeprom # eeprom (really a front-end for the MK48Txx) device mk48txx # Mostek MK48Txx clocks device rtc # rtc (really a front-end for the MC146818) device mc146818 # Motorola MC146818 and compatible clocks +device sbbc # Sun BootBus controller # # Optional devices: # device auxio # auxiliary I/O device device epic # Sun Fire V215/V245 LEDs device creator # Creator, Creator3D and Elite3D framebuffers device machfb # ATI Mach64 framebuffers device ofw_console # Open Firmware console device option OFWCONS_POLL_HZ=4 # 20 or more works best on Ultra2 # PS/2 mouse device psm # Options for psm: options PSM_HOOKRESUME #hook the system resume event, useful #for some laptops options PSM_RESETAFTERSUSPEND #reset the device at the resume event # The keyboard controller; it controls the keyboard and the PS/2 mouse. device atkbdc # The AT keyboard device atkbd # Options for atkbd: options ATKBD_DFLT_KEYMAP # specify the built-in keymap makeoptions ATKBD_DFLT_KEYMAP=jp.106 # `flags' for atkbd: # 0x01 Force detection of keyboard, else we always assume a keyboard # 0x02 Don't reset keyboard, useful for some newer ThinkPads # 0x03 Force detection and avoid reset, might help with certain # dockingstations # 0x04 Old-style (XT) keyboard support, useful for older ThinkPads # Sun type 4/5/6 RS-232@TTL keyboard #device sunkbd # Options for sunkbd: options SUNKBD_EMULATE_ATKBD # allows to use the AT keyboard maps # in share/syscons/keymaps, required # for SUNKBD_DFLT_KEYMAP and kbdmux options SUNKBD_DFLT_KEYMAP # specify the built-in keymap makeoptions SUNKBD_DFLT_KEYMAP=jp.106 ##################################################################### # Devices we don't want to deal with nodevice daemon_saver nodevice snake_saver nodevice star_saver nodevice bktr nodevice fdc nodevice ppc nodevice snd_ad1816 nodevice snd_als4000 nodevice snd_cmi nodevice snd_cs4281 nodevice snd_csa nodevice snd_ds1 nodevice snd_emu10k1 nodevice snd_ess nodevice snd_fm801 nodevice snd_gusc nodevice snd_ich nodevice snd_maestro nodevice snd_maestro3 nodevice snd_mss nodevice snd_neomagic nodevice snd_sb16 nodevice snd_sb8 nodevice snd_sbc nodevice snd_solo nodevice snd_t4dwave nodevice snd_via8233 nodevice snd_via82c686 nodevice snd_vibes nodevice snd_uaudio nodevice aha nodevice bt nodevice wds nodevice ep nodevice ex ##################################################################### # Options we don't want to deal with nooption FDC_DEBUG nooption COMPAT_FREEBSD4 nooption SC_RENDER_DEBUG nooption SC_DEBUG_LEVEL nooption PPC_DEBUG nooption PPC_PROBE_CHIPSET nooption SC_NO_SUSPEND_VTYSWITCH nooption SC_NO_FONT_LOADING nooption SC_KERNEL_CONS_REV_ATTR nooption SC_KERNEL_CONS_ATTR nooption SC_NORM_REV_ATTR nooption SC_NORM_ATTR nooption SC_DFLT_FONT nooption SC_ALT_MOUSE_IMAGE nooption EXT2FS ##################################################################### # Make options we don't want to deal with nomakeoption SC_DFLT_FONT Index: head/sys/sparc64/pci/sbbc.c =================================================================== --- head/sys/sparc64/pci/sbbc.c (nonexistent) +++ head/sys/sparc64/pci/sbbc.c (revision 206451) @@ -0,0 +1,1074 @@ +/* $OpenBSD: sbbc.c,v 1.7 2009/11/09 17:53:39 nicm Exp $ */ +/* + * Copyright (c) 2008 Mark Kettenis + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/*- + * Copyright (c) 2010 Marius Strobl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "clock_if.h" +#include "uart_if.h" + +#define SBBC_PCI_BAR PCIR_BAR(0) +#define SBBC_PCI_VENDOR 0x108e +#define SBBC_PCI_PRODUCT 0xc416 + +#define SBBC_REGS_OFFSET 0x800000 +#define SBBC_REGS_SIZE 0x6230 +#define SBBC_EPLD_OFFSET 0x8e0000 +#define SBBC_EPLD_SIZE 0x20 +#define SBBC_SRAM_OFFSET 0x900000 +#define SBBC_SRAM_SIZE 0x20000 /* 128KB SRAM */ + +#define SBBC_PCI_INT_STATUS 0x2320 +#define SBBC_PCI_INT_ENABLE 0x2330 +#define SBBC_PCI_ENABLE_INT_A 0x11 + +#define SBBC_EPLD_INTERRUPT 0x13 +#define SBBC_EPLD_INTERRUPT_ON 0x01 + +#define SBBC_SRAM_CONS_IN 0x00000001 +#define SBBC_SRAM_CONS_OUT 0x00000002 +#define SBBC_SRAM_CONS_BRK 0x00000004 +#define SBBC_SRAM_CONS_SPACE_IN 0x00000008 +#define SBBC_SRAM_CONS_SPACE_OUT 0x00000010 + +#define SBBC_TAG_KEY_SIZE 8 +#define SBBC_TAG_KEY_SCSOLIE "SCSOLIE" /* SC -> OS int. enable */ +#define SBBC_TAG_KEY_SCSOLIR "SCSOLIR" /* SC -> OS int. reason */ +#define SBBC_TAG_KEY_SOLCONS "SOLCONS" /* OS console buffer */ +#define SBBC_TAG_KEY_SOLSCIE "SOLSCIE" /* OS -> SC int. enable */ +#define SBBC_TAG_KEY_SOLSCIR "SOLSCIR" /* OS -> SC int. reason */ +#define SBBC_TAG_KEY_TODDATA "TODDATA" /* OS TOD struct */ +#define SBBC_TAG_OFF(x) offsetof(struct sbbc_sram_tag, x) + +struct sbbc_sram_tag { + char tag_key[SBBC_TAG_KEY_SIZE]; + uint32_t tag_size; + uint32_t tag_offset; +} __packed; + +#define SBBC_TOC_MAGIC "TOCSRAM" +#define SBBC_TOC_MAGIC_SIZE 8 +#define SBBC_TOC_TAGS_MAX 32 +#define SBBC_TOC_OFF(x) offsetof(struct sbbc_sram_toc, x) + +struct sbbc_sram_toc { + char toc_magic[SBBC_TOC_MAGIC_SIZE]; + uint8_t toc_reserved; + uint8_t toc_type; + uint16_t toc_version; + uint32_t toc_ntags; + struct sbbc_sram_tag toc_tag[SBBC_TOC_TAGS_MAX]; +} __packed; + +#define SBBC_TOD_MAGIC 0x54443100 /* "TD1" */ +#define SBBC_TOD_VERSION 1 +#define SBBC_TOD_OFF(x) offsetof(struct sbbc_sram_tod, x) + +struct sbbc_sram_tod { + uint32_t tod_magic; + uint32_t tod_version; + uint64_t tod_time; + uint64_t tod_skew; + uint32_t tod_reserved; + uint32_t tod_heartbeat; + uint32_t tod_timeout; +} __packed; + +#define SBBC_CONS_MAGIC 0x434f4e00 /* "CON" */ +#define SBBC_CONS_VERSION 1 +#define SBBC_CONS_OFF(x) offsetof(struct sbbc_sram_cons, x) + +struct sbbc_sram_cons { + uint32_t cons_magic; + uint32_t cons_version; + uint32_t cons_size; + + uint32_t cons_in_begin; + uint32_t cons_in_end; + uint32_t cons_in_rdptr; + uint32_t cons_in_wrptr; + + uint32_t cons_out_begin; + uint32_t cons_out_end; + uint32_t cons_out_rdptr; + uint32_t cons_out_wrptr; +} __packed; + +struct sbbc_softc { + struct resource *sc_res; +}; + +#define SBBC_READ_N(wdth, offs) \ + bus_space_read_ ## wdth((bst), (bsh), (offs)) +#define SBBC_WRITE_N(wdth, offs, val) \ + bus_space_write_ ## wdth((bst), (bsh), (offs), (val)) + +#define SBBC_READ_1(offs) \ + SBBC_READ_N(1, (offs)) +#define SBBC_READ_2(offs) \ + bswap16(SBBC_READ_N(2, (offs))) +#define SBBC_READ_4(offs) \ + bswap32(SBBC_READ_N(4, (offs))) +#define SBBC_READ_8(offs) \ + bswap64(SBBC_READ_N(8, (offs))) +#define SBBC_WRITE_1(offs, val) \ + SBBC_WRITE_N(1, (offs), (val)) +#define SBBC_WRITE_2(offs, val) \ + SBBC_WRITE_N(2, (offs), bswap16(val)) +#define SBBC_WRITE_4(offs, val) \ + SBBC_WRITE_N(4, (offs), bswap32(val)) +#define SBBC_WRITE_8(offs, val) \ + SBBC_WRITE_N(8, (offs), bswap64(val)) + +#define SBBC_REGS_READ_1(offs) \ + SBBC_READ_1((offs) + SBBC_REGS_OFFSET) +#define SBBC_REGS_READ_2(offs) \ + SBBC_READ_2((offs) + SBBC_REGS_OFFSET) +#define SBBC_REGS_READ_4(offs) \ + SBBC_READ_4((offs) + SBBC_REGS_OFFSET) +#define SBBC_REGS_READ_8(offs) \ + SBBC_READ_8((offs) + SBBC_REGS_OFFSET) +#define SBBC_REGS_WRITE_1(offs, val) \ + SBBC_WRITE_1((offs) + SBBC_REGS_OFFSET, (val)) +#define SBBC_REGS_WRITE_2(offs, val) \ + SBBC_WRITE_2((offs) + SBBC_REGS_OFFSET, (val)) +#define SBBC_REGS_WRITE_4(offs, val) \ + SBBC_WRITE_4((offs) + SBBC_REGS_OFFSET, (val)) +#define SBBC_REGS_WRITE_8(offs, val) \ + SBBC_WRITE_8((offs) + SBBC_REGS_OFFSET, (val)) + +#define SBBC_EPLD_READ_1(offs) \ + SBBC_READ_1((offs) + SBBC_EPLD_OFFSET) +#define SBBC_EPLD_READ_2(offs) \ + SBBC_READ_2((offs) + SBBC_EPLD_OFFSET) +#define SBBC_EPLD_READ_4(offs) \ + SBBC_READ_4((offs) + SBBC_EPLD_OFFSET) +#define SBBC_EPLD_READ_8(offs) \ + SBBC_READ_8((offs) + SBBC_EPLD_OFFSET) +#define SBBC_EPLD_WRITE_1(offs, val) \ + SBBC_WRITE_1((offs) + SBBC_EPLD_OFFSET, (val)) +#define SBBC_EPLD_WRITE_2(offs, val) \ + SBBC_WRITE_2((offs) + SBBC_EPLD_OFFSET, (val)) +#define SBBC_EPLD_WRITE_4(offs, val) \ + SBBC_WRITE_4((offs) + SBBC_EPLD_OFFSET, (val)) +#define SBBC_EPLD_WRITE_8(offs, val) \ + SBBC_WRITE_8((offs) + SBBC_EPLD_OFFSET, (val)) + +#define SBBC_SRAM_READ_1(offs) \ + SBBC_READ_1((offs) + SBBC_SRAM_OFFSET) +#define SBBC_SRAM_READ_2(offs) \ + SBBC_READ_2((offs) + SBBC_SRAM_OFFSET) +#define SBBC_SRAM_READ_4(offs) \ + SBBC_READ_4((offs) + SBBC_SRAM_OFFSET) +#define SBBC_SRAM_READ_8(offs) \ + SBBC_READ_8((offs) + SBBC_SRAM_OFFSET) +#define SBBC_SRAM_WRITE_1(offs, val) \ + SBBC_WRITE_1((offs) + SBBC_SRAM_OFFSET, (val)) +#define SBBC_SRAM_WRITE_2(offs, val) \ + SBBC_WRITE_2((offs) + SBBC_SRAM_OFFSET, (val)) +#define SBBC_SRAM_WRITE_4(offs, val) \ + SBBC_WRITE_4((offs) + SBBC_SRAM_OFFSET, (val)) +#define SBBC_SRAM_WRITE_8(offs, val) \ + SBBC_WRITE_8((offs) + SBBC_SRAM_OFFSET, (val)) + +#define SUNW_SETCONSINPUT "SUNW,set-console-input" +#define SUNW_SETCONSINPUT_CLNT "CON_CLNT" +#define SUNW_SETCONSINPUT_OBP "CON_OBP" + +static u_int sbbc_console; + +static uint32_t sbbc_scsolie; +static uint32_t sbbc_scsolir; +static uint32_t sbbc_solcons; +static uint32_t sbbc_solscie; +static uint32_t sbbc_solscir; +static uint32_t sbbc_toddata; + +/* + * internal helpers + */ +static int sbbc_parse_toc(bus_space_tag_t bst, bus_space_handle_t bsh); +static inline void sbbc_send_intr(bus_space_tag_t bst, + bus_space_handle_t bsh); +static const char *sbbc_serengeti_set_console_input(char *new); + +/* + * SBBC PCI interface + */ +static bus_alloc_resource_t sbbc_bus_alloc_resource; +static bus_release_resource_t sbbc_bus_release_resource; +static bus_get_resource_list_t sbbc_bus_get_resource_list; +static bus_setup_intr_t sbbc_bus_setup_intr; +static bus_teardown_intr_t sbbc_bus_teardown_intr; + +static device_attach_t sbbc_pci_attach; +static device_probe_t sbbc_pci_probe; + +static clock_gettime_t sbbc_tod_gettime; +static clock_settime_t sbbc_tod_settime; + +static device_method_t sbbc_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, sbbc_pci_probe), + DEVMETHOD(device_attach, sbbc_pci_attach), + + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_alloc_resource, sbbc_bus_alloc_resource), + DEVMETHOD(bus_release_resource, sbbc_bus_release_resource), + DEVMETHOD(bus_setup_intr, sbbc_bus_setup_intr), + DEVMETHOD(bus_teardown_intr, sbbc_bus_teardown_intr), + DEVMETHOD(bus_get_resource_list, sbbc_bus_get_resource_list), + + /* clock interface */ + DEVMETHOD(clock_gettime, sbbc_tod_gettime), + DEVMETHOD(clock_settime, sbbc_tod_settime), + + KOBJMETHOD_END +}; + +static devclass_t sbbc_devclass; + +DEFINE_CLASS_0(sbbc, sbbc_driver, sbbc_pci_methods, sizeof(struct sbbc_softc)); +DRIVER_MODULE(sbbc, pci, sbbc_driver, sbbc_devclass, 0, 0); + +static int +sbbc_pci_probe(device_t dev) +{ + + if (pci_get_vendor(dev) == SBBC_PCI_VENDOR && + pci_get_device(dev) == SBBC_PCI_PRODUCT) { + device_set_desc(dev, "Sun BootBus controller"); + return (BUS_PROBE_DEFAULT); + } + return (ENXIO); +} + +static int +sbbc_pci_attach(device_t dev) +{ + struct sbbc_softc *sc; + struct timespec ts; + device_t child; + bus_space_tag_t bst; + bus_space_handle_t bsh; + phandle_t node; + int error, rid; + uint32_t val; + + /* Nothing to to if we're not the chosen one. */ + if ((node = OF_finddevice("/chosen")) == -1) { + device_printf(dev, "failed to find /chosen\n"); + return (ENXIO); + } + if (OF_getprop(node, "iosram", &node, sizeof(node)) == -1) { + device_printf(dev, "failed to get iosram\n"); + return (ENXIO); + } + if (node != ofw_bus_get_node(dev)) + return (0); + + sc = device_get_softc(dev); + rid = SBBC_PCI_BAR; + /* + * Note that we don't activate the resource so it's not mapped twice + * but only once by the the firmware. + */ + sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0); + if (sc->sc_res == NULL) { + device_printf(dev, "failed to allocate resources\n"); + return (ENXIO); + } + bst = rman_get_bustag(sc->sc_res); + bsh = rman_get_bushandle(sc->sc_res); + if (sbbc_console != 0) { + /* Once again the interrupt pin isn't set. */ + if (pci_get_intpin(dev) == 0) + pci_set_intpin(dev, 1); + child = device_add_child(dev, NULL, -1); + if (child == NULL) + device_printf(dev, "failed to add UART device\n"); + error = bus_generic_attach(dev); + if (error != 0) + device_printf(dev, "failed to attach UART device\n"); + } else { + error = sbbc_parse_toc(rman_get_bustag(sc->sc_res), + rman_get_bushandle(sc->sc_res)); + if (error != 0) { + device_printf(dev, "failed to parse TOC\n"); + if (sbbc_console != 0) { + bus_release_resource(dev, SYS_RES_MEMORY, rid, + sc->sc_res); + return (error); + } + } + } + if (sbbc_toddata != 0) { + if ((val = SBBC_SRAM_READ_4(sbbc_toddata + + SBBC_TOD_OFF(tod_magic))) != SBBC_TOD_MAGIC) + device_printf(dev, "invalid TOD magic %#x\n", val); + else if ((val = SBBC_SRAM_READ_4(sbbc_toddata + + SBBC_TOD_OFF(tod_version))) < SBBC_TOD_VERSION) + device_printf(dev, "invalid TOD version %#x\n", val); + else { + clock_register(dev, 1000000); /* 1 sec. resolution */ + if (bootverbose) { + sbbc_tod_gettime(dev, &ts); + device_printf(dev, + "current time: %ld.%09ld\n", + (long)ts.tv_sec, ts.tv_nsec); + } + } + } + return (0); +} + +/* + * Note that the bus methods don't pass-through the uart(4) requests but act + * as if they would come from sbbc(4) in order to avoid complications with + * pci(4) (actually, uart(4) isn't a real child but rather a function of + * sbbc(4) anyway). + */ + +static struct resource * +sbbc_bus_alloc_resource(device_t dev, device_t child __unused, int type, + int *rid, u_long start, u_long end, u_long count, u_int flags) +{ + struct sbbc_softc *sc; + + sc = device_get_softc(dev); + switch (type) { + case SYS_RES_IRQ: + return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type, + rid, start, end, count, flags)); + case SYS_RES_MEMORY: + return (sc->sc_res); + default: + return (NULL); + /* NOTREACHED */ + } +} + +static int +sbbc_bus_release_resource(device_t dev, device_t child __unused, int type, + int rid, struct resource *res) +{ + + if (type == SYS_RES_IRQ) + return (BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, + type, rid, res)); + return (0); +} + +static struct resource_list * +sbbc_bus_get_resource_list(device_t dev, device_t child __unused) +{ + + return (BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev)); +} + +static int +sbbc_bus_setup_intr(device_t dev, device_t child __unused, + struct resource *res, int flags, driver_filter_t *filt, + driver_intr_t *intr, void *arg, void **cookiep) +{ + + return (BUS_SETUP_INTR(device_get_parent(dev), dev, res, flags, filt, + intr, arg, cookiep)); +} + +static int +sbbc_bus_teardown_intr(device_t dev, device_t child __unused, + struct resource *res, void *cookie) +{ + + return (BUS_TEARDOWN_INTR(device_get_parent(dev), dev, res, cookie)); +} + +/* + * internal helpers + */ +static int +sbbc_parse_toc(bus_space_tag_t bst, bus_space_handle_t bsh) +{ + char buf[MAX(SBBC_TAG_KEY_SIZE, SBBC_TOC_MAGIC_SIZE)]; + bus_size_t tag; + phandle_t node; + uint32_t off, sram_toc; + u_int i, tags; + + if ((node = OF_finddevice("/chosen")) == -1) + return (ENXIO); + /* SRAM TOC offset defaults to 0. */ + if (OF_getprop(node, "iosram-toc", &sram_toc, sizeof(sram_toc)) <= 0) + sram_toc = 0; + + bus_space_read_region_1(bst, bsh, SBBC_SRAM_OFFSET + sram_toc + + SBBC_TOC_OFF(toc_magic), buf, SBBC_TOC_MAGIC_SIZE); + buf[SBBC_TOC_MAGIC_SIZE - 1] = '\0'; + if (strcmp(buf, SBBC_TOC_MAGIC) != 0) + return (ENXIO); + + tags = SBBC_SRAM_READ_4(sram_toc + SBBC_TOC_OFF(toc_ntags)); + for (i = 0; i < tags; i++) { + tag = sram_toc + SBBC_TOC_OFF(toc_tag) + + i * sizeof(struct sbbc_sram_tag); + bus_space_read_region_1(bst, bsh, SBBC_SRAM_OFFSET + tag + + SBBC_TAG_OFF(tag_key), buf, SBBC_TAG_KEY_SIZE); + buf[SBBC_TAG_KEY_SIZE - 1] = '\0'; + off = SBBC_SRAM_READ_4(tag + SBBC_TAG_OFF(tag_offset)); + if (strcmp(buf, SBBC_TAG_KEY_SCSOLIE) == 0) + sbbc_scsolie = off; + else if (strcmp(buf, SBBC_TAG_KEY_SCSOLIR) == 0) + sbbc_scsolir = off; + else if (strcmp(buf, SBBC_TAG_KEY_SOLCONS) == 0) + sbbc_solcons = off; + else if (strcmp(buf, SBBC_TAG_KEY_SOLSCIE) == 0) + sbbc_solscie = off; + else if (strcmp(buf, SBBC_TAG_KEY_SOLSCIR) == 0) + sbbc_solscir = off; + else if (strcmp(buf, SBBC_TAG_KEY_TODDATA) == 0) + sbbc_toddata = off; + } + return (0); +} + +static const char * +sbbc_serengeti_set_console_input(char *new) +{ + struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t new; + cell_t old; + } args = { + (cell_t)SUNW_SETCONSINPUT, + 1, + 1, + }; + + args.new = (cell_t)new; + if (ofw_entry(&args) == -1) + return (NULL); + return ((const char *)args.old); +} + +static inline void +sbbc_send_intr(bus_space_tag_t bst, bus_space_handle_t bsh) +{ + + SBBC_EPLD_WRITE_1(SBBC_EPLD_INTERRUPT, SBBC_EPLD_INTERRUPT_ON); + bus_space_barrier(bst, bsh, SBBC_EPLD_OFFSET + SBBC_EPLD_INTERRUPT, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); +} + +/* + * TOD interface + */ +static int +sbbc_tod_gettime(device_t dev, struct timespec *ts) +{ + struct sbbc_softc *sc; + bus_space_tag_t bst; + bus_space_handle_t bsh; + + sc = device_get_softc(dev); + bst = rman_get_bustag(sc->sc_res); + bsh = rman_get_bushandle(sc->sc_res); + + ts->tv_sec = SBBC_SRAM_READ_8(sbbc_toddata + SBBC_TOD_OFF(tod_time)) + + SBBC_SRAM_READ_8(sbbc_toddata + SBBC_TOD_OFF(tod_skew)); + ts->tv_nsec = 0; + return (0); +} + +static int +sbbc_tod_settime(device_t dev, struct timespec *ts) +{ + struct sbbc_softc *sc; + bus_space_tag_t bst; + bus_space_handle_t bsh; + + sc = device_get_softc(dev); + bst = rman_get_bustag(sc->sc_res); + bsh = rman_get_bushandle(sc->sc_res); + + SBBC_SRAM_WRITE_8(sbbc_toddata + SBBC_TOD_OFF(tod_skew), ts->tv_sec - + SBBC_SRAM_READ_8(sbbc_toddata + SBBC_TOD_OFF(tod_time))); + return (0); +} + +/* + * UART bus front-end + */ +static device_probe_t sbbc_uart_sbbc_probe; + +static device_method_t sbbc_uart_sbbc_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, sbbc_uart_sbbc_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + + KOBJMETHOD_END +}; + +DEFINE_CLASS_0(uart, sbbc_uart_driver, sbbc_uart_sbbc_methods, + sizeof(struct uart_softc)); +DRIVER_MODULE(uart, sbbc, sbbc_uart_driver, uart_devclass, 0, 0); + +static int +sbbc_uart_sbbc_probe(device_t dev) +{ + struct uart_softc *sc; + + sc = device_get_softc(dev); + sc->sc_class = &uart_sbbc_class; + device_set_desc(dev, "Serengeti console"); + return (uart_bus_probe(dev, 0, 0, SBBC_PCI_BAR, 0)); +} + +/* + * Low-level UART interface + */ +static int sbbc_uart_probe(struct uart_bas *bas); +static void sbbc_uart_init(struct uart_bas *bas, int baudrate, int databits, + int stopbits, int parity); +static void sbbc_uart_term(struct uart_bas *bas); +static void sbbc_uart_putc(struct uart_bas *bas, int c); +static int sbbc_uart_rxready(struct uart_bas *bas); +static int sbbc_uart_getc(struct uart_bas *bas, struct mtx *hwmtx); + +static struct uart_ops sbbc_uart_ops = { + .probe = sbbc_uart_probe, + .init = sbbc_uart_init, + .term = sbbc_uart_term, + .putc = sbbc_uart_putc, + .rxready = sbbc_uart_rxready, + .getc = sbbc_uart_getc, +}; + +static int +sbbc_uart_probe(struct uart_bas *bas) +{ + bus_space_tag_t bst; + bus_space_handle_t bsh; + int error; + + sbbc_console = 1; + bst = bas->bst; + bsh = bas->bsh; + error = sbbc_parse_toc(bst, bsh); + if (error != 0) + return (error); + + if (sbbc_scsolie == 0 || sbbc_scsolir == 0 || sbbc_solcons == 0 || + sbbc_solscie == 0 || sbbc_solscir == 0) + return (ENXIO); + + if (SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_magic)) != + SBBC_CONS_MAGIC || SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_version)) < SBBC_CONS_VERSION) + return (ENXIO); + return (0); +} + +static void +sbbc_uart_init(struct uart_bas *bas, int baudrate __unused, + int databits __unused, int stopbits __unused, int parity __unused) +{ + bus_space_tag_t bst; + bus_space_handle_t bsh; + + bst = bas->bst; + bsh = bas->bsh; + + /* Enable output to and space in from the SC interrupts. */ + SBBC_SRAM_WRITE_4(sbbc_solscie, SBBC_SRAM_READ_4(sbbc_solscie) | + SBBC_SRAM_CONS_OUT | SBBC_SRAM_CONS_SPACE_IN); + uart_barrier(bas); + + /* Take over the console input. */ + sbbc_serengeti_set_console_input(SUNW_SETCONSINPUT_CLNT); +} + +static void +sbbc_uart_term(struct uart_bas *bas __unused) +{ + + /* Give back the console input. */ + sbbc_serengeti_set_console_input(SUNW_SETCONSINPUT_OBP); +} + +static void +sbbc_uart_putc(struct uart_bas *bas, int c) +{ + bus_space_tag_t bst; + bus_space_handle_t bsh; + uint32_t wrptr; + + bst = bas->bst; + bsh = bas->bsh; + + wrptr = SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_out_wrptr)); + SBBC_SRAM_WRITE_1(sbbc_solcons + wrptr, c); + uart_barrier(bas); + if (++wrptr == SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_out_end))) + wrptr = SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_out_begin)); + SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_wrptr), + wrptr); + uart_barrier(bas); + + SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) | + SBBC_SRAM_CONS_OUT); + uart_barrier(bas); + sbbc_send_intr(bst, bsh); +} + +static int +sbbc_uart_rxready(struct uart_bas *bas) +{ + bus_space_tag_t bst; + bus_space_handle_t bsh; + + bst = bas->bst; + bsh = bas->bsh; + + if (SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr)) == + SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_wrptr))) + return (0); + return (1); +} + +static int +sbbc_uart_getc(struct uart_bas *bas, struct mtx *hwmtx) +{ + bus_space_tag_t bst; + bus_space_handle_t bsh; + int c; + uint32_t rdptr; + + bst = bas->bst; + bsh = bas->bsh; + + uart_lock(hwmtx); + + while (sbbc_uart_rxready(bas) == 0) { + uart_unlock(hwmtx); + DELAY(4); + uart_lock(hwmtx); + } + + rdptr = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr)); + c = SBBC_SRAM_READ_1(sbbc_solcons + rdptr); + uart_barrier(bas); + if (++rdptr == SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_in_end))) + rdptr = SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_in_begin)); + SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr), + rdptr); + uart_barrier(bas); + SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) | + SBBC_SRAM_CONS_SPACE_IN); + uart_barrier(bas); + sbbc_send_intr(bst, bsh); + + uart_unlock(hwmtx); + return (c); +} + +/* + * High-level UART interface + */ +static int sbbc_uart_bus_attach(struct uart_softc *sc); +static int sbbc_uart_bus_detach(struct uart_softc *sc); +static int sbbc_uart_bus_flush(struct uart_softc *sc, int what); +static int sbbc_uart_bus_getsig(struct uart_softc *sc); +static int sbbc_uart_bus_ioctl(struct uart_softc *sc, int request, + intptr_t data); +static int sbbc_uart_bus_ipend(struct uart_softc *sc); +static int sbbc_uart_bus_param(struct uart_softc *sc, int baudrate, + int databits, int stopbits, int parity); +static int sbbc_uart_bus_probe(struct uart_softc *sc); +static int sbbc_uart_bus_receive(struct uart_softc *sc); +static int sbbc_uart_bus_setsig(struct uart_softc *sc, int sig); +static int sbbc_uart_bus_transmit(struct uart_softc *sc); + +static kobj_method_t sbbc_uart_methods[] = { + KOBJMETHOD(uart_attach, sbbc_uart_bus_attach), + KOBJMETHOD(uart_detach, sbbc_uart_bus_detach), + KOBJMETHOD(uart_flush, sbbc_uart_bus_flush), + KOBJMETHOD(uart_getsig, sbbc_uart_bus_getsig), + KOBJMETHOD(uart_ioctl, sbbc_uart_bus_ioctl), + KOBJMETHOD(uart_ipend, sbbc_uart_bus_ipend), + KOBJMETHOD(uart_param, sbbc_uart_bus_param), + KOBJMETHOD(uart_probe, sbbc_uart_bus_probe), + KOBJMETHOD(uart_receive, sbbc_uart_bus_receive), + KOBJMETHOD(uart_setsig, sbbc_uart_bus_setsig), + KOBJMETHOD(uart_transmit, sbbc_uart_bus_transmit), + + KOBJMETHOD_END +}; + +struct uart_class uart_sbbc_class = { + "sbbc", + sbbc_uart_methods, + sizeof(struct uart_softc), + .uc_ops = &sbbc_uart_ops, + .uc_range = 1, + .uc_rclk = 0x5bbc /* arbitrary */ +}; + +#define SIGCHG(c, i, s, d) \ + if ((c) != 0) { \ + i |= (((i) & (s)) != 0) ? (s) : (s) | (d); \ + } else { \ + i = (((i) & (s)) != 0) ? ((i) & ~(s)) | (d) : (i); \ + } + +static int +sbbc_uart_bus_attach(struct uart_softc *sc) +{ + struct uart_bas *bas; + bus_space_tag_t bst; + bus_space_handle_t bsh; + uint32_t wrptr; + + bas = &sc->sc_bas; + bst = bas->bst; + bsh = bas->bsh; + + sc->sc_rxfifosz = SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_in_end)) - SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_in_begin)) - 1; + sc->sc_txfifosz = SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_out_end)) - SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_out_begin)) - 1; + + uart_lock(sc->sc_hwmtx); + + /* + * Let the current output drain before enabling interrupts. Not + * doing so tends to cause lost output when turning them on. + */ + wrptr = SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_out_wrptr)); + while (SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_out_rdptr)) != wrptr); + cpu_spinwait(); + + /* Clear and acknowledge possibly outstanding interrupts. */ + SBBC_SRAM_WRITE_4(sbbc_scsolir, 0); + uart_barrier(bas); + SBBC_REGS_WRITE_4(SBBC_PCI_INT_STATUS, + SBBC_SRAM_READ_4(sbbc_scsolir)); + uart_barrier(bas); + /* Enable PCI interrupts. */ + SBBC_REGS_WRITE_4(SBBC_PCI_INT_ENABLE, SBBC_PCI_ENABLE_INT_A); + uart_barrier(bas); + /* Enable input from and output to SC as well as break interrupts. */ + SBBC_SRAM_WRITE_4(sbbc_scsolie, SBBC_SRAM_READ_4(sbbc_scsolie) | + SBBC_SRAM_CONS_IN | SBBC_SRAM_CONS_BRK | + SBBC_SRAM_CONS_SPACE_OUT); + uart_barrier(bas); + + uart_unlock(sc->sc_hwmtx); + return (0); +} + +static int +sbbc_uart_bus_detach(struct uart_softc *sc) +{ + + /* Give back the console input. */ + sbbc_serengeti_set_console_input(SUNW_SETCONSINPUT_OBP); + return (0); +} + +static int +sbbc_uart_bus_flush(struct uart_softc *sc, int what) +{ + struct uart_bas *bas; + bus_space_tag_t bst; + bus_space_handle_t bsh; + + bas = &sc->sc_bas; + bst = bas->bst; + bsh = bas->bsh; + + if ((what & UART_FLUSH_TRANSMITTER) != 0) + return (ENODEV); + if ((what & UART_FLUSH_RECEIVER) != 0) { + SBBC_SRAM_WRITE_4(sbbc_solcons + + SBBC_CONS_OFF(cons_in_rdptr), + SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_in_wrptr))); + uart_barrier(bas); + } + return (0); +} + +static int +sbbc_uart_bus_getsig(struct uart_softc *sc) +{ + uint32_t dummy, new, old, sig; + + do { + old = sc->sc_hwsig; + sig = old; + dummy = 0; + SIGCHG(dummy, sig, SER_CTS, SER_DCTS); + SIGCHG(dummy, sig, SER_DCD, SER_DDCD); + SIGCHG(dummy, sig, SER_DSR, SER_DDSR); + new = sig & ~SER_MASK_DELTA; + } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); + return (sig); +} + +static int +sbbc_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) +{ + int error; + + error = 0; + uart_lock(sc->sc_hwmtx); + switch (request) { + case UART_IOCTL_BAUD: + *(int*)data = 9600; /* arbitrary */ + break; + default: + error = EINVAL; + break; + } + uart_unlock(sc->sc_hwmtx); + return (error); +} + +static int +sbbc_uart_bus_ipend(struct uart_softc *sc) +{ + struct uart_bas *bas; + bus_space_tag_t bst; + bus_space_handle_t bsh; + int ipend; + uint32_t reason, status; + + bas = &sc->sc_bas; + bst = bas->bst; + bsh = bas->bsh; + + uart_lock(sc->sc_hwmtx); + status = SBBC_REGS_READ_4(SBBC_PCI_INT_STATUS); + if (status == 0) { + uart_unlock(sc->sc_hwmtx); + return (0); + } + + /* + * Unfortunately, we can't use compare and swap for non-cachable + * memory. + */ + reason = SBBC_SRAM_READ_4(sbbc_scsolir); + SBBC_SRAM_WRITE_4(sbbc_scsolir, 0); + uart_barrier(bas); + /* Acknowledge the interrupt. */ + SBBC_REGS_WRITE_4(SBBC_PCI_INT_STATUS, status); + uart_barrier(bas); + + uart_unlock(sc->sc_hwmtx); + + ipend = 0; + if ((reason & SBBC_SRAM_CONS_IN) != 0) + ipend |= SER_INT_RXREADY; + if ((reason & SBBC_SRAM_CONS_BRK) != 0) + ipend |= SER_INT_BREAK; + if ((reason & SBBC_SRAM_CONS_SPACE_OUT) != 0 && + SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_rdptr)) == + SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_wrptr))) + ipend |= SER_INT_TXIDLE; + return (ipend); +} + +static int +sbbc_uart_bus_param(struct uart_softc *sc __unused, int baudrate __unused, + int databits __unused, int stopbits __unused, int parity __unused) +{ + + return (0); +} + +static int +sbbc_uart_bus_probe(struct uart_softc *sc __unused) +{ + + if (sbbc_console != 0) + return (0); + return (ENXIO); +} + +static int +sbbc_uart_bus_receive(struct uart_softc *sc) +{ + struct uart_bas *bas; + bus_space_tag_t bst; + bus_space_handle_t bsh; + int c; + uint32_t end, rdptr, wrptr; + + bas = &sc->sc_bas; + bst = bas->bst; + bsh = bas->bsh; + + uart_lock(sc->sc_hwmtx); + + end = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_end)); + rdptr = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr)); + wrptr = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_wrptr)); + while (rdptr != wrptr) { + if (uart_rx_full(sc) != 0) { + sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; + break; + } + c = SBBC_SRAM_READ_1(sbbc_solcons + rdptr); + uart_rx_put(sc, c); + if (++rdptr == end) + rdptr = SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_in_begin)); + } + uart_barrier(bas); + SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_in_rdptr), + rdptr); + uart_barrier(bas); + SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) | + SBBC_SRAM_CONS_SPACE_IN); + uart_barrier(bas); + sbbc_send_intr(bst, bsh); + + uart_unlock(sc->sc_hwmtx); + return (0); +} + +static int +sbbc_uart_bus_setsig(struct uart_softc *sc, int sig) +{ + struct uart_bas *bas; + uint32_t new, old; + + bas = &sc->sc_bas; + do { + old = sc->sc_hwsig; + new = old; + if ((sig & SER_DDTR) != 0) { + SIGCHG(sig & SER_DTR, new, SER_DTR, SER_DDTR); + } + if ((sig & SER_DRTS) != 0) { + SIGCHG(sig & SER_RTS, new, SER_RTS, SER_DRTS); + } + } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); + return (0); +} + +static int +sbbc_uart_bus_transmit(struct uart_softc *sc) +{ + struct uart_bas *bas; + bus_space_tag_t bst; + bus_space_handle_t bsh; + int i; + uint32_t end, wrptr; + + bas = &sc->sc_bas; + bst = bas->bst; + bsh = bas->bsh; + + uart_lock(sc->sc_hwmtx); + + end = SBBC_SRAM_READ_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_end)); + wrptr = SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_out_wrptr)); + for (i = 0; i < sc->sc_txdatasz; i++) { + SBBC_SRAM_WRITE_1(sbbc_solcons + wrptr, sc->sc_txbuf[i]); + if (++wrptr == end) + wrptr = SBBC_SRAM_READ_4(sbbc_solcons + + SBBC_CONS_OFF(cons_out_begin)); + } + uart_barrier(bas); + SBBC_SRAM_WRITE_4(sbbc_solcons + SBBC_CONS_OFF(cons_out_wrptr), + wrptr); + uart_barrier(bas); + SBBC_SRAM_WRITE_4(sbbc_solscir, SBBC_SRAM_READ_4(sbbc_solscir) | + SBBC_SRAM_CONS_OUT); + uart_barrier(bas); + sbbc_send_intr(bst, bsh); + sc->sc_txbusy = 1; + + uart_unlock(sc->sc_hwmtx); + return (0); +} Property changes on: head/sys/sparc64/pci/sbbc.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property