From 67a2288991ce3662a588ee83c0bea9c9efae5f1e Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 23 Jul 1998 22:02:34 +0000 Subject: Patch from Eric VALETTE : Here is a enhanced version of my previous patch. This patch enables to potentially share the new interrupt management code for all Intel targets (pc386, go32 and force386) bsp. Note : this patch is complete only for pc386. It still needs to be completed for go32 and force386. I carrefully checked that anything needed is in for force386 (only some function name changes for IDT manipulation and GDT segment manipulation). But anyway I will not be able to test any of theses targets... --- c/src/exec/score/cpu/i386/cpu.c | 99 -------------- c/src/exec/score/cpu/i386/cpu.h | 2 + c/src/exec/score/cpu/i386/cpu_asm.s | 40 ------ c/src/exec/score/cpu/i386/i386.h | 257 ------------------------------------ 4 files changed, 2 insertions(+), 396 deletions(-) (limited to 'c/src/exec/score/cpu') diff --git a/c/src/exec/score/cpu/i386/cpu.c b/c/src/exec/score/cpu/i386/cpu.c index 2ad1528a89..abdb3f2702 100644 --- a/c/src/exec/score/cpu/i386/cpu.c +++ b/c/src/exec/score/cpu/i386/cpu.c @@ -76,102 +76,3 @@ unsigned32 _CPU_ISR_Get_level( void ) return level; } -/*PAGE - * - * _CPU_ISR_install_raw_handler - */ - -#if __GO32__ -#include -#include -#endif /* __GO32__ */ - -void _CPU_ISR_install_raw_handler( - unsigned32 vector, - proc_ptr new_handler, - proc_ptr *old_handler -) -{ -#if __GO32__ - _go32_dpmi_seginfo handler_info; - - /* get the address of the old handler */ - _go32_dpmi_get_protected_mode_interrupt_vector( vector, &handler_info); - - /* Notice how we're failing to save the pm_segment portion of the */ - /* structure here? That means we might crash the system if we */ - /* try to restore the ISR. Can't fix this until i386_isr is */ - /* redefined. XXX [BHC]. */ - *old_handler = (proc_ptr *) handler_info.pm_offset; - - handler_info.pm_offset = (u_long) new_handler; - handler_info.pm_selector = _go32_my_cs(); - - /* install the IDT entry */ - _go32_dpmi_set_protected_mode_interrupt_vector( vector, &handler_info ); -#else - i386_IDT_slot idt; - unsigned32 handler; - - *old_handler = 0; /* XXX not supported */ - - handler = (unsigned32) new_handler; - - /* build the IDT entry */ - idt.offset_0_15 = handler & 0xffff; - idt.segment_selector = i386_get_cs(); - idt.reserved = 0x00; - idt.p_dpl = 0x8e; /* present, ISR */ - idt.offset_16_31 = handler >> 16; - - /* install the IDT entry */ - i386_Install_idt( - (unsigned32) &idt, - _CPU_Table.interrupt_table_segment, - (unsigned32) _CPU_Table.interrupt_table_offset + (8 * vector) - ); -#endif -} - -/*PAGE - * - * _CPU_ISR_install_vector - * - * This kernel routine installs the RTEMS handler for the - * specified vector. - * - * Input parameters: - * vector - interrupt vector number - * old_handler - former ISR for this vector number - * new_handler - replacement ISR for this vector number - * - * Output parameters: NONE - * - */ - -void _ISR_Handler_0(), _ISR_Handler_1(); - -#define PER_ISR_ENTRY \ - (((unsigned32) _ISR_Handler_1 - (unsigned32) _ISR_Handler_0)) - -#define _Interrupt_Handler_entry( _vector ) \ - (((unsigned32)_ISR_Handler_0) + ((_vector) * PER_ISR_ENTRY)) - -void _CPU_ISR_install_vector( - unsigned32 vector, - proc_ptr new_handler, - proc_ptr *old_handler -) -{ - proc_ptr ignored; - unsigned32 unique_handler; - - *old_handler = _ISR_Vector_table[ vector ]; - - /* calculate the unique entry point for this vector */ - unique_handler = _Interrupt_Handler_entry( vector ); - - _CPU_ISR_install_raw_handler( vector, (void *)unique_handler, &ignored ); - - _ISR_Vector_table[ vector ] = new_handler; -} diff --git a/c/src/exec/score/cpu/i386/cpu.h b/c/src/exec/score/cpu/i386/cpu.h index 42ec7db6f5..4bca613eb7 100644 --- a/c/src/exec/score/cpu/i386/cpu.h +++ b/c/src/exec/score/cpu/i386/cpu.h @@ -22,6 +22,8 @@ extern "C" { #endif #include /* pick up machine definitions */ +#include + #ifndef ASM #include #endif diff --git a/c/src/exec/score/cpu/i386/cpu_asm.s b/c/src/exec/score/cpu/i386/cpu_asm.s index 2bc63fa1d5..b84d41afc2 100644 --- a/c/src/exec/score/cpu/i386/cpu_asm.s +++ b/c/src/exec/score/cpu/i386/cpu_asm.s @@ -552,46 +552,6 @@ SYM (_ISR_Dispatch): */ #ifndef __GO32__ -/*PAGE - * - * void i386_Install_idt( - * unsigned32 source_offset, - * unsigned16 destination_segment, - * unsigned32 destination_offset - * ); - */ - - .p2align 2 - PUBLIC (i386_Install_idt) - -.set INSTALL_IDT_SAVED_REGS, 8 - -.set SOURCE_OFFSET_ARG, INSTALL_IDT_SAVED_REGS + 4 -.set DESTINATION_SEGMENT_ARG, INSTALL_IDT_SAVED_REGS + 8 -.set DESTINATION_OFFSET_ARG, INSTALL_IDT_SAVED_REGS + 12 - -SYM (i386_Install_idt): - push esi - push edi - - movl SOURCE_OFFSET_ARG(esp),esi - movl DESTINATION_OFFSET_ARG(esp),edi - - pushf # save flags - cli # DISABLE INTERRUPTS!!! - - movw DESTINATION_SEGMENT_ARG+4(esp),ax - push es # save es - movw ax,es - movsl # copy 1st half of IDT entry - movsl # copy 2nd half of IDT entry - pop es # restore es - - popf # ENABLE INTERRUPTS!!! - - pop edi - pop esi - ret /* * void *i386_Logical_to_physical( diff --git a/c/src/exec/score/cpu/i386/i386.h b/c/src/exec/score/cpu/i386/i386.h index dfb8b062f6..9e49b5ab84 100644 --- a/c/src/exec/score/cpu/i386/i386.h +++ b/c/src/exec/score/cpu/i386/i386.h @@ -98,82 +98,6 @@ extern "C" { #ifndef ASM -/* - * Structure which makes it easier to deal with LxDT and SxDT instructions. - */ - -typedef struct { - unsigned short limit; - unsigned short physical_address[ 2 ]; -} i386_DTR_load_save_format; - -/* See Chapter 5 - Memory Management in i386 manual */ - -typedef struct { - unsigned short limit_0_15; - unsigned short base_0_15; - unsigned char base_16_23; - unsigned char type_dt_dpl_p; - unsigned char limit_16_19_granularity; - unsigned char base_24_31; -} i386_GDT_slot; - -/* See Chapter 9 - Exceptions and Interrupts in i386 manual - * - * NOTE: This is the IDT entry for interrupt gates ONLY. - */ - -typedef struct { - unsigned short offset_0_15; - unsigned short segment_selector; - unsigned char reserved; - unsigned char p_dpl; - unsigned short offset_16_31; -} i386_IDT_slot; - -/* - * Interrupt Level Macros - */ - -#define i386_disable_interrupts( _level ) \ - { \ - _level = 0; /* avoids warnings */ \ - asm volatile ( "pushf ; \ - cli ; \ - pop %0" \ - : "=r" ((_level)) : "0" ((_level)) \ - ); \ - } - -#define i386_enable_interrupts( _level ) \ - { \ - asm volatile ( "push %0 ; \ - popf" \ - : "=r" ((_level)) : "0" ((_level)) \ - ); \ - } - -#define i386_flash_interrupts( _level ) \ - { \ - asm volatile ( "push %0 ; \ - popf ; \ - cli" \ - : "=r" ((_level)) : "0" ((_level)) \ - ); \ - } - -#define i386_get_interrupt_level( _level ) \ - do { \ - register unsigned32 _eflags = 0; \ - \ - asm volatile ( "pushf ; \ - pop %0" \ - : "=r" ((_eflags)) : "0" ((_eflags)) \ - ); \ - \ - _level = (_eflags & 0x0200) ? 0 : 1; \ - } while (0) - /* * The following routine swaps the endian format of an unsigned int. * It must be static so it can be referenced indirectly. @@ -205,67 +129,6 @@ static inline unsigned int i386_swap_U16( return (sout); } -/* - * Segment Access Routines - * - * NOTE: Unfortunately, these are still static inlines even when the - * "macro" implementation of the generic code is used. - */ - -static inline unsigned short i386_get_cs() -{ - register unsigned short segment = 0; - - asm volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) ); - - return segment; -} - -static inline unsigned short i386_get_ds() -{ - register unsigned short segment = 0; - - asm volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) ); - - return segment; -} - -static inline unsigned short i386_get_es() -{ - register unsigned short segment = 0; - - asm volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) ); - - return segment; -} - -static inline unsigned short i386_get_ss() -{ - register unsigned short segment = 0; - - asm volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) ); - - return segment; -} - -static inline unsigned short i386_get_fs() -{ - register unsigned short segment = 0; - - asm volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) ); - - return segment; -} - -static inline unsigned short i386_get_gs() -{ - register unsigned short segment = 0; - - asm volatile ( "movw %%gs,%0" : "=r" (segment) : "0" (segment) ); - - return segment; -} - /* * IO Port Access Routines */ @@ -327,101 +190,6 @@ static inline unsigned short i386_get_gs() _value = __value; \ } -/* - * Descriptor Table helper routines - */ - - -#define i386_get_GDTR( _gdtr_address ) \ - { \ - void *_gdtr = (_gdtr_address); \ - \ - asm volatile( "sgdt (%0)" : "=r" (_gdtr) : "0" (_gdtr) ); \ - } - -#define i386_get_GDT_slot( _gdtr_base, _segment, _slot_address ) \ - { \ - register unsigned int _gdt_slot = (_gdtr_base) + (_segment); \ - register volatile void *_slot = (_slot_address); \ - register unsigned int _temporary = 0; \ - \ - asm volatile( "movl %%gs:(%0),%1 ; \ - movl %1,(%2) ; \ - movl %%gs:4(%0),%1 ; \ - movl %1,4(%2)" \ - : "=r" (_gdt_slot), "=r" (_temporary), "=r" (_slot) \ - : "0" (_gdt_slot), "1" (_temporary), "2" (_slot) \ - ); \ - } - -#define i386_set_GDT_slot( _gdtr_base, _segment, _slot_address ) \ - { \ - register unsigned int _gdt_slot = (_gdtr_base) + (_segment); \ - register volatile void *_slot = (_slot_address); \ - register unsigned int _temporary = 0; \ - \ - asm volatile( "movl (%2),%1 ; \ - movl %1,%%gs:(%0) ; \ - movl 4(%2),%1 ; \ - movl %1,%%gs:4(%0) \ - " \ - : "=r" (_gdt_slot), "=r" (_temporary), "=r" (_slot) \ - : "0" (_gdt_slot), "1" (_temporary), "2" (_slot) \ - ); \ - } - -static inline void i386_set_segment( - unsigned short segment, - unsigned int base, - unsigned int limit -) -{ - i386_DTR_load_save_format gdtr; - volatile i386_GDT_slot Gdt_slot; - volatile i386_GDT_slot *gdt_slot = &Gdt_slot; - unsigned short tmp_segment = 0; - unsigned int limit_adjusted; - - /* load physical address of the GDT */ - - i386_get_GDTR( &gdtr ); - - gdt_slot->type_dt_dpl_p = 0x92; /* present, dpl=0, */ - /* application=1, */ - /* type=data read/write */ - gdt_slot->limit_16_19_granularity = 0x40; /* 32 bit segment */ - - limit_adjusted = limit; - if ( limit > 4095 ) { - gdt_slot->limit_16_19_granularity |= 0x80; /* set granularity bit */ - limit_adjusted /= 4096; - } - - gdt_slot->limit_16_19_granularity |= (limit_adjusted >> 16) & 0xff; - gdt_slot->limit_0_15 = limit_adjusted & 0xffff; - - gdt_slot->base_0_15 = base & 0xffff; - gdt_slot->base_16_23 = (base >> 16) & 0xff; - gdt_slot->base_24_31 = (base >> 24); - - i386_set_GDT_slot( - gdtr.physical_address[0] + (gdtr.physical_address[1] << 16), - segment, - gdt_slot - ); - - /* Now, reload all segment registers so the limit takes effect. */ - - asm volatile( "movw %%ds,%0 ; movw %0,%%ds - movw %%es,%0 ; movw %0,%%es - movw %%fs,%0 ; movw %0,%%fs - movw %%gs,%0 ; movw %0,%%gs - movw %%ss,%0 ; movw %0,%%ss" - : "=r" (tmp_segment) - : "0" (tmp_segment) - ); - -} /* routines */ @@ -447,17 +215,6 @@ void *i386_Physical_to_logical( void *address ); -/* - * i386_Install_idt - * - * This routine installs an IDT entry. - */ - -void i386_Install_idt( - unsigned int source_offset, - unsigned short destination_segment, - unsigned int destination_offset -); /* * "Simpler" names for a lot of the things defined in this file @@ -484,20 +241,6 @@ void i386_Install_idt( #define inport_word( _port, _value ) i386_inport_word( _port, _value ) #define inport_long( _port, _value ) i386_inport_long( _port, _value ) -/* complicated static inline functions */ - -#define get_GDTR( _gdtr_address ) \ - i386_get_GDTR( _gdtr_address ) - -#define get_GDT_slot( _gdtr_base, _segment, _slot_address ) \ - i386_get_GDT_slot( _gdtr_base, _segment, _slot_address ) - -#define set_GDT_slot( _gdtr_base, _segment, _slot_address ) \ - i386_set_GDT_slot( _gdtr_base, _segment, _slot_address ) - -#define set_segment( _segment, _base, _limit ) \ - i386_set_segment( _segment, _base, _limit ) - #ifdef __cplusplus } -- cgit v1.2.3