kboot: move to generic syscall interface

Just have the MD code provide syscall and have generic code for the
rest.

Sponsored by:		Netflix
Differential Revision:	https://reviews.freebsd.org/D33515
This commit is contained in:
Warner Losh 2021-12-30 16:07:20 -07:00
parent 6497250f6f
commit 5974cfe1ba
5 changed files with 136 additions and 89 deletions

View File

@ -17,7 +17,7 @@ NEWVERSWHAT= "kboot loader" ${MACHINE_ARCH}
INSTALLFLAGS= -b
# Architecture-specific loader code
SRCS= vers.c main.c hostcons.c hostdisk.c kbootfdt.c gfx_fb_stub.c
SRCS= vers.c main.c host_syscalls.c hostcons.c hostdisk.c kbootfdt.c gfx_fb_stub.c
CFLAGS.gfx_fb_stub.c += -I${SRCTOP}/contrib/pnglite -I${SRCTOP}/sys/teken

View File

@ -1,88 +1,32 @@
/*
*
* $FreeBSD$
*/
#include <machine/asm.h>
ENTRY(host_read)
li %r0, 3 # SYS_read
sc
bso 1f
blr
1:
li %r3, 0
blr
END(host_read)
ENTRY(host_write)
li %r0, 4 # SYS_write
/*
* Emulate the Linux system call interface. The system call number is set in
* %r0, and %r3 -> %r8 have the 6 system call arguments. errno is returned
* as a negative value, but we use it more as a flag something went wrong
* rather than using its value.
*
* Return value in %r3. If it is positive or < -4096, it's a successful
* system call. If it is between -1 and -4095 then it's an failed system
* call with -x as the errno. Errors from the kernel are signaled via the
* the 'so' bit, but we don't test that here at all. There are at most 6
* arguments to system calls in Linux.
*
* We expose the raw system call result, rather than do the POSIX
* converion to -1 and setting errno.
*
* Note: The code this replaced used bso to set %r3 to 0 for the read and
* open system calls for reasons that are still under investigation.
*/
ENTRY(host_syscall)
mr %r0, %r3 /* SYS_ number in $r0 */
mr %r3, %r4 /* arg2 -> 1 */
mr %r4, %r5 /* arg3 -> 2 */
mr %r5, %r6 /* arg4 -> 3 */
mr %r6, %r7 /* arg5 -> 4 */
mr %r7, %r8 /* arg6 -> 5 */
mr %r8, %r9 /* arg7 -> 6 */
sc
blr
END(host_write)
ENTRY(host_llseek)
li %r0, 140 # SYS_llseek
sc
blr
END(host_llseek)
ENTRY(host_open)
li %r0, 5 # SYS_open
sc
bso 1f
blr
1:
li %r3, 0
blr
END(host_open)
ENTRY(host_close)
li %r0, 6 # SYS_close
sc
blr
END(host_close)
ENTRY(host_mmap)
li %r0, 90 # SYS_mmap
sc
blr
END(host_mmap)
ENTRY(host_uname)
li %r0, 122 # SYS_uname
sc
blr
END(host_uname)
ENTRY(host_gettimeofday)
li %r0, 78 # SYS_gettimeofday
sc
blr
END(host_gettimeofday)
ENTRY(host_select)
li %r0, 142 # SYS_select
sc
blr
END(host_select)
ENTRY(kexec_load)
lis %r6,21 # KEXEC_ARCH_PPC64
li %r0,268 # __NR_kexec_load
sc
blr
END(kexec_load)
ENTRY(host_reboot)
li %r0,88 # SYS_reboot
sc
blr
END(host_reboot)
ENTRY(host_getdents)
li %r0,141 # SYS_getdents
sc
blr
END(host_getdents)
/* Note: We're exposing the raw return value to the caller */
END(host_syscall)

View File

