// 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 ... }
void __init __setup_vga(void) { #ifdef CONFIG_IGUANA char* vga_obj; envitem_t *ig_ref; if ((ig_ref = (envitem_t *)iguana_getenv("vga")) == NULL) L4_KDB_Enter("didn't find the iguana ref to vga"); if ((vga_obj = env_memsection_base(ig_ref)) == NULL) L4_KDB_Enter("vga_obj returned is 0"); VGA_offset = (unsigned long)vga_obj - video_ram_resource.start; request_resource(&iomem_resource, &video_ram_resource); #endif }
// 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; }
int okl4_open(const char *path, int oflag, ...) { struct fdesc *f; int fd, r; int socket_vector[2]; const envitem_t *the_file; memsection_ref_t file_memsec; struct regfile *new_file; /* * check that the file exists */ if (path == NULL) { errno = ENOENT; return -1; } if (strcmp(path, "intervm_test") == 0) { r = okl4_socketpair(0, SOCK_STREAM, 0, socket_vector, 1); if (r < 0) { return r; } return socket_vector[0]; } if (strcmp(path, "serial") == 0) { #ifdef __USE_POSIX fd = 3; while (ftable[fd].refcount > 0) { fd++; } if (fd >= MAX_FILES) { errno = ENFILE; return -1; } f = &(ftable[fd]); f->ftype = SERIAL; f->refcount++; f->U.s.serial = fopen("serial", "rw"); if (f->U.s.serial == NULL) { f->refcount--; return -1; } return fd; #else errno = ENXIO; return -1; #endif } if (strcmp(path, "test_file") != 0 && strcmp(path, "test_file_2") != 0) { /* * check that the flags are ok */ if ((oflag & O_WRONLY) == O_WRONLY || (oflag & O_CREAT) == O_CREAT || (oflag & O_TRUNC) == O_TRUNC) { errno = EROFS; return -1; } the_file = iguana_getenv(path); if (the_file == NULL) { errno = ENOENT; return -1; } if (env_type(the_file) != ENV_MEMSECTION) { errno = EINVAL; return -1; } file_memsec = env_memsection(the_file); new_file = env_memsection_base(the_file); } else if (strcmp(path, "test_file") == 0) { new_file = &test_file; } else { new_file = &test_file_2; } /* * allocate a new file descriptor */ fd = 3; while (ftable[fd].refcount > 0) { fd++; } if (fd >= MAX_FILES) { errno = ENFILE; return -1; } f = &(ftable[fd]); f->size = strtol(new_file->file_size, (char **)NULL, 10); f->U.r.base = (uintptr_t)&(new_file->data); f->ftype = REGULAR; f->flags = oflag; f->refcount++; f->U.r.offset = 0; return fd; }