Changeset bfa4ffa in mainline


Ignore:
Timestamp:
2016-12-27T13:34:08Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9185e42
Parents:
0d9b4a8 (diff), 73d8600 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jakub/helenos/sun4u

This merge brings support for serial console on the QEMU sun4u machine
and by extension on any system that provides at least one device driver
for a serial port device in the 'serial' location service category and
points the 'console' boot argument to it.

The 'console' boot argument is used to differentiate character devices
that are used as a console from other character devices that may be used
for other purposes (e.g. SLIP or keyboard).

Support for real-world sun4u machines is temporarily broken. The legacy
ns16550 input port driver has been discontinued. Real-world Ultra 5,
which is fairly close to the QEMU machine should be easy to revive. In
order to support the sun4u QEMU machine, a new sun4u platform driver was
added. The isa driver was modified to be usable also for the EBUS bus.

On sparc64 the boot argument is passed in the boot-args boot prom
environment variable. On ia32 and amd64, the boot argument can be set in
grub.cfg as an argument to the multiboot command. The backslashes need
to be properly escaped. Other platforms don't have support for boot
arguments yet.

Because the user input/output subsystem is apparently not ready to drive
the serial console next to the ordinary console or the GUI, the serial
console mode is mutually exclusive with the normal
keyboard/ega/fb/compositor mode.

Files:
9 added
1 deleted
26 edited

Legend:

