/* * asm-e2k/system.h */ #ifndef _E2K_SYSTEM_H_ #define _E2K_SYSTEM_H_ #ifndef __ASSEMBLY__ #include #endif /* !(__ASSEMBLY__) */ #include #include #include #include #include #include #include #include #define set_mb(var, value) do { var = value; smp_mb(); } while (0) #define set_wmb(var, value) do { var = value; smp_wmb(); } while (0) #define NATIVE_PSR_SET_LAST_WISH() \ do { \ unsigned long __psr = NATIVE_NV_READ_PSR_REG_VALUE(); \ __psr |= PSR_LW; \ NATIVE_WRITE_PSR_REG_VALUE(__psr); \ } while (0) #define PSR_SET_LAST_WISH() \ do { \ unsigned long __psr = READ_PSR_REG_VALUE(); \ __psr |= PSR_LW; \ WRITE_PSR_REG_VALUE(__psr); \ } while (0) #define boot_native_set_sge() \ ({ \ NATIVE_WRITE_PSR_REG_VALUE( \ NATIVE_NV_READ_PSR_REG_VALUE() | PSR_SGE); \ }) static inline bool native_sge_is_set(void) { e2k_psr_t psr = NATIVE_NV_READ_PSR_REG(); return psr.PSR_sge; } #ifdef CONFIG_E2K_PROFILING typedef struct { // FIRST ELEMENT long max_disable_interrupt; // max #ticks of disable_interrupt long sum_disable_interrupt; // all #ticks of disable_interrupt long number_interrupt; // number of interrupts long number_irqs; // number of closed irq long number_system_call; // number of system_call long max_disable_interrupt_after_dump; // max #ticks of disable_interrupt // after last read or write profile file long interrupts[exc_max_num]; // interrupt table long interrupts_time[exc_max_num]; // interrupt time (in ticks) long max_interrupts_time[exc_max_num]; // max interrupt time (in ticks) long syscall[NR_syscalls]; // syscall table long syscall_time[NR_syscalls]; // syscall time (in ticks) long max_syscall_time[NR_syscalls]; // max syscall time long clk; // time of interrupt's begining // NR_VECTORS 256 long max_do_irq_time[256]; // max DO_IRQ's time long do_irq[256]; // number of DO_IRQ long do_irq_time[256]; // time of DO_IRQ long clk_of_do_irq; // time of DO_IRQ's begining long last_element; } disable_interrupt_t ; extern unsigned long get_cmos_time(void); extern disable_interrupt_t disable_interrupt[NR_CPUS]; #define read_ticks(n) (n = NATIVE_READ_CLKR_REG_VALUE()) #define add_info_interrupt(n, ticks) \ ({ long t; int cpu; \ t = NATIVE_READ_CLKR_REG_VALUE() - ticks; \ cpu = boot_smp_processor_id(); \ disable_interrupt[cpu].interrupts[n]++; \ disable_interrupt[cpu].interrupts_time[n] += t; \ if (t > disable_interrupt[cpu].max_interrupts_time[n]) { \ disable_interrupt[cpu].max_interrupts_time[n] = t; \ } \ }) #define add_info_syscall(n, ticks) \ ({ long t; int cpu; \ cpu = boot_smp_processor_id(); \ t = NATIVE_READ_CLKR_REG_VALUE() - ticks; \ disable_interrupt[cpu].syscall[n]++; \ disable_interrupt[cpu].syscall_time[n] += t; \ if (t > disable_interrupt[cpu].max_syscall_time[n]) { \ disable_interrupt[cpu].max_syscall_time[n] = t; \ } \ }) typedef struct { long max_time; long full_time; long begin_time; long number; long beg_ip; long beg_parent_ip; long end_ip; long end_parent_ip; long max_beg_ip; long max_beg_parent_ip; long max_end_ip; long max_begin_time; long max_end_parent_ip; } time_info_t; /* * For adding new element you need do following things: * - add new "time_info_t" element after last one * - add name of your elemen in system_info_name (file e2k_sysworks.c) * - create two new define similar below: * #define info_save_mmu_reg(tick) \ * store_max_time_in_system_info(tick,max_mmu_reg) * #define info_save_mmu_reg(tick) - null for not CONFIG_E2K_PROFILING * - used your new define for merging what you want */ typedef struct { time_info_t max_disabled_interrupt; // max time of disabled inerrupts time_info_t max_stack_reg; // max time of saving of stack_registers time_info_t max_tir_reg; // max time for storing TIR time_info_t max_mmu_reg; // max time for storing mmu registers time_info_t max_restore_stack_reg; // max time for restoring of stack_registers time_info_t max_restoring_reg; // max time for restoring all registers time_info_t max_restore_mmu_reg; // max time for restoring mmu registers time_info_t max_cpu_idle; // max time for cpu_idle } system_info_t ; extern char* system_info_name[]; extern system_info_t system_info[NR_CPUS]; extern int enable_collect_interrupt_ticks; #define collect_disable_interrupt_ticks() \ ({ int cpu; \ cpu = boot_smp_processor_id(); \ if (system_info[cpu].max_disabled_interrupt.begin_time >0){ \ store_max_time_in_system_info( \ system_info[cpu].max_disabled_interrupt.begin_time, \ max_disabled_interrupt); \ system_info[cpu].max_disabled_interrupt.begin_time = 0; \ } \ }) #define mark_disable_interrupt_ticks() \ store_begin_ip_in_system_info(max_disabled_interrupt) #define store_do_irq_ticks() \ ({ int cpu = boot_smp_processor_id(); \ disable_interrupt[cpu].clk_of_do_irq = NATIVE_READ_CLKR_REG_VALUE(); \ }) #define define_time_of_do_irq(N) \ ({ long t; int cpu; \ cpu = boot_smp_processor_id(); \ t = NATIVE_READ_CLKR_REG_VALUE() - \ disable_interrupt[cpu].clk_of_do_irq; \ disable_interrupt[cpu].do_irq_time[N] += t; \ disable_interrupt[cpu].do_irq[N]++; \ if (disable_interrupt[cpu].max_do_irq_time[N] < t) { \ disable_interrupt[cpu].max_do_irq_time[N] = t; \ } \ }) #define info_save_stack_reg(tick) \ store_max_time_in_system_info(tick,max_stack_reg) #define info_restore_stack_reg(tick) \ store_max_time_in_system_info(tick,max_restore_stack_reg) #define info_save_mmu_reg(tick) \ store_max_time_in_system_info(tick,max_mmu_reg) #define info_restore_mmu_reg(tick) \ store_max_time_in_system_info(tick,max_restore_mmu_reg) #define info_save_tir_reg(tick) \ store_max_time_in_system_info(tick,max_tir_reg) #define info_restore_all_reg(tick) \ store_max_time_in_system_info(tick,max_restoring_reg); \ #define cpu_idle_time() \ store_begin_time_in_system_info(max_cpu_idle) #define calculate_cpu_idle_time() \ calculate_max_time_in_system_info(max_cpu_idle) #define store_begin_time_in_system_info(FIELD) \ ({ long t; int cpu; \ register e2k_cr0_hi_t cr0_hi; \ if (enable_collect_interrupt_ticks) { \ cpu = boot_smp_processor_id(); \ t = NATIVE_READ_CLKR_REG_VALUE(); \ AS_WORD(cr0_hi) = NATIVE_NV_READ_CR0_HI_REG_VALUE(); \ system_info[cpu].FIELD.begin_time = tick; \ system_info[cpu].FIELD.beg_ip = NATIVE_READ_IP_REG_VALUE(); \ system_info[cpu].FIELD.beg_parent_ip = \ (AS_STRUCT(cr0_hi)).ip<<3; \ } \ }) #define store_begin_ip_in_system_info(FIELD) \ ({ \ int cpu; \ register e2k_cr0_hi_t cr0_hi; \ cpu = boot_smp_processor_id(); \ disable_interrupt[cpu].clk = NATIVE_READ_CLKR_REG_VALUE(); \ cr0_hi = NATIVE_NV_READ_CR0_HI_REG_VALUE(); \ system_info[cpu].FIELD.beg_ip = NATIVE_READ_IP_REG_VALUE(); \ system_info[cpu].FIELD.beg_parent_ip = \ (AS_STRUCT(cr0_hi)).ip<<3; \ }) #define store_begin_time_ip_in_system_info(cpu, tick, FIELD) \ ({ \ register e2k_cr0_hi_t cr0_hi; \ if (enable_collect_interrupt_ticks) { \ system_info[cpu].FIELD.begin_time = tick; \ cr0_hi = NATIVE_NV_READ_CR0_HI_REG_VALUE(); \ system_info[cpu].FIELD.beg_ip = NATIVE_READ_IP_REG_VALUE(); \ system_info[cpu].FIELD.beg_parent_ip = \ (AS_STRUCT(cr0_hi)).ip<<3; \ } \ }) #define store_end_ip_in_system_info(mutex, FIELD) \ ({ \ int cpu; \ register e2k_cr0_hi_t cr0_hi; \ cpu = boot_smp_processor_id(); \ cr0_hi = NATIVE_NV_READ_CR0_HI_REG_VALUE(); \ system_info[cpu].FIELD.beg_ip = mutex->ip; \ system_info[cpu].FIELD.beg_parent_ip = mutex->caller; \ system_info[cpu].FIELD.end_ip = NATIVE_READ_IP_REG_VALUE(); \ system_info[cpu].FIELD.end_parent_ip = \ (AS_STRUCT(cr0_hi)).ip<<3; \ }) #define calculate_max_time_in_system_info(FIELD) \ ({ \ long t; int cpu; \ register e2k_cr0_hi_t cr0_hi; \ cpu = boot_smp_processor_id(); \ if (enable_collect_interrupt_ticks) { \ t = NATIVE_READ_CLKR_REG_VALUE()-system_info[cpu]. \ FIELD.begin_time; \ system_info[cpu].FIELD.number++; \ system_info[cpu].FIELD.full_time += t; \ if (system_info[cpu].FIELD.max_time < t) { \ system_info[cpu].FIELD.max_time = t; \ system_info[cpu].FIELD.max_beg_ip = \ system_info[cpu].FIELD.beg_ip; \ system_info[cpu].FIELD.max_beg_parent_ip = \ system_info[cpu].FIELD.beg_parent_ip; \ system_info[cpu].FIELD.max_end_ip = \ NATIVE_READ_IP_REG_VALUE(); \ cr0_hi = NATIVE_NV_READ_CR0_HI_REG_VALUE(); \ system_info[cpu].FIELD.max_end_parent_ip = \ (AS_STRUCT(cr0_hi)).ip<<3; \ system_info[cpu].FIELD.max_begin_time = \ system_info[cpu].FIELD.begin_time; \ } \ system_info[cpu].FIELD.begin_time = 0; \ } \ }) extern long TIME; #define store_max_time_in_system_info(tick, FIELD) \ ({ \ long t; int cpu; \ register e2k_cr0_hi_t cr0_hi; \ cpu = boot_smp_processor_id(); \ t = NATIVE_READ_CLKR_REG_VALUE()-tick; \ if (enable_collect_interrupt_ticks) { \ system_info[cpu].FIELD.number++; \ system_info[cpu].FIELD.full_time += t; \ if (system_info[cpu].FIELD.max_time < t) { \ system_info[cpu].FIELD.max_time = t; \ system_info[cpu].FIELD.max_beg_ip = \ system_info[cpu].FIELD.beg_ip; \ system_info[cpu].FIELD.max_beg_parent_ip = \ system_info[cpu].FIELD.beg_parent_ip; \ system_info[cpu].FIELD.max_end_ip = \ NATIVE_READ_IP_REG_VALUE(); \ cr0_hi = NATIVE_NV_READ_CR0_HI_REG_VALUE(); \ system_info[cpu].FIELD.max_end_parent_ip = \ (AS_STRUCT(cr0_hi)).ip<<3; \ system_info[cpu].FIELD.max_begin_time = \ system_info[cpu].FIELD.begin_time; \ } \ system_info[cpu].FIELD.begin_time = 0; \ } \ }) #define UPSR_RESTORE(__src_upsr) \ ({ \ unsigned long upsr1 = READ_UPSR_REG_VALUE(); \ int _cond_ = (upsr1 & UPSR_IE) != ((__src_upsr) & UPSR_IE); \ if (enable_collect_interrupt_ticks && _cond_) { \ if (__src_upsr & UPSR_IE) { \ collect_disable_interrupt_ticks(); \ } else { \ mark_disable_interrupt_ticks(); \ } \ } \ WRITE_UPSR_IRQ_BARRIER(__src_upsr); \ }) #define condition_mark_disable_interrupt_ticks(_cond_) \ ({ \ if (enable_collect_interrupt_ticks) { \ mark_disable_interrupt_ticks(); \ } \ }) #define condition_collect_disable_interrupt_ticks(_cond_) \ ({ \ if (enable_collect_interrupt_ticks && _cond_) { \ collect_disable_interrupt_ticks(); \ } \ }) # else /* !CONFIG_E2K_PROFILING */ #define store_max_time_in_system_info(tick,FIELD) #define calculate_max_time_in_system_info(FIELD) #define store_begin_time_in_system_info(FIELD) #define store_begin_ip_in_system_info(FIELD) #define info_save_tir_reg(tick) #define info_restore_all_reg(tick) #define info_save_stack_reg(tick) #define info_restore_stack_reg(tick) #define info_save_mmu_reg(tick) #define info_restore_mmu_reg(tick) #define cpu_idle_time() #define calculate_cpu_idle_time() #define store_do_irq_ticks() #define define_time_of_do_irq(N) #define condition_collect_disable_interrupt_ticks(_cond_) #define condition_mark_disable_interrupt_ticks(_cond_) #define collect_disable_interrupt_ticks() #define mark_disable_interrupt_ticks() #define add_info_syscall(n, ticks) #define add_info_interrupt(n, ticks) #define read_ticks(n) #define UPSR_RESTORE(__src_upsr) (WRITE_UPSR_IRQ_BARRIER(__src_upsr)) #endif /* CONFIG_E2K_PROFILING */ #define E2K_KERNEL_PSR_ENABLED ((e2k_psr_t) { { \ pm : 1, \ ie : 1, \ sge : 1, \ lw : 0, \ uie : 1, \ nmie : 1, \ unmie : 1, \ } }) #define E2K_KERNEL_PSR_DISABLED ((e2k_psr_t) { { \ pm : 1, \ ie : 0, \ sge : 1, \ lw : 0, \ uie : 0, \ nmie : 0, \ unmie : 0, \ } }) #define E2K_KERNEL_PSR_DIS_LWISH_EN ((e2k_psr_t) { { \ pm : 1, \ ie : 0, \ sge : 1, \ lw : 1, \ uie : 0, \ nmie : 0, \ unmie : 0, \ } }) #define E2K_KERNEL_PSR_LWISH_DIS ((e2k_psr_t) { { \ pm : 1, \ ie : 0, \ sge : 1, \ lw : 0, \ uie : 0, \ nmie : 0, \ unmie : 0, \ } }) #ifndef CONFIG_ACCESS_CONTROL #define E2K_KERNEL_UPSR_ENABLED_ASM 0xa1 #define E2K_KERNEL_UPSR_DISABLED_ALL_ASM 0x01 #define E2K_KERNEL_UPSR_DISABLED ((e2k_upsr_t) { { \ fe : 1, \ se : 0, \ ac : 0, \ a20 : 0, \ ie : 0, \ nmie : 1 \ } }) #define E2K_KERNEL_UPSR_ENABLED ((e2k_upsr_t) { { \ fe : 1, \ se : 0, \ ac : 0, \ a20 : 0, \ ie : 1, \ nmie : 1 \ } }) #define E2K_KERNEL_UPSR_DISABLED_ALL ((e2k_upsr_t) { { \ fe : 1, \ se : 0, \ ac : 0, \ a20 : 0, \ ie : 0, \ nmie : 0 \ } }) #else #define E2K_KERNEL_UPSR_ENABLED_ASM 0xa5 #define E2K_KERNEL_UPSR_DISABLED_ALL_ASM 0x05 #define E2K_KERNEL_UPSR_DISABLED ((e2k_upsr_t) { { \ fe : 1, \ se : 0, \ ac : 1, \ a20 : 0, \ ie : 0, \ nmie : 1 \ } }) #define E2K_KERNEL_UPSR_ENABLED ((e2k_upsr_t) { { \ fe : 1, \ se : 0, \ ac : 1, \ a20 : 0, \ ie : 1, \ nmie : 1 \ } }) #define E2K_KERNEL_UPSR_DISABLED_ALL ((e2k_upsr_t) { { \ fe : 1, \ se : 0, \ ac : 1, \ a20 : 0, \ ie : 0, \ nmie : 0 \ } }) #endif /* ! (CONFIG_ACCESS_CONTROL) */ #define E2K_KERNEL_INITIAL_UPSR E2K_KERNEL_UPSR_DISABLED #define E2K_KERNEL_INITIAL_UPSR_WITH_DISABLED_NMI \ E2K_KERNEL_UPSR_DISABLED_ALL #define E2K_USER_INITIAL_UPSR ((e2k_upsr_t) { { \ fe : 1, \ se : 0, \ ac : 0, \ di : 0, \ wp : 0, \ ie : 0, \ a20 : 0, \ nmie : 0 \ } }) #define E2K_USER_INITIAL_PSR ((e2k_psr_t) { { \ pm : 0, \ ie : 1, \ sge : 1, \ lw : 0, \ uie : 0, \ nmie : 1, \ unmie : 0 \ } }) #define PREFIX_INIT_KERNEL_UPSR_REG(PV_TYPE, irq_en, nmirq_dis) \ do { \ e2k_upsr_t upsr = E2K_KERNEL_UPSR_DISABLED; \ if (irq_en) \ AS(upsr).ie = 1; \ if (nmirq_dis) \ AS(upsr).nmie = 0; \ PV_TYPE##_WRITE_UPSR_REG(upsr); \ } while (0) #define BOOT_PREFIX_INIT_KERNEL_UPSR_REG(PV_TYPE, irq_en, nmirq_dis) \ do { \ e2k_upsr_t upsr = E2K_KERNEL_UPSR_DISABLED; \ if (irq_en) \ AS(upsr).ie = 1; \ if (nmirq_dis) \ AS(upsr).nmie = 0; \ BOOT_##PV_TYPE##_WRITE_UPSR_REG(upsr); \ } while (0) #define NATIVE_INIT_KERNEL_UPSR_REG(irq_en, nmirq_dis) \ PREFIX_INIT_KERNEL_UPSR_REG(NATIVE, irq_en, nmirq_dis) #define BOOT_NATIVE_INIT_KERNEL_UPSR_REG(irq_en, nmirq_dis) \ BOOT_PREFIX_INIT_KERNEL_UPSR_REG(NATIVE, irq_en, nmirq_dis) #define NATIVE_INIT_USER_UPSR_REG() \ NATIVE_WRITE_UPSR_REG(E2K_USER_INITIAL_UPSR) #define INIT_USER_UPSR_REG() WRITE_UPSR_REG(E2K_USER_INITIAL_UPSR) #define PREFIX_SET_KERNEL_UPSR(PV_TYPE) \ ({ \ PV_TYPE##_INIT_KERNEL_UPSR_REG(false, false); \ PV_TYPE##_SWITCH_IRQ_TO_UPSR(); \ }) #define PREFIX_SET_KERNEL_UPSR_WITH_DISABLED_NMI(PV_TYPE) \ ({ \ PV_TYPE##_INIT_KERNEL_UPSR_REG(false, true); \ PV_TYPE##_SWITCH_IRQ_TO_UPSR(); \ }) #define BOOT_PREFIX_SET_KERNEL_UPSR(PV_TYPE) \ ({ \ BOOT_##PV_TYPE##_INIT_KERNEL_UPSR_REG(false, false); \ BOOT_##PV_TYPE##_SWITCH_IRQ_TO_UPSR(); \ }) #define NATIVE_SET_KERNEL_UPSR_WITH_DISABLED_NMI() \ PREFIX_SET_KERNEL_UPSR_WITH_DISABLED_NMI(NATIVE) #define BOOT_NATIVE_SET_KERNEL_UPSR() \ BOOT_PREFIX_SET_KERNEL_UPSR(NATIVE) /* * UPSR should be saved and set to kernel initial state (where interrupts * are disabled) independently of trap or interrupt occurred on user * or kernel process. * In user process case it is as above. * In kernel process case: * Kernel process can be interrupted (so UPSR enable interrupts) * Hardware trap or system call operation disables interrupts mask * in PSR and PSR becomes main register to control interrupts. * Trap handler should switch interrupts control from PSR to UPSR * previously it should set UPSR to initial state for kernel with disabled * interrupts (so UPSR disable interrupts) * If trap handler returns to trap point without UPSR restore, then * interrupted kernel process will have UPSR with disabled interrupts. * So UPSR should be saved and restored in any case * * Trap can occur on light hypercall, where switch of user data stack * to kernel stack is not executed, so these traps handle as user traps * (SBR < TASK_SIZE) Light hypercall already switch control from PSR to UPSR * so it need save current UPSR state (enable/disable interrupts) * to restore this state before return to trapped light hypercall. * Interrupt control by UPSR will be restored from PSR saved into CR1_LO */ #define PREFIX_DO_SWITCH_TO_KERNEL_UPSR(PV_TYPE, pv_type, \ irq_en, nmirq_dis) \ ({ \ PV_TYPE##_INIT_KERNEL_UPSR_REG(irq_en, nmirq_dis); \ PV_TYPE##_SWITCH_IRQ_TO_UPSR(); \ if (!irq_en) \ trace_hardirqs_off(); \ }) #define PREFIX_SWITCH_TO_KERNEL_UPSR(PV_TYPE, pv_type, \ upsr_reg, irq_en, nmirq_dis) \ ({ \ PV_TYPE##_DO_SAVE_UPSR_REG((upsr_reg)); \ PREFIX_DO_SWITCH_TO_KERNEL_UPSR(PV_TYPE, pv_type, \ irq_en, nmirq_dis); \ }) #define BOOT_PREFIX_SWITCH_TO_KERNEL_UPSR(PV_TYPE, pv_type) \ ({ \ unsigned long cur_upsr; \ BOOT_##PV_TYPE##_DO_SAVE_UPSR_REG((cur_upsr)); \ BOOT_##PV_TYPE##_INIT_KERNEL_UPSR_REG(false, false); \ BOOT_##PV_TYPE##_SWITCH_IRQ_TO_UPSR(false); \ }) /* Native version of macroses (all read/write from/to real registers) */ #define NATIVE_DO_SWITCH_TO_KERNEL_UPSR(irq_en, nmirq_dis) \ PREFIX_DO_SWITCH_TO_KERNEL_UPSR(NATIVE, native, \ irq_en, nmirq_dis) #define NATIVE_SWITCH_TO_KERNEL_UPSR(upsr_reg, irq_en, nmirq_dis) \ PREFIX_SWITCH_TO_KERNEL_UPSR(NATIVE, native, \ upsr_reg, irq_en, nmirq_dis) #define NATIVE_RETURN_TO_KERNEL_UPSR(upsr_reg) \ do { \ NATIVE_WRITE_PSR_IRQ_BARRIER(AW(E2K_KERNEL_PSR_DISABLED)); \ NATIVE_DO_RESTORE_UPSR_REG(upsr_reg); \ } while (false) #define PREFIX_RETURN_TO_USER_UPSR(PV_TYPE, pv_type, upsr_reg, under_upsr) \ do { \ PV_TYPE##_WRITE_PSR_IRQ_BARRIER(AW(E2K_KERNEL_PSR_DISABLED)); \ PV_TYPE##_DO_RESTORE_UPSR_REG(upsr_reg); \ } while (false) #define NATIVE_RETURN_TO_USER_UPSR(upsr_reg) \ PREFIX_RETURN_TO_USER_UPSR(NATIVE, native, upsr_reg, true) #define NATIVE_RETURN_PSR_IRQ_TO_USER_UPSR(upsr_reg, lwish_en) \ do { \ if (lwish_en) { \ NATIVE_WRITE_PSR_IRQ_BARRIER(AW(E2K_KERNEL_PSR_DIS_LWISH_EN)); \ } else { \ NATIVE_WRITE_PSR_IRQ_BARRIER(AW(E2K_KERNEL_PSR_LWISH_DIS)); \ } \ NATIVE_DO_RESTORE_UPSR_REG(upsr_reg); \ } while (false) #ifdef CONFIG_ACCESS_CONTROL #define ACCESS_CONTROL_DISABLE_AND_SAVE(upsr_to_save) \ ({ \ e2k_upsr_t upsr; \ upsr_to_save = read_UPSR_reg(); \ upsr = upsr_to_save; \ AS_STRUCT(upsr).ac = 0; \ write_UPSR_reg(upsr); \ }) #define ACCESS_CONTROL_RESTORE(upsr_to_restore) \ ({ \ write_UPSR_reg(upsr_to_restore); \ }) #else /* !CONFIG_ACCESS_CONTROL */ #define ACCESS_CONTROL_DISABLE_AND_SAVE(upsr_to_save) do { } while (0) #define ACCESS_CONTROL_RESTORE(upsr_to_restore) do { } while (0) #endif /* CONFIG_ACCESS_CONTROL */ extern void * __e2k_read_kernel_return_address(int n); /* If n == 0 we can read return address directly from cr0.hi */ #define __e2k_kernel_return_address(n) \ ({ (n == 0) ? \ ((void *) (NATIVE_NV_READ_CR0_HI_REG_VALUE() & ~7UL)) \ : \ __e2k_read_kernel_return_address(n); }) #ifndef CONFIG_CPU_HW_CLEAR_RF typedef void (*clear_rf_t)(void); extern const clear_rf_t clear_rf_fn[]; static __always_inline void clear_rf_kernel_except_current(u64 num_q) { clear_rf_fn[num_q](); } #endif #define SWITCH_TO_KERNEL_UPSR(upsr_reg, irq_en, nmirq_dis) \ NATIVE_SWITCH_TO_KERNEL_UPSR(upsr_reg, irq_en, nmirq_dis) #define RETURN_TO_USER_UPSR(upsr_reg) \ NATIVE_RETURN_TO_USER_UPSR(upsr_reg) #if defined(CONFIG_PARAVIRT_GUEST) #include #elif defined(CONFIG_KVM_GUEST_KERNEL) #include #else /* native kernel */ #define INIT_KERNEL_UPSR_REG NATIVE_INIT_KERNEL_UPSR_REG #define BOOT_SET_KERNEL_UPSR() BOOT_NATIVE_SET_KERNEL_UPSR() #define RETURN_TO_KERNEL_UPSR(upsr_reg) \ NATIVE_RETURN_TO_KERNEL_UPSR(upsr_reg) #define SET_KERNEL_UPSR_WITH_DISABLED_NMI() \ NATIVE_SET_KERNEL_UPSR_WITH_DISABLED_NMI() static inline void *nested_kernel_return_address(int n) { return __e2k_read_kernel_return_address(n); } #endif /* CONFIG_PARAVIRT_GUEST */ #endif /* _E2K_SYSTEM_H_ */