Changeset 811770c in mainline


Ignore:
Timestamp:
2016-05-05T12:06:04Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
57c2a87
Parents:
0f17bff
Message:

Avoid magic numbers and specialized functions to set/get register bits

Location:
kernel/arch/amd64
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/include/arch/asm.h

    r0f17bff r811770c  
    208208}
    209209
    210 /** Enable interrupts.
    211  *
    212  * Enable interrupts and return previous
    213  * value of EFLAGS.
    214  *
    215  * @return Old interrupt priority level.
    216  *
    217  */
    218 NO_TRACE static inline ipl_t interrupts_enable(void) {
    219         ipl_t v;
    220        
     210NO_TRACE static inline uint64_t read_rflags(void)
     211{
     212        uint64_t rflags;
     213
    221214        asm volatile (
    222215                "pushfq\n"
    223216                "popq %[v]\n"
    224                 "sti\n"
    225                 : [v] "=r" (v)
    226         );
    227        
    228         return v;
     217                : [v] "=r" (rflags)
     218        );
     219
     220        return rflags;
     221}
     222
     223NO_TRACE static inline void write_rflags(uint64_t rflags)
     224{
     225        asm volatile (
     226                "pushq %[v]\n"
     227                "popfq\n"
     228                :: [v] "r" (rflags)
     229        );
     230}
     231
     232/** Return interrupt priority level.
     233 *
     234 * Return the current interrupt priority level.
     235 *
     236 * @return Current interrupt priority level.
     237 */
     238NO_TRACE static inline ipl_t interrupts_read(void) {
     239        return (ipl_t) read_rflags();
     240}
     241
     242/** Enable interrupts.
     243 *
     244 * Enable interrupts and return the previous interrupt priority level.
     245 *
     246 * @return Old interrupt priority level.
     247 */
     248NO_TRACE static inline ipl_t interrupts_enable(void) {
     249        ipl_t ipl = interrupts_read();
     250       
     251        asm volatile ("sti\n");
     252       
     253        return ipl;
    229254}
    230255
    231256/** Disable interrupts.
    232257 *
    233  * Disable interrupts and return previous
    234  * value of EFLAGS.
     258 * Disable interrupts and return the previous interrupt priority level.
    235259 *
    236260 * @return Old interrupt priority level.
    237  *
    238261 */
    239262NO_TRACE static inline ipl_t interrupts_disable(void) {
    240         ipl_t v;
    241        
    242         asm volatile (
    243                 "pushfq\n"
    244                 "popq %[v]\n"
    245                 "cli\n"
    246                 : [v] "=r" (v)
    247         );
    248        
    249         return v;
     263        ipl_t ipl = interrupts_read();
     264       
     265        asm volatile ("cli\n");
     266       
     267        return ipl;
    250268}
    251269
    252270/** Restore interrupt priority level.
    253271 *
    254  * Restore EFLAGS.
     272 * Restore the previously save interrupt priority level.
    255273 *
    256274 * @param ipl Saved interrupt priority level.
     
    258276 */
    259277NO_TRACE static inline void interrupts_restore(ipl_t ipl) {
    260         asm volatile (
    261                 "pushq %[ipl]\n"
    262                 "popfq\n"
    263                 :: [ipl] "r" (ipl)
    264         );
    265 }
    266 
    267 /** Return interrupt priority level.
    268  *
    269  * Return EFLAFS.
    270  *
    271  * @return Current interrupt priority level.
    272  *
    273  */
    274 NO_TRACE static inline ipl_t interrupts_read(void) {
    275         ipl_t v;
    276        
    277         asm volatile (
    278                 "pushfq\n"
    279                 "popq %[v]\n"
    280                 : [v] "=r" (v)
    281         );
    282        
    283         return v;
     278        write_rflags((uint64_t) ipl);
    284279}
    285280
     
    291286NO_TRACE static inline bool interrupts_disabled(void)
    292287{
    293         ipl_t v;
    294        
    295         asm volatile (
    296                 "pushfq\n"
    297                 "popq %[v]\n"
    298                 : [v] "=r" (v)
    299         );
    300        
    301         return ((v & RFLAGS_IF) == 0);
     288        return ((read_rflags() & RFLAGS_IF) == 0);
    302289}
    303290
     
    324311       
    325312        return ((uint64_t) dx << 32) | ax;
    326 }
    327 
    328 /** Enable local APIC
    329  *
    330  * Enable local APIC in MSR.
    331  *
    332  */
    333 NO_TRACE static inline void enable_l_apic_in_msr(void)
    334 {
    335         asm volatile (
    336                 "movl $0x1b, %%ecx\n"
    337                 "rdmsr\n"
    338                 "orl $(1 << 11),%%eax\n"
    339                 "orl $(0xfee00000),%%eax\n"
    340                 "wrmsr\n"
    341                 ::: "%eax", "%ecx", "%edx"
    342         );
    343313}
    344314
     
    426396
    427397GEN_READ_REG(cr0)
     398GEN_WRITE_REG(cr0)
    428399GEN_READ_REG(cr2)
    429400GEN_READ_REG(cr3)
    430401GEN_WRITE_REG(cr3)
     402GEN_READ_REG(cr4)
     403GEN_WRITE_REG(cr4)
    431404
    432405GEN_READ_REG(dr0)
     
    512485extern uintptr_t int_63;
    513486
     487extern void enable_l_apic_in_msr(void);
     488
    514489#endif
    515490
  • kernel/arch/amd64/include/arch/cpu.h

    r0f17bff r811770c  
    3636#define KERN_amd64_CPU_H_
    3737
    38 #define RFLAGS_CF  (1 << 0)
    39 #define RFLAGS_PF  (1 << 2)
    40 #define RFLAGS_AF  (1 << 4)
    41 #define RFLAGS_ZF  (1 << 6)
    42 #define RFLAGS_SF  (1 << 7)
    43 #define RFLAGS_TF  (1 << 8)
    44 #define RFLAGS_IF  (1 << 9)
    45 #define RFLAGS_DF  (1 << 10)
    46 #define RFLAGS_OF  (1 << 11)
    47 #define RFLAGS_NT  (1 << 14)
    48 #define RFLAGS_RF  (1 << 16)
     38#define RFLAGS_CF       (1 << 0)
     39#define RFLAGS_PF       (1 << 2)
     40#define RFLAGS_AF       (1 << 4)
     41#define RFLAGS_ZF       (1 << 6)
     42#define RFLAGS_SF       (1 << 7)
     43#define RFLAGS_TF       (1 << 8)
     44#define RFLAGS_IF       (1 << 9)
     45#define RFLAGS_DF       (1 << 10)
     46#define RFLAGS_OF       (1 << 11)
     47#define RFLAGS_IOPL     (3 << 12)
     48#define RFLAGS_NT       (1 << 14)
     49#define RFLAGS_RF       (1 << 16)
     50#define RFLAGS_ID       (1 << 21)
    4951
    50 #define EFER_MSR_NUM    0xc0000080
    51 #define AMD_SCE_FLAG    0
    52 #define AMD_LME_FLAG    8
    53 #define AMD_LMA_FLAG    10
    54 #define AMD_FFXSR_FLAG  14
    55 #define AMD_NXE_FLAG    11
     52#define CR0_MP          (1 << 1)
     53#define CR0_EM          (1 << 2)
     54#define CR0_TS          (1 << 3)
     55#define CR0_AM          (1 << 18)
     56#define CR0_PG          (1 << 31)
     57
     58#define CR4_PAE         (1 << 5)
     59#define CR4_OSFXSR      (1 << 9)
     60
     61/* EFER bits */
     62#define AMD_SCE         (1 << 0)
     63#define AMD_LME         (1 << 8)
     64#define AMD_LMA         (1 << 10)
     65#define AMD_NXE         (1 << 11)
     66#define AMD_FFXSR       (1 << 14)
     67
     68#define AMD_APIC_BASE_GE        (1 << 11)
    5669
    5770/* MSR registers */
     71#define AMD_MSR_APIC_BASE       0x0000001b
     72#define AMD_MSR_EFER            0xc0000080
    5873#define AMD_MSR_STAR            0xc0000081
    5974#define AMD_MSR_LSTAR           0xc0000082
     
    85100};
    86101
    87 extern void set_efer_flag(int flag);
    88 extern uint64_t read_efer_flag(void);
    89102void cpu_setup_fpu(void);
    90103
  • kernel/arch/amd64/src/amd64.c

    r0f17bff r811770c  
    6464#endif
    6565
    66 /** Disable I/O on non-privileged levels
    67  *
    68  * Clean IOPL(12,13) and NT(14) flags in EFLAGS register
    69  */
    70 static void clean_IOPL_NT_flags(void)
    71 {
    72         asm volatile (
    73                 "pushfq\n"
    74                 "pop %%rax\n"
    75                 "and $~(0x7000), %%rax\n"
    76                 "pushq %%rax\n"
    77                 "popfq\n"
    78                 ::: "%rax"
    79         );
    80 }
    81 
    82 /** Disable alignment check
    83  *
    84  * Clean AM(18) flag in CR0 register
    85  */
    86 static void clean_AM_flag(void)
    87 {
    88         asm volatile (
    89                 "mov %%cr0, %%rax\n"
    90                 "and $~(0x40000), %%rax\n"
    91                 "mov %%rax, %%cr0\n"
    92                 ::: "%rax"
    93         );
    94 }
    95 
    9666/** Perform amd64-specific initialization before main_bsp() is called.
    9767 *
     
    11686{
    11787        /* Enable no-execute pages */
    118         set_efer_flag(AMD_NXE_FLAG);
     88        write_msr(AMD_MSR_EFER, read_msr(AMD_MSR_EFER) | AMD_NXE);
    11989        /* Enable FPU */
    12090        cpu_setup_fpu();
     
    12393        pm_init();
    12494       
    125         /* Disable I/O on nonprivileged levels
    126          * clear the NT (nested-thread) flag
    127          */
    128         clean_IOPL_NT_flags();
     95        /* Disable I/O on nonprivileged levels, clear the nested-thread flag */
     96        write_rflags(read_rflags() & ~(RFLAGS_IOPL | RFLAGS_NT));
    12997        /* Disable alignment check */
    130         clean_AM_flag();
     98        write_cr0(read_cr0() & ~CR0_AM);
    13199       
    132100        if (config.cpu_active == 1) {
  • kernel/arch/amd64/src/asm.S

    r0f17bff r811770c  
    3333#include <arch/kseg_struct.h>
    3434#include <arch/cpu.h>
     35#include <arch/smp/apic.h>
    3536
    3637.text
     
    9394       
    9495        /* Flip the ID bit */
    95         btcl $21, %edx
     96        xorl $RFLAGS_ID, %edx
    9697       
    9798        /* Store RFLAGS */
     
    102103        /* Get the ID bit again */
    103104        popq %rdx
    104         andl $(1 << 21), %eax
    105         andl $(1 << 21), %edx
     105        andl $RFLAGS_ID, %eax
     106        andl $RFLAGS_ID, %edx
    106107       
    107108        /* 0 if not supported, 1 if supported */
     
    127128FUNCTION_END(cpuid)
    128129
    129 FUNCTION_BEGIN(set_efer_flag)
    130         movl $0xc0000080, %ecx
     130/** Enable local APIC
     131 *
     132 * Enable local APIC in MSR.
     133 *
     134 */
     135FUNCTION_BEGIN(enable_l_apic_in_msr)
     136        movl $AMD_MSR_APIC_BASE, %ecx
    131137        rdmsr
    132         btsl %edi, %eax
     138        orl $(L_APIC_BASE | AMD_APIC_BASE_GE), %eax
    133139        wrmsr
    134140        ret
    135 FUNCTION_END(set_efer_flag)
    136 
    137 FUNCTION_BEGIN(read_efer_flag)
    138         movl $0xc0000080, %ecx
    139         rdmsr
    140         ret
    141 FUNCTION_END(read_efer_flag)
     141FUNCTION_END(enable_l_apic_in_msr)
    142142
    143143/*
     
    541541        ret
    542542FUNCTION_END(early_putchar)
    543 
  • kernel/arch/amd64/src/boot/multiboot.S

    r0f17bff r811770c  
    168168       
    169169        movl %cr4, %eax
    170         btsl $5, %eax
     170        orl $CR4_PAE, %eax
    171171        movl %eax, %cr4
    172172       
     
    176176       
    177177        /* Enable long mode */
    178         movl $EFER_MSR_NUM, %ecx
     178        movl $AMD_MSR_EFER, %ecx
    179179        rdmsr                     /* read EFER */
    180         btsl $AMD_LME_FLAG, %eax  /* set LME = 1 */
     180        orl $AMD_LME, %eax        /* set LME = 1 */
    181181        wrmsr
    182182       
    183183        /* Enable paging to activate long mode (set CR0.PG = 1) */
    184184        movl %cr0, %eax
    185         btsl $31, %eax
     185        orl $CR0_PG, %eax
    186186        movl %eax, %cr0
    187187       
  • kernel/arch/amd64/src/boot/multiboot2.S

    r0f17bff r811770c  
    209209       
    210210        movl %cr4, %eax
    211         btsl $5, %eax
     211        orl $CR4_PAE, %eax
    212212        movl %eax, %cr4
    213213       
     
    217217       
    218218        /* Enable long mode */
    219         movl $EFER_MSR_NUM, %ecx
     219        movl $AMD_MSR_EFER, %ecx
    220220        rdmsr                     /* read EFER */
    221         btsl $AMD_LME_FLAG, %eax  /* set LME = 1 */
     221        orl $AMD_LME, %eax        /* set LME = 1 */
    222222        wrmsr
    223223       
    224224        /* Enable paging to activate long mode (set CR0.PG = 1) */
    225225        movl %cr0, %eax
    226         btsl $31, %eax
     226        orl $CR0_PG, %eax
    227227        movl %eax, %cr0
    228228       
  • kernel/arch/amd64/src/cpu/cpu.c

    r0f17bff r811770c  
    7676void cpu_setup_fpu(void)
    7777{
    78         asm volatile (
    79                 "movq %%cr0, %%rax\n"
    80                 "btsq $1, %%rax\n"  /* cr0.mp */
    81                 "btrq $2, %%rax\n"  /* cr0.em */
    82                 "movq %%rax, %%cr0\n"
    83                
    84                 "movq %%cr4, %%rax\n"
    85                 "bts $9, %%rax\n"   /* cr4.osfxsr */
    86                 "movq %%rax, %%cr4\n"
    87                 ::: "%rax"
    88         );
     78        write_cr0((read_cr0() & ~CR0_EM) | CR0_MP);
     79        write_cr4(read_cr4() | CR4_OSFXSR);
    8980}
    9081
     
    9788void fpu_disable(void)
    9889{
    99         asm volatile (
    100                 "mov %%cr0, %%rax\n"
    101                 "bts $3, %%rax\n"
    102                 "mov %%rax, %%cr0\n"
    103                 ::: "%rax"
    104         );
     90        write_cr0(read_cr0() | CR0_TS);
    10591}
    10692
    10793void fpu_enable(void)
    10894{
    109         asm volatile (
    110                 "mov %%cr0, %%rax\n"
    111                 "btr $3, %%rax\n"
    112                 "mov %%rax, %%cr0\n"
    113                 ::: "%rax"
    114         );
     95        write_cr0(read_cr0() & ~CR0_TS);
    11596}
    11697
  • kernel/arch/amd64/src/smp/ap.S

    r0f17bff r811770c  
    7575       
    7676        movl %cr4, %eax
    77         btsl $5, %eax
     77        orl $CR4_PAE, %eax
    7878        movl %eax, %cr4
    7979       
     
    8282       
    8383        # Enable long mode
    84         movl $EFER_MSR_NUM, %ecx  # EFER MSR number
     84        movl $AMD_MSR_EFER, %ecx  # EFER MSR number
    8585        rdmsr                     # Read EFER
    86         btsl $AMD_LME_FLAG, %eax  # Set LME=1
     86        orl $AMD_LME, %eax        # Set LME=1
    8787        wrmsr                     # Write EFER
    8888       
    8989        # Enable paging to activate long mode (set CR0.PG = 1)
    9090        movl %cr0, %eax
    91         btsl $31, %eax
     91        orl $CR0_PG, %eax
    9292        movl %eax, %cr0
    9393       
  • kernel/arch/amd64/src/syscall.c

    r0f17bff r811770c  
    4848{
    4949        /* Enable SYSCALL/SYSRET */
    50         set_efer_flag(AMD_SCE_FLAG);
     50        write_msr(AMD_MSR_EFER, read_msr(AMD_MSR_EFER) | AMD_SCE);
    5151
    5252        /* Setup syscall entry address */
  • kernel/arch/amd64/src/userspace.c

    r0f17bff r811770c  
    4848void userspace(uspace_arg_t *kernel_uarg)
    4949{
    50         ipl_t ipl = interrupts_disable();
     50        uint64_t rflags = read_rflags();
    5151       
    52         ipl &= ~(RFLAGS_CF | RFLAGS_PF | RFLAGS_AF | RFLAGS_ZF | RFLAGS_SF |
    53             RFLAGS_DF | RFLAGS_OF);
     52        rflags &= ~RFLAGS_NT;
     53        rflags |= RFLAGS_IF;
    5454       
    5555        asm volatile (
    5656                "pushq %[udata_des]\n"
    5757                "pushq %[stack_top]\n"
    58                 "pushq %[ipl]\n"
     58                "pushq %[rflags]\n"
    5959                "pushq %[utext_des]\n"
    6060                "pushq %[entry]\n"
     
    6767                   [stack_top] "r" ((uint8_t *) kernel_uarg->uspace_stack +
    6868                       kernel_uarg->uspace_stack_size),
    69                    [ipl] "r" (ipl),
     69                   [rflags] "r" (rflags),
    7070                   [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
    7171                   [entry] "r" (kernel_uarg->uspace_entry),
Note: See TracChangeset for help on using the changeset viewer.