Unmodified
Added
Removed
  • boot/Makefile

    r0d9b4a8 rbfa4ffa  
    113113                file_dir="`dirname "$$file"`" ; \
    114114                file_name="`basename "$$file"`" ; \
    115                 cp "$(USPACE_PATH)/$(DRVS_PATH)/$$file_dir/$$file_name/$$file_name.dev" "$(DIST_PATH)/$(DRVS_PATH)/$$file_name/" ; \
     115                cp "$(USPACE_PATH)/$(DRVS_PATH)/$$file_dir/$$file_name/"*".dev" "$(DIST_PATH)/$(DRVS_PATH)/$$file_name/" ; \
    116116        done
    117117        for file in $(RD_DRVS_FW) ; do \
  • boot/arch/sparc64/Makefile.inc

    r0d9b4a8 rbfa4ffa  
    3939EXTRA_CFLAGS = -mcpu=ultrasparc -m64 -mno-fpu -mcmodel=medlow
    4040
     41RD_DRVS_ESSENTIAL += \
     42        platform/sun4u \
     43        bus/pci/pciintel \
     44        bus/isa \
     45        char/ns8250
     46
     47RD_DRV_CFG += \
     48        bus/isa
     49
    4150RD_SRVS_NON_ESSENTIAL +=
    4251
  • kernel/arch/sparc64/src/drivers/pci.c

    r0d9b4a8 rbfa4ffa  
    112112            PAGE_WRITE | PAGE_NOT_CACHEABLE);
    113113
    114         /*
    115          * Set sysinfo data needed by the uspace OBIO driver.
    116          */
    117         sysinfo_set_item_val("obio.base.physical", NULL, paddr);
    118         sysinfo_set_item_val("kbd.cir.obio", NULL, 1);
    119 
    120114        return pci;
    121115}
     
    159153        pci->reg = (uint64_t *) km_map(paddr, reg[PSYCHO_INTERNAL_REG].size,
    160154            PAGE_WRITE | PAGE_NOT_CACHEABLE);
    161 
    162         /*
    163          * Set sysinfo data needed by the uspace OBIO driver.
    164          */
    165         sysinfo_set_item_val("obio.base.physical", NULL, paddr);
    166         sysinfo_set_item_val("kbd.cir.obio", NULL, 1);
    167155
    168156        return pci;
  • kernel/arch/sparc64/src/sparc64.c

    r0d9b4a8 rbfa4ffa  
    3636#include <arch/arch.h>
    3737#include <mm/slab.h>
     38#include <sysinfo/sysinfo.h>
    3839#include <config.h>
    3940#include <arch/proc/thread.h>
     
    7374                uwb_cache = slab_cache_create("uwb_cache", UWB_SIZE,
    7475                    UWB_ALIGNMENT, NULL, NULL, SLAB_CACHE_MAGDEFERRED);
     76
     77                /* Copy boot arguments */
     78                ofw_tree_node_t *options = ofw_tree_lookup("/options");
     79                if (options) {
     80                        ofw_tree_property_t *prop;
     81               
     82                        prop = ofw_tree_getprop(options, "boot-args");
     83                        if (prop && prop->value) {
     84                                str_ncpy(bargs, CONFIG_BOOT_ARGUMENTS_BUFLEN,
     85                                    prop->value, prop->size);
     86                        }
     87                }
    7588        }
    7689}
  • kernel/genarch/src/multiboot/multiboot.c

    r0d9b4a8 rbfa4ffa  
    100100}
    101101
     102static void multiboot_cmdline(char *cmdline)
     103{
     104        /*
     105         * GRUB passes the command line in an escaped form.
     106         */
     107        for (size_t i = 0, j = 0;
     108            cmdline[i] && j < CONFIG_BOOT_ARGUMENTS_BUFLEN;
     109            i++, j++) {
     110                if (cmdline[i] == '\\') {
     111                        switch (cmdline[i + 1]) {
     112                        case '\\':
     113                        case '\'':
     114                        case '\"':
     115                                i++;
     116                                break;
     117                        }
     118                }
     119                bargs[j] = cmdline[i];
     120        }
     121}
     122
    102123static void multiboot_modules(uint32_t count, multiboot_module_t *mods)
    103124{
     
    153174        if (signature != MULTIBOOT_LOADER_MAGIC)
    154175                return;
    155        
     176
     177        /* Copy command line. */
     178        if ((info->flags & MULTIBOOT_INFO_FLAGS_CMDLINE) != 0)
     179                multiboot_cmdline((char *) MULTIBOOT_PTR(info->cmd_line));
     180
    156181        /* Copy modules information. */
    157182        if ((info->flags & MULTIBOOT_INFO_FLAGS_MODS) != 0)
  • kernel/generic/include/config.h

    r0d9b4a8 rbfa4ffa  
    4343
    4444#define STACK_SIZE_USER  (1 * 1024 * 1024)
     45
     46#define CONFIG_BOOT_ARGUMENTS_BUFLEN 256
    4547
    4648#define CONFIG_INIT_TASKS        32
     
    102104
    103105extern config_t config;
     106extern char bargs[];
    104107extern init_t init;
    105108extern ballocs_t ballocs;
  • kernel/generic/src/main/main.c

    r0d9b4a8 rbfa4ffa  
    117117};
    118118
     119/** Boot arguments. */
     120char bargs[CONFIG_BOOT_ARGUMENTS_BUFLEN] = {};
     121
    119122/** Initial user-space tasks */
    120123init_t init = {
     
    276279        thread_init();
    277280        futex_init();
    278        
     281
     282        sysinfo_set_item_data("boot_args", NULL, bargs, str_size(bargs) + 1);
     283
    279284        if (init.cnt > 0) {
    280285                size_t i;
  • tools/ew.py

    r0d9b4a8 rbfa4ffa  
    9595                return 'system-ppc', '-m 256'
    9696        elif platform == 'sparc64':
    97                 return 'system-sparc64', ''
     97                return 'system-sparc64', '--prom-env boot-args="console=devices/\\hw\\pci0\\00:03.0\\com1\\a"'
    9898
    9999def hdisk_mk():
     
    266266                                'run' : qemu_run,
    267267                                'image' : 'image.iso',
    268                                 'audio' : False
     268                                'audio' : False,
     269                                'console' : False,
    269270                        },
    270271                        'sun4v' : {
  • uspace/Makefile

    r0d9b4a8 rbfa4ffa  
    202202        DIRS += \
    203203                srv/hw/irc/obio
     204ifeq ($(MACHINE),generic)
     205        DIRS += \
     206                drv/platform/sun4u \
     207                drv/bus/pci/pciintel \
     208                drv/bus/isa \
     209                drv/char/ns8250
     210endif
    204211endif
    205212
  • uspace/app/init/init.c

    r0d9b4a8 rbfa4ffa  
    4949#include <loc.h>
    5050#include <str_error.h>
     51#include <config.h>
    5152#include "init.h"
    5253
     
    306307int main(int argc, char *argv[])
    307308{
     309        int rc;
     310
    308311        info_print();
    309312       
     
    356359        srv_start("/srv/hound");
    357360       
    358         int rc = compositor(HID_INPUT, HID_COMPOSITOR_SERVER);
    359         if (rc == EOK) {
    360                 gui_start("/app/barber", HID_COMPOSITOR_SERVER);
    361                 gui_start("/app/vlaunch", HID_COMPOSITOR_SERVER);
    362                 gui_start("/app/vterm", HID_COMPOSITOR_SERVER);
     361        if (!config_key_exists("console")) {
     362                rc = compositor(HID_INPUT, HID_COMPOSITOR_SERVER);
     363                if (rc == EOK) {
     364                        gui_start("/app/barber", HID_COMPOSITOR_SERVER);
     365                        gui_start("/app/vlaunch", HID_COMPOSITOR_SERVER);
     366                        gui_start("/app/vterm", HID_COMPOSITOR_SERVER);
     367                }
    363368        }
    364369       
  • uspace/drv/bus/isa/isa.c

    r0d9b4a8 rbfa4ffa  
    6666#include <device/pio_window.h>
    6767
     68#include <pci_dev_iface.h>
     69
    6870#include "i8237.h"
    6971
    7072#define NAME "isa"
    71 #define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev"
     73#define ISA_CHILD_FUN_CONF_PATH "/drv/isa/isa.dev"
     74#define EBUS_CHILD_FUN_CONF_PATH "/drv/isa/ebus.dev"
    7275
    7376#define ISA_MAX_HW_RES 5
     
    7578typedef struct {
    7679        fibril_mutex_t mutex;
     80        uint16_t pci_vendor_id;
     81        uint16_t pci_device_id;
     82        uint8_t pci_class;
     83        uint8_t pci_subclass;
    7784        ddf_dev_t *dev;
    7885        ddf_fun_t *fctl;
     
    593600static void isa_functions_add(isa_bus_t *isa)
    594601{
    595         char *conf = fun_conf_read(CHILD_FUN_CONF_PATH);
     602#define BASE_CLASS_BRIDGE       0x06
     603#define SUB_CLASS_BRIDGE_ISA    0x01
     604        bool isa_bridge = ((isa->pci_class == BASE_CLASS_BRIDGE) &&
     605            (isa->pci_subclass == SUB_CLASS_BRIDGE_ISA));
     606
     607#define VENDOR_ID_SUN   0x108e
     608#define DEVICE_ID_EBUS  0x1000
     609        bool ebus = ((isa->pci_vendor_id == VENDOR_ID_SUN) &&
     610            (isa->pci_device_id == DEVICE_ID_EBUS));
     611
     612        const char *conf_path = NULL;
     613        if (isa_bridge)
     614                conf_path = ISA_CHILD_FUN_CONF_PATH;
     615        else if (ebus)
     616                conf_path = EBUS_CHILD_FUN_CONF_PATH;
     617
     618        char *conf = fun_conf_read(conf_path);
    596619        while (conf != NULL && *conf != '\0') {
    597620                conf = isa_fun_read_info(conf, isa);
     
    623646        }
    624647
     648        rc = pci_config_space_read_16(sess, PCI_VENDOR_ID, &isa->pci_vendor_id);
     649        if (rc != EOK)
     650                return rc;
     651        rc = pci_config_space_read_16(sess, PCI_DEVICE_ID, &isa->pci_device_id);
     652        if (rc != EOK)
     653                return rc;
     654        rc = pci_config_space_read_8(sess, PCI_BASE_CLASS, &isa->pci_class);
     655        if (rc != EOK)
     656                return rc;
     657        rc = pci_config_space_read_8(sess, PCI_SUB_CLASS, &isa->pci_subclass);
     658        if (rc != EOK)
     659                return rc;
     660       
    625661        rc = pio_window_get(sess, &isa->pio_win);
    626662        if (rc != EOK) {
  • uspace/drv/bus/isa/isa.ma

    r0d9b4a8 rbfa4ffa  
    1 9 pci/class=06&subclass=01
     1# ISA bridge
     210 pci/class=06&subclass=01
     3
     4# EBUS
     51 pci/ven=108e&dev=1000
  • uspace/drv/bus/pci/pciintel/pci.c

    r0d9b4a8 rbfa4ffa  
    6363#define NAME "pciintel"
    6464
     65#define CONF_ADDR_ENABLE        (1 << 31)
    6566#define CONF_ADDR(bus, dev, fn, reg) \
    66         ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
     67        ((bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
    6768
    6869/** Obtain PCI function soft-state from DDF function node */
     
    232233        fibril_mutex_lock(&bus->conf_mutex);
    233234
    234         pio_write_32(bus->conf_addr_reg, host2uint32_t_le(conf_addr));
    235 
    236         /*
    237          * Always read full 32-bits from the PCI conf_data_port register and
    238          * get the desired portion of it afterwards. Some architectures do not
    239          * support shorter PIO reads offset from this register.
    240          */
    241         val = uint32_t_le2host(pio_read_32(bus->conf_data_reg));
     235        if (bus->conf_addr_reg) {
     236                pio_write_32(bus->conf_addr_reg,
     237                    host2uint32_t_le(CONF_ADDR_ENABLE | conf_addr));
     238                /*
     239                 * Always read full 32-bits from the PCI conf_data_port
     240                 * register and get the desired portion of it afterwards. Some
     241                 * architectures do not support shorter PIO reads offset from
     242                 * this register.
     243                 */
     244                val = uint32_t_le2host(pio_read_32(bus->conf_data_reg));
     245        } else {
     246                val = uint32_t_le2host(pio_read_32(
     247                    &bus->conf_space[conf_addr / sizeof(ioport32_t)]));
     248        }
    242249
    243250        switch (len) {
     
    260267        const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg);
    261268        pci_bus_t *bus = pci_bus_from_fun(fun);
    262         uint32_t val = 0; // Prevent -Werror=maybe-uninitialized
     269        uint32_t val;
    263270       
    264271        fibril_mutex_lock(&bus->conf_mutex);
     
    275282                 * missing bits first.
    276283                 */
    277                 pio_write_32(bus->conf_addr_reg, host2uint32_t_le(conf_addr));
    278                 val = uint32_t_le2host(pio_read_32(bus->conf_data_reg));
     284                if (bus->conf_addr_reg) {
     285                        pio_write_32(bus->conf_addr_reg,
     286                            host2uint32_t_le(CONF_ADDR_ENABLE | conf_addr));
     287                        val = uint32_t_le2host(pio_read_32(bus->conf_data_reg));
     288                } else {
     289                        val = uint32_t_le2host(pio_read_32(
     290                            &bus->conf_space[conf_addr / sizeof(ioport32_t)]));
     291                }
    279292        }
    280293       
     
    293306        }
    294307
    295         pio_write_32(bus->conf_addr_reg, host2uint32_t_le(conf_addr));
    296         pio_write_32(bus->conf_data_reg, host2uint32_t_le(val));
     308        if (bus->conf_addr_reg) {
     309                pio_write_32(bus->conf_addr_reg,
     310                    host2uint32_t_le(CONF_ADDR_ENABLE | conf_addr));
     311                pio_write_32(bus->conf_data_reg, host2uint32_t_le(val));
     312        } else {
     313                pio_write_32(&bus->conf_space[conf_addr / sizeof(ioport32_t)],
     314                    host2uint32_t_le(val));
     315        }
    297316       
    298317        fibril_mutex_unlock(&bus->conf_mutex);
     
    620639                        ddf_msg(LVL_DEBUG, "Adding new function %s.",
    621640                            ddf_fun_get_name(fun->fnode));
    622                        
     641
    623642                        pci_fun_create_match_ids(fun);
    624643                       
     
    688707       
    689708       
    690         assert(hw_resources.count > 1);
    691         assert(hw_resources.resources[0].type == IO_RANGE);
    692         assert(hw_resources.resources[0].res.io_range.size >= 4);
    693        
    694         assert(hw_resources.resources[1].type == IO_RANGE);
    695         assert(hw_resources.resources[1].res.io_range.size >= 4);
    696        
    697         ddf_msg(LVL_DEBUG, "conf_addr = %" PRIx64 ".",
    698             hw_resources.resources[0].res.io_range.address);
    699         ddf_msg(LVL_DEBUG, "data_addr = %" PRIx64 ".",
    700             hw_resources.resources[1].res.io_range.address);
    701        
    702         if (pio_enable_resource(&bus->pio_win, &hw_resources.resources[0],
    703             (void **) &bus->conf_addr_reg)) {
    704                 ddf_msg(LVL_ERROR, "Failed to enable configuration ports.");
    705                 rc = EADDRNOTAVAIL;
    706                 goto fail;
    707         }
    708         if (pio_enable_resource(&bus->pio_win, &hw_resources.resources[1],
    709             (void **) &bus->conf_data_reg)) {
    710                 ddf_msg(LVL_ERROR, "Failed to enable configuration ports.");
    711                 rc = EADDRNOTAVAIL;
    712                 goto fail;
     709        assert(hw_resources.count >= 1);
     710
     711        if (hw_resources.count == 1) {
     712                assert(hw_resources.resources[0].type == MEM_RANGE);
     713
     714                ddf_msg(LVL_DEBUG, "conf_addr_space = %" PRIx64 ".",
     715                    hw_resources.resources[0].res.mem_range.address);
     716
     717                if (pio_enable_resource(&bus->pio_win,
     718                    &hw_resources.resources[0],
     719                    (void **) &bus->conf_space)) {
     720                        ddf_msg(LVL_ERROR,
     721                            "Failed to map configuration space.");
     722                        rc = EADDRNOTAVAIL;
     723                        goto fail;
     724                }
     725               
     726        } else {
     727                assert(hw_resources.resources[0].type == IO_RANGE);
     728                assert(hw_resources.resources[0].res.io_range.size >= 4);
     729       
     730                assert(hw_resources.resources[1].type == IO_RANGE);
     731                assert(hw_resources.resources[1].res.io_range.size >= 4);
     732       
     733                ddf_msg(LVL_DEBUG, "conf_addr = %" PRIx64 ".",
     734                    hw_resources.resources[0].res.io_range.address);
     735                ddf_msg(LVL_DEBUG, "data_addr = %" PRIx64 ".",
     736                    hw_resources.resources[1].res.io_range.address);
     737       
     738                if (pio_enable_resource(&bus->pio_win,
     739                    &hw_resources.resources[0],
     740                    (void **) &bus->conf_addr_reg)) {
     741                        ddf_msg(LVL_ERROR,
     742                            "Failed to enable configuration ports.");
     743                        rc = EADDRNOTAVAIL;
     744                        goto fail;
     745                }
     746                if (pio_enable_resource(&bus->pio_win,
     747                    &hw_resources.resources[1],
     748                    (void **) &bus->conf_data_reg)) {
     749                        ddf_msg(LVL_ERROR,
     750                            "Failed to enable configuration ports.");
     751                        rc = EADDRNOTAVAIL;
     752                        goto fail;
     753                }
    713754        }
    714755       
  • uspace/drv/bus/pci/pciintel/pci.h

    r0d9b4a8 rbfa4ffa  
    4747        ioport32_t *conf_addr_reg;
    4848        ioport32_t *conf_data_reg;
     49        ioport32_t *conf_space;
    4950        pio_window_t pio_win;
    5051        fibril_mutex_t conf_mutex;
  • uspace/drv/char/ns8250/ns8250.c

    r0d9b4a8 rbfa4ffa  
    163163        int irq;
    164164        /** The base i/o address of the devices registers. */
    165         uint32_t io_addr;
     165        uintptr_t io_addr;
    166166        /** The i/o port used to access the serial ports registers. */
    167167        ioport8_t *port;
     
    330330       
    331331        /* Gain control over port's registers. */
    332         if (pio_enable((void *)(uintptr_t) ns->io_addr, REG_COUNT,
     332        if (pio_enable((void *) ns->io_addr, REG_COUNT,
    333333            (void **) &ns->port)) {
    334                 ddf_msg(LVL_ERROR, "Cannot map the port %#" PRIx32
     334                ddf_msg(LVL_ERROR, "Cannot map the port %#" PRIxn
    335335                    " for device %s.", ns->io_addr, ddf_dev_get_name(ns->dev));
    336336                return false;
     
    432432                        ioport = true;
    433433                        ddf_msg(LVL_NOTE, "Device %s was assigned I/O address = "
    434                             "0x%x.", ddf_dev_get_name(ns->dev), ns->io_addr);
     434                            "0x%#" PRIxn ".", ddf_dev_get_name(ns->dev), ns->io_addr);
    435435                        break;
    436436                       
     
    771771{
    772772        ns8250_t *ns = dev_ns8250(dev);
    773 
    774773        uint8_t iir = pio_read_8(&ns->regs->iid);
    775774        if ((iir & NS8250_IID_CAUSE_MASK) == NS8250_IID_CAUSE_RXSTATUS) {
     
    781780       
    782781        ns8250_read_from_device(ns);
     782        irc_disable_interrupt(ns->irq);
    783783}
    784784
     
    857857        }
    858858        need_unreg_intr_handler = true;
    859        
     859
    860860        /* Enable interrupt. */
    861861        rc = ns8250_interrupt_enable(ns);
  • uspace/lib/c/Makefile

    r0d9b4a8 rbfa4ffa  
    6565        generic/cap.c \
    6666        generic/clipboard.c \
     67        generic/config.c \
    6768        generic/corecfg.c \
    6869        generic/devman.c \
  • uspace/lib/drv/include/pci_dev_iface.h

    r0d9b4a8 rbfa4ffa  
    4040#include "ddf/driver.h"
    4141
    42 #define PCI_VENDOR_ID  0x00
    43 #define PCI_DEVICE_ID  0x02
     42#define PCI_VENDOR_ID   0x00
     43#define PCI_DEVICE_ID   0x02
     44#define PCI_SUB_CLASS   0x0A
     45#define PCI_BASE_CLASS  0x0B
    4446
    4547extern int pci_config_space_read_8(async_sess_t *, uint32_t, uint8_t *);
  • uspace/srv/devman/match.c

    r0d9b4a8 rbfa4ffa  
    4141#include "devman.h"
    4242#include "match.h"
     43
     44#define COMMENT '#'
    4345
    4446/** Compute compound score of driver and device.
     
    145147                if (!skip_spaces(&buf))
    146148                        break;
     149
     150                if (*buf == COMMENT) {
     151                        skip_line(&buf);
     152                        continue;
     153                }
    147154               
    148155                /* read score */
  • uspace/srv/devman/util.c

    r0d9b4a8 rbfa4ffa  
    7373}
    7474
     75void skip_line(char **buf)
     76{
     77        while (**buf && **buf != '\n')
     78                (*buf)++;
     79}
     80
    7581size_t get_nonspace_len(const char *str)
    7682{
  • uspace/srv/devman/util.h

    r0d9b4a8 rbfa4ffa  
    4242
    4343extern bool skip_spaces(char **);
     44extern void skip_line(char **);
    4445extern size_t get_nonspace_len(const char *);
    4546extern void replace_char(char *, char, char);
  • uspace/srv/hid/input/Makefile

    r0d9b4a8 rbfa4ffa  
    3030USPACE_PREFIX = ../../..
    3131BINARY = input
     32LIBS = $(LIBDRV_PREFIX)/libdrv.a
     33EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
    3234
    3335SOURCES = \
     
    4143        port/msim.c \
    4244        port/niagara.c \
    43         port/ns16550.c \
    4445        port/ski.c \
    4546        proto/adb.c \
  • uspace/srv/hid/input/input.c

    r0d9b4a8 rbfa4ffa  
    4242#include <ipc/services.h>
    4343#include <ipc/input.h>
    44 #include <sysinfo.h>
     44#include <config.h>
    4545#include <stdio.h>
    4646#include <unistd.h>
     
    5454#include <loc.h>
    5555#include <str_error.h>
     56#include <char_dev_iface.h>
     57#include <fibril.h>
    5658#include "layout.h"
    5759#include "kbd.h"
     
    6062#include "mouse.h"
    6163#include "mouse_proto.h"
     64#include "serial.h"
    6265#include "input.h"
    63 
    64 bool irc_service = false;
    65 async_sess_t *irc_sess = NULL;
    6666
    6767#define NUM_LAYOUTS  4
     
    9292static bool active = true;
    9393
     94/** Serial console specified by the user */
     95static char *serial_console;
     96
    9497/** List of keyboard devices */
    9598static list_t kbd_devs;
     
    97100/** List of mouse devices */
    98101static list_t mouse_devs;
     102
     103/** List of serial devices */
     104static list_t serial_devs;
    99105
    100106static FIBRIL_MUTEX_INITIALIZE(discovery_lock);
     
    395401        mouse_dev_t *mdev = calloc(1, sizeof(mouse_dev_t));
    396402        if (mdev == NULL) {
    397                 printf("%s: Error allocating keyboard device. "
     403                printf("%s: Error allocating mouse device. "
    398404                    "Out of memory.\n", NAME);
    399405                return NULL;
     
    403409       
    404410        return mdev;
     411}
     412
     413static serial_dev_t *serial_dev_new(void)
     414{
     415        serial_dev_t *sdev = calloc(1, sizeof(serial_dev_t));
     416        if (sdev == NULL) {
     417                printf("%s: Error allocating serial device. "
     418                    "Out of memory.\n", NAME);
     419                return NULL;
     420        }
     421       
     422        sdev->kdev = kbd_dev_new();
     423        if (sdev->kdev == NULL) {
     424                free(sdev);
     425                return NULL;
     426        }
     427
     428        link_initialize(&sdev->link);
     429       
     430        return sdev;
    405431}
    406432
     
    532558        return -1;
    533559}
     560
     561static int serial_consumer(void *arg)
     562{
     563        serial_dev_t *sdev = (serial_dev_t *) arg;
     564
     565        while (true) {
     566                uint8_t data;
     567
     568                char_dev_read(sdev->sess, &data, sizeof(data));
     569                kbd_push_data(sdev->kdev, data);
     570        }
     571
     572        return EOK;
     573}
     574
     575/** Add new serial console device.
     576 *
     577 * @param service_id Service ID of the chardev device
     578 *
     579 */
     580static int serial_add_srldev(service_id_t service_id, serial_dev_t **sdevp)
     581{
     582        bool match = false;
     583
     584        serial_dev_t *sdev = serial_dev_new();
     585        if (sdev == NULL)
     586                return -1;
     587       
     588        sdev->kdev->svc_id = service_id;
     589       
     590        int rc = loc_service_get_name(service_id, &sdev->kdev->svc_name);
     591        if (rc != EOK)
     592                goto fail;
     593
     594        list_append(&sdev->link, &serial_devs);
     595
     596        /*
     597         * Is this the device the user wants to use as a serial console?
     598         */
     599        match = (serial_console != NULL) &&
     600            !str_cmp(serial_console, sdev->kdev->svc_name);
     601
     602        if (match) {
     603                sdev->kdev->ctl_ops = &stty_ctl;
     604
     605                /* Initialize controller driver. */
     606                if ((*sdev->kdev->ctl_ops->init)(sdev->kdev) != 0) {
     607                        list_remove(&sdev->link);
     608                        goto fail;
     609                }
     610
     611                sdev->sess = loc_service_connect(service_id, INTERFACE_DDF,
     612                    IPC_FLAG_BLOCKING);
     613
     614                fid_t fid = fibril_create(serial_consumer, sdev);
     615                fibril_add_ready(fid);
     616        }
     617       
     618        *sdevp = sdev;
     619        return EOK;
     620       
     621fail:
     622        if (sdev->kdev->svc_name != NULL)
     623                free(sdev->kdev->svc_name);
     624        free(sdev->kdev);
     625        free(sdev);
     626        return -1;
     627}
     628
    534629
    535630/** Add legacy drivers/devices. */
     
    555650        kbd_add_dev(&niagara_port, &stty_ctl);
    556651#endif
    557 #if defined(UARCH_sparc64) && defined(MACHINE_generic)
    558         kbd_add_dev(&ns16550_port, &sun_ctl);
    559 #endif
    560652        /* Silence warning on abs32le about kbd_add_dev() being unused */
    561653        (void) kbd_add_dev;
     
    678770}
    679771
     772static int dev_check_new_serialdevs(void)
     773{
     774        category_id_t serial_cat;
     775        service_id_t *svcs;
     776        size_t count, i;
     777        bool already_known;
     778        int rc;
     779       
     780        rc = loc_category_get_id("serial", &serial_cat, IPC_FLAG_BLOCKING);
     781        if (rc != EOK) {
     782                printf("%s: Failed resolving category 'serial'.\n", NAME);
     783                return ENOENT;
     784        }
     785       
     786        /*
     787         * Check for new serial devices
     788         */
     789        rc = loc_category_get_svcs(serial_cat, &svcs, &count);
     790        if (rc != EOK) {
     791                printf("%s: Failed getting list of serial devices.\n",
     792                    NAME);
     793                return EIO;
     794        }
     795
     796        for (i = 0; i < count; i++) {
     797                already_known = false;
     798               
     799                /* Determine whether we already know this device. */
     800                list_foreach(serial_devs, link, serial_dev_t, sdev) {
     801                        if (sdev->kdev->svc_id == svcs[i]) {
     802                                already_known = true;
     803                                break;
     804                        }
     805                }
     806               
     807                if (!already_known) {
     808                        serial_dev_t *sdev;
     809                        if (serial_add_srldev(svcs[i], &sdev) == EOK) {
     810                                printf("%s: Connected serial device '%s'\n",
     811                                    NAME, sdev->kdev->svc_name);
     812                        }
     813                }
     814        }
     815       
     816        free(svcs);
     817       
     818        /* XXX Handle device removal */
     819       
     820        return EOK;
     821}
     822
    680823static int dev_check_new(void)
    681824{
     
    684827        fibril_mutex_lock(&discovery_lock);
    685828       
    686         rc = dev_check_new_kbdevs();
    687         if (rc != EOK) {
    688                 fibril_mutex_unlock(&discovery_lock);
    689                 return rc;
    690         }
    691        
    692         rc = dev_check_new_mousedevs();
    693         if (rc != EOK) {
    694                 fibril_mutex_unlock(&discovery_lock);
    695                 return rc;
     829        if (!serial_console) {
     830                rc = dev_check_new_kbdevs();
     831                if (rc != EOK) {
     832                        fibril_mutex_unlock(&discovery_lock);
     833                        return rc;
     834                }
     835       
     836                rc = dev_check_new_mousedevs();
     837                if (rc != EOK) {
     838                        fibril_mutex_unlock(&discovery_lock);
     839                        return rc;
     840                }
     841        } else {
     842                rc = dev_check_new_serialdevs();
     843                if (rc != EOK) {
     844                        fibril_mutex_unlock(&discovery_lock);
     845                        return rc;
     846                }
    696847        }
    697848       
     
    726877int main(int argc, char **argv)
    727878{
     879        int rc;
     880
    728881        if (argc < 2) {
    729882                usage(argv[0]);
     
    733886        printf("%s: HelenOS input service\n", NAME);
    734887       
    735         sysarg_t obio;
    736        
    737888        list_initialize(&clients);
    738889        list_initialize(&kbd_devs);
    739890        list_initialize(&mouse_devs);
    740        
    741         if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))
    742                 irc_service = true;
    743        
    744         if (irc_service) {
    745                 while (irc_sess == NULL)
    746                         irc_sess = service_connect_blocking(SERVICE_IRC,
    747                             INTERFACE_IRC, 0);
    748         }
     891        list_initialize(&serial_devs);
     892       
     893        serial_console = config_get_value("console");
    749894       
    750895        /* Add legacy keyboard devices. */
     
    759904        async_set_fallback_port_handler(client_connection, NULL);
    760905       
    761         int rc = loc_server_register(NAME);
     906        rc = loc_server_register(NAME);
    762907        if (rc != EOK) {
    763908                printf("%s: Unable to register server\n", NAME);
  • uspace/srv/hid/output/Makefile

    r0d9b4a8 rbfa4ffa  
    3030USPACE_PREFIX = ../../..
    3131BINARY = output
     32LIBS = $(LIBDRV_PREFIX)/libdrv.a
     33EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
    3234
    3335SOURCES = \
     
    3739        port/niagara.c \
    3840        port/ski.c \
     41        port/chardev.c \
    3942        proto/vt100.c \
    4043        output.c
  • uspace/srv/hid/output/output.c

    r0d9b4a8 rbfa4ffa  
    3434#include <task.h>
    3535#include <ipc/output.h>
     36#include <config.h>
    3637#include "port/ega.h"
    3738#include "port/kchar.h"
    3839#include "port/niagara.h"
    3940#include "port/ski.h"
     41#include "port/chardev.h"
    4042#include "output.h"
    4143
     
    401403               
    402404                switch (IPC_GET_IMETHOD(call)) {
    403                         case OUTPUT_YIELD:
    404                                 srv_yield(callid, &call);
    405                                 break;
    406                         case OUTPUT_CLAIM:
    407                                 srv_claim(callid, &call);
    408                                 break;
    409                         case OUTPUT_GET_DIMENSIONS:
    410                                 srv_get_dimensions(callid, &call);
    411                                 break;
    412                         case OUTPUT_GET_CAPS:
    413                                 srv_get_caps(callid, &call);
    414                                 break;
    415                        
    416                         case OUTPUT_FRONTBUF_CREATE:
    417                                 srv_frontbuf_create(callid, &call);
    418                                 break;
    419                         case OUTPUT_FRONTBUF_DESTROY:
    420                                 srv_frontbuf_destroy(callid, &call);
    421                                 break;
    422                        
    423                         case OUTPUT_CURSOR_UPDATE:
    424                                 srv_cursor_update(callid, &call);
    425                                 break;
    426                         case OUTPUT_SET_STYLE:
    427                                 srv_set_style(callid, &call);
    428                                 break;
    429                         case OUTPUT_SET_COLOR:
    430                                 srv_set_color(callid, &call);
    431                                 break;
    432                         case OUTPUT_SET_RGB_COLOR:
    433                                 srv_set_rgb_color(callid, &call);
    434                                 break;
    435                         case OUTPUT_UPDATE:
    436                                 srv_update(callid, &call);
    437                                 break;
    438                         case OUTPUT_DAMAGE:
    439                                 srv_damage(callid, &call);
    440                                 break;
    441                        
    442                         default:
    443                                 async_answer_0(callid, EINVAL);
     405                case OUTPUT_YIELD:
     406                        srv_yield(callid, &call);
     407                        break;
     408                case OUTPUT_CLAIM:
     409                        srv_claim(callid, &call);
     410                        break;
     411                case OUTPUT_GET_DIMENSIONS:
     412                        srv_get_dimensions(callid, &call);
     413                        break;
     414                case OUTPUT_GET_CAPS:
     415                        srv_get_caps(callid, &call);
     416                        break;
     417               
     418                case OUTPUT_FRONTBUF_CREATE:
     419                        srv_frontbuf_create(callid, &call);
     420                        break;
     421                case OUTPUT_FRONTBUF_DESTROY:
     422                        srv_frontbuf_destroy(callid, &call);
     423                        break;
     424                       
     425                case OUTPUT_CURSOR_UPDATE:
     426                        srv_cursor_update(callid, &call);
     427                        break;
     428                case OUTPUT_SET_STYLE:
     429                        srv_set_style(callid, &call);
     430                        break;
     431                case OUTPUT_SET_COLOR:
     432                        srv_set_color(callid, &call);
     433                        break;
     434                case OUTPUT_SET_RGB_COLOR:
     435                        srv_set_rgb_color(callid, &call);
     436                        break;
     437                case OUTPUT_UPDATE:
     438                        srv_update(callid, &call);
     439                        break;
     440                case OUTPUT_DAMAGE:
     441                        srv_damage(callid, &call);
     442                        break;
     443                       
     444                default:
     445                        async_answer_0(callid, EINVAL);
    444446                }
    445447        }
     
    475477        }
    476478       
    477         ega_init();
    478         kchar_init();
    479         niagara_init();
    480         ski_init();
     479        if (!config_key_exists("console")) {
     480                ega_init();
     481                kchar_init();
     482                niagara_init();
     483                ski_init();
     484        } else {
     485                chardev_init();
     486        }
    481487       
    482488        printf("%s: Accepting connections\n", NAME);
  • uspace/srv/hid/output/proto/vt100.c

    r0d9b4a8 rbfa4ffa  
    141141    vt100_putchar_t putchar_fn, vt100_control_puts_t control_puts_fn)
    142142{
    143         vt100_state_t *state =
    144             malloc(sizeof(vt100_state_t));
     143        vt100_state_t *state = malloc(sizeof(vt100_state_t));
    145144        if (state == NULL)
    146145                return NULL;
     
    164163        state->control_puts("\033[2J");
    165164        state->control_puts("\033[?25l");
    166        
     165
    167166        return state;
    168167}
  • uspace/srv/hw/irc/obio/obio.c

    r0d9b4a8 rbfa4ffa  
    4545#include <ipc/irc.h>
    4646#include <ns.h>
    47 #include <sysinfo.h>
    4847#include <as.h>
    4948#include <ddi.h>
     
    9493                switch (IPC_GET_IMETHOD(call)) {
    9594                case IRC_ENABLE_INTERRUPT:
    96                         /* Noop */
     95                        inr = IPC_GET_ARG1(call);
     96                        base_virt[OBIO_IMR(inr & INO_MASK)] |= (1UL << 31);
    9797                        async_answer_0(callid, EOK);
    9898                        break;
     
    111111/** Initialize the OBIO driver.
    112112 *
    113  * So far, the driver heavily depends on information provided by the kernel via
    114  * sysinfo. In the future, there should be a standalone OBIO driver.
     113 * In the future, the OBIO driver should be integrated with the sun4u platform driver.
    115114 */
    116115static bool obio_init(void)
    117116{
    118         sysarg_t paddr;
    119        
    120         if (sysinfo_get_value("obio.base.physical", &paddr) != EOK) {
    121                 printf("%s: No OBIO registers found\n", NAME);
    122                 return false;
    123         }
    124        
    125         base_phys = (uintptr_t) paddr;
     117        base_phys = (uintptr_t) 0x1fe00000000ULL;
    126118       
    127119        int flags = AS_AREA_READ | AS_AREA_WRITE;
     
    135127        }
    136128       
    137         printf("%s: OBIO registers with base at %zu\n", NAME, base_phys);
     129        printf("%s: OBIO registers with base at %lx\n", NAME, base_phys);
    138130       
    139131        async_set_fallback_port_handler(obio_connection, NULL);
Note: See TracChangeset for help on using the changeset viewer.