/branches/network/kernel/arch/ia32/src/ia32.c |
---|
1,5 → 1,7 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2009 Jiri Svoboda |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
38,9 → 40,12 |
#include <arch/pm.h> |
#include <arch/drivers/ega.h> |
#include <genarch/multiboot/multiboot.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <genarch/drivers/ega/ega.h> |
#include <arch/drivers/vesa.h> |
#include <genarch/kbd/i8042.h> |
#include <genarch/drivers/i8042/i8042.h> |
#include <genarch/kbrd/kbrd.h> |
#include <arch/drivers/i8254.h> |
#include <arch/drivers/i8259.h> |
60,12 → 65,30 |
#include <proc/thread.h> |
#include <syscall/syscall.h> |
#include <console/console.h> |
#include <ddi/device.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/boot/boot.h> |
#ifdef CONFIG_SMP |
#include <arch/smp/apic.h> |
#endif |
/** Perform ia32-specific initialization before main_bsp() is called. |
* |
* @param signature Should contain the multiboot signature. |
* @param mi Pointer to the multiboot information structure. |
*/ |
void arch_pre_main(uint32_t signature, const multiboot_info_t *mi) |
{ |
/* Parse multiboot information obtained from the bootloader. */ |
multiboot_info_parse(signature, mi); |
#ifdef CONFIG_SMP |
/* Copy AP bootstrap routines below 1 MB. */ |
memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET, |
(size_t) &_hardcoded_unmapped_size); |
#endif |
} |
void arch_pre_mm_init(void) |
{ |
pm_init(); |
87,13 → 110,17 |
/* hard clock */ |
i8254_init(); |
#ifdef CONFIG_FB |
if (vesa_present()) |
if (vesa_present()) |
vesa_init(); |
else |
#endif |
ega_init(); /* video */ |
#ifdef CONFIG_EGA |
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */ |
#else |
{} |
#endif |
/* Enable debugger */ |
debugger_init(); |
123,10 → 150,28 |
void arch_post_smp_init(void) |
{ |
devno_t kbd = device_assign_devno(); |
devno_t mouse = device_assign_devno(); |
/* keyboard controller */ |
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE); |
#ifdef CONFIG_PC_KBD |
/* |
* Initialize the i8042 controller. Then initialize the keyboard |
* module and connect it to i8042. Enable keyboard interrupts. |
*/ |
indev_t *kbrdin = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (kbrdin) { |
kbrd_init(kbrdin); |
trap_virtual_enable_irqs(1 << IRQ_KBD); |
} |
/* |
* This is the necessary evil until the userspace driver is entirely |
* self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
#endif |
} |
void calibrate_delay_loop(void) |
159,15 → 204,38 |
*/ |
void arch_grab_console(void) |
{ |
i8042_grab(); |
#ifdef CONFIG_FB |
if (vesa_present()) |
vesa_redraw(); |
else |
#endif |
#ifdef CONFIG_EGA |
ega_redraw(); |
#else |
{} |
#endif |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
i8042_release(); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
/** @} |
*/ |
/branches/network/kernel/arch/ia32/src/fpu_context.c |
---|
44,46 → 44,43 |
static void fpu_context_f_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fnsave %0" |
: "=m"(*fctx) |
); |
"fnsave %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
static void fpu_context_f_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"frstor %0" |
: "=m"(*fctx) |
); |
"frstor %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
static void fpu_context_fx_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxsave %0" |
: "=m"(*fctx) |
); |
"fxsave %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
static void fpu_context_fx_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxrstor %0" |
: "=m"(*fctx) |
); |
"fxrstor %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
/* |
Setup using fxsr instruction |
*/ |
/* Setup using fxsr instruction */ |
void fpu_fxsr(void) |
{ |
fpu_save=fpu_context_fx_save; |
fpu_restore=fpu_context_fx_restore; |
} |
/* |
Setup using not fxsr instruction |
*/ |
/* Setup using not fxsr instruction */ |
void fpu_fsr(void) |
{ |
fpu_save = fpu_context_f_save; |
102,16 → 99,18 |
void fpu_init() |
{ |
uint32_t help0 = 0, help1 = 0; |
uint32_t help0 = 0; |
uint32_t help1 = 0; |
asm volatile ( |
"fninit;\n" |
"stmxcsr %0\n" |
"mov %0,%1;\n" |
"or %2,%1;\n" |
"mov %1,%0;\n" |
"ldmxcsr %0;\n" |
: "+m" (help0), "+r" (help1) |
: "i" (0x1f80) |
"fninit\n" |
"stmxcsr %[help0]\n" |
"mov %[help0], %[help1]\n" |
"or %[magic], %[help1]\n" |
"mov %[help1], %[help0]\n" |
"ldmxcsr %[help0]\n" |
: [help0] "+m" (help0), [help1] "+r" (help1) |
: [magic] "i" (0x1f80) |
); |
} |
/branches/network/kernel/arch/ia32/src/asm.S |
---|
147,6 → 147,46 |
popfl |
.endm |
/* |
* The SYSENTER syscall mechanism can be used for syscalls with |
* four or fewer arguments. To pass these four arguments, we |
* use four registers: EDX, ECX, EBX, ESI. The syscall number |
* is passed in EAX. We use EDI to remember the return address |
* and EBP to remember the stack. The INT-based syscall mechanism |
* can actually handle six arguments plus the syscall number |
* entirely in registers. |
*/ |
.global sysenter_handler |
sysenter_handler: |
sti |
pushl %ebp # remember user stack |
pushl %edi # remember return user address |
pushl %gs # remember TLS |
pushl %eax # syscall number |
subl $8, %esp # unused sixth and fifth argument |
pushl %esi # fourth argument |
pushl %ebx # third argument |
pushl %ecx # second argument |
pushl %edx # first argument |
movw $16, %ax |
movw %ax, %ds |
movw %ax, %es |
cld |
call syscall_handler |
addl $28, %esp # remove arguments from stack |
pop %gs # restore TLS |
pop %edx # prepare return EIP for SYSEXIT |
pop %ecx # prepare userspace ESP for SYSEXIT |
sysexit # return to userspace |
## Declare interrupt handlers |
# |
# Declare interrupt handlers for n interrupt |
228,14 → 268,6 |
pushl %fs |
pushl %gs |
#ifdef CONFIG_DEBUG_ALLREGS |
pushl %ebx |
pushl %ebp |
pushl %edi |
pushl %esi |
#else |
subl $16, %esp |
#endif |
pushl %edx |
pushl %ecx |
pushl %eax |
257,14 → 289,6 |
popl %eax |
popl %ecx |
popl %edx |
#ifdef CONFIG_DEBUG_ALLREGS |
popl %esi |
popl %edi |
popl %ebp |
popl %ebx |
#else |
addl $16, %esp |
#endif |
popl %gs |
popl %fs |
/branches/network/kernel/arch/ia32/src/cpu/cpu.c |
---|
42,22 → 42,23 |
#include <fpu_context.h> |
#include <arch/smp/apic.h> |
#include <arch/syscall.h> |
/* |
* Identification of CPUs. |
* Contains only non-MP-Specification specific SMP code. |
*/ |
#define AMD_CPUID_EBX 0x68747541 |
#define AMD_CPUID_ECX 0x444d4163 |
#define AMD_CPUID_EDX 0x69746e65 |
#define AMD_CPUID_EBX 0x68747541 |
#define AMD_CPUID_ECX 0x444d4163 |
#define AMD_CPUID_EDX 0x69746e65 |
#define INTEL_CPUID_EBX 0x756e6547 |
#define INTEL_CPUID_ECX 0x6c65746e |
#define INTEL_CPUID_EDX 0x49656e69 |
#define INTEL_CPUID_EBX 0x756e6547 |
#define INTEL_CPUID_ECX 0x6c65746e |
#define INTEL_CPUID_EDX 0x49656e69 |
enum vendor { |
VendorUnknown=0, |
VendorUnknown = 0, |
VendorAMD, |
VendorIntel |
}; |
64,19 → 65,17 |
static char *vendor_str[] = { |
"Unknown Vendor", |
"AuthenticAMD", |
"GenuineIntel" |
"AMD", |
"Intel" |
}; |
void fpu_disable(void) |
{ |
asm volatile ( |
"mov %%cr0,%%eax;" |
"or $8,%%eax;" |
"mov %%eax,%%cr0;" |
: |
: |
:"%eax" |
"mov %%cr0, %%eax\n" |
"or $8, %%eax\n" |
"mov %%eax, %%cr0\n" |
::: "%eax" |
); |
} |
83,13 → 82,11 |
void fpu_enable(void) |
{ |
asm volatile ( |
"mov %%cr0,%%eax;" |
"and $0xffFFffF7,%%eax;" |
"mov %%eax,%%cr0;" |
: |
: |
:"%eax" |
); |
"mov %%cr0, %%eax\n" |
"and $0xffFFffF7, %%eax\n" |
"mov %%eax,%%cr0\n" |
::: "%eax" |
); |
} |
void cpu_arch_init(void) |
101,11 → 98,11 |
CPU->arch.tss = tss_p; |
CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((uint8_t *) CPU->arch.tss); |
CPU->fpu_owner = NULL; |
cpuid(1, &info); |
fi.word = info.cpuid_edx; |
efi.word = info.cpuid_ecx; |
112,17 → 109,20 |
if (fi.bits.fxsr) |
fpu_fxsr(); |
else |
fpu_fsr(); |
fpu_fsr(); |
if (fi.bits.sse) { |
asm volatile ( |
"mov %%cr4,%0\n" |
"or %1,%0\n" |
"mov %0,%%cr4\n" |
: "+r" (help) |
: "i" (CR4_OSFXSR_MASK|(1<<10)) |
"mov %%cr4, %[help]\n" |
"or %[mask], %[help]\n" |
"mov %[help], %%cr4\n" |
: [help] "+r" (help) |
: [mask] "i" (CR4_OSFXSR_MASK | (1 << 10)) |
); |
} |
/* Setup fast SYSENTER/SYSEXIT syscalls */ |
syscall_setup_cpu(); |
} |
void cpu_identify(void) |
136,29 → 136,31 |
/* |
* Check for AMD processor. |
*/ |
if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) { |
if ((info.cpuid_ebx == AMD_CPUID_EBX) |
&& (info.cpuid_ecx == AMD_CPUID_ECX) |
&& (info.cpuid_edx == AMD_CPUID_EDX)) |
CPU->arch.vendor = VendorAMD; |
} |
/* |
* Check for Intel processor. |
*/ |
if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) { |
if ((info.cpuid_ebx == INTEL_CPUID_EBX) |
&& (info.cpuid_ecx == INTEL_CPUID_ECX) |
&& (info.cpuid_edx == INTEL_CPUID_EDX)) |
CPU->arch.vendor = VendorIntel; |
} |
cpuid(1, &info); |
CPU->arch.family = (info.cpuid_eax>>8)&0xf; |
CPU->arch.model = (info.cpuid_eax>>4)&0xf; |
CPU->arch.stepping = (info.cpuid_eax>>0)&0xf; |
CPU->arch.family = (info.cpuid_eax >> 8) & 0x0f; |
CPU->arch.model = (info.cpuid_eax >> 4) & 0x0f; |
CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0f; |
} |
} |
void cpu_print_report(cpu_t* m) |
void cpu_print_report(cpu_t* cpu) |
{ |
printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n", |
m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping, |
m->frequency_mhz); |
printf("cpu%u: (%s family=%u model=%u stepping=%u) %" PRIu16 " MHz\n", |
cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family, |
cpu->arch.model, cpu->arch.stepping, cpu->frequency_mhz); |
} |
/** @} |
/branches/network/kernel/arch/ia32/src/syscall.c |
---|
0,0 → 1,53 |
/* |
* Copyright (c) 2008 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/syscall.h> |
#include <arch/cpu.h> |
#include <arch/asm.h> |
#include <arch/types.h> |
#include <arch/pm.h> |
/** Enable & setup support for SYSENTER/SYSEXIT */ |
void syscall_setup_cpu(void) |
{ |
extern void sysenter_handler(void); |
/* set kernel mode CS selector */ |
write_msr(IA32_MSR_SYSENTER_CS, gdtselector(KTEXT_DES)); |
/* set kernel mode entry point */ |
write_msr(IA32_MSR_SYSENTER_EIP, (uint32_t) sysenter_handler); |
} |
/** @} |
*/ |
/branches/network/kernel/arch/ia32/src/pm.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
112,7 → 112,7 |
void tss_initialize(tss_t *t) |
{ |
memsetb(t, sizeof(struct tss), 0); |
memsetb(t, sizeof(tss_t), 0); |
} |
/* |
127,7 → 127,7 |
d = &idt[i]; |
d->unused = 0; |
d->selector = selector(KTEXT_DES); |
d->selector = gdtselector(KTEXT_DES); |
d->access = AR_PRESENT | AR_INTERRUPT; /* masking interrupt */ |
154,7 → 154,7 |
"and $0xffff8fff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
: : : "eax" |
::: "eax" |
); |
} |
165,7 → 165,7 |
"mov %%cr0, %%eax\n" |
"and $0xfffbffff, %%eax\n" |
"mov %%eax, %%cr0\n" |
: : : "eax" |
::: "eax" |
); |
} |
198,7 → 198,7 |
else { |
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC); |
if (!tss_p) |
panic("could not allocate TSS\n"); |
panic("Cannot allocate TSS."); |
} |
tss_initialize(tss_p); |
214,7 → 214,7 |
* As of this moment, the current CPU has its own GDT pointing |
* to its own TSS. We just need to load the TR register. |
*/ |
tr_load(selector(TSS_DES)); |
tr_load(gdtselector(TSS_DES)); |
clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels and clear NT flag. */ |
clean_AM_flag(); /* Disable alignment check */ |
/branches/network/kernel/arch/ia32/src/smp/smp.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
75,12 → 75,12 |
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, |
FRAME_ATOMIC | FRAME_KA); |
if (!l_apic_address) |
panic("cannot allocate address for l_apic\n"); |
panic("Cannot allocate address for l_apic."); |
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, |
FRAME_ATOMIC | FRAME_KA); |
if (!io_apic_address) |
panic("cannot allocate address for io_apic\n"); |
panic("Cannot allocate address for io_apic."); |
if (config.cpu_count > 1) { |
page_mapping_insert(AS_KERNEL, l_apic_address, |
122,8 → 122,8 |
* Save 0xa to address 0xf of the CMOS RAM. |
* BIOS will not do the POST after the INIT signal. |
*/ |
outb(0x70, 0xf); |
outb(0x71, 0xa); |
pio_write_8((ioport8_t *)0x70, 0xf); |
pio_write_8((ioport8_t *)0x71, 0xa); |
pic_disable_irqs(0xffff); |
apic_init(); |
131,8 → 131,8 |
uint8_t apic = l_apic_id(); |
for (i = 0; i < ops->cpu_count(); i++) { |
struct descriptor *gdt_new; |
descriptor_t *gdt_new; |
/* |
* Skip processors marked unusable. |
*/ |
154,14 → 154,19 |
/* |
* Prepare new GDT for CPU in question. |
*/ |
gdt_new = (struct descriptor *) malloc(GDT_ITEMS * |
sizeof(struct descriptor), FRAME_ATOMIC | FRAME_LOW_4_GiB); |
/* XXX Flag FRAME_LOW_4_GiB was removed temporarily, |
* it needs to be replaced by a generic fuctionality of |
* the memory subsystem |
*/ |
gdt_new = (descriptor_t *) malloc(GDT_ITEMS * |
sizeof(descriptor_t), FRAME_ATOMIC); |
if (!gdt_new) |
panic("couldn't allocate memory for GDT\n"); |
panic("Cannot allocate memory for GDT."); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor)); |
memsetb(&gdt_new[TSS_DES], sizeof(struct descriptor), 0); |
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t)); |
memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0); |
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(descriptor_t); |
protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new); |
gdtr.base = (uintptr_t) gdt_new; |
/branches/network/kernel/arch/ia32/src/smp/apic.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
132,12 → 132,12 |
#endif |
} |
static irq_ownership_t l_apic_timer_claim(void) |
static irq_ownership_t l_apic_timer_claim(irq_t *irq) |
{ |
return IRQ_ACCEPT; |
} |
static void l_apic_timer_irq_handler(irq_t *irq, void *arg __attribute__((unused)), ...) |
static void l_apic_timer_irq_handler(irq_t *irq) |
{ |
/* |
* Holding a spinlock could prevent clock() from preempting |
/branches/network/kernel/arch/ia32/src/ddi/ddi.c |
---|
156,7 → 156,7 |
* type must be changed to describe inactive TSS. |
*/ |
gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL; |
tr_load(selector(TSS_DES)); |
tr_load(gdtselector(TSS_DES)); |
/* |
* Update the generation count so that faults caused by |
/branches/network/kernel/arch/ia32/src/boot/vga323.pal |
---|
1,256 → 1,256 |
.byte 0x3f, 0x3f, 0x3f, 0x00 |
.byte 0x36, 0x3f, 0x3f, 0x00 |
.byte 0x2d, 0x3f, 0x3f, 0x00 |
.byte 0x24, 0x3f, 0x3f, 0x00 |
.byte 0x1b, 0x3f, 0x3f, 0x00 |
.byte 0x12, 0x3f, 0x3f, 0x00 |
.byte 0x09, 0x3f, 0x3f, 0x00 |
.byte 0x00, 0x3f, 0x3f, 0x00 |
.byte 0x3f, 0x2a, 0x3f, 0x00 |
.byte 0x36, 0x2a, 0x3f, 0x00 |
.byte 0x2d, 0x2a, 0x3f, 0x00 |
.byte 0x24, 0x2a, 0x3f, 0x00 |
.byte 0x1b, 0x2a, 0x3f, 0x00 |
.byte 0x12, 0x2a, 0x3f, 0x00 |
.byte 0x09, 0x2a, 0x3f, 0x00 |
.byte 0x00, 0x2a, 0x3f, 0x00 |
.byte 0x3f, 0x15, 0x3f, 0x00 |
.byte 0x36, 0x15, 0x3f, 0x00 |
.byte 0x2d, 0x15, 0x3f, 0x00 |
.byte 0x24, 0x15, 0x3f, 0x00 |
.byte 0x1b, 0x15, 0x3f, 0x00 |
.byte 0x12, 0x15, 0x3f, 0x00 |
.byte 0x09, 0x15, 0x3f, 0x00 |
.byte 0x00, 0x15, 0x3f, 0x00 |
.byte 0x3f, 0x00, 0x3f, 0x00 |
.byte 0x36, 0x00, 0x3f, 0x00 |
.byte 0x2d, 0x00, 0x3f, 0x00 |
.byte 0x24, 0x00, 0x3f, 0x00 |
.byte 0x1b, 0x00, 0x3f, 0x00 |
.byte 0x12, 0x00, 0x3f, 0x00 |
.byte 0x09, 0x00, 0x3f, 0x00 |
.byte 0x00, 0x00, 0x3f, 0x00 |
.byte 0x3f, 0x3f, 0x36, 0x00 |
.byte 0x36, 0x3f, 0x36, 0x00 |
.byte 0x2d, 0x3f, 0x36, 0x00 |
.byte 0x24, 0x3f, 0x36, 0x00 |
.byte 0x1b, 0x3f, 0x36, 0x00 |
.byte 0x12, 0x3f, 0x36, 0x00 |
.byte 0x09, 0x3f, 0x36, 0x00 |
.byte 0x00, 0x3f, 0x36, 0x00 |
.byte 0x3f, 0x2a, 0x36, 0x00 |
.byte 0x36, 0x2a, 0x36, 0x00 |
.byte 0x2d, 0x2a, 0x36, 0x00 |
.byte 0x24, 0x2a, 0x36, 0x00 |
.byte 0x1b, 0x2a, 0x36, 0x00 |
.byte 0x12, 0x2a, 0x36, 0x00 |
.byte 0x09, 0x2a, 0x36, 0x00 |
.byte 0x00, 0x2a, 0x36, 0x00 |
.byte 0x3f, 0x15, 0x36, 0x00 |
.byte 0x36, 0x15, 0x36, 0x00 |
.byte 0x2d, 0x15, 0x36, 0x00 |
.byte 0x24, 0x15, 0x36, 0x00 |
.byte 0x1b, 0x15, 0x36, 0x00 |
.byte 0x12, 0x15, 0x36, 0x00 |
.byte 0x09, 0x15, 0x36, 0x00 |
.byte 0x00, 0x15, 0x36, 0x00 |
.byte 0x3f, 0x00, 0x36, 0x00 |
.byte 0x36, 0x00, 0x36, 0x00 |
.byte 0x2d, 0x00, 0x36, 0x00 |
.byte 0x24, 0x00, 0x36, 0x00 |
.byte 0x1b, 0x00, 0x36, 0x00 |
.byte 0x12, 0x00, 0x36, 0x00 |
.byte 0x09, 0x00, 0x36, 0x00 |
.byte 0x00, 0x00, 0x36, 0x00 |
.byte 0x3f, 0x3f, 0x2d, 0x00 |
.byte 0x36, 0x3f, 0x2d, 0x00 |
.byte 0x2d, 0x3f, 0x2d, 0x00 |
.byte 0x24, 0x3f, 0x2d, 0x00 |
.byte 0x1b, 0x3f, 0x2d, 0x00 |
.byte 0x12, 0x3f, 0x2d, 0x00 |
.byte 0x09, 0x3f, 0x2d, 0x00 |
.byte 0x00, 0x3f, 0x2d, 0x00 |
.byte 0x3f, 0x2a, 0x2d, 0x00 |
.byte 0x36, 0x2a, 0x2d, 0x00 |
.byte 0x2d, 0x2a, 0x2d, 0x00 |
.byte 0x24, 0x2a, 0x2d, 0x00 |
.byte 0x1b, 0x2a, 0x2d, 0x00 |
.byte 0x12, 0x2a, 0x2d, 0x00 |
.byte 0x09, 0x2a, 0x2d, 0x00 |
.byte 0x00, 0x2a, 0x2d, 0x00 |
.byte 0x3f, 0x15, 0x2d, 0x00 |
.byte 0x36, 0x15, 0x2d, 0x00 |
.byte 0x2d, 0x15, 0x2d, 0x00 |
.byte 0x24, 0x15, 0x2d, 0x00 |
.byte 0x1b, 0x15, 0x2d, 0x00 |
.byte 0x12, 0x15, 0x2d, 0x00 |
.byte 0x09, 0x15, 0x2d, 0x00 |
.byte 0x00, 0x15, 0x2d, 0x00 |
.byte 0x3f, 0x00, 0x2d, 0x00 |
.byte 0x36, 0x00, 0x2d, 0x00 |
.byte 0x2d, 0x00, 0x2d, 0x00 |
.byte 0x24, 0x00, 0x2d, 0x00 |
.byte 0x1b, 0x00, 0x2d, 0x00 |
.byte 0x12, 0x00, 0x2d, 0x00 |
.byte 0x09, 0x00, 0x2d, 0x00 |
.byte 0x00, 0x00, 0x2d, 0x00 |
.byte 0x3f, 0x3f, 0x24, 0x00 |
.byte 0x36, 0x3f, 0x24, 0x00 |
.byte 0x2d, 0x3f, 0x24, 0x00 |
.byte 0x24, 0x3f, 0x24, 0x00 |
.byte 0x1b, 0x3f, 0x24, 0x00 |
.byte 0x12, 0x3f, 0x24, 0x00 |
.byte 0x09, 0x3f, 0x24, 0x00 |
.byte 0x00, 0x3f, 0x24, 0x00 |
.byte 0x3f, 0x2a, 0x24, 0x00 |
.byte 0x36, 0x2a, 0x24, 0x00 |
.byte 0x2d, 0x2a, 0x24, 0x00 |
.byte 0x24, 0x2a, 0x24, 0x00 |
.byte 0x1b, 0x2a, 0x24, 0x00 |
.byte 0x12, 0x2a, 0x24, 0x00 |
.byte 0x09, 0x2a, 0x24, 0x00 |
.byte 0x00, 0x2a, 0x24, 0x00 |
.byte 0x3f, 0x15, 0x24, 0x00 |
.byte 0x36, 0x15, 0x24, 0x00 |
.byte 0x2d, 0x15, 0x24, 0x00 |
.byte 0x24, 0x15, 0x24, 0x00 |
.byte 0x1b, 0x15, 0x24, 0x00 |
.byte 0x12, 0x15, 0x24, 0x00 |
.byte 0x09, 0x15, 0x24, 0x00 |
.byte 0x00, 0x15, 0x24, 0x00 |
.byte 0x3f, 0x00, 0x24, 0x00 |
.byte 0x36, 0x00, 0x24, 0x00 |
.byte 0x2d, 0x00, 0x24, 0x00 |
.byte 0x24, 0x00, 0x24, 0x00 |
.byte 0x1b, 0x00, 0x24, 0x00 |
.byte 0x12, 0x00, 0x24, 0x00 |
.byte 0x09, 0x00, 0x24, 0x00 |
.byte 0x00, 0x00, 0x24, 0x00 |
.byte 0x3f, 0x3f, 0x1b, 0x00 |
.byte 0x36, 0x3f, 0x1b, 0x00 |
.byte 0x2d, 0x3f, 0x1b, 0x00 |
.byte 0x24, 0x3f, 0x1b, 0x00 |
.byte 0x1b, 0x3f, 0x1b, 0x00 |
.byte 0x12, 0x3f, 0x1b, 0x00 |
.byte 0x09, 0x3f, 0x1b, 0x00 |
.byte 0x00, 0x3f, 0x1b, 0x00 |
.byte 0x3f, 0x2a, 0x1b, 0x00 |
.byte 0x36, 0x2a, 0x1b, 0x00 |
.byte 0x2d, 0x2a, 0x1b, 0x00 |
.byte 0x24, 0x2a, 0x1b, 0x00 |
.byte 0x1b, 0x2a, 0x1b, 0x00 |
.byte 0x12, 0x2a, 0x1b, 0x00 |
.byte 0x09, 0x2a, 0x1b, 0x00 |
.byte 0x00, 0x2a, 0x1b, 0x00 |
.byte 0x3f, 0x15, 0x1b, 0x00 |
.byte 0x36, 0x15, 0x1b, 0x00 |
.byte 0x2d, 0x15, 0x1b, 0x00 |
.byte 0x24, 0x15, 0x1b, 0x00 |
.byte 0x1b, 0x15, 0x1b, 0x00 |
.byte 0x12, 0x15, 0x1b, 0x00 |
.byte 0x09, 0x15, 0x1b, 0x00 |
.byte 0x00, 0x15, 0x1b, 0x00 |
.byte 0x3f, 0x00, 0x1b, 0x00 |
.byte 0x36, 0x00, 0x1b, 0x00 |
.byte 0x2d, 0x00, 0x1b, 0x00 |
.byte 0x24, 0x00, 0x1b, 0x00 |
.byte 0x1b, 0x00, 0x1b, 0x00 |
.byte 0x12, 0x00, 0x1b, 0x00 |
.byte 0x09, 0x00, 0x1b, 0x00 |
.byte 0x00, 0x00, 0x1b, 0x00 |
.byte 0x3f, 0x3f, 0x12, 0x00 |
.byte 0x36, 0x3f, 0x12, 0x00 |
.byte 0x2d, 0x3f, 0x12, 0x00 |
.byte 0x24, 0x3f, 0x12, 0x00 |
.byte 0x1b, 0x3f, 0x12, 0x00 |
.byte 0x12, 0x3f, 0x12, 0x00 |
.byte 0x09, 0x3f, 0x12, 0x00 |
.byte 0x00, 0x3f, 0x12, 0x00 |
.byte 0x3f, 0x2a, 0x12, 0x00 |
.byte 0x36, 0x2a, 0x12, 0x00 |
.byte 0x2d, 0x2a, 0x12, 0x00 |
.byte 0x24, 0x2a, 0x12, 0x00 |
.byte 0x1b, 0x2a, 0x12, 0x00 |
.byte 0x12, 0x2a, 0x12, 0x00 |
.byte 0x09, 0x2a, 0x12, 0x00 |
.byte 0x00, 0x2a, 0x12, 0x00 |
.byte 0x3f, 0x15, 0x12, 0x00 |
.byte 0x36, 0x15, 0x12, 0x00 |
.byte 0x2d, 0x15, 0x12, 0x00 |
.byte 0x24, 0x15, 0x12, 0x00 |
.byte 0x1b, 0x15, 0x12, 0x00 |
.byte 0x12, 0x15, 0x12, 0x00 |
.byte 0x09, 0x15, 0x12, 0x00 |
.byte 0x00, 0x15, 0x12, 0x00 |
.byte 0x3f, 0x00, 0x12, 0x00 |
.byte 0x36, 0x00, 0x12, 0x00 |
.byte 0x2d, 0x00, 0x12, 0x00 |
.byte 0x24, 0x00, 0x12, 0x00 |
.byte 0x1b, 0x00, 0x12, 0x00 |
.byte 0x12, 0x00, 0x12, 0x00 |
.byte 0x09, 0x00, 0x12, 0x00 |
.byte 0x00, 0x00, 0x12, 0x00 |
.byte 0x3f, 0x3f, 0x09, 0x00 |
.byte 0x36, 0x3f, 0x09, 0x00 |
.byte 0x2d, 0x3f, 0x09, 0x00 |
.byte 0x24, 0x3f, 0x09, 0x00 |
.byte 0x1b, 0x3f, 0x09, 0x00 |
.byte 0x12, 0x3f, 0x09, 0x00 |
.byte 0x09, 0x3f, 0x09, 0x00 |
.byte 0x00, 0x3f, 0x09, 0x00 |
.byte 0x3f, 0x2a, 0x09, 0x00 |
.byte 0x36, 0x2a, 0x09, 0x00 |
.byte 0x2d, 0x2a, 0x09, 0x00 |
.byte 0x24, 0x2a, 0x09, 0x00 |
.byte 0x1b, 0x2a, 0x09, 0x00 |
.byte 0x12, 0x2a, 0x09, 0x00 |
.byte 0x09, 0x2a, 0x09, 0x00 |
.byte 0x00, 0x2a, 0x09, 0x00 |
.byte 0x3f, 0x15, 0x09, 0x00 |
.byte 0x36, 0x15, 0x09, 0x00 |
.byte 0x2d, 0x15, 0x09, 0x00 |
.byte 0x24, 0x15, 0x09, 0x00 |
.byte 0x1b, 0x15, 0x09, 0x00 |
.byte 0x12, 0x15, 0x09, 0x00 |
.byte 0x09, 0x15, 0x09, 0x00 |
.byte 0x00, 0x15, 0x09, 0x00 |
.byte 0x3f, 0x00, 0x09, 0x00 |
.byte 0x36, 0x00, 0x09, 0x00 |
.byte 0x2d, 0x00, 0x09, 0x00 |
.byte 0x24, 0x00, 0x09, 0x00 |
.byte 0x1b, 0x00, 0x09, 0x00 |
.byte 0x12, 0x00, 0x09, 0x00 |
.byte 0x09, 0x00, 0x09, 0x00 |
.byte 0x00, 0x00, 0x09, 0x00 |
.byte 0x3f, 0x3f, 0x00, 0x00 |
.byte 0x36, 0x3f, 0x00, 0x00 |
.byte 0x2d, 0x3f, 0x00, 0x00 |
.byte 0x24, 0x3f, 0x00, 0x00 |
.byte 0x1b, 0x3f, 0x00, 0x00 |
.byte 0x12, 0x3f, 0x00, 0x00 |
.byte 0x09, 0x3f, 0x00, 0x00 |
.byte 0x00, 0x3f, 0x00, 0x00 |
.byte 0x3f, 0x2a, 0x00, 0x00 |
.byte 0x36, 0x2a, 0x00, 0x00 |
.byte 0x2d, 0x2a, 0x00, 0x00 |
.byte 0x24, 0x2a, 0x00, 0x00 |
.byte 0x1b, 0x2a, 0x00, 0x00 |
.byte 0x12, 0x2a, 0x00, 0x00 |
.byte 0x09, 0x2a, 0x00, 0x00 |
.byte 0x00, 0x2a, 0x00, 0x00 |
.byte 0x3f, 0x15, 0x00, 0x00 |
.byte 0x36, 0x15, 0x00, 0x00 |
.byte 0x2d, 0x15, 0x00, 0x00 |
.byte 0x24, 0x15, 0x00, 0x00 |
.byte 0x1b, 0x15, 0x00, 0x00 |
.byte 0x12, 0x15, 0x00, 0x00 |
.byte 0x09, 0x15, 0x00, 0x00 |
.byte 0x00, 0x15, 0x00, 0x00 |
.byte 0x3f, 0x00, 0x00, 0x00 |
.byte 0x36, 0x00, 0x00, 0x00 |
.byte 0x2d, 0x00, 0x00, 0x00 |
.byte 0x24, 0x00, 0x00, 0x00 |
.byte 0x1b, 0x00, 0x00, 0x00 |
.byte 0x12, 0x00, 0x00, 0x00 |
.byte 0x09, 0x00, 0x00, 0x00 |
.byte 0x00, 0x00, 0x00, 0x00 |
.byte 0x09, 0x00, 0x00, 0x00 |
.byte 0x12, 0x00, 0x00, 0x00 |
.byte 0x1b, 0x00, 0x00, 0x00 |
.byte 0x24, 0x00, 0x00, 0x00 |
.byte 0x2d, 0x00, 0x00, 0x00 |
.byte 0x36, 0x00, 0x00, 0x00 |
.byte 0x3f, 0x00, 0x00, 0x00 |
.byte 0x00, 0x15, 0x00, 0x00 |
.byte 0x09, 0x15, 0x00, 0x00 |
.byte 0x12, 0x15, 0x00, 0x00 |
.byte 0x1b, 0x15, 0x00, 0x00 |
.byte 0x24, 0x15, 0x00, 0x00 |
.byte 0x2d, 0x15, 0x00, 0x00 |
.byte 0x36, 0x15, 0x00, 0x00 |
.byte 0x3f, 0x15, 0x00, 0x00 |
.byte 0x00, 0x2a, 0x00, 0x00 |
.byte 0x09, 0x2a, 0x00, 0x00 |
.byte 0x12, 0x2a, 0x00, 0x00 |
.byte 0x1b, 0x2a, 0x00, 0x00 |
.byte 0x24, 0x2a, 0x00, 0x00 |
.byte 0x2d, 0x2a, 0x00, 0x00 |
.byte 0x36, 0x2a, 0x00, 0x00 |
.byte 0x3f, 0x2a, 0x00, 0x00 |
.byte 0x00, 0x3f, 0x00, 0x00 |
.byte 0x09, 0x3f, 0x00, 0x00 |
.byte 0x12, 0x3f, 0x00, 0x00 |
.byte 0x1b, 0x3f, 0x00, 0x00 |
.byte 0x24, 0x3f, 0x00, 0x00 |
.byte 0x2d, 0x3f, 0x00, 0x00 |
.byte 0x36, 0x3f, 0x00, 0x00 |
.byte 0x3f, 0x3f, 0x00, 0x00 |
.byte 0x00, 0x00, 0x09, 0x00 |
.byte 0x09, 0x00, 0x09, 0x00 |
.byte 0x12, 0x00, 0x09, 0x00 |
.byte 0x1b, 0x00, 0x09, 0x00 |
.byte 0x24, 0x00, 0x09, 0x00 |
.byte 0x2d, 0x00, 0x09, 0x00 |
.byte 0x36, 0x00, 0x09, 0x00 |
.byte 0x3f, 0x00, 0x09, 0x00 |
.byte 0x00, 0x15, 0x09, 0x00 |
.byte 0x09, 0x15, 0x09, 0x00 |
.byte 0x12, 0x15, 0x09, 0x00 |
.byte 0x1b, 0x15, 0x09, 0x00 |
.byte 0x24, 0x15, 0x09, 0x00 |
.byte 0x2d, 0x15, 0x09, 0x00 |
.byte 0x36, 0x15, 0x09, 0x00 |
.byte 0x3f, 0x15, 0x09, 0x00 |
.byte 0x00, 0x2a, 0x09, 0x00 |
.byte 0x09, 0x2a, 0x09, 0x00 |
.byte 0x12, 0x2a, 0x09, 0x00 |
.byte 0x1b, 0x2a, 0x09, 0x00 |
.byte 0x24, 0x2a, 0x09, 0x00 |
.byte 0x2d, 0x2a, 0x09, 0x00 |
.byte 0x36, 0x2a, 0x09, 0x00 |
.byte 0x3f, 0x2a, 0x09, 0x00 |
.byte 0x00, 0x3f, 0x09, 0x00 |
.byte 0x09, 0x3f, 0x09, 0x00 |
.byte 0x12, 0x3f, 0x09, 0x00 |
.byte 0x1b, 0x3f, 0x09, 0x00 |
.byte 0x24, 0x3f, 0x09, 0x00 |
.byte 0x2d, 0x3f, 0x09, 0x00 |
.byte 0x36, 0x3f, 0x09, 0x00 |
.byte 0x3f, 0x3f, 0x09, 0x00 |
.byte 0x00, 0x00, 0x12, 0x00 |
.byte 0x09, 0x00, 0x12, 0x00 |
.byte 0x12, 0x00, 0x12, 0x00 |
.byte 0x1b, 0x00, 0x12, 0x00 |
.byte 0x24, 0x00, 0x12, 0x00 |
.byte 0x2d, 0x00, 0x12, 0x00 |
.byte 0x36, 0x00, 0x12, 0x00 |
.byte 0x3f, 0x00, 0x12, 0x00 |
.byte 0x00, 0x15, 0x12, 0x00 |
.byte 0x09, 0x15, 0x12, 0x00 |
.byte 0x12, 0x15, 0x12, 0x00 |
.byte 0x1b, 0x15, 0x12, 0x00 |
.byte 0x24, 0x15, 0x12, 0x00 |
.byte 0x2d, 0x15, 0x12, 0x00 |
.byte 0x36, 0x15, 0x12, 0x00 |
.byte 0x3f, 0x15, 0x12, 0x00 |
.byte 0x00, 0x2a, 0x12, 0x00 |
.byte 0x09, 0x2a, 0x12, 0x00 |
.byte 0x12, 0x2a, 0x12, 0x00 |
.byte 0x1b, 0x2a, 0x12, 0x00 |
.byte 0x24, 0x2a, 0x12, 0x00 |
.byte 0x2d, 0x2a, 0x12, 0x00 |
.byte 0x36, 0x2a, 0x12, 0x00 |
.byte 0x3f, 0x2a, 0x12, 0x00 |
.byte 0x00, 0x3f, 0x12, 0x00 |
.byte 0x09, 0x3f, 0x12, 0x00 |
.byte 0x12, 0x3f, 0x12, 0x00 |
.byte 0x1b, 0x3f, 0x12, 0x00 |
.byte 0x24, 0x3f, 0x12, 0x00 |
.byte 0x2d, 0x3f, 0x12, 0x00 |
.byte 0x36, 0x3f, 0x12, 0x00 |
.byte 0x3f, 0x3f, 0x12, 0x00 |
.byte 0x00, 0x00, 0x1b, 0x00 |
.byte 0x09, 0x00, 0x1b, 0x00 |
.byte 0x12, 0x00, 0x1b, 0x00 |
.byte 0x1b, 0x00, 0x1b, 0x00 |
.byte 0x24, 0x00, 0x1b, 0x00 |
.byte 0x2d, 0x00, 0x1b, 0x00 |
.byte 0x36, 0x00, 0x1b, 0x00 |
.byte 0x3f, 0x00, 0x1b, 0x00 |
.byte 0x00, 0x15, 0x1b, 0x00 |
.byte 0x09, 0x15, 0x1b, 0x00 |
.byte 0x12, 0x15, 0x1b, 0x00 |
.byte 0x1b, 0x15, 0x1b, 0x00 |
.byte 0x24, 0x15, 0x1b, 0x00 |
.byte 0x2d, 0x15, 0x1b, 0x00 |
.byte 0x36, 0x15, 0x1b, 0x00 |
.byte 0x3f, 0x15, 0x1b, 0x00 |
.byte 0x00, 0x2a, 0x1b, 0x00 |
.byte 0x09, 0x2a, 0x1b, 0x00 |
.byte 0x12, 0x2a, 0x1b, 0x00 |
.byte 0x1b, 0x2a, 0x1b, 0x00 |
.byte 0x24, 0x2a, 0x1b, 0x00 |
.byte 0x2d, 0x2a, 0x1b, 0x00 |
.byte 0x36, 0x2a, 0x1b, 0x00 |
.byte 0x3f, 0x2a, 0x1b, 0x00 |
.byte 0x00, 0x3f, 0x1b, 0x00 |
.byte 0x09, 0x3f, 0x1b, 0x00 |
.byte 0x12, 0x3f, 0x1b, 0x00 |
.byte 0x1b, 0x3f, 0x1b, 0x00 |
.byte 0x24, 0x3f, 0x1b, 0x00 |
.byte 0x2d, 0x3f, 0x1b, 0x00 |
.byte 0x36, 0x3f, 0x1b, 0x00 |
.byte 0x3f, 0x3f, 0x1b, 0x00 |
.byte 0x00, 0x00, 0x24, 0x00 |
.byte 0x09, 0x00, 0x24, 0x00 |
.byte 0x12, 0x00, 0x24, 0x00 |
.byte 0x1b, 0x00, 0x24, 0x00 |
.byte 0x24, 0x00, 0x24, 0x00 |
.byte 0x2d, 0x00, 0x24, 0x00 |
.byte 0x36, 0x00, 0x24, 0x00 |
.byte 0x3f, 0x00, 0x24, 0x00 |
.byte 0x00, 0x15, 0x24, 0x00 |
.byte 0x09, 0x15, 0x24, 0x00 |
.byte 0x12, 0x15, 0x24, 0x00 |
.byte 0x1b, 0x15, 0x24, 0x00 |
.byte 0x24, 0x15, 0x24, 0x00 |
.byte 0x2d, 0x15, 0x24, 0x00 |
.byte 0x36, 0x15, 0x24, 0x00 |
.byte 0x3f, 0x15, 0x24, 0x00 |
.byte 0x00, 0x2a, 0x24, 0x00 |
.byte 0x09, 0x2a, 0x24, 0x00 |
.byte 0x12, 0x2a, 0x24, 0x00 |
.byte 0x1b, 0x2a, 0x24, 0x00 |
.byte 0x24, 0x2a, 0x24, 0x00 |
.byte 0x2d, 0x2a, 0x24, 0x00 |
.byte 0x36, 0x2a, 0x24, 0x00 |
.byte 0x3f, 0x2a, 0x24, 0x00 |
.byte 0x00, 0x3f, 0x24, 0x00 |
.byte 0x09, 0x3f, 0x24, 0x00 |
.byte 0x12, 0x3f, 0x24, 0x00 |
.byte 0x1b, 0x3f, 0x24, 0x00 |
.byte 0x24, 0x3f, 0x24, 0x00 |
.byte 0x2d, 0x3f, 0x24, 0x00 |
.byte 0x36, 0x3f, 0x24, 0x00 |
.byte 0x3f, 0x3f, 0x24, 0x00 |
.byte 0x00, 0x00, 0x2d, 0x00 |
.byte 0x09, 0x00, 0x2d, 0x00 |
.byte 0x12, 0x00, 0x2d, 0x00 |
.byte 0x1b, 0x00, 0x2d, 0x00 |
.byte 0x24, 0x00, 0x2d, 0x00 |
.byte 0x2d, 0x00, 0x2d, 0x00 |
.byte 0x36, 0x00, 0x2d, 0x00 |
.byte 0x3f, 0x00, 0x2d, 0x00 |
.byte 0x00, 0x15, 0x2d, 0x00 |
.byte 0x09, 0x15, 0x2d, 0x00 |
.byte 0x12, 0x15, 0x2d, 0x00 |
.byte 0x1b, 0x15, 0x2d, 0x00 |
.byte 0x24, 0x15, 0x2d, 0x00 |
.byte 0x2d, 0x15, 0x2d, 0x00 |
.byte 0x36, 0x15, 0x2d, 0x00 |
.byte 0x3f, 0x15, 0x2d, 0x00 |
.byte 0x00, 0x2a, 0x2d, 0x00 |
.byte 0x09, 0x2a, 0x2d, 0x00 |
.byte 0x12, 0x2a, 0x2d, 0x00 |
.byte 0x1b, 0x2a, 0x2d, 0x00 |
.byte 0x24, 0x2a, 0x2d, 0x00 |
.byte 0x2d, 0x2a, 0x2d, 0x00 |
.byte 0x36, 0x2a, 0x2d, 0x00 |
.byte 0x3f, 0x2a, 0x2d, 0x00 |
.byte 0x00, 0x3f, 0x2d, 0x00 |
.byte 0x09, 0x3f, 0x2d, 0x00 |
.byte 0x12, 0x3f, 0x2d, 0x00 |
.byte 0x1b, 0x3f, 0x2d, 0x00 |
.byte 0x24, 0x3f, 0x2d, 0x00 |
.byte 0x2d, 0x3f, 0x2d, 0x00 |
.byte 0x36, 0x3f, 0x2d, 0x00 |
.byte 0x3f, 0x3f, 0x2d, 0x00 |
.byte 0x00, 0x00, 0x36, 0x00 |
.byte 0x09, 0x00, 0x36, 0x00 |
.byte 0x12, 0x00, 0x36, 0x00 |
.byte 0x1b, 0x00, 0x36, 0x00 |
.byte 0x24, 0x00, 0x36, 0x00 |
.byte 0x2d, 0x00, 0x36, 0x00 |
.byte 0x36, 0x00, 0x36, 0x00 |
.byte 0x3f, 0x00, 0x36, 0x00 |
.byte 0x00, 0x15, 0x36, 0x00 |
.byte 0x09, 0x15, 0x36, 0x00 |
.byte 0x12, 0x15, 0x36, 0x00 |
.byte 0x1b, 0x15, 0x36, 0x00 |
.byte 0x24, 0x15, 0x36, 0x00 |
.byte 0x2d, 0x15, 0x36, 0x00 |
.byte 0x36, 0x15, 0x36, 0x00 |
.byte 0x3f, 0x15, 0x36, 0x00 |
.byte 0x00, 0x2a, 0x36, 0x00 |
.byte 0x09, 0x2a, 0x36, 0x00 |
.byte 0x12, 0x2a, 0x36, 0x00 |
.byte 0x1b, 0x2a, 0x36, 0x00 |
.byte 0x24, 0x2a, 0x36, 0x00 |
.byte 0x2d, 0x2a, 0x36, 0x00 |
.byte 0x36, 0x2a, 0x36, 0x00 |
.byte 0x3f, 0x2a, 0x36, 0x00 |
.byte 0x00, 0x3f, 0x36, 0x00 |
.byte 0x09, 0x3f, 0x36, 0x00 |
.byte 0x12, 0x3f, 0x36, 0x00 |
.byte 0x1b, 0x3f, 0x36, 0x00 |
.byte 0x24, 0x3f, 0x36, 0x00 |
.byte 0x2d, 0x3f, 0x36, 0x00 |
.byte 0x36, 0x3f, 0x36, 0x00 |
.byte 0x3f, 0x3f, 0x36, 0x00 |
.byte 0x00, 0x00, 0x3f, 0x00 |
.byte 0x09, 0x00, 0x3f, 0x00 |
.byte 0x12, 0x00, 0x3f, 0x00 |
.byte 0x1b, 0x00, 0x3f, 0x00 |
.byte 0x24, 0x00, 0x3f, 0x00 |
.byte 0x2d, 0x00, 0x3f, 0x00 |
.byte 0x36, 0x00, 0x3f, 0x00 |
.byte 0x3f, 0x00, 0x3f, 0x00 |
.byte 0x00, 0x15, 0x3f, 0x00 |
.byte 0x09, 0x15, 0x3f, 0x00 |
.byte 0x12, 0x15, 0x3f, 0x00 |
.byte 0x1b, 0x15, 0x3f, 0x00 |
.byte 0x24, 0x15, 0x3f, 0x00 |
.byte 0x2d, 0x15, 0x3f, 0x00 |
.byte 0x36, 0x15, 0x3f, 0x00 |
.byte 0x3f, 0x15, 0x3f, 0x00 |
.byte 0x00, 0x2a, 0x3f, 0x00 |
.byte 0x09, 0x2a, 0x3f, 0x00 |
.byte 0x12, 0x2a, 0x3f, 0x00 |
.byte 0x1b, 0x2a, 0x3f, 0x00 |
.byte 0x24, 0x2a, 0x3f, 0x00 |
.byte 0x2d, 0x2a, 0x3f, 0x00 |
.byte 0x36, 0x2a, 0x3f, 0x00 |
.byte 0x3f, 0x2a, 0x3f, 0x00 |
.byte 0x00, 0x3f, 0x3f, 0x00 |
.byte 0x09, 0x3f, 0x3f, 0x00 |
.byte 0x12, 0x3f, 0x3f, 0x00 |
.byte 0x1b, 0x3f, 0x3f, 0x00 |
.byte 0x24, 0x3f, 0x3f, 0x00 |
.byte 0x2d, 0x3f, 0x3f, 0x00 |
.byte 0x36, 0x3f, 0x3f, 0x00 |
.byte 0x3f, 0x3f, 0x3f, 0x00 |
/branches/network/kernel/arch/ia32/src/boot/vesa_ret.inc |
---|
0,0 → 1,12 |
.code32 |
vesa_init_protected: |
movw $gdtselector(KDATA_DES), %cx |
movw %cx, %es |
movw %cx, %fs |
movw %cx, %gs |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
movl $START_STACK, %esp # initialize stack pointer |
jmpl $gdtselector(KTEXT_DES), $vesa_meeting_point |
/branches/network/kernel/arch/ia32/src/boot/boot.S |
---|
42,178 → 42,63 |
multiboot_header: |
.long MULTIBOOT_HEADER_MAGIC |
.long MULTIBOOT_HEADER_FLAGS |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum |
.long multiboot_header |
.long unmapped_ktext_start |
.long 0 |
.long 0 |
.long multiboot_image_start |
multiboot_image_start: |
cld |
movl $START_STACK, %esp # initialize stack pointer |
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register |
movw $selector(KDATA_DES), %cx |
movl $START_STACK, %esp # initialize stack pointer |
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register |
movw $gdtselector(KDATA_DES), %cx |
movw %cx, %es |
movw %cx, %fs |
movw %cx, %gs |
movw %cx, %ds # kernel data + stack |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
jmpl $selector(KTEXT_DES), $multiboot_meeting_point |
jmpl $gdtselector(KTEXT_DES), $multiboot_meeting_point |
multiboot_meeting_point: |
movl %eax, grub_eax # save parameters from GRUB |
movl %eax, grub_eax # save parameters from GRUB |
movl %ebx, grub_ebx |
xorl %eax, %eax |
cpuid |
cmp $0x0, %eax # any function > 0? |
xorl %eax, %eax |
cpuid |
cmp $0x0, %eax # any function > 0? |
jbe pse_unsupported |
movl $0x1, %eax # Basic function code 1 |
movl $0x1, %eax # basic function code 1 |
cpuid |
bt $3, %edx # Test if PSE is supported |
bt $3, %edx # test if PSE is supported |
jc pse_supported |
pse_unsupported: |
movl $pse_msg, %esi |
jmp error_halt |
pse_supported: |
#ifdef CONFIG_FB |
mov $vesa_init, %esi |
mov $VESA_INIT_SEGMENT << 4, %edi |
mov $e_vesa_init - vesa_init, %ecx |
rep movsb |
mov $VESA_INIT_SEGMENT << 4, %edi |
jmpl *%edi |
#include "vesa_prot.inc" |
# map kernel and turn paging on |
call map_kernel |
vesa_meeting_point: |
# call arch_pre_main(grub_eax, grub_ebx) |
pushl grub_ebx |
pushl grub_eax |
call arch_pre_main |
mov %esi, KA2PA(vesa_ph_addr) |
mov %di, KA2PA(vesa_height) |
shr $16, %edi |
mov %di, KA2PA(vesa_width) |
mov %bx, KA2PA(vesa_scanline) |
shr $16, %ebx |
mov %bx, KA2PA(vesa_bpp) |
#endif |
call main_bsp |
call map_kernel # map kernel and turn paging on |
movl grub_eax, %eax |
movl grub_ebx, %ebx |
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature |
je valid_boot |
xorl %ecx, %ecx # no memory map available |
movl %ecx, e820counter |
jmp invalid_boot |
valid_boot: |
movl (%ebx), %eax # ebx = physical address of struct multiboot_info |
bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid) |
jc mods_valid |
xorl %ecx, %ecx |
movl %ecx, init |
jmp mods_end |
mods_valid: |
movl 20(%ebx), %ecx # mbi->mods_count |
movl %ecx, init |
cmpl $0, %ecx |
je mods_end |
movl 24(%ebx), %esi # mbi->mods_addr |
movl $init, %edi |
mods_loop: |
movl 0(%esi), %edx # mods->mod_start |
addl $0x80000000, %edx |
movl %edx, 4(%edi) |
movl 4(%esi), %edx |
subl 0(%esi), %edx # mods->mod_end - mods->mod_start |
movl %edx, 8(%edi) |
addl $16, %esi |
addl $8 , %edi |
loop mods_loop |
mods_end: |
bt $6, %eax # mbi->flags[6] (mmap_length, mmap_addr valid) |
jc mmap_valid |
xorl %edx, %edx |
jmp mmap_invalid |
mmap_valid: |
movl 44(%ebx), %ecx # mbi->mmap_length |
movl 48(%ebx), %esi # mbi->mmap_addr |
movl $e820table, %edi |
xorl %edx, %edx |
mmap_loop: |
cmpl $0, %ecx |
jle mmap_end |
movl 4(%esi), %eax # mmap->base_addr_low |
movl %eax, (%edi) |
movl 8(%esi), %eax # mmap->base_addr_high |
movl %eax, 4(%edi) |
movl 12(%esi), %eax # mmap->length_low |
movl %eax, 8(%edi) |
movl 16(%esi), %eax # mmap->length_high |
movl %eax, 12(%edi) |
movl 20(%esi), %eax # mmap->type |
movl %eax, 16(%edi) |
movl (%esi), %eax # mmap->size |
addl $0x4, %eax |
addl %eax, %esi |
subl %eax, %ecx |
addl $MEMMAP_E820_RECORD_SIZE, %edi |
incl %edx |
jmp mmap_loop |
mmap_end: |
mmap_invalid: |
movl %edx, e820counter |
invalid_boot: |
#ifdef CONFIG_SMP |
# copy AP bootstrap routines below 1 MB |
movl $BOOT_OFFSET, %esi |
movl $AP_BOOT_OFFSET, %edi |
movl $_hardcoded_unmapped_size, %ecx |
rep movsb |
#endif |
call main_bsp # never returns |
# not reached |
cli |
hlt |
hlt0: |
hlt |
jmp hlt0 |
.global map_kernel |
map_kernel: |
222,8 → 107,8 |
# For simplicity, we map the entire 4G space. |
# |
movl %cr4, %ecx |
orl $(1 << 4), %ecx # turn PSE on |
andl $(~(1 << 5)), %ecx # turn PAE off |
orl $(1 << 4), %ecx # turn PSE on |
andl $(~(1 << 5)), %ecx # turn PAE off |
movl %ecx, %cr4 |
movl $(page_directory + 0), %esi |
230,30 → 115,31 |
movl $(page_directory + 2048), %edi |
xorl %ecx, %ecx |
xorl %ebx, %ebx |
0: |
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax |
orl %ebx, %eax |
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
addl $(4 * 1024 * 1024), %ebx |
incl %ecx |
cmpl $512, %ecx |
jl 0b |
floop: |
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax |
orl %ebx, %eax |
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
addl $(4 * 1024 * 1024), %ebx |
incl %ecx |
cmpl $512, %ecx |
jl floop |
movl %esi, %cr3 |
movl %cr0, %ebx |
orl $(1 << 31), %ebx # turn paging on |
orl $(1 << 31), %ebx # turn paging on |
movl %ebx, %cr0 |
ret |
# Print string from %esi to EGA display (in red) and halt |
error_halt: |
movl $0xb8000, %edi # base of EGA text mode memory |
movl $0xb8000, %edi # base of EGA text mode memory |
xorl %eax, %eax |
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address |
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address |
movb $0xe, %al |
outb %al, %dx |
261,7 → 147,7 |
inb %dx, %al |
shl $8, %ax |
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address |
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address |
movb $0xf, %al |
outb %al, %dx |
270,7 → 156,9 |
cmp $1920, %ax |
jbe cursor_ok |
movw $1920, %ax # sanity check for the cursor on the last line |
movw $1920, %ax # sanity check for the cursor on the last line |
cursor_ok: |
movw %ax, %bx |
277,7 → 165,7 |
shl $1, %eax |
addl %eax, %edi |
movw $0x0c00, %ax # black background, light red foreground |
movw $0x0c00, %ax # black background, light red foreground |
ploop: |
lodsb |
284,11 → 172,11 |
cmp $0, %al |
je ploop_end |
stosw |
inc %bx |
inc %bx |
jmp ploop |
ploop_end: |
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address |
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address |
movb $0xe, %al |
outb %al, %dx |
296,7 → 184,7 |
movb %bh, %al |
outb %al, %dx |
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address |
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address |
movb $0xf, %al |
outb %al, %dx |
303,240 → 191,14 |
movw $0x3d5, %dx |
movb %bl, %al |
outb %al, %dx |
cli |
hlt |
hlt1: |
hlt |
jmp hlt1 |
#ifdef CONFIG_FB |
vesa_init: |
jmp $selector(VESA_INIT_DES), $vesa_init_real - vesa_init |
.code16 |
vesa_init_real: |
mov %cr0, %eax |
and $~1, %eax |
mov %eax, %cr0 |
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init |
vesa_init_real2: |
mov $VESA_INIT_SEGMENT, %bx |
mov %bx, %es |
mov %bx, %fs |
mov %bx, %gs |
mov %bx, %ds |
mov %bx, %ss |
movl %esp, %eax |
movl $0x0000fffc, %esp |
movl $0x0000fffc, %ebp |
pushl %eax |
#define VESA_INFO_SIZE 1024 |
#include "vesa_real.inc" |
#define VESA_MODE_ATTRIBUTES_OFFSET 0 |
#define VESA_MODE_LIST_PTR_OFFSET 14 |
#define VESA_MODE_SCANLINE_OFFSET 16 |
#define VESA_MODE_WIDTH_OFFSET 18 |
#define VESA_MODE_HEIGHT_OFFSET 20 |
#define VESA_MODE_BPP_OFFSET 25 |
#define VESA_MODE_PHADDR_OFFSET 40 |
#define VESA_END_OF_MODES 0xffff |
#define VESA_OK 0x4f |
#define VESA_GET_INFO 0x4f00 |
#define VESA_GET_MODE_INFO 0x4f01 |
#define VESA_SET_MODE 0x4f02 |
#define VESA_SET_PALETTE 0x4f09 |
#if CONFIG_VESA_BPP == 24 |
#define CONFIG_VESA_BPP_VARIANT 32 |
#endif |
mov $VESA_GET_INFO, %ax |
mov $e_vesa_init - vesa_init, %di |
push %di |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz 0f |
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si |
mov %si, %gs |
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si |
add $VESA_INFO_SIZE, %di |
1:# Try next mode |
mov %gs:(%si), %cx |
cmp $VESA_END_OF_MODES, %cx |
jz 0f |
inc %si |
inc %si |
push %cx |
push %di |
push %si |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %si |
pop %di |
pop %cx |
cmp $VESA_OK, %al |
jnz 0f |
mov $CONFIG_VESA_WIDTH, %ax |
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax |
jnz 1b |
mov $CONFIG_VESA_HEIGHT, %ax |
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax |
jnz 1b |
mov $CONFIG_VESA_BPP, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
#ifdef CONFIG_VESA_BPP_VARIANT |
jz 2f |
mov $CONFIG_VESA_BPP_VARIANT, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
#endif |
jnz 1b |
2: |
mov %cx, %bx |
or $0xc000, %bx |
push %di |
mov $VESA_SET_MODE, %ax |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz 0f |
#if CONFIG_VESA_BPP == 8 |
# Set 3:2:3 VGA palette |
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax |
push %di |
mov $vga323 - vesa_init, %di |
mov $0x100, %ecx |
bt $5, %ax # Test if VGA compatible registers are present |
jnc vga_compat |
# Try VESA routine to set palette |
mov $VESA_SET_PALETTE, %ax |
xor %bl, %bl |
xor %dx, %dx |
int $0x10 |
jmp vga_not_compat |
vga_compat: |
# Try VGA registers to set palette |
movw $0x3c6, %dx # Set palette mask |
movb $0xff, %al |
outb %al, %dx |
movw $0x3c8, %dx # First index to set |
xor %al, %al |
outb %al, %dx |
movw $0x3c9, %dx # Data port |
vga_loop: |
movb %es:2(%di), %al |
outb %al, %dx |
movb %es:1(%di), %al |
outb %al, %dx |
movb %es:(%di), %al |
outb %al, %dx |
addw $4, %di |
loop vga_loop |
vga_not_compat: |
pop %di |
#endif |
mov VESA_MODE_PHADDR_OFFSET(%di), %esi |
mov VESA_MODE_WIDTH_OFFSET(%di), %ax |
shl $16, %eax |
mov VESA_MODE_HEIGHT_OFFSET(%di), %ax |
mov VESA_MODE_BPP_OFFSET(%di), %bl |
xor %bh, %bh |
shl $16, %ebx |
mov VESA_MODE_SCANLINE_OFFSET(%di), %bx |
mov %eax, %edi |
8: |
mov %cr0, %eax |
or $1, %eax |
mov %eax, %cr0 |
jmp 9f |
9: |
ljmpl $selector(KTEXT_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4) |
0:# No prefered mode found |
mov $0x111, %cx |
push %di |
push %cx |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %cx |
pop %di |
cmp $VESA_OK, %al |
jnz 1f |
jz 2b # Force relative jump |
1: |
mov $0x0003, %ax |
int $0x10 |
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA |
xor %ax, %ax |
jz 8b # Force relative jump |
vga323: |
#include "vga323.pal" |
.code32 |
vesa_init_protect: |
movw $selector(KDATA_DES), %cx |
movw %cx, %es |
movw %cx, %fs |
movw %cx, %gs |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
movl $START_STACK, %esp # initialize stack pointer |
jmpl $selector(KTEXT_DES), $vesa_meeting_point |
.align 4 |
e_vesa_init: |
#endif |
.section K_DATA_START, "aw", @progbits |
.align 4096 |
/branches/network/kernel/arch/ia32/src/boot/vesa_real.inc |
---|
0,0 → 1,373 |
#ifdef CONFIG_FB |
#include <macros.h> |
#define VESA_INFO_SIZE 1024 |
#define VESA_MODE_ATTRIBUTES_OFFSET 0 |
#define VESA_MODE_LIST_PTR_OFFSET 14 |
#define VESA_MODE_SCANLINE_OFFSET 16 |
#define VESA_MODE_WIDTH_OFFSET 18 |
#define VESA_MODE_HEIGHT_OFFSET 20 |
#define VESA_MODE_BPP_OFFSET 25 |
#define VESA_MODE_RED_MASK_OFFSET 31 |
#define VESA_MODE_RED_POS_OFFSET 32 |
#define VESA_MODE_GREEN_MASK_OFFSET 33 |
#define VESA_MODE_GREEN_POS_OFFSET 34 |
#define VESA_MODE_BLUE_MASK_OFFSET 35 |
#define VESA_MODE_BLUE_POS_OFFSET 36 |
#define VESA_MODE_PHADDR_OFFSET 40 |
#define VESA_END_OF_MODES 0xffff |
#define VESA_OK 0x4f |
#define VESA_GET_INFO 0x4f00 |
#define VESA_GET_MODE_INFO 0x4f01 |
#define VESA_SET_MODE 0x4f02 |
#define VESA_SET_PALETTE 0x4f09 |
.code32 |
vesa_init: |
jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init |
.code16 |
vesa_init_real: |
mov %cr0, %eax |
and $~1, %eax |
mov %eax, %cr0 |
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init |
vesa_init_real2: |
mov $VESA_INIT_SEGMENT, %bx |
mov %bx, %es |
mov %bx, %fs |
mov %bx, %gs |
mov %bx, %ds |
mov %bx, %ss |
movl %esp, %eax |
movl $0x0000fffc, %esp |
movl $0x0000fffc, %ebp |
pushl %eax |
# parse default mode string |
mov $default_mode - vesa_init, %di |
xor %eax, %eax |
xor %ebx, %ebx |
mov $8, %ecx |
parse_width: |
mov (%di), %al |
# check for digit |
cmp $'0', %al |
jb parse_width_done |
cmp $'9', %al |
ja parse_width_done |
sub $'0', %al |
# multiply default_width by 10 and add digit |
mov default_width - vesa_init, %bx |
lea (%ebx, %ebx, 4), %ebx |
shl $1, %ebx |
add %ax, %bx |
mov %bx, default_width - vesa_init |
inc %di |
loop parse_width |
parse_width_done: |
mov (%di), %al |
cmp $0, %al |
jz parse_done |
inc %di |
mov $8, %ecx |
parse_height: |
mov (%di), %al |
# check for digit |
cmp $'0', %al |
jb parse_height_done |
cmp $'9', %al |
ja parse_height_done |
sub $'0', %al |
# multiply default_height by 10 and add digit |
mov default_height - vesa_init, %bx |
lea (%ebx, %ebx, 4), %ebx |
shl $1, %ebx |
add %ax, %bx |
mov %bx, default_height - vesa_init |
inc %di |
loop parse_height |
parse_height_done: |
mov (%di), %al |
cmp $0, %al |
jz parse_done |
inc %di |
mov $4, %ecx |
parse_bpp: |
mov (%di), %al |
# check for digit |
cmp $'0', %al |
jb parse_bpp_done |
cmp $'9', %al |
ja parse_bpp_done |
sub $'0', %al |
# multiply default_bpp by 10 and add digit |
mov default_bpp - vesa_init, %bx |
lea (%ebx, %ebx, 4), %ebx |
shl $1, %ebx |
add %ax, %bx |
mov %bx, default_bpp - vesa_init |
inc %di |
loop parse_bpp |
parse_bpp_done: |
parse_done: |
mov $VESA_GET_INFO, %ax |
mov $e_vesa_init - vesa_init, %di |
push %di |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz no_mode |
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si |
mov %si, %gs |
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si |
add $VESA_INFO_SIZE, %di |
next_mode: |
# try next mode |
mov %gs:(%si), %cx |
cmp $VESA_END_OF_MODES, %cx |
je no_mode |
inc %si |
inc %si |
push %cx |
push %di |
push %si |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %si |
pop %di |
pop %cx |
cmp $VESA_OK, %al |
jne no_mode |
# check for proper attributes (supported, color, graphics, linear framebuffer) |
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax |
and $0x99, %ax |
cmp $0x99, %ax |
jne next_mode |
# check for proper resolution |
mov default_width - vesa_init, %ax |
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax |
jne next_mode |
mov default_height - vesa_init, %ax |
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax |
jne next_mode |
# check for proper bpp |
mov default_bpp - vesa_init, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
je set_mode |
mov $24, %al |
cmp default_bpp - vesa_init, %al |
jne next_mode |
# for 24 bpp modes accept also 32 bit bpp |
mov $32, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
jne next_mode |
set_mode: |
mov %cx, %bx |
or $0xc000, %bx |
push %di |
mov $VESA_SET_MODE, %ax |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz no_mode |
# set 3:2:3 VGA palette |
mov VESA_MODE_BPP_OFFSET(%di), %al |
cmp $8, %al |
jnz vga_not_set |
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax |
push %di |
mov $vga323 - vesa_init, %di |
mov $0x100, %ecx |
bt $5, %ax # test if VGA compatible registers are present |
jnc vga_compat |
# try VESA routine to set palette |
mov $VESA_SET_PALETTE, %ax |
xor %bl, %bl |
xor %dx, %dx |
int $0x10 |
cmp $0x00, %ah |
je vga_not_compat |
vga_compat: |
# try VGA registers to set palette |
movw $0x3c6, %dx # set palette mask |
movb $0xff, %al |
outb %al, %dx |
movw $0x3c8, %dx # first index to set |
xor %al, %al |
outb %al, %dx |
movw $0x3c9, %dx # data port |
vga_loop: |
movb %es:2(%di), %al |
outb %al, %dx |
movb %es:1(%di), %al |
outb %al, %dx |
movb %es:(%di), %al |
outb %al, %dx |
addw $4, %di |
loop vga_loop |
vga_not_compat: |
pop %di |
vga_not_set: |
# store mode parameters |
# eax = bpp[8] scanline[16] |
# ebx = width[16] height[16] |
# edx = red_mask[8] red_pos[8] green_mask[8] green_pos[8] |
# esi = blue_mask[8] blue_pos[8] |
# edi = linear frame buffer |
mov VESA_MODE_BPP_OFFSET(%di), %al |
xor %ah, %ah |
shl $16, %eax |
mov VESA_MODE_SCANLINE_OFFSET(%di), %ax |
mov VESA_MODE_WIDTH_OFFSET(%di), %bx |
shl $16, %ebx |
mov VESA_MODE_HEIGHT_OFFSET(%di), %bx |
mov VESA_MODE_BLUE_MASK_OFFSET(%di), %dl |
shl $8, %edx |
mov VESA_MODE_BLUE_POS_OFFSET(%di), %dl |
mov %edx, %esi |
mov VESA_MODE_RED_MASK_OFFSET(%di), %dl |
shl $8, %edx |
mov VESA_MODE_RED_POS_OFFSET(%di), %dl |
shl $8, %edx |
mov VESA_MODE_GREEN_MASK_OFFSET(%di), %dl |
shl $8, %edx |
mov VESA_MODE_GREEN_POS_OFFSET(%di), %dl |
mov VESA_MODE_PHADDR_OFFSET(%di), %edi |
vesa_leave_real: |
mov %cr0, %ecx |
or $1, %ecx |
mov %ecx, %cr0 |
jmp vesa_leave_real2 |
vesa_leave_real2: |
ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4) |
no_mode: |
# no prefered mode found |
mov $0x111, %cx |
push %di |
push %cx |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %cx |
pop %di |
cmp $VESA_OK, %al |
jnz text_mode |
jz set_mode # force relative jump |
text_mode: |
# reset to EGA text mode (because of problems with VESA) |
mov $0x0003, %ax |
int $0x10 |
mov $0xffffffff, %edi |
xor %ax, %ax |
jz vesa_leave_real # force relative jump |
vga323: |
#include "vga323.pal" |
default_width: |
.word 0 |
default_height: |
.word 0 |
default_bpp: |
.byte 0 |
default_mode: |
.ascii STRING(CONFIG_VESA_MODE) |
.ascii "-" |
.asciz STRING(CONFIG_VESA_BPP) |
.fill 24 |
#include "vesa_ret.inc" |
.align 4 |
e_vesa_init: |
#endif |
/branches/network/kernel/arch/ia32/src/boot/vesa_prot.inc |
---|
0,0 → 1,107 |
#ifdef CONFIG_FB |
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002 |
#define MBINFO_BIT_CMDLINE 2 |
#define MBINFO_OFFSET_CMDLINE 16 |
# copy real mode VESA initialization code |
mov $vesa_init, %esi |
mov $VESA_INIT_SEGMENT << 4, %edi |
mov $e_vesa_init - vesa_init, %ecx |
rep movsb |
# check for GRUB command line |
mov grub_eax, %eax |
cmp $MULTIBOOT_LOADER_MAGIC, %eax |
jne no_cmdline |
mov grub_ebx, %ebx |
mov (%ebx), %eax |
bt $MBINFO_BIT_CMDLINE, %eax |
jnc no_cmdline |
# skip the kernel path in command line |
mov MBINFO_OFFSET_CMDLINE(%ebx), %esi |
skip_loop: |
lodsb |
cmp $0, %al |
je no_cmdline |
cmp $' ', %al |
je skip_loop_done |
jmp skip_loop |
skip_loop_done: |
space_loop: |
mov (%esi), %al |
cmp $0, %al |
je no_cmdline |
cmp $' ', %al |
jne space_loop_done |
inc %esi |
jmp space_loop |
space_loop_done: |
# copy at most 23 characters from command line |
mov $VESA_INIT_SEGMENT << 4, %edi |
add $default_mode - vesa_init, %edi |
mov $23, %ecx |
cmd_loop: |
lodsb |
stosb |
cmp $0, %al |
je cmd_loop_done |
loop cmd_loop |
cmd_loop_done: |
# zero termination |
xor %eax, %eax |
stosb |
no_cmdline: |
# jump to the real mode |
mov $VESA_INIT_SEGMENT << 4, %edi |
jmpl *%edi |
vesa_meeting_point: |
# returned back to protected mode |
mov %ax, KA2PA(vesa_scanline) |
shr $16, %eax |
mov %ax, KA2PA(vesa_bpp) |
mov %bx, KA2PA(vesa_height) |
shr $16, %ebx |
mov %bx, KA2PA(vesa_width) |
mov %dl, KA2PA(vesa_green_pos) |
shr $8, %edx |
mov %dl, KA2PA(vesa_green_mask) |
shr $8, %edx |
mov %dl, KA2PA(vesa_red_pos) |
shr $8, %edx |
mov %dl, KA2PA(vesa_red_mask) |
mov %esi, %edx |
mov %dl, KA2PA(vesa_blue_pos) |
shr $8, %edx |
mov %dl, KA2PA(vesa_blue_mask) |
mov %edi, KA2PA(vesa_ph_addr) |
#endif |
/branches/network/kernel/arch/ia32/src/proc/scheduler.c |
---|
38,7 → 38,6 |
#include <proc/thread.h> |
#include <arch.h> |
#include <arch/context.h> /* SP_DELTA */ |
#include <arch/debugger.h> |
#include <arch/pm.h> |
#include <arch/asm.h> |
#include <arch/ddi/ddi.h> |
58,21 → 57,18 |
*/ |
void before_thread_runs_arch(void) |
{ |
CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
SP_DELTA]; |
CPU->arch.tss->ss0 = selector(KDATA_DES); |
/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */ |
write_msr(IA32_MSR_SYSENTER_ESP, kstk); |
/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */ |
CPU->arch.tss->esp0 = kstk; |
CPU->arch.tss->ss0 = gdtselector(KDATA_DES); |
/* Set up TLS in GS register */ |
set_tls_desc(THREAD->arch.tls); |
#ifdef CONFIG_DEBUG_AS_WATCHPOINT |
/* Set watchpoint on AS to ensure that nobody sets it to zero */ |
if (CPU->id < BKPOINTS_MAX) { |
the_t *the = THE; |
breakpoint_add(&((the_t *) the->thread->kstack)->as, |
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, the->cpu->id); |
} |
#endif |
} |
void after_thread_ran_arch(void) |
/branches/network/kernel/arch/ia32/src/mm/tlb.c |
---|
67,5 → 67,13 |
invlpg(page + i * PAGE_SIZE); |
} |
void tlb_arch_init(void) |
{ |
} |
void tlb_print(void) |
{ |
} |
/** @} |
*/ |
/branches/network/kernel/arch/ia32/src/mm/frame.c |
---|
54,26 → 54,57 |
static void init_e820_memory(pfn_t minconf) |
{ |
unsigned int i; |
pfn_t start, conf; |
size_t size; |
for (i = 0; i < e820counter; i++) { |
uint64_t base = e820table[i].base_address; |
uint64_t size = e820table[i].size; |
#ifdef __32_BITS__ |
/* Ignore physical memory above 4 GB */ |
if ((base >> 32) != 0) |
continue; |
/* Clip regions above 4 GB */ |
if (((base + size) >> 32) != 0) |
size = 0xffffffff - base; |
#endif |
pfn_t pfn; |
count_t count; |
if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { |
start = ADDR2PFN(ALIGN_UP(e820table[i].base_address, FRAME_SIZE)); |
size = SIZE2FRAMES(ALIGN_DOWN(e820table[i].size, FRAME_SIZE)); |
/* To be safe, make available zone possibly smaller */ |
pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)); |
if ((minconf < start) || (minconf >= start + size)) |
conf = start; |
pfn_t conf; |
if ((minconf < pfn) || (minconf >= pfn + count)) |
conf = pfn; |
else |
conf = minconf; |
zone_create(start, size, conf, 0); |
zone_create(pfn, count, conf, ZONE_AVAILABLE); |
if (last_frame < ALIGN_UP(e820table[i].base_address + |
e820table[i].size, FRAME_SIZE)) |
last_frame = |
ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE); |
} |
// XXX this has to be removed |
if (last_frame < ALIGN_UP(base + size, FRAME_SIZE)) |
last_frame = ALIGN_UP(base + size, FRAME_SIZE); |
} |
if (e820table[i].type == MEMMAP_MEMORY_RESERVED) { |
/* To be safe, make reserved zone possibly larger */ |
pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE)); |
zone_create(pfn, count, 0, ZONE_RESERVED); |
} |
if (e820table[i].type == MEMMAP_MEMORY_ACPI) { |
/* To be safe, make firmware zone possibly larger */ |
pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE)); |
zone_create(pfn, count, 0, ZONE_FIRMWARE); |
} |
} |
} |
113,16 → 144,14 |
if (config.cpu_active == 1) { |
minconf = 1; |
#ifdef CONFIG_SMP |
minconf = max(minconf, |
ADDR2PFN(AP_BOOT_OFFSET + hardcoded_unmapped_ktext_size + |
hardcoded_unmapped_kdata_size)); |
#endif |
#ifdef CONFIG_SIMICS_FIX |
minconf = max(minconf, ADDR2PFN(0x10000)); |
#endif |
init_e820_memory(minconf); |
/* Reserve frame 0 (BIOS data) */ |
frame_mark_unavailable(0, 1); |
131,12 → 160,7 |
frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH, |
(hardcoded_unmapped_ktext_size + |
hardcoded_unmapped_kdata_size) >> FRAME_WIDTH); |
#ifdef CONFIG_SIMICS_FIX |
/* Don't know why, but these addresses help */ |
frame_mark_unavailable(0xd000 >> FRAME_WIDTH, 3); |
#endif |
#endif |
} |
} |
/branches/network/kernel/arch/ia32/src/mm/page.c |
---|
53,7 → 53,7 |
{ |
uintptr_t cur; |
int flags; |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
66,12 → 66,12 |
flags |= PAGE_GLOBAL; |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
exc_register(14, "page_fault", (iroutine) page_fault); |
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); |
} else |
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); |
paging_on(); |
} |
79,7 → 79,7 |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%d bytes)", physaddr, size) |
panic("Unable to map physical memory %p (%d bytes).", physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
101,8 → 101,8 |
page = read_cr2(); |
if (istate->error_word & PFERR_CODE_RSVD) |
panic("Reserved bit set in page directory.\n"); |
panic("Reserved bit set in page directory."); |
if (istate->error_word & PFERR_CODE_RW) |
access = PF_ACCESS_WRITE; |
else |
109,11 → 109,11 |
access = PF_ACCESS_READ; |
if (as_page_fault(page, access, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault: %#x", page); |
fault_if_from_uspace(istate, "Page fault: %#x.", page); |
decode_istate(istate); |
printf("page fault address: %#lx\n", page); |
panic("page fault\n"); |
panic("Page fault."); |
} |
} |
/branches/network/kernel/arch/ia32/src/userspace.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
47,10 → 47,8 |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
ipl_t ipl = interrupts_disable(); |
asm volatile ( |
/* |
* Clear nested task flag. |
60,35 → 58,33 |
"and $0xffffbfff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
/* Set up GS register (TLS) */ |
"movl %6, %%gs\n" |
"pushl %0\n" |
"pushl %1\n" |
"pushl %2\n" |
"pushl %3\n" |
"pushl %4\n" |
"movl %5, %%eax\n" |
"movl %[tls_des], %%gs\n" |
"pushl %[udata_des]\n" |
"pushl %[stack_size]\n" |
"pushl %[ipl]\n" |
"pushl %[utext_des]\n" |
"pushl %[entry]\n" |
"movl %[uarg], %%eax\n" |
/* %ebx is defined to hold pcb_ptr - set it to 0 */ |
"xorl %%ebx, %%ebx\n" |
"xorl %%ebx, %%ebx\n" |
"iret\n" |
: |
: "i" (selector(UDATA_DES) | PL_USER), |
"r" ((uint8_t *) kernel_uarg->uspace_stack + |
THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (selector(UTEXT_DES) | PL_USER), |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg), |
"r" (selector(TLS_DES)) |
: |
: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER), |
[stack_size] "r" ((uint8_t *) kernel_uarg->uspace_stack + THREAD_STACK_SIZE), |
[ipl] "r" (ipl), |
[utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER), |
[entry] "r" (kernel_uarg->uspace_entry), |
[uarg] "r" (kernel_uarg->uspace_uarg), |
[tls_des] "r" (gdtselector(TLS_DES)) |
: "eax"); |
/* Unreachable */ |
for(;;) |
; |
while (1); |
} |
/** @} |
/branches/network/kernel/arch/ia32/src/interrupt.c |
---|
44,7 → 44,6 |
#include <mm/tlb.h> |
#include <mm/as.h> |
#include <arch.h> |
#include <symtab.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <synch/spinlock.h> |
52,6 → 51,7 |
#include <ipc/sysipc.h> |
#include <interrupt.h> |
#include <ddi/irq.h> |
#include <symtab.h> |
/* |
* Interrupt and exception dispatching. |
63,10 → 63,9 |
void decode_istate(istate_t *istate) |
{ |
char *symbol = get_symtab_entry(istate->eip); |
char *symbol; |
if (!symbol) |
symbol = ""; |
symbol = symtab_fmt_name_lookup(istate->eip); |
if (CPU) |
printf("----------------EXCEPTION OCCURED (cpu%u)----------------\n", CPU->id); |
77,9 → 76,6 |
printf("ERROR_WORD=%#lx\n", istate->error_word); |
printf("%%cs=%#lx,flags=%#lx\n", istate->cs, istate->eflags); |
printf("%%eax=%#lx, %%ecx=%#lx, %%edx=%#lx, %%esp=%p\n", istate->eax, istate->ecx, istate->edx, &istate->stack[0]); |
#ifdef CONFIG_DEBUG_ALLREGS |
printf("%%esi=%#lx, %%edi=%#lx, %%ebp=%#lx, %%ebx=%#lx\n", istate->esi, istate->edi, istate->ebp, istate->ebx); |
#endif |
printf("stack: %#lx, %#lx, %#lx, %#lx\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]); |
printf(" %#lx, %#lx, %#lx, %#lx\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]); |
} |
89,16 → 85,16 |
if (eoi_function) |
eoi_function(); |
else |
panic("no eoi_function\n"); |
panic("No eoi_function."); |
} |
static void null_interrupt(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "unserviced interrupt: %d", n); |
fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n); |
decode_istate(istate); |
panic("unserviced interrupt: %d\n", n); |
panic("Unserviced interrupt: %d.", n); |
} |
/** General Protection Fault. */ |
122,19 → 118,19 |
io_perm_bitmap_install(); |
return; |
} |
fault_if_from_uspace(istate, "general protection fault"); |
fault_if_from_uspace(istate, "General protection fault."); |
} |
decode_istate(istate); |
panic("general protection fault\n"); |
panic("General protection fault."); |
} |
static void ss_fault(int n __attribute__((unused)), istate_t *istate) |
{ |
fault_if_from_uspace(istate, "stack fault"); |
fault_if_from_uspace(istate, "Stack fault."); |
decode_istate(istate); |
panic("stack fault\n"); |
panic("Stack fault."); |
} |
static void simd_fp_exception(int n __attribute__((unused)), istate_t *istate) |
141,15 → 137,15 |
{ |
uint32_t mxcsr; |
asm ( |
"stmxcsr %0;\n" |
: "=m" (mxcsr) |
"stmxcsr %[mxcsr]\n" |
: [mxcsr] "=m" (mxcsr) |
); |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx", |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx.", |
(unative_t) mxcsr); |
decode_istate(istate); |
printf("MXCSR: %#lx\n", mxcsr); |
panic("SIMD FP exception(19)\n"); |
panic("SIMD FP exception(19)."); |
} |
static void nm_fault(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) |
157,8 → 153,8 |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "fpu fault"); |
panic("fpu fault"); |
fault_if_from_uspace(istate, "FPU fault."); |
panic("FPU fault."); |
#endif |
} |
191,7 → 187,7 |
trap_virtual_eoi(); |
ack = true; |
} |
irq->handler(irq, irq->arg); |
irq->handler(irq); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
233,7 → 229,7 |
if (enable_irqs_function) |
enable_irqs_function(irqmask); |
else |
panic("no enable_irqs_function\n"); |
panic("No enable_irqs_function."); |
} |
void trap_virtual_disable_irqs(uint16_t irqmask) |
241,7 → 237,7 |
if (disable_irqs_function) |
disable_irqs_function(irqmask); |
else |
panic("no disable_irqs_function\n"); |
panic("No disable_irqs_function."); |
} |
/** @} |
/branches/network/kernel/arch/ia32/src/drivers/ega.c |
---|
File deleted |
/branches/network/kernel/arch/ia32/src/drivers/vesa.c |
---|
56,12 → 56,20 |
uint16_t vesa_bpp; |
uint16_t vesa_scanline; |
uint8_t vesa_red_mask; |
uint8_t vesa_red_pos; |
uint8_t vesa_green_mask; |
uint8_t vesa_green_pos; |
uint8_t vesa_blue_mask; |
uint8_t vesa_blue_pos; |
int vesa_present(void) |
{ |
if (vesa_width != 0xffff) |
if ((vesa_width != 0xffff) && (vesa_height != 0xffff)) |
return true; |
if (vesa_height != 0xffff) |
return true; |
return false; |
} |
74,7 → 82,12 |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
visual = VISUAL_RGB_5_6_5; |
if ((vesa_red_mask == 5) && (vesa_red_pos == 10) |
&& (vesa_green_mask == 5) && (vesa_green_pos == 5) |
&& (vesa_blue_mask == 5) && (vesa_blue_pos == 0)) |
visual = VISUAL_RGB_5_5_5; |
else |
visual = VISUAL_RGB_5_6_5; |
break; |
case 24: |
visual = VISUAL_RGB_8_8_8; |
83,12 → 96,25 |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
panic("Unsupported bits per pixel"); |
panic("Unsupported bits per pixel."); |
} |
fb_init(vesa_ph_addr, vesa_width, vesa_height, vesa_scanline, visual); |
fb_properties_t vesa_props = { |
.addr = vesa_ph_addr, |
.offset = 0, |
.x = vesa_width, |
.y = vesa_height, |
.scan = vesa_scanline, |
.visual = visual, |
}; |
fb_init(&vesa_props); |
} |
void vesa_redraw(void) |
{ |
fb_redraw(); |
} |
#endif |
/** @} |
/branches/network/kernel/arch/ia32/src/drivers/i8259.c |
---|
49,28 → 49,28 |
void i8259_init(void) |
{ |
/* ICW1: this is ICW1, ICW4 to follow */ |
outb(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4); |
pio_write_8(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4); |
/* ICW2: IRQ 0 maps to INT IRQBASE */ |
outb(PIC_PIC0PORT2, IVT_IRQBASE); |
pio_write_8(PIC_PIC0PORT2, IVT_IRQBASE); |
/* ICW3: pic1 using IRQ IRQ_PIC1 */ |
outb(PIC_PIC0PORT2, 1 << IRQ_PIC1); |
pio_write_8(PIC_PIC0PORT2, 1 << IRQ_PIC1); |
/* ICW4: i8086 mode */ |
outb(PIC_PIC0PORT2, 1); |
pio_write_8(PIC_PIC0PORT2, 1); |
/* ICW1: ICW1, ICW4 to follow */ |
outb(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4); |
pio_write_8(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4); |
/* ICW2: IRQ 8 maps to INT (IVT_IRQBASE + 8) */ |
outb(PIC_PIC1PORT2, IVT_IRQBASE + 8); |
pio_write_8(PIC_PIC1PORT2, IVT_IRQBASE + 8); |
/* ICW3: pic1 is known as IRQ_PIC1 */ |
outb(PIC_PIC1PORT2, IRQ_PIC1); |
pio_write_8(PIC_PIC1PORT2, IRQ_PIC1); |
/* ICW4: i8086 mode */ |
outb(PIC_PIC1PORT2, 1); |
pio_write_8(PIC_PIC1PORT2, 1); |
/* |
* Register interrupt handler for the PIC spurious interrupt. |
94,12 → 94,12 |
uint8_t x; |
if (irqmask & 0xff) { |
x = inb(PIC_PIC0PORT2); |
outb(PIC_PIC0PORT2, (uint8_t) (x & (~(irqmask & 0xff)))); |
x = pio_read_8(PIC_PIC0PORT2); |
pio_write_8(PIC_PIC0PORT2, (uint8_t) (x & (~(irqmask & 0xff)))); |
} |
if (irqmask >> 8) { |
x = inb(PIC_PIC1PORT2); |
outb(PIC_PIC1PORT2, (uint8_t) (x & (~(irqmask >> 8)))); |
x = pio_read_8(PIC_PIC1PORT2); |
pio_write_8(PIC_PIC1PORT2, (uint8_t) (x & (~(irqmask >> 8)))); |
} |
} |
108,19 → 108,19 |
uint8_t x; |
if (irqmask & 0xff) { |
x = inb(PIC_PIC0PORT2); |
outb(PIC_PIC0PORT2, (uint8_t) (x | (irqmask & 0xff))); |
x = pio_read_8(PIC_PIC0PORT2); |
pio_write_8(PIC_PIC0PORT2, (uint8_t) (x | (irqmask & 0xff))); |
} |
if (irqmask >> 8) { |
x = inb(PIC_PIC1PORT2); |
outb(PIC_PIC1PORT2, (uint8_t) (x | (irqmask >> 8))); |
x = pio_read_8(PIC_PIC1PORT2); |
pio_write_8(PIC_PIC1PORT2, (uint8_t) (x | (irqmask >> 8))); |
} |
} |
void pic_eoi(void) |
{ |
outb(0x20, 0x20); |
outb(0xa0, 0x20); |
pio_write_8((ioport8_t *)0x20, 0x20); |
pio_write_8((ioport8_t *)0xa0, 0x20); |
} |
void pic_spurious(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) |
/branches/network/kernel/arch/ia32/src/drivers/i8254.c |
---|
26,12 → 26,12 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** |
* @file |
* @brief i8254 chip driver. |
* @brief i8254 chip driver. |
* |
* Low level time functions. |
*/ |
53,8 → 53,8 |
#include <ddi/irq.h> |
#include <ddi/device.h> |
#define CLK_PORT1 0x40 |
#define CLK_PORT4 0x43 |
#define CLK_PORT1 ((ioport8_t *)0x40) |
#define CLK_PORT4 ((ioport8_t *)0x43) |
#define CLK_CONST 1193180 |
#define MAGIC_NUMBER 1194 |
61,12 → 61,12 |
static irq_t i8254_irq; |
static irq_ownership_t i8254_claim(void) |
static irq_ownership_t i8254_claim(irq_t *irq) |
{ |
return IRQ_ACCEPT; |
} |
static void i8254_irq_handler(irq_t *irq, void *arg __attribute__((unused)), ...) |
static void i8254_irq_handler(irq_t *irq) |
{ |
/* |
* This IRQ is responsible for kernel preemption. |
94,10 → 94,10 |
void i8254_normal_operation(void) |
{ |
outb(CLK_PORT4, 0x36); |
pio_write_8(CLK_PORT4, 0x36); |
pic_disable_irqs(1 << IRQ_CLK); |
outb(CLK_PORT1, (CLK_CONST / HZ) & 0xf); |
outb(CLK_PORT1, (CLK_CONST / HZ) >> 8); |
pio_write_8(CLK_PORT1, (CLK_CONST / HZ) & 0xf); |
pio_write_8(CLK_PORT1, (CLK_CONST / HZ) >> 8); |
pic_enable_irqs(1 << IRQ_CLK); |
} |
114,36 → 114,36 |
* One-shot timer. Count-down from 0xffff at 1193180Hz |
* MAGIC_NUMBER is the magic value for 1ms. |
*/ |
outb(CLK_PORT4, 0x30); |
outb(CLK_PORT1, 0xff); |
outb(CLK_PORT1, 0xff); |
pio_write_8(CLK_PORT4, 0x30); |
pio_write_8(CLK_PORT1, 0xff); |
pio_write_8(CLK_PORT1, 0xff); |
do { |
/* will read both status and count */ |
outb(CLK_PORT4, 0xc2); |
not_ok = (uint8_t) ((inb(CLK_PORT1) >> 6) & 1); |
t1 = inb(CLK_PORT1); |
t1 |= inb(CLK_PORT1) << 8; |
pio_write_8(CLK_PORT4, 0xc2); |
not_ok = (uint8_t) ((pio_read_8(CLK_PORT1) >> 6) & 1); |
t1 = pio_read_8(CLK_PORT1); |
t1 |= pio_read_8(CLK_PORT1) << 8; |
} while (not_ok); |
asm_delay_loop(LOOPS); |
outb(CLK_PORT4, 0xd2); |
t2 = inb(CLK_PORT1); |
t2 |= inb(CLK_PORT1) << 8; |
pio_write_8(CLK_PORT4, 0xd2); |
t2 = pio_read_8(CLK_PORT1); |
t2 |= pio_read_8(CLK_PORT1) << 8; |
/* |
* We want to determine the overhead of the calibrating mechanism. |
*/ |
outb(CLK_PORT4, 0xd2); |
o1 = inb(CLK_PORT1); |
o1 |= inb(CLK_PORT1) << 8; |
pio_write_8(CLK_PORT4, 0xd2); |
o1 = pio_read_8(CLK_PORT1); |
o1 |= pio_read_8(CLK_PORT1) << 8; |
asm_fake_loop(LOOPS); |
outb(CLK_PORT4, 0xd2); |
o2 = inb(CLK_PORT1); |
o2 |= inb(CLK_PORT1) << 8; |
pio_write_8(CLK_PORT4, 0xd2); |
o2 = pio_read_8(CLK_PORT1); |
o2 |= pio_read_8(CLK_PORT1) << 8; |
CPU->delay_loop_const = |
((MAGIC_NUMBER * LOOPS) / 1000) / ((t1 - t2) - (o1 - o2)) + |