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) } while(0)
info->elf64 = IS_ELF64(eh64); if (IS_ELF64(eh64))
if (info->elf64)
{ {
#ifndef __riscv64
panic("can't run 64-bit ELF on 32-bit arch");
#endif
Elf64_Ehdr* eh; Elf64_Ehdr* eh;
Elf64_Phdr* ph; Elf64_Phdr* ph;
LOAD_ELF; LOAD_ELF;
} }
else if (IS_ELF32(eh64)) else if (IS_ELF32(eh64))
{ {
#ifdef __riscv64
panic("can't run 32-bit ELF on 64-bit arch");
#endif
Elf32_Ehdr* eh; Elf32_Ehdr* eh;
Elf32_Phdr* ph; Elf32_Phdr* ph;
LOAD_ELF; LOAD_ELF;

9
pk/init.c

@ -16,16 +16,9 @@ int uarch_counters_enabled;
long uarch_counters[NUM_COUNTERS]; long uarch_counters[NUM_COUNTERS];
char* uarch_counter_names[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)); 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->status = read_csr(sstatus);
tf->gpr[2] = sp; tf->gpr[2] = sp;
tf->epc = pc; tf->epc = pc;

7
pk/pk.c

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

3
pk/pk.h

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

46
pk/syscall.c

@ -10,15 +10,6 @@
typedef long (*syscall_t)(long, long, long, long, long, long, long); 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 #define CLOCK_FREQ 1000000000
void sys_exit(int code) 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) int sys_rt_sigaction(int sig, const void* act, void* oact, size_t sssz)
{ {
if (oact) if (oact)
{ memset(oact, 0, sizeof(long) * 3);
size_t sz = long_bytes * 3;
populate_mapping(oact, sz, PROT_WRITE);
memset(oact, 0, sz);
}
return 0; return 0;
} }
long sys_time(void* loc) long sys_time(long* loc)
{ {
uintptr_t t = rdcycle() / CLOCK_FREQ; uintptr_t t = rdcycle() / CLOCK_FREQ;
if (loc) if (loc)
{ *loc = t;
populate_mapping(loc, long_bytes, PROT_WRITE);
put_long(loc, 0, t);
}
return 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(); uintptr_t t = rdcycle();
kassert(CLOCK_FREQ % 1000000 == 0); kassert(CLOCK_FREQ % 1000000 == 0);
put_long(loc, 0, t / (CLOCK_FREQ / 1000000)); loc[0] = t / (CLOCK_FREQ / 1000000);
put_long(loc, 1, 0); loc[1] = 0;
put_long(loc, 2, 0); loc[2] = 0;
put_long(loc, 3, 0); loc[3] = 0;
return 0; return 0;
} }
int sys_gettimeofday(long* loc) int sys_gettimeofday(long* loc)
{ {
populate_mapping(loc, 2*long_bytes, PROT_WRITE);
uintptr_t t = rdcycle(); uintptr_t t = rdcycle();
put_long(loc, 0, t/CLOCK_FREQ); loc[0] = t / CLOCK_FREQ;
put_long(loc, 1, (t % CLOCK_FREQ) / (CLOCK_FREQ / 1000000)); loc[1] = (t % CLOCK_FREQ) / (CLOCK_FREQ / 1000000);
return 0; 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; ssize_t ret = 0;
for (int i = 0; i < cnt; i++) 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) if (r < 0)
return r; return r;
ret += r; ret += r;

5
pk/vm.c

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

Loading…
Cancel
Save