arm-semi.c revision 0b1a84571c04503c5fb1ac012483f03454e2b140
1d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org/* 245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Arm "Angel" semihosting syscalls 345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright (c) 2005, 2007 CodeSourcery. 545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Written by Paul Brook. 645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This program is free software; you can redistribute it and/or modify 845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * it under the terms of the GNU General Public License as published by 945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the Free Software Foundation; either version 2 of the License, or 1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * (at your option) any later version. 1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This program is distributed in the hope that it will be useful, 1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * but WITHOUT ANY WARRANTY; without even the implied warranty of 1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * GNU General Public License for more details. 1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * You should have received a copy of the GNU General Public License 1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * along with this program; if not, see <http://www.gnu.org/licenses/>. 1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <sys/types.h> 2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <sys/stat.h> 2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <fcntl.h> 2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <unistd.h> 2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <stdlib.h> 2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <stdio.h> 2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <time.h> 2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "cpu.h" 3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifdef CONFIG_USER_ONLY 3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "qemu.h" 3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024) 3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#else 3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "qemu-common.h" 3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "exec/gdbstub.h" 3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "hw/arm/arm.h" 3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_OPEN 0x01 4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_CLOSE 0x02 4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_WRITEC 0x03 4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_WRITE0 0x04 4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_WRITE 0x05 4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_READ 0x06 4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_READC 0x07 4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_ISTTY 0x09 4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_SEEK 0x0a 4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_FLEN 0x0c 5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_TMPNAM 0x0d 5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_REMOVE 0x0e 5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_RENAME 0x0f 5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_CLOCK 0x10 5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_TIME 0x11 5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_SYSTEM 0x12 5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_ERRNO 0x13 5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_GET_CMDLINE 0x15 5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_HEAPINFO 0x16 5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define TARGET_SYS_EXIT 0x18 6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef O_BINARY 6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define O_BINARY 0 6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define GDB_O_RDONLY 0x000 6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define GDB_O_WRONLY 0x001 6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define GDB_O_RDWR 0x002 6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define GDB_O_APPEND 0x008 6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define GDB_O_CREAT 0x200 7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define GDB_O_TRUNC 0x400 7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define GDB_O_BINARY 0 7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int gdb_open_modeflags[12] = { 7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_RDONLY, 7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_RDONLY | GDB_O_BINARY, 7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_RDWR, 7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_RDWR | GDB_O_BINARY, 7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC, 7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY, 8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC, 8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY, 8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND, 8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY, 8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND, 8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY 8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int open_modeflags[12] = { 8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_RDONLY, 9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_RDONLY | O_BINARY, 9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_RDWR, 9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_RDWR | O_BINARY, 9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_WRONLY | O_CREAT | O_TRUNC, 9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_RDWR | O_CREAT | O_TRUNC, 9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_WRONLY | O_CREAT | O_APPEND, 9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_WRONLY | O_CREAT | O_APPEND | O_BINARY, 9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_RDWR | O_CREAT | O_APPEND, 10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org O_RDWR | O_CREAT | O_APPEND | O_BINARY 10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifdef CONFIG_USER_ONLY 10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic inline uint32_t set_swi_errno(TaskState *ts, uint32_t code) 10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (code == (uint32_t)-1) 10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ts->swi_errno = errno; 10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return code; 10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#else 11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic inline uint32_t set_swi_errno(CPUARMState *env, uint32_t code) 11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return code; 11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "exec/softmmu-semi.h" 11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic target_ulong arm_semi_syscall_len; 12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#if !defined(CONFIG_USER_ONLY) 12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic target_ulong syscall_err; 12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void arm_semi_cb(CPUState *cpu, target_ulong ret, target_ulong err) 12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org CPUARMState *env = cpu->env_ptr; 12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifdef CONFIG_USER_ONLY 12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TaskState *ts = env->opaque; 13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ret == (target_ulong)-1) { 13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifdef CONFIG_USER_ONLY 13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ts->swi_errno = err; 13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#else 13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org syscall_err = err; 13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org env->regs[0] = ret; 13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Fixup syscalls that use nonstardard return conventions. */ 14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (env->regs[0]) { 14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_WRITE: 14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_READ: 14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org env->regs[0] = arm_semi_syscall_len - ret; 14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_SEEK: 14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org env->regs[0] = 0; 14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org env->regs[0] = ret; 15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void arm_semi_flen_cb(CPUState *cpu, target_ulong ret, target_ulong err) 15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* The size is always stored in big-endian order, extract 15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org the value. We assume the size always fit in 32 bits. */ 16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org CPUARMState *env = cpu->env_ptr; 16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org uint32_t size; 16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cpu_memory_rw_debug(cpu, env->regs[13]-64+32, (uint8_t *)&size, 4, 0); 16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org env->regs[0] = be32_to_cpu(size); 16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifdef CONFIG_USER_ONLY 16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ((TaskState *)env->opaque)->swi_errno = err; 16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#else 16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org syscall_err = err; 16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Read the input value from the argument block; fail the semihosting 17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * call if the memory read fails. 17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define GET_ARG(n) do { \ 17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (get_user_ual(arg ## n, args + (n) * 4)) { \ 17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (uint32_t)-1; \ 17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } \ 17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} while (0) 17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define SET_ARG(n, val) put_user_ual(val, args + (n) * 4) 18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orguint32_t do_arm_semihosting(CPUARMState *env) 18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org target_ulong args; 18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org target_ulong arg0, arg1, arg2, arg3; 18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char * s; 18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int nr; 18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org uint32_t ret; 18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org uint32_t len; 18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifdef CONFIG_USER_ONLY 19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TaskState *ts = env->opaque; 19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#else 19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org CPUARMState *ts = env; 19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org nr = env->regs[0]; 19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org args = env->regs[1]; 19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (nr) { 19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_OPEN: 19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(0); 20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(1); 20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(2); 20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s = lock_user_string(arg0); 20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!s) { 20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* FIXME - should this error code be -TARGET_EFAULT ? */ 20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (uint32_t)-1; 20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (arg1 >= 12) { 20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unlock_user(s, arg0, 0); 20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (uint32_t)-1; 21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (strcmp(s, ":tt") == 0) { 21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int result_fileno = arg1 < 4 ? STDIN_FILENO : STDOUT_FILENO; 21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unlock_user(s, arg0, 0); 21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return result_fileno; 21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", arg0, 21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (int)arg2+1, gdb_open_modeflags[arg1]); 21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = env->regs[0]; 22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = set_swi_errno(ts, open(s, open_modeflags[arg1], 0644)); 22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unlock_user(s, arg0, 0); 22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return ret; 22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_CLOSE: 22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(0); 22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_cb, "close,%x", arg0); 22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return env->regs[0]; 23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return set_swi_errno(ts, close(arg0)); 23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_WRITEC: 23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char c; 23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (get_user_u8(c, args)) 23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* FIXME - should this error code be -TARGET_EFAULT ? */ 23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (uint32_t)-1; 24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Write to debug console. stderr is near enough. */ 24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_cb, "write,2,%x,1", args); 24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return env->regs[0]; 24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return write(STDERR_FILENO, &c, 1); 24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_WRITE0: 24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!(s = lock_user_string(args))) 25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* FIXME - should this error code be -TARGET_EFAULT ? */ 25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (uint32_t)-1; 25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = strlen(s); 25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_cb, "write,2,%x,%x\n", args, len); 25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = env->regs[0]; 25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = write(STDERR_FILENO, s, len); 25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unlock_user(s, args, 0); 26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return ret; 26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_WRITE: 26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(0); 26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(1); 26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(2); 26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = arg2; 26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org arm_semi_syscall_len = len; 26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", arg0, arg1, len); 26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return env->regs[0]; 27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s = lock_user(VERIFY_READ, arg1, len, 1); 27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!s) { 27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* FIXME - should this error code be -TARGET_EFAULT ? */ 27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (uint32_t)-1; 27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = set_swi_errno(ts, write(arg0, s, len)); 27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unlock_user(s, arg1, 0); 27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ret == (uint32_t)-1) 27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return len - ret; 28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_READ: 28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(0); 28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(1); 28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(2); 28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org len = arg2; 28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org arm_semi_syscall_len = len; 28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", arg0, arg1, len); 29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return env->regs[0]; 29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s = lock_user(VERIFY_WRITE, arg1, len, 0); 29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!s) { 29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* FIXME - should this error code be -TARGET_EFAULT ? */ 29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (uint32_t)-1; 29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do { 29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = set_swi_errno(ts, read(arg0, s, len)); 29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } while (ret == -1 && errno == EINTR); 30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unlock_user(s, arg1, len); 30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ret == (uint32_t)-1) 30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return len - ret; 30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_READC: 30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* XXX: Read from debug console. Not implemented. */ 30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_ISTTY: 30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(0); 31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_cb, "isatty,%x", arg0); 31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return env->regs[0]; 31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return isatty(arg0); 31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_SEEK: 31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(0); 31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(1); 31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_cb, "lseek,%x,%x,0", arg0, arg1); 32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return env->regs[0]; 32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = set_swi_errno(ts, lseek(arg0, arg1, SEEK_SET)); 32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ret == (uint32_t)-1) 32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_FLEN: 32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(0); 33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_flen_cb, "fstat,%x,%x", 33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org arg0, env->regs[13]-64); 33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return env->regs[0]; 33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct stat buf; 33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = set_swi_errno(ts, fstat(arg0, &buf)); 33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (ret == (uint32_t)-1) 33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return buf.st_size; 34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_TMPNAM: 34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* XXX: Not implemented. */ 34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_REMOVE: 34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(0); 34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(1); 34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_cb, "unlink,%s", arg0, (int)arg1+1); 34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = env->regs[0]; 35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s = lock_user_string(arg0); 35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!s) { 35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* FIXME - should this error code be -TARGET_EFAULT ? */ 35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (uint32_t)-1; 35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = set_swi_errno(ts, remove(s)); 35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unlock_user(s, arg0, 0); 35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return ret; 36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_RENAME: 36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(0); 36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(1); 36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(2); 36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(3); 36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_cb, "rename,%s,%s", 36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org arg0, (int)arg1+1, arg2, (int)arg3+1); 36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return env->regs[0]; 36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *s2; 37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s = lock_user_string(arg0); 37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s2 = lock_user_string(arg2); 37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!s || !s2) 37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* FIXME - should this error code be -TARGET_EFAULT ? */ 37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = (uint32_t)-1; 37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = set_swi_errno(ts, rename(s, s2)); 37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (s2) 37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unlock_user(s2, arg2, 0); 38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (s) 38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unlock_user(s, arg0, 0); 38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return ret; 38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_CLOCK: 38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return clock() / (CLOCKS_PER_SEC / 100); 38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_TIME: 38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return set_swi_errno(ts, time(NULL)); 38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_SYSTEM: 38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(0); 39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(1); 39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (use_gdb_syscalls()) { 39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org gdb_do_syscall(arm_semi_cb, "system,%s", arg0, (int)arg1+1); 39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return env->regs[0]; 39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s = lock_user_string(arg0); 39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!s) { 39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* FIXME - should this error code be -TARGET_EFAULT ? */ 39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (uint32_t)-1; 39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ret = set_swi_errno(ts, system(s)); 40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unlock_user(s, arg0, 0); 40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return ret; 40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_ERRNO: 40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifdef CONFIG_USER_ONLY 40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return ts->swi_errno; 40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#else 40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return syscall_err; 40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case TARGET_SYS_GET_CMDLINE: 41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Build a command-line from the original argv. 41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The inputs are: 41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * * arg0, pointer to a buffer of at least the size 41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * specified in arg1. 41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * * arg1, size of the buffer pointed to by arg0 in 41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * bytes. 41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The outputs are: 42145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * * arg0, pointer to null-terminated string of the 42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * command line. 42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * * arg1, length of the string pointed to by arg0. 42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *output_buffer; 42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t input_size; 42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t output_size; 42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int status = 0; 43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(0); 43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org GET_ARG(1); 43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org input_size = arg1; 43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Compute the size of the output string. */ 43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#if !defined(CONFIG_USER_ONLY) 43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org output_size = strlen(ts->boot_info->kernel_filename) 43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org + 1 /* Separating space. */ 43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org + strlen(ts->boot_info->kernel_cmdline) 43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org + 1; /* Terminating null byte. */ 43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#else 44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int i; 44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 44245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org output_size = ts->info->arg_end - ts->info->arg_start; 44345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!output_size) { 44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* We special-case the "empty command line" case (argc==0). 44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org Just provide the terminating 0. */ 44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org output_size = 1; 44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (output_size > input_size) { 45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Not enough space to store command-line arguments. */ 45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Adjust the command-line length. */ 45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (SET_ARG(1, output_size - 1)) { 457 /* Couldn't write back to argument block */ 458 return -1; 459 } 460 461 /* Lock the buffer on the ARM side. */ 462 output_buffer = lock_user(VERIFY_WRITE, arg0, output_size, 0); 463 if (!output_buffer) { 464 return -1; 465 } 466 467 /* Copy the command-line arguments. */ 468#if !defined(CONFIG_USER_ONLY) 469 pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename); 470 pstrcat(output_buffer, output_size, " "); 471 pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline); 472#else 473 if (output_size == 1) { 474 /* Empty command-line. */ 475 output_buffer[0] = '\0'; 476 goto out; 477 } 478 479 if (copy_from_user(output_buffer, ts->info->arg_start, 480 output_size)) { 481 status = -1; 482 goto out; 483 } 484 485 /* Separate arguments by white spaces. */ 486 for (i = 0; i < output_size - 1; i++) { 487 if (output_buffer[i] == 0) { 488 output_buffer[i] = ' '; 489 } 490 } 491 out: 492#endif 493 /* Unlock the buffer on the ARM side. */ 494 unlock_user(output_buffer, arg0, output_size); 495 496 return status; 497 } 498 case TARGET_SYS_HEAPINFO: 499 { 500 uint32_t *ptr; 501 uint32_t limit; 502 GET_ARG(0); 503 504#ifdef CONFIG_USER_ONLY 505 /* Some C libraries assume the heap immediately follows .bss, so 506 allocate it using sbrk. */ 507 if (!ts->heap_limit) { 508 abi_ulong ret; 509 510 ts->heap_base = do_brk(0); 511 limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE; 512 /* Try a big heap, and reduce the size if that fails. */ 513 for (;;) { 514 ret = do_brk(limit); 515 if (ret >= limit) { 516 break; 517 } 518 limit = (ts->heap_base >> 1) + (limit >> 1); 519 } 520 ts->heap_limit = limit; 521 } 522 523 ptr = lock_user(VERIFY_WRITE, arg0, 16, 0); 524 if (!ptr) { 525 /* FIXME - should this error code be -TARGET_EFAULT ? */ 526 return (uint32_t)-1; 527 } 528 ptr[0] = tswap32(ts->heap_base); 529 ptr[1] = tswap32(ts->heap_limit); 530 ptr[2] = tswap32(ts->stack_base); 531 ptr[3] = tswap32(0); /* Stack limit. */ 532 unlock_user(ptr, arg0, 16); 533#else 534 limit = ram_size; 535 ptr = lock_user(VERIFY_WRITE, arg0, 16, 0); 536 if (!ptr) { 537 /* FIXME - should this error code be -TARGET_EFAULT ? */ 538 return (uint32_t)-1; 539 } 540 /* TODO: Make this use the limit of the loaded application. */ 541 ptr[0] = tswap32(limit / 2); 542 ptr[1] = tswap32(limit); 543 ptr[2] = tswap32(limit); /* Stack base */ 544 ptr[3] = tswap32(0); /* Stack limit. */ 545 unlock_user(ptr, arg0, 16); 546#endif 547 return 0; 548 } 549 case TARGET_SYS_EXIT: 550 //gdb_exit(env, 0); 551 exit(0); 552 default: 553 fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr); 554 cpu_dump_state(ENV_GET_CPU(env), stderr, fprintf, 0); 555 abort(); 556 } 557} 558