mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-09 13:42:56 +00:00
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:
parent
6497250f6f
commit
5974cfe1ba
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
15
stand/kboot/arch/powerpc64/syscall_nr.h
Normal file
15
stand/kboot/arch/powerpc64/syscall_nr.h
Normal 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
|
@ -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
|
||||
|
86
stand/kboot/host_syscalls.c
Normal file
86
stand/kboot/host_syscalls.c
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user