@ -0,0 +1,15 @@
#define SYS_read 3
#define SYS_write 4
#define SYS_open 5
#define SYS_close 6
#define SYS_gettimeofday 78
#define SYS_reboot 88
#define SYS_mmap 90
#define SYS_uname 120
#define SYS_llseek 140
#define SYS_getdents 141
#define SYS_select 142
#define __NR_kexec_load 268
#define KEXEC_ARCH_PPC64 21
#define KEXEC_ARCH KEXEC_ARCH_PPC64

View File

@ -30,12 +30,14 @@
#include <stand.h>
long host_syscall(int number, ...);
ssize_t host_read(int fd, void *buf, size_t nbyte);
ssize_t host_write(int fd, const void *buf, size_t nbyte);
int host_open(const char *path, int flags, int mode);
ssize_t host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence);
int host_close(int fd);
void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, int);
void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off);
#define host_getmem(size) host_mmap(0, size, 3 /* RW */, 0x22 /* ANON */, -1, 0);
struct old_utsname {
char sysname[65];
@ -46,14 +48,14 @@ struct old_utsname {
};
int host_uname(struct old_utsname *);
struct host_timeval {
int tv_sec;
int tv_usec;
time_t tv_sec;
long tv_usec;
};
int host_gettimeofday(struct host_timeval *a, void *b);
int host_select(int nfds, long *readfds, long *writefds, long *exceptfds,
struct host_timeval *timeout);
int kexec_load(uint32_t start, int nsegs, uint32_t segs);
int host_reboot(int, int, int, uint32_t);
int host_reboot(int, int, int, uintptr_t);
int host_getdents(int fd, void *dirp, int count);
#endif

View File

@ -0,0 +1,86 @@
#include "host_syscall.h"
#include "syscall_nr.h"
#include <stand.h>
ssize_t
host_read(int fd, void *buf, size_t nbyte)
{
return host_syscall(SYS_read, fd, (uintptr_t)buf, nbyte);
/* XXX original overrode errors */
}
ssize_t
host_write(int fd, const void *buf, size_t nbyte)
{
return host_syscall(SYS_write, fd, (uintptr_t)buf, nbyte);
}
int
host_open(const char *path, int flags, int mode)
{
return host_syscall(SYS_open, (uintptr_t)path, flags, mode);
/* XXX original overrode errors */
}
ssize_t
host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence)
{
#ifdef SYS_llseek
return host_syscall(SYS_llseek, fd, offset_high, offset_lo, (uintptr_t)result, whence);
#else
int64_t rv = host_syscall(SYS_lseek, fd,
(int64_t)((uint64_t)offset_high << 32 | (uint32_t)offset_lo), whence);
if (rv > 0)
*result = (uint64_t)rv;
return (rv);
#endif
}
int
host_close(int fd)
{
return host_syscall(SYS_close, fd);
}
void *
host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off)
{
return (void *)host_syscall(SYS_mmap, (uintptr_t)addr, len, prot, flags, fd, off);
}
int
host_uname(struct old_utsname *uts)
{
return host_syscall(SYS_uname, (uintptr_t)uts);
}
int
host_gettimeofday(struct host_timeval *a, void *b)
{
return host_syscall(SYS_gettimeofday, (uintptr_t)a, (uintptr_t)b);
}
int
host_select(int nfds, long *readfds, long *writefds, long *exceptfds,
struct host_timeval *timeout)
{
return host_syscall(SYS_select, nfds, (uintptr_t)readfds, (uintptr_t)writefds, (uintptr_t)exceptfds, (uintptr_t)timeout, 0);
}
int
kexec_load(uint32_t start, int nsegs, uint32_t segs)
{
return host_syscall(__NR_kexec_load, start, nsegs, segs, KEXEC_ARCH << 16);
}
int
host_reboot(int magic1, int magic2, int cmd, uintptr_t arg)
{
return host_syscall(SYS_reboot, magic1, magic2, cmd, arg);
}
int
host_getdents(int fd, void *dirp, int count)
{
return host_syscall(SYS_getdents, fd, (uintptr_t)dirp, count);
}