static int l4x_rtc_platform_remove(struct platform_device *pdev) { rtc_device_unregister(rtc_dev); free_irq(irq, NULL); l4x_unregister_irq(irq); L4XV_FN_v(l4_task_delete_obj(L4RE_THIS_TASK_CAP, irq_cap)); l4x_cap_free(irq_cap); return 0; }
static void l4ser_shm_rx_chars(struct uart_port *port) { struct l4ser_shm_uart_port *l4port = (struct l4ser_shm_uart_port *)port; struct tty_struct *tty = port->state->port.tty; struct chunk_head *chhead; struct ring_chunk_head *rph; unsigned long offs; chhead = (struct chunk_head *)l4shmc_chunk_ptr(&l4port->rx_chunk); offs = chhead->next_offs_to_read; while (1) { unsigned long l; rph = (struct ring_chunk_head *)(l4port->rx_ring_start + offs); if (!rph->size) break; offs += sizeof(struct ring_chunk_head); offs %= l4port->rx_ring_size; if (offs + rph->size > l4port->rx_ring_size) l = l4port->rx_ring_size - offs; else l = rph->size; port->icount.rx += rph->size; tty_insert_flip_string(tty, (const unsigned char *)l4port->rx_ring_start + offs, l); if (l != rph->size) tty_insert_flip_string(tty, (const unsigned char *)l4port->rx_ring_start, rph->size - l); offs = (offs + rph->size + sizeof(struct ring_chunk_head) - 1) & ~(sizeof(struct ring_chunk_head) - 1); offs %= l4port->rx_ring_size; chhead->next_offs_to_read = offs; rph->size = 0; } tty_flip_buffer_push(tty); if (chhead->writer_blocked) L4XV_FN_v(l4shmc_trigger(&l4port->tx_sig)); chhead = (struct chunk_head *)l4shmc_chunk_ptr(&l4port->tx_chunk); chhead->writer_blocked = 0; return; }
static void l4ser_shm_tx_chars(struct uart_port *port) { struct l4ser_shm_uart_port *l4port = (struct l4ser_shm_uart_port *)port; struct circ_buf *xmit = &port->state->xmit; int c, do_trigger = 0; struct tty_struct *tty = port->state->port.tty; tty->hw_stopped = 0; tty->stopped = 0; if (port->x_char) { if (tx_buf(port, &port->x_char, 1)) { port->icount.tx++; port->x_char = 0; L4XV_FN_v(l4shmc_trigger(&l4port->tx_sig)); } return; } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { return; } while (!uart_circ_empty(xmit)) { unsigned long r; c = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); if (!(r = tx_buf(port, &xmit->buf[xmit->tail], c))) break; xmit->tail = (xmit->tail + r) & (UART_XMIT_SIZE - 1); port->icount.tx += r; do_trigger = 1; } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (do_trigger) L4XV_FN_v(l4shmc_trigger(&l4port->tx_sig)); }
unsigned long l4x_set_pte(struct mm_struct *mm, unsigned long addr, pte_t old, pte_t pteval) { /* * Check if any invalidation is necessary * * Invalidation (flush) necessary if: * old page was present * new page is not present OR * new page has another physical address OR * new page has another protection OR * new page has other access attributes */ /* old was present && new not -> flush */ int flush_rights = L4_FPAGE_RWX; #if 0 if ((pte_val(old) & PAGE_MASK) != (pte_val(pteval) & PAGE_MASK)) printk("spte %x->%x\n", pte_val(old), pte_val(pteval)); #endif if (pte_present(pteval)) { /* new page is present, * now we have to find out what has changed */ if (((pte_val(old) ^ pte_val(pteval)) & PAGE_MASK) || (pte_young(old) && !pte_young(pteval))) { /* physical page frame changed * || access attribute changed -> flush */ /* flush is the default */ //pteval.pte_low &= ~_PAGE_MAPPED; pteval = __pte(pte_val(pteval) & ~_PAGE_MAPPED); } else if ((pte_write(old) && !pte_write(pteval)) || (pte_dirty(old) && !pte_dirty(pteval))) { /* Protection changed from r/w to ro * or page now clean -> remap */ flush_rights = L4_FPAGE_W; check_pte_mapped(old, pteval, "RW->RO"); } else { /* nothing changed, simply return */ check_pte_mapped(old, pteval, "NoChg"); return pte_val(pteval); } } /* Ok, now actually flush or remap the page */ L4XV_FN_v(l4x_flush_page(mm, pte_val(old), addr, PAGE_SHIFT, flush_rights)); return pte_val(pteval); }
void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val) { L4XV_FN_v(l4vbus_pci_cfg_write(vbus, root_bridge, bus, (slot << 16) | func, offset, val, 32)); }
static int l4x_rtc_platform_probe(struct platform_device *pdev) { int r; if (l4x_re_resolve_name("rtc", &rtc_server)) { pr_err("l4x-rtc: Could not find 'rtc' cap.\n"); return -ENOENT; } irq_cap = l4x_cap_alloc(); if (l4_is_invalid_cap(irq_cap)) { pr_err("l4x-rtc: Could not allocate irq cap.\n"); return -ENOMEM; } if (L4XV_FN_e(l4_factory_create_irq(l4re_env()->factory, irq_cap))) { pr_err("l4x-rtc: Could not create user irq.\n"); r = -ENOMEM; goto free_cap; } if (L4XV_FN_e(l4_icu_bind(rtc_server, 0, irq_cap))) { pr_err("l4x-rtc: Error registering for time updates.\n"); r = -ENOSYS; goto free_irq_cap; } irq = l4x_register_irq(irq_cap); if (irq < 0) { pr_err("l4x-rtc: Error registering IRQ with L4Linux.\n"); r = irq; goto free_irq_cap; } r = request_irq(irq, l4x_rtc_int, IRQF_TRIGGER_RISING, "l4x_rtc", NULL); if (r) { pr_err("l4x-rtc: Could not register IRQ.\n"); goto unregister_irq; } if (l4x_rtc_update_offset()) { pr_err("l4x-rtc: Could not get the time offset to real time.\n"); r = -ENOSYS; goto free_irq; } rtc_dev = rtc_device_register(driver_name, &(pdev->dev), &l4x_rtc_ops, THIS_MODULE); if (IS_ERR(rtc_dev)) { pr_err("l4x-rtc: Could not register as rtc device.\n"); r = PTR_ERR(rtc_dev); goto free_irq; } INIT_WORK(&w_update_time, l4x_rtc_update_time); return 0; free_irq: free_irq(irq, NULL); unregister_irq: l4x_unregister_irq(irq); free_irq_cap: L4XV_FN_v(l4_task_release_cap(L4RE_THIS_TASK_CAP, irq_cap)); free_cap: l4x_cap_free(irq_cap); return r; }
static int __init l4x_timer_init_ret(void) { int r; l4lx_thread_t thread; int irq; L4XV_V(f); timer_irq_cap = l4x_cap_alloc(); if (l4_is_invalid_cap(timer_irq_cap)) { printk(KERN_ERR "l4timer: Failed to alloc\n"); return -ENOMEM; } r = L4XV_FN_i(l4_error(l4_factory_create_irq(l4re_env()->factory, timer_irq_cap))); if (r) { printk(KERN_ERR "l4timer: Failed to create irq: %d\n", r); goto out1; } if ((irq = l4x_register_irq(timer_irq_cap)) < 0) { r = -ENOMEM; goto out2; } printk("l4timer: Using IRQ%d\n", irq); setup_irq(irq, &l4timer_irq); L4XV_L(f); thread = l4lx_thread_create (timer_thread, /* thread function */ smp_processor_id(), /* cpu */ NULL, /* stack */ &timer_irq_cap, sizeof(timer_irq_cap), /* data */ l4x_cap_alloc(), /* cap */ PRIO_TIMER, /* prio */ 0, /* vcpup */ "timer", /* name */ NULL); L4XV_U(f); timer_srv = l4lx_thread_get_cap(thread); if (!l4lx_thread_is_valid(thread)) { printk(KERN_ERR "l4timer: Failed to create thread\n"); r = -ENOMEM; goto out3; } l4timer_clockevent.irq = irq; l4timer_clockevent.mult = div_sc(1000000, NSEC_PER_SEC, l4timer_clockevent.shift); l4timer_clockevent.max_delta_ns = clockevent_delta2ns(0xffffffff, &l4timer_clockevent); l4timer_clockevent.min_delta_ns = clockevent_delta2ns(0xf, &l4timer_clockevent); l4timer_clockevent.cpumask = cpumask_of(0); clockevents_register_device(&l4timer_clockevent); return 0; out3: l4x_unregister_irq(irq); out2: L4XV_FN_v(l4_task_delete_obj(L4RE_THIS_TASK_CAP, timer_irq_cap)); out1: l4x_cap_free(timer_irq_cap); return r; }
void l4x_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t pteval) { /* Invalidate page */ L4XV_FN_v(l4x_flush_page(mm, pte_val(pteval), addr, PAGE_SHIFT, L4_FPAGE_RWX)); }