From cff1aa3a84ee587535fd532aa7ecfb4dcf518020 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 17 Oct 2000 20:33:24 +0000 Subject: 2000-10-17 Joel Sherrill * idt.c, Makefile.am: Moved idt.c to libbsp/i386/shared so i386 RTEMS can be multilib'ed. --- c/src/lib/libcpu/i386/ChangeLog | 5 + c/src/lib/libcpu/i386/Makefile.am | 3 +- c/src/lib/libcpu/i386/idt.c | 288 -------------------------------------- 3 files changed, 6 insertions(+), 290 deletions(-) delete mode 100644 c/src/lib/libcpu/i386/idt.c (limited to 'c') diff --git a/c/src/lib/libcpu/i386/ChangeLog b/c/src/lib/libcpu/i386/ChangeLog index 98b55ac314..824137322c 100644 --- a/c/src/lib/libcpu/i386/ChangeLog +++ b/c/src/lib/libcpu/i386/ChangeLog @@ -1,3 +1,8 @@ +2000-10-17 Joel Sherrill + + * idt.c, Makefile.am: Moved idt.c to libbsp/i386/shared so + i386 RTEMS can be multilib'ed. + 2000-09-04 Ralf Corsepius * Makefile.am: Include compile.am diff --git a/c/src/lib/libcpu/i386/Makefile.am b/c/src/lib/libcpu/i386/Makefile.am index 778e23c8fb..d3004e56e6 100644 --- a/c/src/lib/libcpu/i386/Makefile.am +++ b/c/src/lib/libcpu/i386/Makefile.am @@ -7,8 +7,7 @@ ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal VPATH = @srcdir@:@srcdir@/../shared/src -C_FILES = cache.c cache_aligned_malloc.c cache_manager.c displayCpu.c idt.c \ - page.c +C_FILES = cache.c cache_aligned_malloc.c cache_manager.c displayCpu.c page.c C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) H_FILES = cache_.h diff --git a/c/src/lib/libcpu/i386/idt.c b/c/src/lib/libcpu/i386/idt.c deleted file mode 100644 index 96eb0ba97f..0000000000 --- a/c/src/lib/libcpu/i386/idt.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * cpu.c - This file contains implementation of C function to - * instantiate IDT entries. More detailled information can be found - * on Intel site and more precisely in the following book : - * - * Pentium Processor family - * Developper's Manual - * - * Volume 3 : Architecture and Programming Manual - * - * Copyright (C) 1998 Eric Valette (valette@crf.canon.fr) - * Canon Centre Recherche France. - * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * $Id$ - */ - -#include -#include - -static rtems_raw_irq_connect_data* raw_irq_table; -static rtems_raw_irq_connect_data default_raw_irq_entry; -static interrupt_gate_descriptor default_idt_entry; -static rtems_raw_irq_global_settings* local_settings; - -void create_interrupt_gate_descriptor (interrupt_gate_descriptor* idtEntry, - rtems_raw_irq_hdl hdl) -{ - idtEntry->low_offsets_bits = (((unsigned) hdl) & 0xffff); - idtEntry->segment_selector = i386_get_cs(); - idtEntry->fixed_value_bits = 0; - idtEntry->gate_type = 0xe; - idtEntry->privilege = 0; - idtEntry->present = 1; - idtEntry->high_offsets_bits = ((((unsigned) hdl) >> 16) & 0xffff); -} - -rtems_raw_irq_hdl get_hdl_from_vector(rtems_vector_offset index) -{ - rtems_raw_irq_hdl hdl; - interrupt_gate_descriptor* idt_entry_tbl; - unsigned limit; - - i386_get_info_from_IDTR (&idt_entry_tbl, &limit); - - /* Convert limit into number of entries */ - limit = (limit + 1) / sizeof(interrupt_gate_descriptor); - - if(index >= limit) { - return 0; - } - - * ((unsigned int*) &hdl) = (idt_entry_tbl[index].low_offsets_bits | - (idt_entry_tbl[index].high_offsets_bits << 16)); - return hdl; -} - -int i386_set_idt_entry (const rtems_raw_irq_connect_data* irq) -{ - interrupt_gate_descriptor* idt_entry_tbl; - unsigned limit; - unsigned int level; - - - i386_get_info_from_IDTR (&idt_entry_tbl, &limit); - - /* Convert limit into number of entries */ - limit = (limit + 1) / sizeof(interrupt_gate_descriptor); - - if (irq->idtIndex >= limit) { - return 0; - } - /* - * Check if default handler is actually connected. If not issue an error. - * You must first get the current handler via i386_get_current_idt_entry - * and then disconnect it using i386_delete_idt_entry. - * RATIONALE : to always have the same transition by forcing the user - * to get the previous handler before accepting to disconnect. - */ - if (get_hdl_from_vector(irq->idtIndex) != default_raw_irq_entry.hdl) { - return 0; - } - - _CPU_ISR_Disable(level); - - raw_irq_table [irq->idtIndex] = *irq; - create_interrupt_gate_descriptor (&idt_entry_tbl[irq->idtIndex], irq->hdl); - irq->on(irq); - - _CPU_ISR_Enable(level); - return 1; -} - -void _CPU_ISR_install_vector (unsigned vector, - void* hdl, - void** oldHdl) -{ - interrupt_gate_descriptor* idt_entry_tbl; - unsigned limit; - interrupt_gate_descriptor new; - unsigned int level; - - i386_get_info_from_IDTR (&idt_entry_tbl, &limit); - - /* Convert limit into number of entries */ - limit = (limit + 1) / sizeof(interrupt_gate_descriptor); - - if (vector >= limit) { - return; - } - _CPU_ISR_Disable(level) - * ((unsigned int *) oldHdl) = idt_entry_tbl[vector].low_offsets_bits | - (idt_entry_tbl[vector].high_offsets_bits << 16); - - create_interrupt_gate_descriptor(&new, hdl); - idt_entry_tbl[vector] = new; - - _CPU_ISR_Enable(level); -} - -int i386_get_current_idt_entry (rtems_raw_irq_connect_data* irq) -{ - interrupt_gate_descriptor* idt_entry_tbl; - unsigned limit; - - i386_get_info_from_IDTR (&idt_entry_tbl, &limit); - - /* Convert limit into number of entries */ - limit = (limit + 1) / sizeof(interrupt_gate_descriptor); - - if (irq->idtIndex >= limit) { - return 0; - } - raw_irq_table [irq->idtIndex].hdl = get_hdl_from_vector(irq->idtIndex); - - *irq = raw_irq_table [irq->idtIndex]; - - return 1; -} - -int i386_delete_idt_entry (const rtems_raw_irq_connect_data* irq) -{ - interrupt_gate_descriptor* idt_entry_tbl; - unsigned limit; - unsigned int level; - - i386_get_info_from_IDTR (&idt_entry_tbl, &limit); - - /* Convert limit into number of entries */ - limit = (limit + 1) / sizeof(interrupt_gate_descriptor); - - if (irq->idtIndex >= limit) { - return 0; - } - /* - * Check if handler passed is actually connected. If not issue an error. - * You must first get the current handler via i386_get_current_idt_entry - * and then disconnect it using i386_delete_idt_entry. - * RATIONALE : to always have the same transition by forcing the user - * to get the previous handler before accepting to disconnect. - */ - if (get_hdl_from_vector(irq->idtIndex) != irq->hdl){ - return 0; - } - _CPU_ISR_Disable(level); - - idt_entry_tbl[irq->idtIndex] = default_idt_entry; - - irq->off(irq); - - raw_irq_table[irq->idtIndex] = default_raw_irq_entry; - raw_irq_table[irq->idtIndex].idtIndex = irq->idtIndex; - - _CPU_ISR_Enable(level); - - return 1; -} - -/* - * Caution this function assumes the IDTR has been already set. - */ -int i386_init_idt (rtems_raw_irq_global_settings* config) -{ - unsigned limit; - unsigned i; - unsigned level; - interrupt_gate_descriptor* idt_entry_tbl; - - i386_get_info_from_IDTR (&idt_entry_tbl, &limit); - - /* Convert limit into number of entries */ - limit = (limit + 1) / sizeof(interrupt_gate_descriptor); - - if (config->idtSize != limit) { - return 0; - } - /* - * store various accelarators - */ - raw_irq_table = config->rawIrqHdlTbl; - local_settings = config; - default_raw_irq_entry = config->defaultRawEntry; - - _CPU_ISR_Disable(level); - - create_interrupt_gate_descriptor (&default_idt_entry, default_raw_irq_entry.hdl); - - for (i=0; i < limit; i++) { - interrupt_gate_descriptor new; - create_interrupt_gate_descriptor (&new, raw_irq_table[i].hdl); - idt_entry_tbl[i] = new; - if (raw_irq_table[i].hdl != default_raw_irq_entry.hdl) { - raw_irq_table[i].on(&raw_irq_table[i]); - } - else { - raw_irq_table[i].off(&raw_irq_table[i]); - } - } - _CPU_ISR_Enable(level); - - return 1; -} - -int i386_get_idt_config (rtems_raw_irq_global_settings** config) -{ - *config = local_settings; - return 1; -} - -/* - * Caution this function assumes the GDTR has been already set. - */ -int i386_set_gdt_entry (unsigned short segment_selector, unsigned base, - unsigned limit) -{ - unsigned gdt_limit; - unsigned short tmp_segment = 0; - unsigned int limit_adjusted; - segment_descriptors* gdt_entry_tbl; - - - i386_get_info_from_GDTR (&gdt_entry_tbl, &gdt_limit); - - if (segment_selector > limit) { - return 0; - } - /* - * set up limit first - */ - limit_adjusted = limit; - if ( limit > 4095 ) { - gdt_entry_tbl[segment_selector].granularity = 1; - limit_adjusted /= 4096; - } - gdt_entry_tbl[segment_selector].limit_15_0 = limit_adjusted & 0xffff; - gdt_entry_tbl[segment_selector].limit_19_16 = (limit_adjusted >> 16) & 0xf; - /* - * set up base - */ - gdt_entry_tbl[segment_selector].base_address_15_0 = base & 0xffff; - gdt_entry_tbl[segment_selector].base_address_23_16 = (base >> 16) & 0xff; - gdt_entry_tbl[segment_selector].base_address_31_24 = (base >> 24) & 0xff; - /* - * set up descriptor type (this may well becomes a parameter if needed) - */ - gdt_entry_tbl[segment_selector].type = 2; /* Data R/W */ - gdt_entry_tbl[segment_selector].descriptor_type = 1; /* Code or Data */ - gdt_entry_tbl[segment_selector].privilege = 0; /* ring 0 */ - gdt_entry_tbl[segment_selector].present = 1; /* not present */ - - /* - * 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) - ); - - return 1; -} -- cgit v1.2.3