790155e29b86c73eac818da5018c5514b9c60f6c
[akaros.git] / user / parlib / src / i386 / ldt.c
1 /*
2  * Copyright (c) 2010 The Regents of the University of California
3  * See LICENSE for details.
4  */
5
6 /** @file
7  * @brief x86 LDT init.
8  *
9  * This function is responsible for correctly setting up the the LDT entry for a
10  * given core. This is in support of thread local storage on x86.  x86 expects
11  * the memory at %gs:0x0 to hold the address of the top of the TLS.
12  *
13  * @author Paul Pearce <pearce@eecs.berkeley.edu>
14  *
15  */
16
17
18 #include <ros/common.h>
19 #include <parlib.h>
20 #include <arch/mmu.h>
21
22 void* core0_tls_top_ptr;
23
24 void ldt_init(uint32_t core_id) {
25
26         extern void **tls_array;
27         extern char core0_tls[];
28
29         void **tls_handle;
30         
31         core0_tls_top_ptr = core0_tls + PARLIB_TLS_SIZE;
32
33         // Get a handle to this core's tls
34         if (core_id == 0) {
35                 tls_handle = &core0_tls_top_ptr;        
36         } else {
37                 tls_handle = &tls_array[core_id];
38         }
39
40         // Build the segment
41         segdesc_t tmp = SEG(STA_W, (uint32_t)tls_handle, (uint32_t)tls_handle + 4, 3);
42
43         // Setup the correct LDT entry for this hart
44         procdata.ldt[core_id] = tmp;
45
46         // Create the GS register.
47         uint32_t gs = (core_id << 3) | 0x07;
48
49         // Set the GS register.
50         asm volatile("movl %0,%%gs" : : "r" (gs));
51
52         // Profit!
53 }