Chameleon

Chameleon Commit Details

Date:2015-03-05 20:33:41 (9 years 1 month ago)
Author:ErmaC
Commit:2592
Parents: 2591
Message:Merge Interrupt Management changes from Zenith432 branch
Changes:
A/trunk/i386/libsa/interrupts.c
M/trunk/i386/libsa/Makefile
M/trunk/i386/boot2/boot.c
M/trunk/i386/boot2/gui.c
M/trunk/i386/libsa/libsa.h
M/trunk/CHANGES
M/trunk/i386/libsaio/bios.s
M/trunk/i386/boot2/options.c
M/trunk/i386/libsaio/biosfn.c

File differences

trunk/i386/libsaio/bios.s
106106
107107
108108
109
110
109111
110112
111113
......
179181
180182
181183
184
182185
183186
184187
*/
LABEL(_bios)
enter $0, $0
pushfl
cli
pushal
movl 8(%ebp), %edx // address of save area
movl %ebp, O_EBP(%edx)
popal
popfl
leave
ret
trunk/i386/libsaio/biosfn.c
5353
5454
5555
56
5657
5758
5859
5960
6061
6162
63
64
6265
6366
6467
......
8588
8689
8790
91
8892
8993
9094
9195
96
97
98
9299
93100
94101
......
96103
97104
98105
106
99107
100108
101109
......
112120
113121
114122
123
124
125
126
115127
116128
117129
130
131
118132
119133
120134
......
578592
579593
580594
581
595
582596
583597
584598
......
741755
742756
743757
758
744759
745760
746761
......
750765
751766
752767
768
753769
754770
755771
......
807823
808824
809825
810
826
811827
812828
813829
......
820836
821837
822838
823
839
824840
825841
826842
......
977993
978994
979995
996
980997
981998
982999
......
9971014
9981015
9991016
1017
10001018
10011019
10021020
1003
1004
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
10051031
10061032
10071033
int bgetc(void)
{
#if 0
/* Poll for the next character. Most real BIOS do not need this as the
INT 16h,AH=0h function will block until one is received.
Unfortunately, Apple's EFI CSM will never wake up. This idea is lifted
from the grub-a20.patch to GRUB's stage2/asm.S file.
*/
while(!readKeyboardStatus());
// Apple's EFI CSM???? Who cares - Zenith432
#endif
bb.intno = 0x16;
bb.eax.r.h = 0x00;
int readKeyboardShiftFlags(void)
{
#if 0
bb.intno = 0x16;
bb.eax.r.h = 0x02;
bios(&bb);
return bb.eax.r.l;
#else
return *(uint8_t const volatile*) 0x417U;
#endif
}
unsigned int time18(void)
{
#if 0
union {
struct {
unsigned int low:16;
time.s.high = bb.ecx.rr;
return time.i;
#else
(void) __sync_lock_test_and_set((uint8_t volatile*) 0x470U, (uint8_t) 0U);
return *(uint32_t const volatile*) 0x46CU;
#endif
}
#if 0
static unsigned long rerangeMemoryMap(unsigned long count);
static unsigned long rerangeMemoryMap(unsigned long count)
{
int i, still_changing, newcount = count;
/*
* BIOS drive information.
*/
void print_drive_info(boot_drive_info_t *dp)
static void print_drive_info(boot_drive_info_t *dp)
{
//printf("buf_size = %x\n", dp->params.buf_size);
printf("info_flags = %x\n", dp->params.info_flags);
//==============================================================================
#if UNUSED
int ebiosEjectMedia(int biosdev)
{
bb.intno = 0x13;
bios(&bb);
return bb.eax.r.h;
}
#endif
void setCursorPosition(int x, int y, int page)
{
#if DEBUG
int terminateDiskEmulation()
static int terminateDiskEmulation()
{
static char cd_spec[0x13];
return bb.eax.r.h;
}
int readDriveParameters(int drive, struct driveParameters *dp)
static int readDriveParameters(int drive, struct driveParameters *dp)
{
bb.intno = 0x13;
bb.edx.r.l = drive;
}
#endif /* EISA_SUPPORT */
#if UNUSED
#define PCI_SIGNATURE 0x20494350 /* "PCI " */
int
}
return -1;
}
#endif
void sleep(int n)
{
unsigned int endtime = (time18() + 18*n);
while (time18() < endtime);
// FIXME: doesn't handle midnight wraparound
unsigned int endtime = (time18() + 18*n);
#ifdef __i386__
while (time18() < endtime)
{
__asm__ volatile ("rep; nop");
}
#else
while (time18() < endtime);
#endif
}
trunk/i386/boot2/boot.c
7777
7878
7979
80
81
8082
8183
8284
......
199201
200202
201203
204
205
206
207
202208
203209
204210
......
224230
225231
226232
233
234
235
236
237
227238
228239
229240
......
235246
236247
237248
249
250
251
252
253
254
238255
239256
240257
241258
242
259
243260
244261
245
246262
247263
248264
......
439455
440456
441457
458
459
460
461
462
463
464
442465
443466
444467
......
833856
834857
835858
859
860
861
862
863
836864
837865
838866
boolgScanSingleDrive;
booluseGUI;
static intinterruptsAvailable = 0;
static boolgUnloadPXEOnExit = false;
static chargCacheNameAdler[64 + 256];
usb_loop();
#if DEBUG
if (interruptsAvailable) ShowInterruptCounters();
#endif
// If we were in text mode, switch to graphics mode.
// This will draw the boot graphics unless we are in
// verbose mode.
// Notify modules that the kernel is about to be started
execute_hook("Kernel Start", (void *)kernelEntry, (void *)bootArgs, NULL, NULL);
if (interruptsAvailable)
{
DisableInterrupts();
}
// Masking out so that Lion doesn't doublefault
outb(0x21, 0xff);/* Maskout all interrupts Pic1 */
outb(0xa1, 0xff);/* Maskout all interrupts Pic2 */
// Notify modules that the kernel is about to be started
execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgsPreLion, NULL, NULL);
if (interruptsAvailable)
{
DisableInterrupts();
}
startprog( kernelEntry, bootArgsPreLion );
}
// Not reached
return 0;
__builtin_unreachable();
}
//==========================================================================
// LoadKernelCache - Try to load Kernel Cache.
// return the length of the loaded cache file or -1 on error
// Initialize boot-log
initBooterLog();
// Enable interrupts
interruptsAvailable = SetupInterrupts();
if (interruptsAvailable)
{
EnableInterrupts();
}
// Initialize boot info structure.
initKernBootStruct();
{
nbpUnloadBaseCode();
}
if (interruptsAvailable)
{
DisableInterrupts();
}
}
/*!
trunk/i386/boot2/gui.c
20722072
20732073
20742074
2075
20752076
20762077
20772078
......
20922093
20932094
20942095
2096
20952097
20962098
20972099
......
21512153
21522154
21532155
2156
21542157
2158
21552159
21562160
21572161
// ====================================================================
#if UNUSED
void animateProgressBar()
{
int y;
pixel(buffBar, buffBar->width-1, 0).value = buff;
}
}
#endif
// ====================================================================
}
blend(&progressbar, blendInto, p);
#if 0
animateProgressBar();
#endif
free(progressbar.pixels);
}
trunk/i386/boot2/options.c
190190
191191
192192
193
193
194
194195
195
196
196
197
198
199
200
201
202
203
204
205
197206
207
208
209
210
198211
199212
200213
......
207220
208221
209222
210
223
211224
212225
213226
for ( time = time18(), timeout++; timeout > 0; )
{
if( time18() > lasttime)
int currenttime;
if (lasttime)
{
multi--;
lasttime=time18();
currenttime = time18();
if( currenttime > lasttime)
{
multi -= (currenttime - lasttime);
if (multi < 0)
{
multi = 0;
}
lasttime=currenttime;
}
}
else
{
lasttime = currenttime = time;
}
if ( (ch = readKeyboardStatus()) )
break;
break;
}
if ( time18() >= time )
if ( currenttime >= time )
{
time += 18;
timeout--;
trunk/i386/libsa/interrupts.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
#ifdef __i386__
#include "libsa.h"
#include "saio_internal.h"
#ifdef DEBUG_INTERRUPTS
#define DBG(x...) printf(x)
#else
#define DBG(x...)
#endif
#define CODE_SEGMENT_SELECTOR 0x28U
#define CODED_EXCEPTION_MASK 0x27D00U
#define IA32_APIC_BASE 27U
#define IA32_APIC_BASE_BSP 0x100U
#define IA32_APIC_BASE_EN 0x800U
#define LAPIC_WANTED_FLAGS (IA32_APIC_BASE_EN | IA32_APIC_BASE_BSP)
#define LAPIC_EOI_OFFSET 0xB0U
#define LAPIC_ISR_OFFSET 0x100U
#define PIC_READ_ISR_COMMAND 11U
#define PIC_EOI_COMMAND 0x20U
#define PIC_PORT0 0
#define PIC_PORT1 1
#define BDA_TICK_COUNT 0x46CU// DWORD
#define BDA_MIDNIGHT_FLAG 0x470U// BYTE
#define BDA_24HR_TURNOVER 0x1800B0U
enum InterruptSources
{
IS_Unknown = 0,
IS_APIC = 1,// Covers both LAPIC and IOAPIC
IS_PIC0 = 2,
IS_PIC1 = 3,
IS_Software = 4
};
struct InterruptFrame
{
uint32_t edx;
uint32_t ecx;
uint32_t eax;
uint32_t index;
uint32_t eip;
uint32_t cs;
uint32_t eflags;
};
struct ExceptionFrame
{
uint32_t edi;
uint32_t esi;
uint32_t ebp;
uint32_t esp;
uint32_t ebx;
uint32_t edx;
uint32_t ecx;
uint32_t eax;
uint32_t index;
uint32_t exception_code;
uint32_t eip;
uint32_t cs;
uint32_t eflags;
};
struct InterruptGate
{
uint16_t offset_0_15;
uint16_t selector;
uint16_t flags;
uint16_t offset_16_31;
};
#pragma mark -
#pragma mark Global Data
#pragma mark -
extern
uint16_t Idtr_prot[];
static
uint32_t* counters = NULL;
static
uint32_t lapic_base = 0U;
static
uint8_t const PicPorts[2][2] = { { 0x20U, 0x21U }, { 0xA0U, 0xA1U } };
#pragma mark -
#pragma mark Assembly Stubs
#pragma mark -
static
__attribute__((naked, noreturn))
void InterruptStub(void)
{
__asm__ volatile ("pushl %%eax\n\t"
"pushl %%ecx\n\t"
"pushl %%edx\n\t"
"pushl %%esp\n\t"
"calll _InterruptHandler\n\t"
"addl $4, %%esp\n\t"
"popl %%edx\n\t"
"popl %%ecx\n\t"
"popl %%eax\n\t"
"addl $4, %%esp\n\t"
"iretl"
:);
}
static
__attribute__((naked, noreturn))
void ExceptionWithCodeStub(void)
{
__asm__ volatile("testl $-57, 8(%%esp)\n\t"
"je 0f\n\t"
"pushal\n\t"
"jmp 1f\n"
"_ExceptionNoCodeStub:\n"
"0:\tsub $4, %%esp\n\t"
"pushal\n\t"
"xorl %%eax, %%eax\n\t"
"xchgl %%eax, 36(%%esp)\n\t"
"movl %%eax, 32(%%esp)\n"
"1:\taddl $20, 12(%%esp)\n\t"
"pushl %%esp\n\t"
"calll _ExceptionHandler\n\t"
"addl $4, %%esp\n\t"
"popal\n\t"
"addl $8, %%esp\n\t"
"iretl"
:);
}
/*
* Make _ExceptionNoCodeStub accessible to C
*/
static
__attribute__((naked, noreturn, weakref("ExceptionNoCodeStub")))
void ExceptionNoCodeStubAlias(void);
static
__attribute__((/* naked, */noinline, regparm(1), section("__INIT,__text")))
void DispatchBiosVector(uint8_t vector)
{
__asm__ volatile ("movb %0, 0f + 1\n\t"
"calll __prot_to_real\n\t"
".code16\n"
"0:\tint $0\n\t"
"calll __real_to_prot\n\t"
".code32"
: : "r"(vector));
}
static
__attribute__((noreturn, noinline, section("__INIT,__text")))
void DisplayErrorAndStop(void)
{
__asm__ volatile ("calll __prot_to_real\n\t"
".code16\n\t"
"movw $2, %%ax\n\t"
"int $0x10\n\t"
"xorw %%ax, %%ax\n\t"
"movw %%ax, %%ds\n\t"
"movw $0x6000, %%si\n\t"
"cld\n"
"0:\tlodsb\n\t"
"testb %%al, %%al\n\t"
"je 1f\n\t"
"movb $0xE, %%ah\n\t"
"movw $0xFF, %%bx\n\t"
"int $0x10\n\t"
"jmp 0b\n"
"1:\thlt\n\t"
"jmp 1b\n\t"
".code32"
:);
__builtin_unreachable();
}
#pragma mark -
#pragma mark Other Inline Assembly
#pragma mark -
static inline
uint32_t ReadLapic(uint32_t offset)
{
return *(uint32_t const volatile*) (lapic_base + offset);
}
static inline
void WriteLapic(uint32_t offset, uint32_t value)
{
*(uint32_t volatile*) (lapic_base + offset) = value;
}
static inline
uint8_t ReadPic(int pic, int index)
{
uint8_t value;
__asm__ volatile ("inb %1, %0" : "=a"(value) : "N"(PicPorts[pic][index]));
return value;
}
static inline
void WritePic(int pic, int index, uint8_t value)
{
__asm__ volatile ("outb %0, %1" : : "a"(value), "N"(PicPorts[pic][index]));
}
#pragma mark -
#pragma mark Main Code
#pragma mark -
static
int IdentifyInterruptSource(uint8_t vector, uint32_t eip)
{
if (lapic_base)
{
uint32_t value = ReadLapic(LAPIC_ISR_OFFSET + ((vector & 0xE0U) >> 1));
if (value & (1U << (vector & 31U)))
return IS_APIC;
}
if (vector >= 8U && vector < 16U)
{
uint8_t value;
WritePic(0, PIC_PORT0, PIC_READ_ISR_COMMAND);
value = ReadPic(0, PIC_PORT0);
if (value & (1U << (vector & 7U)))
return IS_PIC0;
}
if (vector >= 0x70U && vector < 0x78U)
{
uint8_t value;
WritePic(1, PIC_PORT0, PIC_READ_ISR_COMMAND);
value = ReadPic(1, PIC_PORT0);
if (value & (1U << (vector & 7U)))
return IS_PIC1;
}
if (eip)
{
uint8_t const volatile* pInstruction = (uint8_t const volatile*) (eip - 2U);
if ((*pInstruction) == 0xCDU && pInstruction[1] == vector)
return IS_Software;
/*
* There are other software interrupt opcodes
* debug breakpoint 0xCC
* interrupt on overflow 0xCE
* bound instruction 0x62
* but those all trigger specific vectors, so are handled as exceptions.
*/
}
return IS_Unknown;
}
static
void SignalEOI(int source)
{
switch (source)
{
case IS_APIC:
if (lapic_base)
WriteLapic(LAPIC_EOI_OFFSET, 0U);
break;
case IS_PIC1:
WritePic(1, PIC_PORT0, PIC_EOI_COMMAND);
case IS_PIC0:
WritePic(0, PIC_PORT0, PIC_EOI_COMMAND);
default:
break;
}
}
static
void HandleIRQ(int source, uint8_t vector)
{
if (source == IS_PIC0 && vector == 8U)
{
uint32_t* pTickCount = (uint32_t*) BDA_TICK_COUNT;
if (++(*pTickCount) == BDA_24HR_TURNOVER)
{
*pTickCount = 0U;
++(*(uint8_t*)BDA_MIDNIGHT_FLAG);
}
SignalEOI(source);
return;
}
/*
* Default Approach: send to bios
*/
DispatchBiosVector(vector);
}
static
__attribute__((used))
void ExceptionHandler(struct ExceptionFrame* pFrame)
{
uint8_t vector;
int interruptSource;
char* errorString;
/*
* FIXME: Should check if 0x10000U <= ESP <= 0x1FFFF0 here and switch stacks if not.
*/
if (!pFrame)
{
return;
}
vector = (uint8_t) pFrame->index;
if (counters)
++counters[vector];
interruptSource = IdentifyInterruptSource(vector, pFrame->eip);
switch (interruptSource)
{
case IS_APIC:
case IS_PIC0:
case IS_PIC1:
HandleIRQ(interruptSource, vector);
case IS_Software:
return;
default:
break;
}
errorString = (char*) 0x6000U;
switch (vector)
{
case 0U:
strcpy(errorString, "Division By Zero Exception");
break;
case 1U:
strcpy(errorString, "Debug Exception");
break;
case 2U:
strcpy(errorString, "NMI Interrupt");
break;
case 3U:
strcpy(errorString, "Debug Breakpoint");
break;
case 4U:
strcpy(errorString, "Overflow Exception");
break;
case 5U:
strcpy(errorString, "BOUND Range Exception");
break;
case 6U:
strcpy(errorString, "Invalid Opcode Exception");
break;
case 7U:
strcpy(errorString, "Math Coprocessor Unavailable Exception");
break;
case 8U:
strcpy(errorString, "Double Fault");
break;
case 9U:
strcpy(errorString, "Coprocessor Segment Overrun Exception");
break;
case 10U:
strcpy(errorString, "Invalid TSS Exception");
break;
case 11U:
strcpy(errorString, "Segment Not Present Exception");
break;
case 12U:
strcpy(errorString, "Stack-Segment Fault");
break;
case 13U:
strcpy(errorString, "General Protection Fault");
break;
case 14U:
strcpy(errorString, "Page Fault");
break;
case 16U:
strcpy(errorString, "x87 FPU Floating-Point Error");
break;
case 17U:
strcpy(errorString, "Alignment Check Exception");
break;
case 18U:
strcpy(errorString, "Machine Check Exception");
break;
case 19U:
strcpy(errorString, "SIMD Floating-Point Exception");
break;
case 20U:
strcpy(errorString, "Virtualization Exception");
break;
default:
sprintf(errorString, "Unknown Exception Vector %d", (int) vector);
break;
}
errorString += strlen(errorString);
errorString += sprintf(errorString, "\r\nEDI 0x%x, ESI 0x%x, EBP 0x%x, ESP 0x%x",
pFrame->edi, pFrame->esi, pFrame->ebp, pFrame->esp);
errorString += sprintf(errorString, "\r\nEBX 0x%x, EDX 0x%x, ECX 0x%x, EAX 0x%x",
pFrame->ebx, pFrame->edx, pFrame->ecx, pFrame->eax);
errorString += sprintf(errorString, "\r\nException Code 0x%x, EIP 0x%x, CS 0x%x, EFLAGS 0x%x\r\nSystem Halted\r\n",
pFrame->exception_code, pFrame->eip, pFrame->cs, pFrame->eflags);
DisplayErrorAndStop();
}
static
__attribute__((used))
void InterruptHandler(struct InterruptFrame* pFrame)
{
uint8_t vector;
int interruptSource;
if (!pFrame)
{
return;
}
vector = (uint8_t) pFrame->index;
if (counters)
++counters[vector];
interruptSource = IdentifyInterruptSource(vector, pFrame->eip);
switch (interruptSource)
{
case IS_APIC:
case IS_PIC0:
case IS_PIC1:
HandleIRQ(interruptSource, vector);
default:
break;
}
}
#if UNUSED
void dumpMasks(void)
{
int idx;
uint8_t port_val;
uint8_t volatile* apic_index;
uint32_t const volatile* apic_data;
port_val = ReadPic(0, 1);
DBG("pic0 Masks 0x%x\n", port_val);
port_val = ReadPic(1, 1);
DBG("pic1 Masks 0x%x\n", port_val);
getchar();
DBG("IOAPIC vectors\n");
apic_index = (uint8_t volatile*) 0xFEC00000U;
apic_data = (uint32_t const volatile*) 0xFEC00010U;
for (idx = 0; idx != 24; ++idx)
{
uint32_t v1, v2;
*apic_index = (uint8_t) (16U + 2U * (unsigned) idx);
v1 = *apic_data;
if (v1 & 0x10000U)
continue;
*apic_index = (uint8_t) (16U + 2U * (unsigned) idx + 1U);
v2 = *apic_data;
DBG("index %d vector 0x%x%08x\n", idx, v2, v1);
}
getchar();
if (!lapic_base)
return;
DBG("LAPIC vectors\n");
for (idx = 0; idx != 7; ++idx)
{
uint32_t offs, v;
if (!idx)
offs = 0x2F0U;
else
offs = 0x320U + 16U * (unsigned) (idx - 1);
v = ReadLapic(offs);
if (v & 0x10000U)
continue;
DBG("index %d vector 0x%x\n", idx, v);
}
}
#endif
void ShowInterruptCounters(void)
{
int j;
if (!counters)
return;
msglog("Interrupt Counters\n");
for (j = 0; j != 256; ++j)
if (counters[j])
msglog("counters[%d] == %d\n", j, counters[j]);
}
int SetupInterrupts(void)
{
int idx;
uint32_t stub_address;
uint64_t ia32_apic_base;
size_t const total = 2048U + 2048U + 1024U;
uint8_t* workArea = (uint8_t*) malloc(total);
if (!workArea)
{
msglog("%s: Memory Allocation Failed\n", __FUNCTION__);
return 0;
}
counters = (uint32_t*) (workArea + 4096);
bzero(counters, 1024U);
for (idx = 0; idx != 256; ++idx)
{
struct InterruptGate* gate = (struct InterruptGate*) (workArea + idx * sizeof(struct InterruptGate));
uint8_t* thunk = workArea + 2048 + idx * 8;
gate->offset_0_15 = ((uint32_t) thunk) & 0xFFFFU;
gate->selector = CODE_SEGMENT_SELECTOR;
gate->flags = 0x8E00U; // Interrupt Gate, Present, DPL 0, 32-bit
gate->offset_16_31 = (((uint32_t) thunk) >> 16) & 0xFFFFU;
thunk[0] = 0x6AU;// push byte
thunk[1] = (uint8_t) idx;
thunk[2] = 0xE9U;// jmp rel32
if (idx >= 32)
stub_address = (uint32_t) &InterruptStub;
else if ((1U << idx) & CODED_EXCEPTION_MASK)
stub_address = (uint32_t) &ExceptionWithCodeStub;
else
stub_address = (uint32_t) &ExceptionNoCodeStubAlias;
*(uint32_t*) (&thunk[3]) = stub_address - (uint32_t) &thunk[7];
thunk[7] = 0x90U;// nop
}
Idtr_prot[0] = 0x7FFU;
Idtr_prot[1] = ((uint32_t) workArea) & 0xFFFFU;
Idtr_prot[2] = (((uint32_t) workArea) >> 16) & 0xFFFFU;
__asm__ volatile ("lidt %0" : : "m"(Idtr_prot[0]));
__asm__ volatile ("rdmsr" : "=A"(ia32_apic_base) : "c"((uint32_t) IA32_APIC_BASE));
if ((ia32_apic_base & LAPIC_WANTED_FLAGS) == LAPIC_WANTED_FLAGS &&
!((ia32_apic_base >> 32) & 255U))
lapic_base = ((uint32_t) ia32_apic_base) & ~0xFFFU;
DBG("%s: Work Area 0x%x, lapic_base 0x%x\n", __FUNCTION__, (uint32_t) workArea, lapic_base);
return 1;
}
#endif
trunk/i386/libsa/libsa.h
154154
155155
156156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
157172
*/
extern struct segment_command *getsegbynamefromheader(struct mach_header *mhp, char *segname);
/*
* interrupts.c
*/
#ifdef __i386__
extern int SetupInterrupts(void);
static inline void EnableInterrupts(void) { __asm__ volatile ("sti"); }
static inline void DisableInterrupts(void) { __asm__ volatile ("cli"); }
extern void ShowInterruptCounters(void);
#else
static inline int SetupInterrupts(void) { return 0; }
static inline void EnableInterrupts(void) { }
static inline void DisableInterrupts(void) { }
static inline void ShowInterruptCounters(void) { }
#endif
#endif /* !__BOOT_LIBSA_H */
trunk/i386/libsa/Makefile
2323
2424
2525
26
26
2727
2828
2929
OBJS = prf.o printf.o zalloc.o \
string.o strtol.o error.o \
setjmp.o qsort.o efi_tables.o
setjmp.o qsort.o efi_tables.o interrupts.o
OBJS := $(addprefix $(OBJROOT)/, $(OBJS))
trunk/CHANGES
1
12
23
34
- Zenith432 : Interrupt Management
- Bungo : Added ability to auto-select last booted partition as the boot volume.
- Bungo : Added MacOSVerCurrent and MacOSVer2Int function to use instead of macros.
- Bungo : Fixed bug in gDarwinBuildVerStr extracting.

Archive Download the corresponding diff file

Revision: 2592