openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

i386.c (4204B)


      1 /* Copyright 1998-1999, Brian J. Swetland. All rights reserved.
      2 ** Copyright 1998-1999, Sidney Cammeresi. All rights reserved.
      3 ** Distributed under the terms of the OpenBLT License
      4 */
      5 
      6 #include "types.h"
      7 #include "i386.h"
      8 #include <i386/io.h>
      9 
     10 void i386SetSegment(void *entry,
     11                     uint32 base, uint32 limit,
     12                     uint8 rights, uint8 gran)
     13 {
     14     *((uint32 *) entry) = (limit & 0xFFFF) | ((base & 0xFFFF) << 16);   
     15 
     16     *((uint32 *) ( ((char *) entry) + 4 ) ) =
     17         ((base & 0x00FF0000) >> 16) | (base & 0xFF000000) |
     18         (rights << 8) | ((gran & 0xF0) << 16) |
     19         ((limit & 0x000F000) << 4);
     20 }
     21 
     22 void i386SetTaskGate(void *entry, uint16 selector, uint8 rights)
     23 {
     24     *((uint32 *) entry) = selector << 16;
     25     *((uint32 *) ( ((char *) entry) + 4 ) ) = (0x05 | (rights & 0xF0)) << 8;  
     26 }
     27 
     28 /* thanks to paul swanson for these... */
     29 
     30 void i386ltr(uint32 selector) 
     31 {
     32     __asm__ __volatile__ ("ltr %%ax": :"eax" (selector));
     33 }
     34 
     35 void i386lidt(uint32 base, uint32 limit) 
     36 {
     37     uint32 i[2];
     38 
     39     i[0] = limit << 16;
     40     i[1] = (uint32) base;
     41     __asm__ __volatile__ ("lidt (%0)": :"p" (((char *) i)+2));
     42 }
     43 
     44 void i386lgdt(uint32 base, uint32 limit) 
     45 {
     46     uint32 i[2];
     47 
     48     i[0] = limit << 16;
     49     i[1] = base;
     50     __asm__ __volatile__ ("lgdt (%0)": :"p" (((char *) i)+2));
     51 }
     52 
     53 uint32 *i386sgdt(uint32 *limit) 
     54 {
     55     uint32 gdtptr[2];
     56     __asm__ __volatile__ ("sgdt (%0)": :"p" (((char *) gdtptr)+2));
     57     *limit = gdtptr[0] >> 16;
     58     return (uint32 *) gdtptr[1];
     59 }
     60 
     61 #if 0
     62 //#ifdef __SMP__
     63 
     64 void remap_irqs (void)
     65 {
     66 	unsigned int i, config;
     67 
     68 	for (i = 0; i < 16; i++)
     69 		{
     70 			config = 
     71 			ioapic_write (IOAPIC_REDIR_TABLE + 2 * i, config);
     72 			config = 0xff << 24; /* logical destination address */
     73 			ioapic_write (IOAPIC_REDIR_TABLE + 2 * i + 1, config);
     74 		}
     75 }
     76 
     77 void unmap_irqs (void)
     78 {
     79 }
     80 
     81 void unmask_irq (int irq)
     82 {
     83 }
     84 
     85 void mask_irq (int irq)
     86 {
     87 }
     88 
     89 #else /* __SMP__ */
     90 
     91 #define PORTA0 0x20
     92 #define PORTB0 0x21
     93 #define PORTA1 0xA0
     94 #define PORTB1 0xA1
     95 
     96 void remap_irqs(void)
     97 {
     98     outb_p(0x11, PORTA0);
     99     outb_p(0x30, PORTB0);
    100     outb_p(0x04, PORTB0);
    101     outb_p(0x01, PORTB0);
    102     outb_p(0xff, PORTB0);                      
    103     
    104     outb_p(0x11, PORTA1);
    105     outb_p(0x38, PORTB1);
    106     outb_p(0x02, PORTB1);
    107     outb_p(0x01, PORTB1);
    108     outb_p(0xff, PORTB1);                       
    109 }
    110 
    111 void unmap_irqs(void)
    112 {
    113     outb_p(0x11, PORTA0);
    114     outb_p(0x08, PORTB0);
    115     outb_p(0x04, PORTB0);
    116     outb_p(0x01, PORTB0);
    117     outb_p(0x00, PORTB0);                       
    118     
    119     outb_p(0x11, PORTA1);
    120     outb_p(0x70, PORTB1);
    121     outb_p(0x02, PORTB1);
    122     outb_p(0x01, PORTB1);    
    123     outb_p(0x00, PORTB1);                       
    124 }
    125 
    126 void unmask_irq(int irq)
    127 {
    128     if(irq < 8)
    129         outb((inb(PORTB0) & ~(1 << irq)), PORTB0);
    130     else
    131         outb((inb(PORTB1) & ~(1 << (irq-8))), PORTB1);
    132 }
    133 
    134 void mask_irq(int irq)
    135 {
    136     if(irq < 8)
    137         outb((inb(PORTB0) | (1 << irq)), PORTB0);
    138     else
    139         outb((inb(PORTB1) | (1 << (irq-8))), PORTB1);
    140 }
    141 
    142 #endif /* __SMP__ */
    143 
    144 static int PIT_COUNTER[2][3]={ { 0x40, 0x41, 0x42 },
    145                               { 0x48, 0x49, 0x4a } };
    146 static int PIT_CONTROL[2] = { 0x43, 0x4b };
    147 
    148 #define PIT_DOSRESET    1       // resert PIT to DOS condition
    149 #define PIT_IKU         2       // start preemptivlly multitasking
    150 
    151 void init_timer(void)
    152 {
    153     outb(0x24,PIT_CONTROL[0]);
    154         /* write to counter 0, binary, high byte, mode 2 */
    155 #if 0
    156     outb(0x2f,PIT_COUNTER[0][0]);
    157         /*0x2f00=12032 * .8380965us ~= 10.083ms*/
    158 #else
    159     outb(0x0e,PIT_COUNTER[0][0]);
    160         /*0x0e00=3584 * .8380965us ~= 3.004ms*/
    161 #endif
    162 }
    163 
    164 void cli (void)
    165 {
    166 	asm ("cli");
    167 }
    168 
    169 void sti (void)
    170 {
    171 	asm ("sti");
    172 }
    173 
    174 void local_flush_tlb (void)
    175 {
    176 	int junk;
    177 
    178 	asm ("mov %%cr3, %0 ; mov %0, %%cr3" : : "r" (junk));
    179 }
    180 
    181 void local_flush_pte (unsigned int addr)
    182 {
    183 #ifdef I386
    184 	local_flush_tlb ();
    185 #else
    186 	asm ("invlpg (%0)" : : "r" (addr));
    187 #endif
    188 }
    189 
    190 void p (unsigned char *lock)
    191 {
    192 	int res;
    193 
    194 	res = 1;
    195 	asm ("lock ; xchgb %1, %0" : "=m" (*lock), "=r" (res) : "1" (res) : "memory");
    196 	while (res)
    197 		asm ("lock ; xchgb %1, %0" : "=m" (*lock), "=r" (res) : "1" (res) :
    198 			"memory");
    199 }
    200 
    201 void v (unsigned char *lock)
    202 {
    203 	asm ("lock ; btrl $0, %0" : "=m" (*lock));
    204 }
    205