// FIXME: Pass a list of 'resources' rather than a single address+irq number, which may // not always be sufficient. static void scan_devices(void) { CORBA_Environment env; L4_ThreadId_t me = L4_Myself(); thread_ref_t server_; cap_t device; /* timer device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VTIMER_SERVER")), &server_); timer_server = thread_l4tid(server_); device_add_resource(timer_server, 0x40a00000,0, MEMORY_RESOURCE, &env); device_add_resource(timer_server, 27,0, INTERRUPT_RESOURCE, &env); device_add_resource(timer_server, 28,0, INTERRUPT_RESOURCE, &env); device = device_create(timer_server, &me, TIMER, &env); timer_device = device.ref.obj; /* rtc device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VRTC_SERVER")), &server_); rtc_server = thread_l4tid(server_); device_add_resource(rtc_server, RTC_PHYS, 0, MEMORY_RESOURCE, &env); device_add_resource(rtc_server, INT_RTC, 0, INTERRUPT_RESOURCE, &env); device = device_create(rtc_server, &me, RTC, &env); rtc_device = device.ref.obj; /* serial device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VSERIAL_SERVER")), &server_); serial_server = thread_l4tid(server_); device_add_resource(serial_server, 0x40100000,0, MEMORY_RESOURCE, &env); device_add_resource(serial_server, 22,0, INTERRUPT_RESOURCE, &env); device = device_create(serial_server, &me, UART1, &env); serial_device = device.ref.obj; #if 0 /* serial device */ memsection_lookup(iguana_getenv(IGUANA_GETENV_VBUS_SERVER), &server_); bus_server = thread_l4tid(server_); device_add_resource(bus_server, 101,0, INTERRUPT_RESOURCE, &env); device = device_create(bus_server, &me, BUS, &env); bus_device = device.ref.obj; DEBUG_TRACE(2, "looking for LCD device\n"); cap_t virtual_bus = virtual_bus_factory_create(bus_server, bus_device, &lcd_server, 0, NULL); /* LCD device */ memsection_lookup(iguana_getenv(IGUANA_GETENV_VLCD_SERVER), &server_); lcd_server = thread_l4tid(server_); device_add_resource(lcd_server, bus_server.raw, virtual_bus.ref.obj, BUS_RESOURCE, &env); device_add_resource(lcd_server, bus_server.raw, virtual_bus.ref.obj, BUS_RESOURCE, &env); device_add_resource(lcd_server, 101,0, INTERRUPT_RESOURCE, &env); device = device_create(lcd_server, &me, LCD, &env); lcd_device = device.ref.obj; #endif // And any other devices you care to add ... }
int _session_create(objref_t object, clist_ref_t clist, L4_ThreadId_t *server_tid, struct session *session) { cap_t cap; thread_ref_t server; memsection_ref_t memsection; if (object == 0 || object == INVALID_ADDR) { return -1; } /* Find memsection */ memsection = memsection_lookup(object, &server); if (memsection == 0 || memsection == INVALID_ADDR) { return -1; } /* TODO: Search for existing session with that server */ cap = iguana_pd_create_session(IGUANA_PAGER, pd_myself(), thread_myself(), server, clist, default_clist, NULL); if (cap.ref.session == 0) { return -1; } *server_tid = thread_l4tid(server); session->ref = cap.ref.session; session->clist = clist; session->own_clist = 0; return 0; }
objref_t device_create_impl(CORBA_Object _caller, objref_t driver, idl4_server_environment * _env) { struct driver_ops *ops; struct timer_service *timer_service; memsection_ref_t memsection; thread_ref_t myself, unused; ops = TIMER_DRIVER.ops.d_ops; /* Let us actually allocate the backed memory.. */ global_timer_service = timer_service = malloc(sizeof(struct timer_service)); #ifdef ENABLE_PM_THREAD thread_start(pm_thread, (uintptr_t)power_management_thread, (uintptr_t)&pm_stack[1000 - 1]); #endif if (timer_service == NULL) { return 0; } timer_service->active = timer_service->active_end = NULL; timer_service->inactive = NULL; global_device = timer_service->device = ops->setup(0, NULL, NULL, NULL); if (timer_service->device == NULL) { free(timer_service); return 0; } driver_enable(timer_service->device); memsection = memsection_lookup((objref_t)timer_service, &unused); myself = thread_id(main_tid); memsection_register_server(memsection, myself); return (objref_t)timer_service; }
// FIXME: Pass a list of 'resources' rather than a single address+irq number, which may // not always be sufficient. static void scan_devices(void) { CORBA_Environment env; L4_ThreadId_t me = L4_Myself(); thread_ref_t server_; cap_t device; /* timer device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VTIMER_SERVER")), &server_); timer_server = thread_l4tid(server_); device_add_resource(timer_server, TIMER2_PHYS, 0, MEMORY_RESOURCE, &env); /* XXX only use timer2 */ device_add_resource(timer_server, INT_TIMER2, 0, INTERRUPT_RESOURCE, &env); device = device_create(timer_server, &me, TIMER, &env); timer_device = device.ref.obj; #if 0 // andy - 4 /* rtc device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VRTC_SERVER")), &server_); rtc_server = thread_l4tid(server_); device_add_resource(rtc_server, RTC_PHYS, 0, MEMORY_RESOURCE, &env); device_add_resource(rtc_server, INT_RTC, 0, INTERRUPT_RESOURCE, &env); device = device_create(rtc_server, &me, RTC, &env); rtc_device = device.ref.obj; #endif // andy - 4 /* This is an example of how to setup a software rtc. */ #if 0 memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VRTC_SERVER")), &server_); rtc_server = thread_l4tid(server_); /* Create virtual timer and pass to rtc_device as a resource.*/ cap_t virtual_timer = virtual_timer_factory_create(timer_server, timer_device, &rtc_server, 0x3, NULL); device_add_resource(rtc_server, timer_server.raw, virtual_timer.ref.obj, TIMER_RESOURCE, &env); device = device_create(rtc_server, &me, RTC, &env); rtc_device = device.ref.obj; #endif /* serial device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VSERIAL_SERVER")), &server_); serial_server = thread_l4tid(server_); device_add_resource(serial_server, UART1_PHYS, 0, MEMORY_RESOURCE, &env); device_add_resource(serial_server, INT_UART1, 0, INTERRUPT_RESOURCE, &env); device = device_create(serial_server, &me, UART, &env); serial_device = device.ref.obj; #if 0 // andy - 5 /* touchscreen device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VTOUCH_SERVER")), &server_); ts_server = thread_l4tid(server_); device_add_resource(ts_server, TS_PHYS, 0, MEMORY_RESOURCE, &env); device_add_resource(ts_server, INT_TC, 0, INTERRUPT_RESOURCE, &env); device_add_resource(ts_server, INT_ADC, 0, INTERRUPT_RESOURCE, &env); device = device_create(ts_server, &me, VTOUCH, &env); ts_device = device.ref.obj; /* spi device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VBUS_SERVER")), &server_); spi_server = thread_l4tid(server_); device_add_resource(spi_server, SPI_PHYS, 0, MEMORY_RESOURCE, &env); device_add_resource(spi_server, INT_SPI1, 0, INTERRUPT_RESOURCE, &env); device = device_create(spi_server, &me, SPI1, &env); spi_device = device.ref.obj; /* nand device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VMTD_SERVER")), &server_); mtd_server = thread_l4tid(server_); device_add_resource(mtd_server, MTD_PHYS, 0, MEMORY_RESOURCE, &env); device = device_create(mtd_server, &me, NAND, &env); mtd_device = device.ref.obj; /* get a bus handle to provide to the lcd driver */ cap_t virtual_spi = virtual_bus_factory_create(spi_server, spi_device, &lcd_server, 0, NULL); #endif // andy - 5 /* lcd device */ // TEMP: REMOVED (jmatthews): causes NPE /* memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VLCD_SERVER")), */ /* &server_); */ /* lcd_server = thread_l4tid(server_); */ /* device_add_resource(lcd_server, LCD_PHYS, 0, MEMORY_RESOURCE, &env); */ /* //device_add_resource(lcd_server, spi_server.raw, virtual_spi.ref.obj, BUS_RESOURCE, &env); */ /* device_add_resource(lcd_server, spi_server.raw, 0, BUS_RESOURCE, &env); */ /* device_add_resource(lcd_server, INT_LCD, 0, INTERRUPT_RESOURCE, &env); */ /* device = device_create(lcd_server, &me, LCD, &env); */ /* lcd_device = device.ref.obj; */ // And any other devices you care to add ... return; }
static int __init ig_input_init(void) { /* Called when we are initialising the device */ void *buffer_area, *control_area, *input_dev; thread_ref_t server_; L4_ThreadId_t server; thread_ref_t dummy; CORBA_Environment env; memsection_ref_t memsect; uintptr_t base; int i, irq; /* Allocate space for the input structure */ ig_input = kmalloc(sizeof(*ig_input), GFP_KERNEL); input_dev = kmalloc(sizeof(struct input_dev), GFP_KERNEL); buffer_area = kmalloc(BUFFER_SIZE, GFP_KERNEL); control_area = kmalloc(sizeof(struct control_block), GFP_KERNEL); if (!ig_input || !buffer_area || !control_area || !input_dev) { kfree(ig_input); kfree(buffer_area); kfree(control_area); kfree(input_dev); return -ENOMEM; } memset(ig_input, 0, sizeof(*ig_input)); memset(input_dev, 0, sizeof(struct input_dev)); memset(buffer_area, 0, BUFFER_SIZE); memset(control_area, 0, sizeof(struct control_block)); irq = iguana_alloc_irq(); printk("IG_KPP got IRQ %d\n", irq); /* First, we find the input device */ memsection_lookup(env_memsection_base(iguana_getenv("OKL4_CORE_DEVICE_SERVER")), &server_); server = thread_l4tid(server_); ig_input->dev = device_core_get_kpp(server, &ig_input->server, &timer_thread, IGUANA_IRQ_NOTIFY_MASK(irq), &env); /* Now, we add the kernel memory section to the server */ memsect = memsection_lookup((objref_t) buffer_area, &dummy); ig_input->memsect_base = base = (uintptr_t) memsection_base(memsect); virtual_kpp_add_memsection(ig_input->server, ig_input->dev, memsect, 0, &env); /* Initialise the control block */ ig_input->control = control_area; ig_input->control->rx = ~0; ig_input->rx_last = NULL; ig_input->free_list = buffer_area; for (i=0; i < BUFFER_SIZE / sizeof(struct stream_packet); i++) { ig_input->free_list[i].next = (uintptr_t) &ig_input->free_list[i+1]; ig_input->free_list[i].data_ptr = &ig_input->free_list[i].data; //vaddr_to_memsect(ig_input, &ig_input->free_list[i].data); } ig_input->free_list[i-1].next = 0; for (i = 0; i < BUFFER_SIZE / sizeof(struct stream_packet); i++) { struct stream_packet *packet; int new_q = 0; packet = ig_input->free_list; if (packet == NULL) { panic("Iguana input driver corrupted\n"); } ig_input->free_list = (void*) packet->next; packet->next = ~0; packet->size = PACKET_SIZE; packet->xferred = 0; packet->status = 0; if (ig_input->rx_last != NULL) { ig_input->rx_last->next = vaddr_to_memsect(ig_input, packet); if (ig_input->rx_last->status & TERMINATED) { new_q = 1; } } else { new_q = 1; } if (new_q) { ig_input->control->rx = vaddr_to_memsect(ig_input, packet); } ig_input->rx_last = packet; } /* Register the control block with the server */ virtual_kpp_register_control_block(ig_input->server, ig_input->dev, vaddr_to_memsect(ig_input, ig_input->control), &env); ig_input->input_dev = input_dev; ig_input->input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); set_bit(KEY_0, ig_input->input_dev->keybit); set_bit(KEY_1, ig_input->input_dev->keybit); set_bit(KEY_2, ig_input->input_dev->keybit); set_bit(KEY_3, ig_input->input_dev->keybit); set_bit(KEY_4, ig_input->input_dev->keybit); set_bit(KEY_5, ig_input->input_dev->keybit); set_bit(KEY_6, ig_input->input_dev->keybit); set_bit(KEY_7, ig_input->input_dev->keybit); set_bit(KEY_8, ig_input->input_dev->keybit); set_bit(KEY_9, ig_input->input_dev->keybit); set_bit(KEY_KPASTERISK, ig_input->input_dev->keybit); set_bit(KEY_CHAT, ig_input->input_dev->keybit); set_bit(KEY_F17, ig_input->input_dev->keybit); set_bit(KEY_F18, ig_input->input_dev->keybit); set_bit(KEY_F19, ig_input->input_dev->keybit); set_bit(KEY_F20, ig_input->input_dev->keybit); set_bit(KEY_F21, ig_input->input_dev->keybit); set_bit(KEY_END, ig_input->input_dev->keybit); set_bit(/*KEY_F22*/KEY_ENTER, ig_input->input_dev->keybit); set_bit(KEY_F23, ig_input->input_dev->keybit); set_bit(KEY_BACK, ig_input->input_dev->keybit); set_bit(KEY_UP, ig_input->input_dev->keybit); set_bit(KEY_DOWN, ig_input->input_dev->keybit); set_bit(KEY_LEFT, ig_input->input_dev->keybit); set_bit(KEY_RIGHT, ig_input->input_dev->keybit); set_bit(BTN_LEFT, ig_input->input_dev->keybit); set_bit(BTN_RIGHT, ig_input->input_dev->keybit); set_bit(REL_X, ig_input->input_dev->relbit); set_bit(REL_Y, ig_input->input_dev->relbit); //set_bit(KEY_CONNECT, ig_input->input_dev->keybit); //set_bit(KEY_FINANCE, ig_input->input_dev->keybit); set_bit(/*KEY_F13*/KEY_F1, ig_input->input_dev->keybit); set_bit(/*KEY_F14*/KEY_F2, ig_input->input_dev->keybit); set_bit(/*KEY_F15*/KEY_F3, ig_input->input_dev->keybit); set_bit(/*KEY_F16*/KEY_F4, ig_input->input_dev->keybit); set_bit(KEY_HOME, ig_input->input_dev->keybit); set_bit(KEY_POWER, ig_input->input_dev->keybit); set_bit(KEY_VOLUMEDOWN, ig_input->input_dev->keybit); set_bit(KEY_VOLUMEUP, ig_input->input_dev->keybit); set_bit(KEY_RECORD, ig_input->input_dev->keybit); ig_input->input_dev->name = "Iguana virtual input device"; request_irq(irq, ig_input_interrupt, 0, ig_input->input_dev->name, ig_input->input_dev); input_register_device(ig_input->input_dev); return 0; }
pd_ref_t create_pd(void) { memsection_ref_t data_ms; pd_ref_t pd; int r; memsection_ref_t rodata_ms; memsection_ref_t text_ms; memsection_ref_t heap_ms; pd = pd_create(); if (pd == 0 || pd == -1) { printf("Failed to create PD.\n"); return -1; } /* * Attach the text, data and heap memsection to the new PD so that * code can run. */ text_ms = memsection_lookup((uintptr_t)&text, NULL); if (text_ms == 0 || text_ms == -1) { printf("Failed to find text section.\n"); return -1; } r = pd_attach(pd, text_ms, L4_ReadeXecOnly); if (r != 0) { printf("Failed to attach text section.\n"); return -1; } rodata_ms = memsection_lookup((uintptr_t)&rodata, NULL); if (rodata_ms == 0 || rodata_ms == -1) { printf("Failed to find rodata section.\n"); return -1; } /* * XXX: Temporary hack on hack... rodata shares the same segment as text * (see linker.lds) due to "problematic toolchains". Thus when this gets * mapped, we lose executable permission on the text segment. So we don't * do it if it's the same segment. * * See AdamC. */ if (text_ms != rodata_ms) { r = pd_attach(pd, rodata_ms, L4_Readable); if (r != 0) { printf("Failed to attach rodata section.\n"); return -1; } } data_ms = memsection_lookup((uintptr_t)&data, NULL); if (data_ms == 0 || data_ms == -1) { printf("Failed to find data section.\n"); return -1; } r = pd_attach(pd, data_ms, L4_ReadWriteOnly); if (r != 0) { printf("Failed to attach data section.\n"); return -1; } if (heap == NULL) { heap = malloc(1); } heap_ms = memsection_lookup((uintptr_t)heap, NULL); if (heap_ms == 0 || heap_ms == -1) { printf("Failed to find heap section.\n"); return -1; } r = pd_attach(pd, heap_ms, L4_ReadWriteOnly); if (r != 0) { printf("Failed to attach heap section.\n"); return -1; } return pd; }