uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result) { uint8_t *ptr; uint64_t val; MemoryRegion *mr; hwaddr l = 1; hwaddr addr1; MemTxResult r; bool release_lock = false; RCU_READ_LOCK(); mr = TRANSLATE(addr, &addr1, &l, false); if (!IS_DIRECT(mr, false)) { release_lock |= prepare_mmio_access(mr); /* I/O case */ r = memory_region_dispatch_read(mr, addr1, &val, 1, attrs); } else { /* RAM case */ ptr = MAP_RAM(mr, addr1); val = ldub_p(ptr); r = MEMTX_OK; } if (result) { *result = r; } if (release_lock) { qemu_mutex_unlock_iothread(); } RCU_READ_UNLOCK(); return val; }
uint64_t sys_openat(HTIFState *htifstate, uint64_t dirfd, uint64_t pname, uint64_t len, uint64_t flags, uint64_t mode) { void * base = htifstate->main_mem_ram_ptr + (uintptr_t)pname; char name[len]; int i; for (i = 0; i < len; i++) { name[i] = ldub_p((void*)(base + i)); } // in case host OS has different val for AT_FDCWD, e.g. OS X dirfd = dirfd == BBL_AT_FDCWD ? AT_FDCWD : dirfd; #ifdef DEBUG_FRONTEND_RISCV fprintf(stderr, "openat: %s\n" "dirfd %ld, flags %ld, mode %ld\n", name, dirfd, flags, mode); #endif real_kernelfd = openat(dirfd, name, flags, mode); #ifdef DEBUG_FRONTEND_RISCV fprintf(stderr, "got real fd: %d\n", real_kernelfd); #endif if (real_kernelfd != -1) { // always give fd 3 to bbl, until we have a better tracking mechanism return 3; } return -1; }
/* * Used by bbl to print. */ uint64_t sys_write(HTIFState *htifstate, uint64_t fd, uint64_t pbuf, uint64_t len) { int i; char * printbuf = malloc(sizeof(char)*(len+1)); printbuf[len] = '\0'; // null term for easy printing void * base = htifstate->main_mem_ram_ptr + (uintptr_t)pbuf; for (i = 0; i < len; i++) { printbuf[i] = ldub_p((void*)(base + i)); } switch(fd) { case 1: case 2: printf("%s", printbuf); break; default: fprintf(stderr, "INVALID SYS_WRITE\n"); exit(1); } free(printbuf); return len; }