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