From 50b56394307f76afe5ed1fac885e6d792d432c58 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 15 Dec 2014 11:05:43 +0100 Subject: arm: semihosting: staticize internal functions The semihosting code exposes internal file handle handling functions to read(), open(), close() and get the length of a certain file handle. However the code using it is only interested in either reading and entire named file into memory or getting the file length of a file referred by name. No file handles are used. Thus make the file handle code internal to this file by removing these functions from the semihosting header file and staticize them. This gives us some freedom to rearrange the semihosting code without affecting the external interface. Cc: Darwin Rambo Cc: AKASHI Takahiro Cc: Mark Hambleton Cc: Tom Rini Acked-by: Steve Rae Signed-off-by: Linus Walleij --- arch/arm/lib/semihosting.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'arch/arm/lib/semihosting.c') diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c index cb5dc26ac3..92bbabe158 100644 --- a/arch/arm/lib/semihosting.c +++ b/arch/arm/lib/semihosting.c @@ -23,6 +23,11 @@ #define MODE_READ 0x0 #define MODE_READBIN 0x1 +static int smh_read(int fd, void *memp, int len); +static int smh_open(const char *fname, char *modestr); +static int smh_close(int fd); +static int smh_len_fd(int fd); + /* * Call the handler */ @@ -96,7 +101,7 @@ int smh_load(const char *fname, void *memp, int avail, int verbose) /* * Read 'len' bytes of file into 'memp'. Returns 0 on success, else failure */ -int smh_read(int fd, void *memp, int len) +static int smh_read(int fd, void *memp, int len) { int ret; struct smh_read_s { @@ -131,7 +136,7 @@ int smh_read(int fd, void *memp, int len) * Open a file on the host. Mode is "r" or "rb" currently. Returns a file * descriptor or -1 on error. */ -int smh_open(const char *fname, char *modestr) +static int smh_open(const char *fname, char *modestr) { int ret, fd, mode; struct smh_open_s { @@ -171,7 +176,7 @@ int smh_open(const char *fname, char *modestr) /* * Close the file using the file descriptor */ -int smh_close(int fd) +static int smh_close(int fd) { int ret; long fdlong; @@ -189,7 +194,7 @@ int smh_close(int fd) /* * Get the file length from the file descriptor */ -int smh_len_fd(int fd) +static int smh_len_fd(int fd) { int ret; long fdlong; -- cgit v1.2.1 From 4e1ef15091b6f42ac13c22e3acc45a9bd9cce852 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 15 Dec 2014 11:05:56 +0100 Subject: arm: semihosting: fix up compile bugs There is currently a regression when using newer ARM64 compilers for semihosting: the way long types are inferred from context is no longer the same. The semihosting runtime uses long and size_t, so use this explicitly in the semihosting code and interface, and voila: the code now works again. Tested with aarch64-linux-gnu-gcc: Linaro GCC 4.9-2014.09. Cc: Darwin Rambo Cc: AKASHI Takahiro Cc: Mark Hambleton Cc: Tom Rini Acked-by: Steve Rae Suggested-by: Mark Hambleton Signed-off-by: Linus Walleij --- arch/arm/lib/semihosting.c | 101 +++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 49 deletions(-) (limited to 'arch/arm/lib/semihosting.c') diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c index 92bbabe158..e9d524e18a 100644 --- a/arch/arm/lib/semihosting.c +++ b/arch/arm/lib/semihosting.c @@ -23,17 +23,17 @@ #define MODE_READ 0x0 #define MODE_READBIN 0x1 -static int smh_read(int fd, void *memp, int len); -static int smh_open(const char *fname, char *modestr); -static int smh_close(int fd); -static int smh_len_fd(int fd); +static long smh_read(long fd, void *memp, size_t len); +static long smh_open(const char *fname, char *modestr); +static long smh_close(long fd); +static long smh_len_fd(long fd); /* * Call the handler */ -static int smh_trap(unsigned int sysnum, void *addr) +static long smh_trap(unsigned int sysnum, void *addr) { - register int result asm("r0"); + register long result asm("r0"); #if defined(CONFIG_ARM64) asm volatile ("hlt #0xf000" : "=r" (result) : "0"(sysnum), "r"(addr)); #else @@ -51,7 +51,9 @@ static int smh_trap(unsigned int sysnum, void *addr) */ int smh_load(const char *fname, void *memp, int avail, int verbose) { - int ret, fd, len; + long ret; + long fd; + size_t len; ret = -1; @@ -61,21 +63,21 @@ int smh_load(const char *fname, void *memp, int avail, int verbose) /* Open the file */ fd = smh_open(fname, "rb"); if (fd == -1) - return ret; + return -1; /* Get the file length */ ret = smh_len_fd(fd); if (ret == -1) { smh_close(fd); - return ret; + return -1; } /* Check that the file will fit in the supplied buffer */ if (ret > avail) { - printf("%s: ERROR ret %d, avail %u\n", __func__, ret, + printf("%s: ERROR ret %ld, avail %u\n", __func__, ret, avail); smh_close(fd); - return ret; + return -1; } len = ret; @@ -87,7 +89,7 @@ int smh_load(const char *fname, void *memp, int avail, int verbose) if (verbose) { printf("\n%s\n", fname); printf(" 0x%8p dest\n", memp); - printf(" 0x%08x size\n", len); + printf(" 0x%08lx size\n", len); printf(" 0x%08x avail\n", avail); } } @@ -101,54 +103,53 @@ int smh_load(const char *fname, void *memp, int avail, int verbose) /* * Read 'len' bytes of file into 'memp'. Returns 0 on success, else failure */ -static int smh_read(int fd, void *memp, int len) +static long smh_read(long fd, void *memp, size_t len) { - int ret; + long ret; struct smh_read_s { - int fd; + long fd; void *memp; - int len; + size_t len; } read; - debug("%s: fd %d, memp %p, len %d\n", __func__, fd, memp, len); + debug("%s: fd %ld, memp %p, len %lu\n", __func__, fd, memp, len); read.fd = fd; read.memp = memp; read.len = len; ret = smh_trap(SYSREAD, &read); - if (ret == 0) { - return 0; - } else { + if (ret < 0) { /* * The ARM handler allows for returning partial lengths, * but in practice this never happens so rather than create * hard to maintain partial read loops and such, just fail * with an error message. */ - printf("%s: ERROR ret %d, fd %d, len %u memp %p\n", + printf("%s: ERROR ret %ld, fd %ld, len %lu memp %p\n", __func__, ret, fd, len, memp); + return -1; } - return ret; + + return 0; } /* * Open a file on the host. Mode is "r" or "rb" currently. Returns a file * descriptor or -1 on error. */ -static int smh_open(const char *fname, char *modestr) +static long smh_open(const char *fname, char *modestr) { - int ret, fd, mode; + long fd; + unsigned long mode; struct smh_open_s { const char *fname; - unsigned int mode; - unsigned int len; + unsigned long mode; + size_t len; } open; debug("%s: file \'%s\', mode \'%s\'\n", __func__, fname, modestr); - ret = -1; - /* Check the file mode */ if (!(strcmp(modestr, "r"))) { mode = MODE_READ; @@ -157,7 +158,7 @@ static int smh_open(const char *fname, char *modestr) } else { printf("%s: ERROR mode \'%s\' not supported\n", __func__, modestr); - return ret; + return -1; } open.fname = fname; @@ -167,7 +168,7 @@ static int smh_open(const char *fname, char *modestr) /* Open the file on the host */ fd = smh_trap(SYSOPEN, &open); if (fd == -1) - printf("%s: ERROR fd %d for file \'%s\'\n", __func__, fd, + printf("%s: ERROR fd %ld for file \'%s\'\n", __func__, fd, fname); return fd; @@ -176,17 +177,15 @@ static int smh_open(const char *fname, char *modestr) /* * Close the file using the file descriptor */ -static int smh_close(int fd) +static long smh_close(long fd) { - int ret; - long fdlong; + long ret; - debug("%s: fd %d\n", __func__, fd); + debug("%s: fd %ld\n", __func__, fd); - fdlong = (long)fd; - ret = smh_trap(SYSCLOSE, &fdlong); + ret = smh_trap(SYSCLOSE, &fd); if (ret == -1) - printf("%s: ERROR fd %d\n", __func__, fd); + printf("%s: ERROR fd %ld\n", __func__, fd); return ret; } @@ -194,17 +193,15 @@ static int smh_close(int fd) /* * Get the file length from the file descriptor */ -static int smh_len_fd(int fd) +static long smh_len_fd(long fd) { - int ret; - long fdlong; + long ret; - debug("%s: fd %d\n", __func__, fd); + debug("%s: fd %ld\n", __func__, fd); - fdlong = (long)fd; - ret = smh_trap(SYSFLEN, &fdlong); + ret = smh_trap(SYSFLEN, &fd); if (ret == -1) - printf("%s: ERROR ret %d\n", __func__, ret); + printf("%s: ERROR ret %ld, fd %ld\n", __func__, ret, fd); return ret; } @@ -212,26 +209,32 @@ static int smh_len_fd(int fd) /* * Get the file length from the filename */ -int smh_len(const char *fname) +long smh_len(const char *fname) { - int ret, fd, len; + long ret; + long fd; + long len; debug("%s: file \'%s\'\n", __func__, fname); /* Open the file */ fd = smh_open(fname, "rb"); - if (fd == -1) + if (fd < 0) return fd; /* Get the file length */ len = smh_len_fd(fd); + if (len < 0) { + smh_close(fd); + return len; + } /* Close the file */ ret = smh_close(fd); - if (ret == -1) + if (ret < 0) return ret; - debug("%s: returning len %d\n", __func__, len); + debug("%s: returning len %ld\n", __func__, len); /* Return the file length (or -1 error indication) */ return len; -- cgit v1.2.1 From 9be5c661beecdb8a9d90ab4869ddb501b4990dd9 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 15 Dec 2014 11:06:05 +0100 Subject: arm: semihosting: get rid of forward declarations By rearranging the functions in the semihosting code we can avoid forward-declaration of the internal static functions. This puts the stuff in a logical order: read/open/close/len and then higher-order functions follow at the end. Cc: Darwin Rambo Cc: AKASHI Takahiro Cc: Mark Hambleton Cc: Tom Rini Acked-by: Steve Rae Signed-off-by: Linus Walleij --- arch/arm/lib/semihosting.c | 173 ++++++++++++++++++++++----------------------- 1 file changed, 84 insertions(+), 89 deletions(-) (limited to 'arch/arm/lib/semihosting.c') diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c index e9d524e18a..fd6d8573f5 100644 --- a/arch/arm/lib/semihosting.c +++ b/arch/arm/lib/semihosting.c @@ -23,11 +23,6 @@ #define MODE_READ 0x0 #define MODE_READBIN 0x1 -static long smh_read(long fd, void *memp, size_t len); -static long smh_open(const char *fname, char *modestr); -static long smh_close(long fd); -static long smh_len_fd(long fd); - /* * Call the handler */ @@ -44,60 +39,43 @@ static long smh_trap(unsigned int sysnum, void *addr) } /* - * Open, load a file into memory, and close it. Check that the available space - * is sufficient to store the entire file. Return the bytes actually read from - * the file as seen by the read function. The verbose flag enables some extra - * printing of successful read status. + * Open a file on the host. Mode is "r" or "rb" currently. Returns a file + * descriptor or -1 on error. */ -int smh_load(const char *fname, void *memp, int avail, int verbose) +static long smh_open(const char *fname, char *modestr) { - long ret; long fd; - size_t len; - - ret = -1; - - debug("%s: fname \'%s\', avail %u, memp %p\n", __func__, fname, - avail, memp); - - /* Open the file */ - fd = smh_open(fname, "rb"); - if (fd == -1) - return -1; + unsigned long mode; + struct smh_open_s { + const char *fname; + unsigned long mode; + size_t len; + } open; - /* Get the file length */ - ret = smh_len_fd(fd); - if (ret == -1) { - smh_close(fd); - return -1; - } + debug("%s: file \'%s\', mode \'%s\'\n", __func__, fname, modestr); - /* Check that the file will fit in the supplied buffer */ - if (ret > avail) { - printf("%s: ERROR ret %ld, avail %u\n", __func__, ret, - avail); - smh_close(fd); + /* Check the file mode */ + if (!(strcmp(modestr, "r"))) { + mode = MODE_READ; + } else if (!(strcmp(modestr, "rb"))) { + mode = MODE_READBIN; + } else { + printf("%s: ERROR mode \'%s\' not supported\n", __func__, + modestr); return -1; } - len = ret; - - /* Read the file into the buffer */ - ret = smh_read(fd, memp, len); - if (ret == 0) { - /* Print successful load information if requested */ - if (verbose) { - printf("\n%s\n", fname); - printf(" 0x%8p dest\n", memp); - printf(" 0x%08lx size\n", len); - printf(" 0x%08x avail\n", avail); - } - } + open.fname = fname; + open.len = strlen(fname); + open.mode = mode; - /* Close the file */ - smh_close(fd); + /* Open the file on the host */ + fd = smh_trap(SYSOPEN, &open); + if (fd == -1) + printf("%s: ERROR fd %ld for file \'%s\'\n", __func__, fd, + fname); - return ret; + return fd; } /* @@ -134,46 +112,6 @@ static long smh_read(long fd, void *memp, size_t len) return 0; } -/* - * Open a file on the host. Mode is "r" or "rb" currently. Returns a file - * descriptor or -1 on error. - */ -static long smh_open(const char *fname, char *modestr) -{ - long fd; - unsigned long mode; - struct smh_open_s { - const char *fname; - unsigned long mode; - size_t len; - } open; - - debug("%s: file \'%s\', mode \'%s\'\n", __func__, fname, modestr); - - /* Check the file mode */ - if (!(strcmp(modestr, "r"))) { - mode = MODE_READ; - } else if (!(strcmp(modestr, "rb"))) { - mode = MODE_READBIN; - } else { - printf("%s: ERROR mode \'%s\' not supported\n", __func__, - modestr); - return -1; - } - - open.fname = fname; - open.len = strlen(fname); - open.mode = mode; - - /* Open the file on the host */ - fd = smh_trap(SYSOPEN, &open); - if (fd == -1) - printf("%s: ERROR fd %ld for file \'%s\'\n", __func__, fd, - fname); - - return fd; -} - /* * Close the file using the file descriptor */ @@ -206,6 +144,63 @@ static long smh_len_fd(long fd) return ret; } +/* + * Open, load a file into memory, and close it. Check that the available space + * is sufficient to store the entire file. Return the bytes actually read from + * the file as seen by the read function. The verbose flag enables some extra + * printing of successful read status. + */ +int smh_load(const char *fname, void *memp, int avail, int verbose) +{ + long ret; + long fd; + size_t len; + + ret = -1; + + debug("%s: fname \'%s\', avail %u, memp %p\n", __func__, fname, + avail, memp); + + /* Open the file */ + fd = smh_open(fname, "rb"); + if (fd == -1) + return -1; + + /* Get the file length */ + ret = smh_len_fd(fd); + if (ret == -1) { + smh_close(fd); + return -1; + } + + /* Check that the file will fit in the supplied buffer */ + if (ret > avail) { + printf("%s: ERROR ret %ld, avail %u\n", __func__, ret, + avail); + smh_close(fd); + return -1; + } + + len = ret; + + /* Read the file into the buffer */ + ret = smh_read(fd, memp, len); + if (ret == 0) { + /* Print successful load information if requested */ + if (verbose) { + printf("\n%s\n", fname); + printf(" 0x%8p dest\n", memp); + printf(" 0x%08lx size\n", len); + printf(" 0x%08x avail\n", avail); + } + } + + /* Close the file */ + smh_close(fd); + + return ret; +} + /* * Get the file length from the filename */ -- cgit v1.2.1