Browse Source

Remove incorrect code supporting ELF32 on RV64 and vice-versa

This is technically possible by running an RV32 supervisor on an
RV64 machine, but the M-mode and S-mode code would need to be
compiled and linked separately.
pull/12/merge
Andrew Waterman 10 years ago
parent
commit
31ad71b8a4
  1. 9
      pk/elf.c
  2. 9
      pk/init.c
  3. 7
      pk/pk.c
  4. 3
      pk/pk.h
  5. 46
      pk/syscall.c
  6. 5
      pk/vm.c

9
pk/elf.c

@ -84,15 +84,20 @@ void load_elf(const char* fn, elf_info* info)
} \
} while(0)
info->elf64 = IS_ELF64(eh64);
if (info->elf64)
if (IS_ELF64(eh64))
{
#ifndef __riscv64
panic("can't run 64-bit ELF on 32-bit arch");
#endif
Elf64_Ehdr* eh;
Elf64_Phdr* ph;
LOAD_ELF;
}
else if (IS_ELF32(eh64))
{
#ifdef __riscv64
panic("can't run 32-bit ELF on 64-bit arch");
#endif
Elf32_Ehdr* eh;
Elf32_Phdr* ph;
LOAD_ELF;

9
pk/init.c

@ -16,16 +16,9 @@ int uarch_counters_enabled;
long uarch_counters[NUM_COUNTERS];
char* uarch_counter_names[NUM_COUNTERS];
void init_tf(trapframe_t* tf, long pc, long sp, int user64)
void init_tf(trapframe_t* tf, long pc, long sp)
{
memset(tf, 0, sizeof(*tf));
#ifdef __riscv64
if (!user64)
panic("can't run 32-bit ELF on 64-bit pk");
#else
if (user64)
panic("can't run 64-bit ELF on 32-bit pk");
#endif
tf->status = read_csr(sstatus);
tf->gpr[2] = sp;
tf->epc = pc;

7
pk/pk.c

@ -66,10 +66,7 @@ void run_loaded_program(struct mainvars* args)
} \
} while (0)
if (current.elf64)
STACK_INIT(uint64_t);
else
STACK_INIT(uint32_t);
STACK_INIT(uintptr_t);
if (current.t0) // start timer if so requested
current.t0 = rdcycle();
@ -92,7 +89,7 @@ void run_loaded_program(struct mainvars* args)
}
trapframe_t tf;
init_tf(&tf, current.entry, stack_top, current.elf64);
init_tf(&tf, current.entry, stack_top);
__clear_cache(0, 0);
write_csr(sscratch, kernel_stack_top);
start_user(&tf);

3
pk/pk.h

@ -57,7 +57,7 @@ void printk(const char* s, ...);
void printm(const char* s, ...);
int vsnprintf(char* out, size_t n, const char* s, va_list vl);
int snprintf(char* out, size_t n, const char* s, ...);
void init_tf(trapframe_t*, long pc, long sp, int user64);
void init_tf(trapframe_t*, long pc, long sp);
void start_user(trapframe_t* tf) __attribute__((noreturn));
void dump_tf(trapframe_t*);
void print_logo();
@ -72,7 +72,6 @@ void run_loaded_program(struct mainvars*);
void boot_other_hart();
typedef struct {
int elf64;
int phent;
int phnum;
int is_supervisor;

46
pk/syscall.c

@ -10,15 +10,6 @@
typedef long (*syscall_t)(long, long, long, long, long, long, long);
#define long_bytes (4 + 4*current.elf64)
#define get_long(base, i) ({ long res; \
if (current.elf64) res = ((long*)base)[i]; \
else res = ((int*)base)[i]; \
res; })
#define put_long(base, i, data) ({ long res; \
if (current.elf64) ((long*)base)[i] = (data); \
else ((int*)base)[i] = (data); })
#define CLOCK_FREQ 1000000000
void sys_exit(int code)
@ -363,59 +354,46 @@ uintptr_t sys_mprotect(uintptr_t addr, size_t length, int prot)
int sys_rt_sigaction(int sig, const void* act, void* oact, size_t sssz)
{
if (oact)
{
size_t sz = long_bytes * 3;
populate_mapping(oact, sz, PROT_WRITE);
memset(oact, 0, sz);
}
memset(oact, 0, sizeof(long) * 3);
return 0;
}
long sys_time(void* loc)
long sys_time(long* loc)
{
uintptr_t t = rdcycle() / CLOCK_FREQ;
if (loc)
{
populate_mapping(loc, long_bytes, PROT_WRITE);
put_long(loc, 0, t);
}
*loc = t;
return t;
}
int sys_times(void* restrict loc)
int sys_times(long* loc)
{
populate_mapping(loc, 4*long_bytes, PROT_WRITE);
uintptr_t t = rdcycle();
kassert(CLOCK_FREQ % 1000000 == 0);
put_long(loc, 0, t / (CLOCK_FREQ / 1000000));
put_long(loc, 1, 0);
put_long(loc, 2, 0);
put_long(loc, 3, 0);
loc[0] = t / (CLOCK_FREQ / 1000000);
loc[1] = 0;
loc[2] = 0;
loc[3] = 0;
return 0;
}
int sys_gettimeofday(long* loc)
{
populate_mapping(loc, 2*long_bytes, PROT_WRITE);
uintptr_t t = rdcycle();
put_long(loc, 0, t/CLOCK_FREQ);
put_long(loc, 1, (t % CLOCK_FREQ) / (CLOCK_FREQ / 1000000));
loc[0] = t / CLOCK_FREQ;
loc[1] = (t % CLOCK_FREQ) / (CLOCK_FREQ / 1000000);
return 0;
}
ssize_t sys_writev(int fd, const void* iov, int cnt)
ssize_t sys_writev(int fd, const long* iov, int cnt)
{
populate_mapping(iov, cnt*2*long_bytes, PROT_READ);
ssize_t ret = 0;
for (int i = 0; i < cnt; i++)
{
ssize_t r = sys_write(fd, (void*)get_long(iov, 2*i), get_long(iov, 2*i+1));
ssize_t r = sys_write(fd, (void*)iov[2*i], iov[2*i+1]);
if (r < 0)
return r;
ret += r;

5
pk/vm.c

@ -482,9 +482,8 @@ void supervisor_vm_init()
uintptr_t pk_vm_init()
{
// keep RV32 addresses positive
if (!current.elf64)
current.mmap_max = MIN(current.mmap_max, 0x80000000U);
// keep user addresses positive
current.mmap_max = MIN(current.mmap_max, (uintptr_t)INTPTR_MAX + 1);
__map_kernel_range(0, 0, current.first_free_paddr, PROT_READ|PROT_WRITE|PROT_EXEC);
__map_kernel_range(first_free_page, first_free_page, free_pages * RISCV_PGSIZE, PROT_READ|PROT_WRITE);

Loading…
Cancel
Save