{
/* Load the LDT for this process. Slightly ghetto doing it here. */
segdesc_t *my_gdt = per_cpu_info[core_id()].gdt;
- /* using local space so we can use this macro */
- segdesc_t ldt_temp = SEG_SYS(STS_LDT, (uint32_t)current->env_procdata->ldt,
- 8192, 3);
-
+ /* copy-in and check the LDT location. the segmentation hardware write the
+ * accessed bit, so we want the memory to be in the user-writeable area. */
+ segdesc_t *ldt = current->env_procdata->ldt;
+ ldt = (segdesc_t*)MIN((uintptr_t)ldt, UTOP - LDT_SIZE);
+ segdesc_t ldt_temp = SEG_SYS(STS_LDT, (uint32_t)ldt, LDT_SIZE, 3);
my_gdt[GD_LDT >> 3] = ldt_temp;
asm volatile("lldt %%ax" :: "a"(GD_LDT));
#define STS_IG32 0xE // 32-bit Interrupt Gate
#define STS_TG32 0xF // 32-bit Trap Gate
-#define SEG_COUNT 7 // Number of segments in the steady state
+#define SEG_COUNT 7 // Number of segments in the steady state
+#define LDT_SIZE (8192 * sizeof(segdesc_t))
/*
*
typedef struct procdata {
#ifdef __i386__
- segdesc_t ldt[8192];
+ segdesc_t *ldt;
#endif
// The actual ring buffers for communicating with user space
syscall_sring_t syscallring; // Per-process ring buffer for async syscalls
int main(int argc, char** argv)
{
-
uint32_t vcoreid;
error_t retval;
#include <ros/procdata.h>
#include <sys/time.h>
#include <errno.h>
+#include <debug.h>
enum {
PG_RDONLY = 4,
void sys_reboot();
void sys_yield();
int gettimeofday(struct timeval* tp, void* tzp);
+void *COUNT(length) sys_mmap(void *SNT addr, size_t length, int prot, int flags,
+ int fd, size_t offset);
#endif // !ASSEMBLER
* the memory at %gs:0x0 to hold the address of the top of the TLS.
*
* @author Paul Pearce <pearce@eecs.berkeley.edu>
- *
+ * @author Barret Rhoden <brho@eecs.berkeley.edu>
*/
-
#include <ros/common.h>
-#include <parlib.h>
+#include <ros/mman.h>
#include <arch/mmu.h>
-
-void* core0_tls_top_ptr;
+#include <parlib.h>
+#include <hart.h>
+#include <stdlib.h>
+#include <assert.h>
void ldt_init(uint32_t core_id) {
extern void **tls_array;
extern char core0_tls[];
+ static void *core0_tls_top_ptr;
+ static bool initialized = 0;
void **tls_handle;
-
+
+ /* mmap in only the LDT that we need. once the kernel supports un-FIXED
+ * mmap(), we can stop hardcoding the location (USTACKBOT - LDTSIZE) */
+ if (!initialized++) {
+ procdata.ldt = sys_mmap((void*)USTACKBOT - LDT_SIZE,
+ sizeof(segdesc_t) * hart_max_harts(),
+ PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_FIXED | MAP_POPULATE, 0, 0);
+ sys_getpid(); // force a kernel crossing to reload the LDT
+ if (!procdata.ldt) {
+ debug("Unable to mmap() an LDT! Exiting...\n");
+ exit(-EFAIL);
+ }
+ }
+
core0_tls_top_ptr = core0_tls + PARLIB_TLS_SIZE;
// Get a handle to this core's tls
{
syscall(SYS_yield,0,0,0,0,0);
}
+
+/* We need to do some hackery to pass 6 arguments. Arg4 pts to the real arg4,
+ * arg5, and arg6. Keep this in sync with kern/src/syscall.c.
+ * TODO: consider a syscall_multi that can take more args, and keep it in sync
+ * with the kernel. Maybe wait til we fix sysenter to have 5 or 6 args. */
+void *CT(length) sys_mmap(void *SNT addr, size_t length, int prot, int flags,
+ int fd, size_t offset)
+{
+ struct args {
+ int _flags;
+ int _fd;
+ size_t _offset;
+ } extra_args;
+ extra_args._flags = flags;
+ extra_args._fd = fd;
+ extra_args._offset = offset;
+ // TODO: deputy bitches about this
+ return (void*CT(length))TC(syscall(SYS_mmap, (uint32_t)addr, length, prot,
+ (int32_t)&extra_args, 0));
+}
+