static int vopen( video_desc_t *vm ) { struct fb_var_screeninfo var; struct fb_fix_screeninfo fix; if( cv->is_open || !cv->has_console ) return 1; /* Put console in graphics mode and open display */ console_set_gfx_mode(1); var = *(struct fb_var_screeninfo*)vm->module_data; var.activate = FB_ACTIVATE_NOW; if( ioctl(cv->fd, FBIOPUT_VSCREENINFO, &var) < 0 ) { perrorm("Could not set VSCREENINFO\n"); goto bail; } /* is this panning necessary? */ var.xoffset = 0; var.yoffset = 0; ioctl(cv->fd, FBIOPAN_DISPLAY, &var); if( ioctl(cv->fd, FBIOGET_FSCREENINFO, &fix) < 0) { perrorm("Could not get FSCREENINFO!\n"); goto bail; } if( vm->offs != ((ulong)fix.smem_start & 0xfff) ) { printm("Framebuffer offset has changed!\n"); goto bail; } if( vm->rowbytes != fix.line_length ) { printm("Rowbytes has changed (was %d, now %d)!\n", vm->rowbytes, fix.line_length); goto bail; } /* runtime fields */ vm->map_base = (ulong)fix.smem_start & ~0xfff; vm->lvbase = map_phys_mem( NULL, vm->map_base, FBBUF_SIZE(vm), PROT_READ | PROT_WRITE ); vm->mmu_flags = MAPPING_PHYSICAL; if( is_newworld_boot() || is_oldworld_boot() ) vm->mmu_flags |= MAPPING_DBAT; /* Use cache with write through bit set */ vm->mmu_flags |= cv->use_cache? MAPPING_FORCE_CACHE : MAPPING_MACOS_CONTROLS_CACHE; use_hw_cursor(0); /* no hw-cursor for now */ cv->is_open = 1; cv->vmode = *vm; return 0; bail: console_set_gfx_mode(0); return 1; }
static int locate_acpi_pointers(struct acpi_rsdp_info *rsdpinfo) { size_t loc = 0; uint8_t *addr; int rc = -1; /* in case we don't find it */ memset(rsdpinfo, 0, sizeof(struct acpi_rsdp_info)); /* use EFI tables if present */ rc = efi_locate_entry("ACPI20", 6, &loc); if ( (rc == 0) && (loc != 0) ) { addr = map_phys_mem(loc, ACPI_RSDP_LENGTH); if ( addr == NULL ) { fprintf(stderr, "%s: failed to map EFI RSDP at phys="UINT_FMT"\n", ACPI_ERROR, loc); return -1; } rc = process_acpi_rsdp(rsdpinfo, addr); unmap_phys_mem(addr, ACPI_RSDP_LENGTH); return rc; } /* locate ACPI entry via memory scan of ROM region */ addr = map_phys_mem(SCAN_ROM_BIOS_BASE, SCAN_ROM_BIOS_SIZE); if ( addr == NULL ) { fprintf(stderr, "%s: failed to map ROM BIOS at phys=%x\n", ACPI_ERROR, SCAN_ROM_BIOS_BASE); return -1; } for ( loc = 0; loc <= (SCAN_ROM_BIOS_SIZE - ACPI_RSDP_LENGTH); loc += 16 ) /* stop before 0xFFDC */ { /* look for RSD PTR signature */ if ( memcmp(addr + loc, "RSD PTR ", 8 ) == 0) { rc = process_acpi_rsdp(rsdpinfo, addr + loc); if ( rc == 0 ) /* found it */ break; } } unmap_phys_mem(addr, SCAN_ROM_BIOS_SIZE); return rc; }
static int locate_xsdt_acpi_table(struct acpi_rsdp_info *rsdpinfo, const char *signature, struct acpi_table_info *ti) { uint64_t *addr_list; uint32_t length, count, i; int rc = -1; uint8_t *addr; if ( rsdpinfo->xsdt_length <= ACPI_TABLE_LENGTH ) { fprintf(stderr, "%s: invalid XSDT - no table pointers\n", ACPI_ERROR); return -1; /* invalid - no tables?? */ } length = rsdpinfo->xsdt_length - ACPI_HEADER_LENGTH; count = length/sizeof(uint64_t); addr_list = (uint64_t*)(rsdpinfo->xsdt_addr + ACPI_HEADER_LENGTH); for ( i = 0; i < count; i++, addr_list++ ) { addr = map_phys_mem(*addr_list, ACPI_HEADER_LENGTH); if ( addr == NULL ) continue; if ( memcmp(addr, signature, 4) == 0 ) { ti->length = (*(uint32_t*)(addr + ACPI_TABLE_LENGTH)); unmap_phys_mem(addr, ACPI_HEADER_LENGTH); addr = map_phys_mem(*addr_list, ti->length); if ( addr == NULL ) { fprintf(stderr, "%s: failed to map table #%d at phys=%lx\n", ACPI_ERROR, i, (long unsigned int)*addr_list); break; } ti->phys_addr = *addr_list; ti->addr = addr; rc = 0; break; } unmap_phys_mem(addr, ACPI_HEADER_LENGTH); } return rc; }
int vixInit(const char *args) { cyberblade_mem = map_phys_mem(pci_info.base0, 0x800000); enable_app_io(); save_colourkey[0]=SRINB(0x50); save_colourkey[1]=SRINB(0x51); save_colourkey[2]=SRINB(0x52); save_colourkey[3]=SRINB(0x54); save_colourkey[4]=SRINB(0x55); save_colourkey[5]=SRINB(0x56); #ifdef DEBUG_LOGFILE logfile=fopen("/tmp/cyberblade_vidix.log","w"); #endif return 0; }
static int process_acpi_rsdp(struct acpi_rsdp_info *rsdpinfo, uint8_t *rsdp) { #define ADDR_CHECK(a, p) if (a == NULL) { \ fprintf(stderr, "%s: failed to map ACPI table at phys="UINT_FMT"\n", ACPI_ERROR, p); \ rc = -1; break;} uint8_t cs; uint32_t count, length; uint8_t *addr; int rc = 0; do { /* checksum sanity check over the RSDP */ if ( rsdp[ACPI_RSDP_REVISION] < 2 ) { length = ACPI_RSDP_CS_LENGTH; rsdpinfo->is_rev1 = 1; } else length = ACPI_RSDP_XCS_LENGTH; for ( cs = 0, count = 0; count < length; count++ ) cs += rsdp[count]; if ( cs != 0 ) { fprintf(stderr, "%s: invalid RSDP checksum\n", ACPI_ERROR); rc = -1; break; } /* looks like the RSDP, get RSDP table */ rsdpinfo->rsdt_phys_addr = (*(uint32_t*)(rsdp + ACPI_RSDP_RSDT_BASE)); rsdpinfo->rsdt_length = ACPI_HEADER_LENGTH; addr = map_phys_mem(rsdpinfo->rsdt_phys_addr, ACPI_HEADER_LENGTH); ADDR_CHECK(addr, rsdpinfo->rsdt_phys_addr); rsdpinfo->rsdt_addr = addr; /* check the signatures for the RSDT */ if ( memcmp(rsdpinfo->rsdt_addr, "RSDT", 4) != 0 ) { fprintf(stderr, "%s: invalid RSDT signature=%.*s\n", ACPI_ERROR, 4, rsdpinfo->rsdt_addr); rc = -1; break; } /* remap the entire table */ rsdpinfo->rsdt_length = (*(uint32_t*)(rsdpinfo->rsdt_addr + ACPI_TABLE_LENGTH)); unmap_phys_mem(rsdpinfo->rsdt_addr, ACPI_HEADER_LENGTH); rsdpinfo->rsdt_addr = NULL; addr = map_phys_mem(rsdpinfo->rsdt_phys_addr, rsdpinfo->rsdt_length); ADDR_CHECK(addr, rsdpinfo->rsdt_phys_addr); rsdpinfo->rsdt_addr = addr; if ( rsdpinfo->is_rev1 ) break; /* Also have an XSDT */ rsdpinfo->xsdt_phys_addr = (*(uint64_t*)(rsdp + ACPI_RSDP_XSDT_BASE)); rsdpinfo->xsdt_length = ACPI_HEADER_LENGTH; addr = map_phys_mem(rsdpinfo->xsdt_phys_addr, ACPI_HEADER_LENGTH); ADDR_CHECK(addr, rsdpinfo->xsdt_phys_addr); rsdpinfo->xsdt_addr = addr; /* check the signatures for the XSDT */ if ( memcmp(rsdpinfo->xsdt_addr, "XSDT", 4) != 0 ) { fprintf(stderr, "%s: invalid XSDT signature=%.*s\n", ACPI_ERROR, 4, rsdpinfo->xsdt_addr); rc = -1; break; } /* remap the entire table */ rsdpinfo->xsdt_length = (*(uint32_t*)(rsdpinfo->xsdt_addr + ACPI_TABLE_LENGTH)); unmap_phys_mem(rsdpinfo->xsdt_addr, ACPI_HEADER_LENGTH); rsdpinfo->xsdt_addr = NULL; addr = map_phys_mem(rsdpinfo->xsdt_phys_addr, rsdpinfo->xsdt_length); ADDR_CHECK(addr, rsdpinfo->xsdt_phys_addr); rsdpinfo->xsdt_addr = addr; } while (0); #undef ADDR_CHECK if ( rc != 0 ) { if ( rsdpinfo->rsdt_addr != NULL ) unmap_phys_mem(rsdpinfo->rsdt_addr, rsdpinfo->rsdt_length); if ( rsdpinfo->xsdt_addr != NULL ) unmap_phys_mem(rsdpinfo->xsdt_addr, rsdpinfo->xsdt_length); } return rc; }
static void pciproxy_setup_bars(pciproxy_device_t *pdev) { char resfile_name[NAME_MAX], rom_file[NAME_MAX]; int i, romfd; /* init the info in pdev */ memset(pdev->bars, 0, sizeof(pdev->bars)); /* read the resource file in the sysfs dir */ snprintf(resfile_name, NAME_MAX, "%s/resource", pdev->sysfs_path); FILE *resfile = fopen(resfile_name, "r"); if (resfile == NULL) { PPLOG("could not open %s: %s", resfile_name, strerror(errno)); return; } /* read it line by line */ for (i = 0; i < MAX_BARS - 1; i++) { unsigned long long start, end, flags; if (fscanf(resfile, "0x%016Lx 0x%016Lx 0x%016Lx\n", &start, &end, &flags) != 3) continue; /* see if it is for real */ if (start == end) continue; /* ok, record the data */ pdev->bars[i].mmum.size = (size_t) (end - start + 1); pdev->bars[i].mmum.mbase = 0; pdev->bars[i].mmum.flags = 0; pdev->bars[i].flags = flags; #ifdef BAR_ACCESS_USERSPACE /* grab linux physical memory (map it into linux virtual address space) */ pdev->bars[i].lvbase = (unsigned char *)(map_phys_mem(NULL, (ulong) start, pdev->bars[i].mmum.size, PROT_READ | PROT_WRITE)); if (pdev->bars[i].lvbase == NULL) { PPLOG("could not map device memory at 0x%08Lx for BAR %d", start, i); continue; } DPRINT("mapped physical memory @ %llx for bar %d to %p\n", start, i, pdev->bars[i].lvbase); #else pdev->bars[i].mmum.flags = MAPPING_PHYSICAL | MAPPING_MACOS_CONTROLS_CACHE | MAPPING_FORCE_WRITABLE; /* lvbase is actually the physical address for MAPPING_PHYSICAL */ pdev->bars[i].mmum.lvbase = (char *) ((unsigned long) start); #endif pdev->bars[i].used = 1; pdev->bars[i].mapped = 0; /* save flags of the physical device */ if ((flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) pdev->bars[i].flags = (~PCI_BASE_ADDRESS_IO_MASK) & flags; else pdev->bars[i].flags = (~PCI_BASE_ADDRESS_MEM_MASK) & flags; } fclose(resfile); /* see if we can find a rom */ snprintf(rom_file, NAME_MAX, "%s/rom", pdev->sysfs_path); romfd = open(rom_file, O_RDONLY); if (romfd != -1) { /* the kernel says there is a rom */ use_pci_rom(pdev->addr, rom_file); pdev->bars[6].mmum.size = lseek(romfd, 0, SEEK_END); pdev->bars[6].mmum.mbase = 0; pdev->bars[6].mmum.flags = PCI_BASE_ADDRESS_SPACE_MEMORY; pdev->bars[6].used = 1; close(romfd); } else { if (errno != ENOENT) PPLOG("cannot access %s: %s", rom_file, strerror(errno)); } }
static void *serve_rx(void *p) { struct serve_data *data = p; int rd; unsigned char b; while ((rd = read(data->rxfd, &b, 1)) == 1) { while (!data->done && !ring_have_space(data->rx)) { struct timespec ts = { .tv_nsec = 1000000, }; nanosleep(&ts, NULL); } if (data->done) break; data->rx->data[data->rx->head] = b; data->rx->head = ring_next_head(data->rx); } data->done = 1; return NULL; } static void *serve_tx(void *p) { struct serve_data *data = p; int wr; unsigned char b; while (!data->done) { if (!ring_have_data(data->tx)) { struct timespec ts = { .tv_nsec = 1000000, }; nanosleep(&ts, NULL); } while (ring_have_data(data->tx)) { wr = write(data->txfd, (void *)(data->tx->data + data->tx->tail), 1); if (wr != 1) break; data->tx->tail = ring_next_tail(data->tx); } } data->done = 1; return NULL; } int main(int argc, char **argv) { struct option opts[] = { {"port", required_argument, NULL, 'p'}, {"rx", required_argument, NULL, 'r'}, {"tx", required_argument, NULL, 't'}, {"stdio", no_argument, NULL, 's'}, {"help", no_argument, NULL, 'h'}, {0} }; struct sockaddr_in sa = { .sin_family = AF_INET, .sin_port = htons(2345), .sin_addr = INADDR_ANY, }; struct ring *rx = NULL; struct ring *tx = NULL; int s; int io; int rc; int opt, idx; int stdio = 0; while((opt = getopt_long(argc, argv, "p:r:t:sh", opts, &idx)) != -1) { switch(opt) { case 'p': sa.sin_port = htons(strtoul(optarg, NULL, 0)); break; case 'r': rx = map_phys_mem(strtoul(optarg, NULL, 0)); break; case 't': tx = map_phys_mem(strtoul(optarg, NULL, 0)); break; case 's': stdio = 1; break; case 'h': print_usage(); return 0; } } if (!rx || !tx) { printf("rx and tx rings location must be specified\n"); abort(); } if (!stdio) { s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s < 0) { perror("socket"); abort(); } rc = bind(s, (struct sockaddr *)&sa, sizeof(sa)); if (rc < 0) { perror("bind"); abort(); } rc = listen(s, 5); if (rc < 0) { perror("listen"); abort(); } } for (;;) { socklen_t sasz = sizeof(sa); struct serve_data data = { .rxfd = STDIN_FILENO, .txfd = STDOUT_FILENO, .rx = rx, .tx = tx, }; pthread_t rx_thread, tx_thread; void *rv; if (!stdio) { io = accept(s, (struct sockaddr *)&sa, &sasz); if (io < 0) { perror("accept"); abort(); } data.rxfd = data.txfd = io; } rc = pthread_create(&rx_thread, NULL, serve_rx, &data); if (rc) { perror("pthread_create(&rx_thread,...)"); abort(); } rc = pthread_create(&tx_thread, NULL, serve_tx, &data); if (rc) { perror("pthread_create(&tx_thread,...)"); abort(); } pthread_join(rx_thread, &rv); pthread_join(tx_thread, &rv); if (!stdio) { close(io); } } }