1/** 2 * \file 3 * \brief Serial port driver. 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2010, 2011, 2012, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, CAB F.78, Universitaetstrasse 6, CH-8092 Zurich, 13 * Attn: Systems Group. 14 */ 15 16#include <barrelfish/barrelfish.h> 17#include <barrelfish/inthandler.h> 18#include <int_route/int_route_client.h> 19#include <driverkit/driverkit.h> 20#include "serial.h" 21#include "serial_debug.h" 22#include <pci/pci.h> 23 24struct serial_kernel { 25 struct serial_common m; 26}; 27 28static void 29serial_interrupt(void *arg) { 30 struct serial_kernel * sk = arg; 31 char c; 32 errval_t err = sys_getchar(&c); 33 assert(err_is_ok(err)); 34 serial_input(&sk->m, &c, 1); 35} 36 37static void 38serial_write(void *m, const char *c, size_t len) 39{ 40 sys_print(c, len); 41} 42 43static errval_t 44serial_kernel_init(struct serial_kernel *sk, struct capref irq_src) 45{ 46 errval_t err; 47 48 sk->m.output = serial_write; 49 sk->m.output_arg = sk; 50 51 // Register interrupt handler 52 if (!capref_is_null(irq_src)) { 53 err = int_route_client_route_and_connect(irq_src, 0, get_default_waitset(), 54 serial_interrupt, sk); 55 if (err_is_fail(err)) { 56 USER_PANIC_ERR(err, "interrupt setup failed."); 57 } 58 } 59 60 // offer service now we're up 61 start_service(&sk->m); 62 return SYS_ERR_OK; 63} 64 65static errval_t 66init_kernel(struct bfdriver_instance* bfi, uint64_t flags, iref_t *dev) 67{ 68 errval_t err; 69 struct serial_kernel *sk = malloc(sizeof(struct serial_kernel)); 70 init_serial_common(&sk->m); 71 72 bfi->dstate = sk; 73 74 struct capref irq_src; 75 irq_src.cnode = bfi->argcn; 76 irq_src.slot = PCIARG_SLOT_INT; 77 if (flags == 1) { 78 irq_src = NULL_CAP; 79 } else { 80 irq_src.cnode = bfi->argcn; 81 irq_src.slot = PCIARG_SLOT_INT; 82 } 83 84 // Initialize serial driver 85 err = serial_kernel_init(sk, irq_src); 86 if (err_is_fail(err)) { 87 DEBUG_ERR(err, "serial_init"); 88 return err; 89 } 90 91 SERIAL_DEBUG("Kernel Serial driver initialized.\n"); 92 93 return SYS_ERR_OK; 94} 95 96static errval_t attach(struct bfdriver_instance* bfi) { 97 return SYS_ERR_OK; 98} 99 100static errval_t detach(struct bfdriver_instance* bfi) { 101 return SYS_ERR_OK; 102} 103 104static errval_t set_sleep_level(struct bfdriver_instance* bfi, uint32_t level) { 105 return SYS_ERR_OK; 106} 107 108static errval_t destroy(struct bfdriver_instance* bfi) { 109 struct serial_common * m = bfi->dstate; 110 free(m); 111 bfi->dstate = NULL; 112 // XXX: Tear-down the service 113 bfi->device = 0x0; 114 return SYS_ERR_OK; 115} 116 117static errval_t get_ep(struct bfdriver_instance* bfi, bool lmp, struct capref* ret_cap) 118{ 119 USER_PANIC("NIY \n"); 120 return SYS_ERR_OK; 121} 122 123DEFINE_MODULE(serial_kernel, init_kernel, attach, detach, set_sleep_level, destroy, get_ep); 124 125